github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/internal/packager/git/pull.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // SPDX-FileCopyrightText: 2021-Present The Jackal Authors
     3  
     4  // Package git contains functions for interacting with git repositories.
     5  package git
     6  
     7  import (
     8  	"fmt"
     9  	"path"
    10  	"strings"
    11  
    12  	"github.com/Racer159/jackal/src/config"
    13  	"github.com/Racer159/jackal/src/pkg/transform"
    14  	"github.com/Racer159/jackal/src/pkg/utils"
    15  	"github.com/go-git/go-git/v5/plumbing"
    16  )
    17  
    18  // DownloadRepoToTemp clones or updates a repo into a temp folder to perform ephemeral actions (i.e. process chart repos).
    19  func (g *Git) DownloadRepoToTemp(gitURL string) error {
    20  	g.Spinner.Updatef("g.DownloadRepoToTemp(%s)", gitURL)
    21  
    22  	path, err := utils.MakeTempDir(config.CommonOptions.TempDirectory)
    23  	if err != nil {
    24  		return fmt.Errorf("unable to create tmpdir: %w", err)
    25  	}
    26  
    27  	// If downloading to temp, set this as a shallow clone to only pull the exact
    28  	// gitURL w/ ref that was specified since we will throw away git history anyway
    29  	if err = g.Pull(gitURL, path, true); err != nil {
    30  		return fmt.Errorf("unable to pull the git repo at %s: %w", gitURL, err)
    31  	}
    32  
    33  	return nil
    34  }
    35  
    36  // Pull clones or updates a git repository into the target folder.
    37  func (g *Git) Pull(gitURL, targetFolder string, shallow bool) error {
    38  	g.Spinner.Updatef("Processing git repo %s", gitURL)
    39  
    40  	// Split the remote url and the jackal reference
    41  	gitURLNoRef, refPlain, err := transform.GitURLSplitRef(gitURL)
    42  	if err != nil {
    43  		return err
    44  	}
    45  
    46  	var ref plumbing.ReferenceName
    47  
    48  	// Parse the ref from the git URL.
    49  	if refPlain != emptyRef {
    50  		ref = ParseRef(refPlain)
    51  	}
    52  
    53  	// Construct a path unique to this git repo
    54  	repoFolder, err := transform.GitURLtoFolderName(gitURL)
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	g.GitPath = path.Join(targetFolder, repoFolder)
    60  
    61  	// Clone the git repository.
    62  	err = g.clone(gitURLNoRef, ref, shallow)
    63  	if err != nil {
    64  		return fmt.Errorf("not a valid git repo or unable to clone (%s): %w", gitURL, err)
    65  	}
    66  
    67  	if ref != emptyRef && !ref.IsBranch() {
    68  		// Remove the "refs/tags/" prefix from the ref.
    69  		stripped := strings.TrimPrefix(refPlain, "refs/tags/")
    70  
    71  		// Use the plain ref as part of the branch name so it is unique and doesn't conflict with other refs.
    72  		alias := fmt.Sprintf("jackal-ref-%s", stripped)
    73  		trunkBranchName := plumbing.NewBranchReferenceName(alias)
    74  
    75  		// Checkout the ref as a branch.
    76  		return g.checkoutRefAsBranch(stripped, trunkBranchName)
    77  	}
    78  
    79  	return nil
    80  }