diff --git a/server/repository/repository.go b/server/repository/repository.go index fe28d97b5c278..c4a7e9a6698d3 100644 --- a/server/repository/repository.go +++ b/server/repository/repository.go @@ -142,11 +142,11 @@ func (s *Server) Delete(ctx context.Context, q *RepoQuery) (*RepoResponse, error // repoURLToSecretName hashes repo URL to the secret name using a formula. // Part of the original repo name is incorporated for debugging purposes func repoURLToSecretName(repo string) string { - repo = git.NormalizeGitURL(repo) + repo = strings.ToLower(git.NormalizeGitURL(repo)) h := fnv.New32a() _, _ = h.Write([]byte(repo)) parts := strings.Split(strings.TrimSuffix(repo, ".git"), "/") - return fmt.Sprintf("repo-%s-%v", strings.ToLower(parts[len(parts)-1]), h.Sum32()) + return fmt.Sprintf("repo-%s-%v", parts[len(parts)-1], h.Sum32()) } // repoToStringData converts a repository object to string data for serialization to a secret diff --git a/server/repository/repository_test.go b/server/repository/repository_test.go index 19a80babde276..f107a3ad4827d 100644 --- a/server/repository/repository_test.go +++ b/server/repository/repository_test.go @@ -4,10 +4,11 @@ import "testing" func TestRepoURLToSecretName(t *testing.T) { tables := map[string]string{ - "git://git@github.com:argoproj/ARGO-cd.git": "repo-argo-cd-83273445", - "https://github.com/argoproj/ARGO-cd": "repo-argo-cd-1890113693", - "https://github.com/argoproj/argo-cd": "repo-argo-cd-42374749", - "ssh://git@github.com/argoproj/argo-cd.git": "repo-argo-cd-3569564120", + "git://git@github.com:argoproj/ARGO-cd.git": "repo-argo-cd-593837413", + "https://github.com/argoproj/ARGO-cd": "repo-argo-cd-821842295", + "https://github.com/argoproj/argo-cd": "repo-argo-cd-821842295", + "https://github.com/argoproj/argo-cd.git": "repo-argo-cd-821842295", + "ssh://git@github.com/argoproj/argo-cd.git": "repo-argo-cd-1019298066", } for k, v := range tables { diff --git a/util/git/git.go b/util/git/git.go index 0f3e365cf5c6d..e092772110f4c 100644 --- a/util/git/git.go +++ b/util/git/git.go @@ -10,18 +10,45 @@ import ( "strings" ) +// EnsurePrefix idempotently ensures that a base string has a given prefix. +func ensurePrefix(s, prefix string) string { + if !strings.HasPrefix(s, prefix) { + s = prefix + s + } + return s +} + +// EnsureSuffix idempotently ensures that a base string has a given suffix. +func ensureSuffix(s, suffix string) string { + if !strings.HasSuffix(s, suffix) { + s += suffix + } + return s +} + // NormalizeGitURL normalizes a git URL for lookup and storage func NormalizeGitURL(repo string) string { + // preprocess + repo = ensureSuffix(repo, ".git") + if IsSshURL(repo) { + repo = ensurePrefix(repo, "ssh://") + } + + // process repoURL, err := url.Parse(repo) if err != nil { - return strings.ToLower(repo) + return "" } - return repoURL.String() + + // postprocess + repoURL.Host = strings.ToLower(repoURL.Host) + normalized := repoURL.String() + return strings.TrimPrefix(normalized, "ssh://") } -// IsSshURL returns true is supplied URL is SSH URL +// IsSshURL returns true if supplied URL is SSH URL func IsSshURL(url string) bool { - return strings.Index(url, "git@") == 0 + return strings.HasPrefix(url, "git@") || strings.HasPrefix(url, "ssh://") } // GetGitCommandOptions returns URL and env options for git operation diff --git a/util/git/git_test.go b/util/git/git_test.go index bc68fdca1ac07..2c5a6da541050 100644 --- a/util/git/git_test.go +++ b/util/git/git_test.go @@ -6,14 +6,74 @@ import ( "github.com/stretchr/testify/assert" ) -func TestReturnsTrueForSSHUrl(t *testing.T) { - assert.True(t, IsSshURL("git@github.com:test.git")) +func TestEnsurePrefix(t *testing.T) { + data := [][]string{ + {"world", "hello", "helloworld"}, + {"helloworld", "hello", "helloworld"}, + {"example.com", "https://", "https://example.com"}, + {"https://example.com", "https://", "https://example.com"}, + {"cd", "argo", "argocd"}, + {"argocd", "argo", "argocd"}, + {"", "argocd", "argocd"}, + {"argocd", "", "argocd"}, + } + for _, table := range data { + result := ensurePrefix(table[0], table[1]) + assert.Equal(t, table[2], result) + } } -func TestReturnsFalseForNonSSHUrl(t *testing.T) { - assert.False(t, IsSshURL("https://github.com/test.git")) +func TestEnsureSuffix(t *testing.T) { + data := [][]string{ + {"hello", "world", "helloworld"}, + {"helloworld", "world", "helloworld"}, + {"repo", ".git", "repo.git"}, + {"repo.git", ".git", "repo.git"}, + {"", "repo.git", "repo.git"}, + {"argo", "cd", "argocd"}, + {"argocd", "cd", "argocd"}, + {"argocd", "", "argocd"}, + {"", "argocd", "argocd"}, + } + for _, table := range data { + result := ensureSuffix(table[0], table[1]) + assert.Equal(t, table[2], result) + } +} + +func TestIsSSHUrl(t *testing.T) { + data := map[string]bool{ + "git://github.com/argoproj/test.git": false, + "git@GITHUB.com:argoproj/test.git": true, + "git@github.com:test": true, + "git@github.com:test.git": true, + "https://github.com/argoproj/test": false, + "https://github.com/argoproj/test.git": false, + "ssh://git@GITHUB.com:argoproj/test": true, + "ssh://git@GITHUB.com:argoproj/test.git": true, + "ssh://git@github.com:test.git": true, + } + for k, v := range data { + assert.Equal(t, v, IsSshURL(k)) + } } func TestNormalizeUrl(t *testing.T) { - assert.Equal(t, NormalizeGitURL("git@GITHUB.com:test.git"), "git@github.com:test.git") + data := map[string]string{ + "git@GITHUB.com:argoproj/test": "git@github.com:argoproj/test.git", + "git@GITHUB.com:argoproj/test.git": "git@github.com:argoproj/test.git", + "git@GITHUB.com:test": "git@github.com:test.git", + "git@GITHUB.com:test.git": "git@github.com:test.git", + "https://GITHUB.com/argoproj/test": "https://github.com/argoproj/test.git", + "https://GITHUB.com/argoproj/test.git": "https://github.com/argoproj/test.git", + "https://github.com/TEST": "https://github.com/TEST.git", + "https://github.com/TEST.git": "https://github.com/TEST.git", + "ssh://git@GITHUB.com:argoproj/test": "git@github.com:argoproj/test.git", + "ssh://git@GITHUB.com:argoproj/test.git": "git@github.com:argoproj/test.git", + "ssh://git@GITHUB.com:test.git": "git@github.com:test.git", + "ssh://git@github.com:test": "git@github.com:test.git", + } + for k, v := range data { + assert.Equal(t, v, NormalizeGitURL(k)) + } }