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  }