From ec5afaf77693641d32d1a44b67050a7da2b2e551 Mon Sep 17 00:00:00 2001 From: Matthias Bertschy Date: Tue, 5 Mar 2024 17:22:29 +0100 Subject: [PATCH] add support for self-hosted gitlab Signed-off-by: Matthias Bertschy --- gitlabparser/v1/parser.go | 9 +- gitlabparser/v1/parser_test.go | 259 +++++++++++++++++++-------------- 2 files changed, 152 insertions(+), 116 deletions(-) diff --git a/gitlabparser/v1/parser.go b/gitlabparser/v1/parser.go index d423ca5..2b14990 100644 --- a/gitlabparser/v1/parser.go +++ b/gitlabparser/v1/parser.go @@ -11,14 +11,11 @@ import ( "github.com/kubescape/go-git-url/apis/gitlabapi" ) -const HOST = "gitlab.com" - // NewGitHubParser empty instance of a github parser func NewGitLabParser() *GitLabURL { return &GitLabURL{ gitLabAPI: gitlabapi.NewGitLabAPI(), - host: HOST, token: os.Getenv("GITLAB_TOKEN"), } } @@ -42,7 +39,7 @@ func (gl *GitLabURL) GetURL() *url.URL { } } -func IsHostGitLab(host string) bool { return strings.HasSuffix(host, HOST) } +func IsHostGitLab(host string) bool { return strings.Contains(host, "gitlab") } func (gl *GitLabURL) GetProvider() string { return apis.ProviderGitLab.String() } func (gl *GitLabURL) GetHostName() string { return gl.host } @@ -53,7 +50,7 @@ func (gl *GitLabURL) GetRepoName() string { return gl.repo } func (gl *GitLabURL) GetPath() string { return gl.path } func (gl *GitLabURL) GetToken() string { return gl.token } func (gl *GitLabURL) GetHttpCloneURL() string { - return fmt.Sprintf("https://gitlab.com/%s/%s.git", gl.GetOwnerName(), gl.GetRepoName()) + return fmt.Sprintf("https://%s/%s/%s.git", gl.host, gl.owner, gl.repo) } func (gl *GitLabURL) SetOwnerName(o string) { gl.owner = o } @@ -70,6 +67,8 @@ func (gl *GitLabURL) Parse(fullURL string) error { return err } + gl.host = parsedURL.Host + index := 0 splittedRepo := strings.FieldsFunc(parsedURL.Path, func(c rune) bool { return c == '/' }) // trim empty fields from returned slice diff --git a/gitlabparser/v1/parser_test.go b/gitlabparser/v1/parser_test.go index becd5cb..d5e2e55 100644 --- a/gitlabparser/v1/parser_test.go +++ b/gitlabparser/v1/parser_test.go @@ -1,125 +1,162 @@ package v1 import ( + "fmt" "testing" "github.com/stretchr/testify/assert" ) -var ( - urlA = "https://gitlab.com/kubescape/testing" // general case - urlB = "https://gitlab.com/kubescape/testing/-/blob/main/stable/acs-engine-autoscaler/Chart.yaml" // file - urlC = "https://gitlab.com/kubescape/testing/-/blob/dev/README.md" // branch - urlD = "https://gitlab.com/kubescape/testing/-/tree/dev" // branch - urlE = "https://gitlab.com/kubescape/testing/-/blob/v0.0.0/README.md" // tag - urlF = "https://gitlab.com/kubescape/testing/-/raw/main/stable/acs-engine-autoscaler/Chart.yaml" - // scp-like syntax supported by git for ssh - // see: https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-clone.html#URLS - // regular form - urlG = "git@gitlab.com:owner/repo.git" - // project and subproject - urlH = "https://gitlab.com/matthyx1/subgroup1/project1.git" - urlI = "https://gitlab.com/matthyx1/subgroup1/subsubgroup1/project1.git" -) - func TestNewGitHubParserWithURL(t *testing.T) { - { - gl, err := NewGitLabParserWithURL(urlA) - assert.NoError(t, err) - assert.Equal(t, "gitlab.com", gl.GetHostName()) - assert.Equal(t, "gitlab", gl.GetProvider()) - assert.Equal(t, "kubescape", gl.GetOwnerName()) - assert.Equal(t, "testing", gl.GetRepoName()) - assert.Equal(t, urlA, gl.GetURL().String()) - assert.Equal(t, "", gl.GetBranchName()) - assert.Equal(t, "", gl.GetPath()) - } - { - gl, err := NewGitLabParserWithURL(urlB) - assert.NoError(t, err) - assert.Equal(t, "gitlab.com", gl.GetHostName()) - assert.Equal(t, "gitlab", gl.GetProvider()) - assert.Equal(t, "kubescape", gl.GetOwnerName()) - assert.Equal(t, "testing", gl.GetRepoName()) - assert.Equal(t, urlA, gl.GetURL().String()) - assert.Equal(t, "main", gl.GetBranchName()) - assert.Equal(t, "stable/acs-engine-autoscaler/Chart.yaml", gl.GetPath()) - } - { - gl, err := NewGitLabParserWithURL(urlC) - assert.NoError(t, err) - assert.Equal(t, "gitlab.com", gl.GetHostName()) - assert.Equal(t, "gitlab", gl.GetProvider()) - assert.Equal(t, "kubescape", gl.GetOwnerName()) - assert.Equal(t, "testing", gl.GetRepoName()) - assert.Equal(t, urlA, gl.GetURL().String()) - assert.Equal(t, "dev", gl.GetBranchName()) - assert.Equal(t, "README.md", gl.GetPath()) - } - { - gl, err := NewGitLabParserWithURL(urlD) - assert.NoError(t, err) - assert.Equal(t, "gitlab.com", gl.GetHostName()) - assert.Equal(t, "gitlab", gl.GetProvider()) - assert.Equal(t, "kubescape", gl.GetOwnerName()) - assert.Equal(t, "testing", gl.GetRepoName()) - assert.Equal(t, urlA, gl.GetURL().String()) - assert.Equal(t, "dev", gl.GetBranchName()) - assert.Equal(t, "", gl.GetPath()) + tests := []struct { + name string + url string + want *GitLabURL + wantErr assert.ErrorAssertionFunc + }{ + { + name: "general case", + url: "https://gitlab.com/kubescape/testing", + want: &GitLabURL{ + host: "gitlab.com", + owner: "kubescape", + repo: "testing", + }, + wantErr: assert.NoError, + }, + { + name: "file", + url: "https://gitlab.com/kubescape/testing/-/blob/main/stable/acs-engine-autoscaler/Chart.yaml", + want: &GitLabURL{ + host: "gitlab.com", + owner: "kubescape", + repo: "testing", + branch: "main", + path: "stable/acs-engine-autoscaler/Chart.yaml", + }, + wantErr: assert.NoError, + }, + { + name: "branch", + url: "https://gitlab.com/kubescape/testing/-/blob/dev/README.md", + want: &GitLabURL{ + host: "gitlab.com", + owner: "kubescape", + repo: "testing", + branch: "dev", + path: "README.md", + }, + wantErr: assert.NoError, + }, + { + name: "branch", + url: "https://gitlab.com/kubescape/testing/-/tree/dev", + want: &GitLabURL{ + host: "gitlab.com", + owner: "kubescape", + repo: "testing", + branch: "dev", + }, + wantErr: assert.NoError, + }, + { + name: "tag", + url: "https://gitlab.com/kubescape/testing/-/blob/v0.0.0/README.md", + want: &GitLabURL{ + host: "gitlab.com", + owner: "kubescape", + repo: "testing", + branch: "v0.0.0", + path: "README.md", + }, + wantErr: assert.NoError, + }, + { + name: "raw", + url: "https://gitlab.com/kubescape/testing/-/raw/main/stable/acs-engine-autoscaler/Chart.yaml", + want: &GitLabURL{ + host: "gitlab.com", + owner: "kubescape", + repo: "testing", + branch: "main", + path: "stable/acs-engine-autoscaler/Chart.yaml", + }, + wantErr: assert.NoError, + }, + { + name: "scp-like syntax", + url: "git@gitlab.com:owner/repo.git", + want: &GitLabURL{ + host: "gitlab.com", + owner: "owner", + repo: "repo", + }, + wantErr: assert.NoError, + }, + { + name: "project and subproject", + url: "https://gitlab.com/matthyx1/subgroup1/project1.git", + want: &GitLabURL{ + host: "gitlab.com", + owner: "matthyx1/subgroup1", + repo: "project1", + }, + wantErr: assert.NoError, + }, + { + name: "project and subproject", + url: "https://gitlab.com/matthyx1/subgroup1/subsubgroup1/project1.git", + want: &GitLabURL{ + host: "gitlab.com", + owner: "matthyx1/subgroup1/subsubgroup1", + repo: "project1", + }, + wantErr: assert.NoError, + }, + { + name: "self-hosted", + url: "https://gitlab.host.com/kubescape/testing", + want: &GitLabURL{ + host: "gitlab.host.com", + owner: "kubescape", + repo: "testing", + }, + wantErr: assert.NoError, + }, } - { - gl, err := NewGitLabParserWithURL(urlE) - assert.NoError(t, err) - assert.Equal(t, "gitlab.com", gl.GetHostName()) - assert.Equal(t, "gitlab", gl.GetProvider()) - assert.Equal(t, "kubescape", gl.GetOwnerName()) - assert.Equal(t, "testing", gl.GetRepoName()) - assert.Equal(t, urlA, gl.GetURL().String()) - assert.Equal(t, "v0.0.0", gl.GetBranchName()) - assert.Equal(t, "README.md", gl.GetPath()) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := NewGitLabParserWithURL(tt.url) + got.gitLabAPI = nil + if !tt.wantErr(t, err, fmt.Sprintf("NewGitLabParserWithURL(%v)", tt.url)) { + return + } + assert.Equalf(t, tt.want, got, "NewGitLabParserWithURL(%v)", tt.url) + }) } - { - gl, err := NewGitLabParserWithURL(urlF) - assert.NoError(t, err) - assert.Equal(t, "gitlab.com", gl.GetHostName()) - assert.Equal(t, "gitlab", gl.GetProvider()) - assert.Equal(t, "kubescape", gl.GetOwnerName()) - assert.Equal(t, "testing", gl.GetRepoName()) - assert.Equal(t, urlA, gl.GetURL().String()) - assert.Equal(t, "main", gl.GetBranchName()) - assert.Equal(t, "stable/acs-engine-autoscaler/Chart.yaml", gl.GetPath()) - } - { - gl, err := NewGitLabParserWithURL(urlG) - assert.NoError(t, err) - assert.Equal(t, "gitlab.com", gl.GetHostName()) - assert.Equal(t, "gitlab", gl.GetProvider()) - assert.Equal(t, "owner", gl.GetOwnerName()) - assert.Equal(t, "repo", gl.GetRepoName()) - assert.Equal(t, "https://gitlab.com/owner/repo", gl.GetURL().String()) - assert.Equal(t, "", gl.GetBranchName()) - assert.Equal(t, "", gl.GetPath()) - } - { - gl, err := NewGitLabParserWithURL(urlH) - assert.NoError(t, err) - assert.Equal(t, "gitlab.com", gl.GetHostName()) - assert.Equal(t, "gitlab", gl.GetProvider()) - assert.Equal(t, "matthyx1/subgroup1", gl.GetOwnerName()) - assert.Equal(t, "project1", gl.GetRepoName()) - assert.Equal(t, "https://gitlab.com/matthyx1/subgroup1/project1", gl.GetURL().String()) - assert.Equal(t, "", gl.GetBranchName()) // invalid input leads to incorrect guess. At least this does not panic. - assert.Equal(t, "", gl.GetPath()) +} + +func TestIsHostGitLab(t *testing.T) { + tests := []struct { + name string + want bool + }{ + { + name: "gitlab.com", + want: true, + }, + { + name: "gitlab.host.com", + want: true, + }, + { + name: "github.com", + want: false, + }, } - { - gl, err := NewGitLabParserWithURL(urlI) - assert.NoError(t, err) - assert.Equal(t, "gitlab.com", gl.GetHostName()) - assert.Equal(t, "gitlab", gl.GetProvider()) - assert.Equal(t, "matthyx1/subgroup1/subsubgroup1", gl.GetOwnerName()) - assert.Equal(t, "project1", gl.GetRepoName()) - assert.Equal(t, "https://gitlab.com/matthyx1/subgroup1/subsubgroup1/project1", gl.GetURL().String()) - assert.Equal(t, "", gl.GetBranchName()) // invalid input leads to incorrect guess. At least this does not panic. - assert.Equal(t, "", gl.GetPath()) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, IsHostGitLab(tt.name), "IsHostGitLab(%v)", tt.name) + }) } }