github.com/argoproj/argo-cd@v1.8.7/util/git/git.go (about) 1 package git 2 3 import ( 4 "net/url" 5 "regexp" 6 "strings" 7 ) 8 9 // EnsurePrefix idempotently ensures that a base string has a given prefix. 10 func ensurePrefix(s, prefix string) string { 11 if !strings.HasPrefix(s, prefix) { 12 s = prefix + s 13 } 14 return s 15 } 16 17 // removeSuffix idempotently removes a given suffix 18 func removeSuffix(s, suffix string) string { 19 if strings.HasSuffix(s, suffix) { 20 return s[0 : len(s)-len(suffix)] 21 } 22 return s 23 } 24 25 var ( 26 commitSHARegex = regexp.MustCompile("^[0-9A-Fa-f]{40}$") 27 sshURLRegex = regexp.MustCompile("^(ssh://)?([^/:]*?)@[^@]+$") 28 httpsURLRegex = regexp.MustCompile("^(https://).*") 29 ) 30 31 // IsCommitSHA returns whether or not a string is a 40 character SHA-1 32 func IsCommitSHA(sha string) bool { 33 return commitSHARegex.MatchString(sha) 34 } 35 36 var truncatedCommitSHARegex = regexp.MustCompile("^[0-9A-Fa-f]{7,}$") 37 38 // IsTruncatedCommitSHA returns whether or not a string is a truncated SHA-1 39 func IsTruncatedCommitSHA(sha string) bool { 40 return truncatedCommitSHARegex.MatchString(sha) 41 } 42 43 // SameURL returns whether or not the two repository URLs are equivalent in location 44 func SameURL(leftRepo, rightRepo string) bool { 45 normalLeft := NormalizeGitURL(leftRepo) 46 normalRight := NormalizeGitURL(rightRepo) 47 return normalLeft != "" && normalRight != "" && normalLeft == normalRight 48 } 49 50 // NormalizeGitURL normalizes a git URL for purposes of comparison, as well as preventing redundant 51 // local clones (by normalizing various forms of a URL to a consistent location). 52 // Prefer using SameURL() over this function when possible. This algorithm may change over time 53 // and should not be considered stable from release to release 54 func NormalizeGitURL(repo string) string { 55 repo = strings.ToLower(strings.TrimSpace(repo)) 56 if yes, _ := IsSSHURL(repo); yes { 57 if !strings.HasPrefix(repo, "ssh://") { 58 // We need to replace the first colon in git@server... style SSH URLs with a slash, otherwise 59 // net/url.Parse will interpret it incorrectly as the port. 60 repo = strings.Replace(repo, ":", "/", 1) 61 repo = ensurePrefix(repo, "ssh://") 62 } 63 } 64 repo = removeSuffix(repo, ".git") 65 repoURL, err := url.Parse(repo) 66 if err != nil { 67 return "" 68 } 69 normalized := repoURL.String() 70 return strings.TrimPrefix(normalized, "ssh://") 71 } 72 73 // IsSSHURL returns true if supplied URL is SSH URL 74 func IsSSHURL(url string) (bool, string) { 75 matches := sshURLRegex.FindStringSubmatch(url) 76 if len(matches) > 2 { 77 return true, matches[2] 78 } 79 return false, "" 80 } 81 82 // IsHTTPSURL returns true if supplied URL is HTTPS URL 83 func IsHTTPSURL(url string) bool { 84 return httpsURLRegex.MatchString(url) 85 } 86 87 // TestRepo tests if a repo exists and is accessible with the given credentials 88 func TestRepo(repo string, creds Creds, insecure bool, enableLfs bool) error { 89 clnt, err := NewClient(repo, creds, insecure, enableLfs) 90 if err != nil { 91 return err 92 } 93 _, err = clnt.LsRemote("HEAD") 94 return err 95 }