github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/internal/util/git/git.go (about) 1 // Copyright 2019 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package git contains git repo cloning functions similar to Kustomize's 16 package git 17 18 import ( 19 "fmt" 20 "os" 21 "os/exec" 22 "path" 23 "path/filepath" 24 "strings" 25 26 "github.com/GoogleContainerTools/kpt/internal/errors" 27 ) 28 29 // RepoSpec specifies a git repository and a branch and path therein. 30 type RepoSpec struct { 31 // Host, e.g. github.com 32 Host string 33 34 // orgRepo name (organization/repoName), 35 // e.g. kubernetes-sigs/kustomize 36 OrgRepo string 37 38 // Dir where the orgRepo is cloned to. 39 Dir string 40 41 // Commit is the commit for the version that was added to Dir. 42 Commit string 43 44 // Relative path in the repository, and in the cloneDir, 45 // to a Kustomization. 46 Path string 47 48 // Branch or tag reference. 49 Ref string 50 51 // e.g. .git or empty in case of _git is present 52 GitSuffix string 53 } 54 55 // AbsPath is the absolute path to the subdirectory 56 func (rs RepoSpec) AbsPath() string { 57 return filepath.Join(rs.Dir, rs.Path) 58 } 59 60 // CloneSpec returns the string to pass to git to clone 61 func (rs *RepoSpec) CloneSpec() string { 62 if isAzureHost(rs.Host) || isAWSHost(rs.Host) { 63 return rs.Host + rs.OrgRepo 64 } 65 return rs.Host + rs.OrgRepo + rs.GitSuffix 66 } 67 68 // isAzureHost returns true if the repo is an Azure repo 69 // The format of Azure repo URL is documented 70 // https://docs.microsoft.com/en-us/azure/devops/repos/git/clone?view=vsts&tabs=visual-studio#clone_url 71 func isAzureHost(host string) bool { 72 return strings.Contains(host, "dev.azure.com") || 73 strings.Contains(host, "visualstudio.com") 74 } 75 76 // isAWSHost returns true if the repo is an AWS repo 77 // The format of AWS repo URL is documented 78 // https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html 79 func isAWSHost(host string) bool { 80 return strings.Contains(host, "amazonaws.com") 81 } 82 83 // lookupCommit looks up the sha of the current commit on the repo at the 84 // provided path. 85 func LookupCommit(repoPath string) (string, error) { 86 const op errors.Op = "git.LookupCommit" 87 cmd := exec.Command("git", "rev-parse", "--verify", "HEAD") 88 cmd.Dir = repoPath 89 cmd.Env = os.Environ() 90 cmd.Stderr = os.Stderr 91 b, err := cmd.Output() 92 if err != nil { 93 return "", errors.E(op, errors.Git, fmt.Errorf("unable to look up commit: %w", err)) 94 } 95 commit := strings.TrimSpace(string(b)) 96 return commit, nil 97 } 98 99 func (rs *RepoSpec) RepoRef() string { 100 repoPath := path.Join(rs.CloneSpec(), rs.Path) 101 if rs.Ref != "" { 102 return repoPath + fmt.Sprintf("@%s", rs.Ref) 103 } 104 return repoPath 105 }