From 10cfeffd6ec9698f5ec12c292c8e9d1cd51f0a1d Mon Sep 17 00:00:00 2001 From: "xian-jie.shen" <327411586@qq.com> Date: Tue, 19 Jul 2022 18:42:45 +0800 Subject: [PATCH 1/2] feat: pkg-util-gitlab Enhancement Signed-off-by: xian-jie.shen <327411586@qq.com> --- go.mod | 1 + pkg/util/gitlab/ci_yml_templates_test.go | 42 +++++++ pkg/util/gitlab/commits.go | 6 +- pkg/util/gitlab/commits_test.go | 133 +++++++++++++++++++++++ pkg/util/gitlab/gitlab.go | 10 -- pkg/util/gitlab/gitlab_test.go | 69 ++++++++++++ pkg/util/gitlab/project_test.go | 109 +++++++++++++++++++ pkg/util/gitlab/repository_files.go | 8 +- pkg/util/gitlab/repository_files_test.go | 43 ++++++++ 9 files changed, 407 insertions(+), 14 deletions(-) create mode 100644 pkg/util/gitlab/ci_yml_templates_test.go create mode 100644 pkg/util/gitlab/commits_test.go create mode 100644 pkg/util/gitlab/gitlab_test.go create mode 100644 pkg/util/gitlab/project_test.go create mode 100644 pkg/util/gitlab/repository_files_test.go diff --git a/go.mod b/go.mod index 157843c10..170171a70 100644 --- a/go.mod +++ b/go.mod @@ -173,6 +173,7 @@ require ( github.com/spf13/cast v1.4.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.2.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect github.com/vmihailenco/go-tinylfu v0.2.1 // indirect github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect diff --git a/pkg/util/gitlab/ci_yml_templates_test.go b/pkg/util/gitlab/ci_yml_templates_test.go new file mode 100644 index 000000000..8c13868f2 --- /dev/null +++ b/pkg/util/gitlab/ci_yml_templates_test.go @@ -0,0 +1,42 @@ +package gitlab + +import ( + "os" + "strings" + "testing" +) + +var gitlab_token = "FAKE_GITLAB_TOKEN" + +func TestClient_GetGitLabCIGolangTemplate(t *testing.T) { + baseURL := "" + os.Setenv("GITLAB_TOKEN", gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + client, err := NewClient(WithBaseURL(baseURL)) + if err != nil { + t.Error(err) + } + tests := []struct { + name string + client *Client + wantContent bool + wantErr bool + }{ + // TODO: Add test cases. + {"base", client, true, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.client.GetGitLabCIGolangTemplate() + if (err != nil) != tt.wantErr { + t.Errorf("Client.GetGitLabCIGolangTemplate() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !strings.Contains(got, "golang") { + t.Errorf("Client.GetGitLabCIGolangTemplate's content doesn't include 'golang'") + } + }) + } +} diff --git a/pkg/util/gitlab/commits.go b/pkg/util/gitlab/commits.go index 3cfa50f5c..69c7d575a 100644 --- a/pkg/util/gitlab/commits.go +++ b/pkg/util/gitlab/commits.go @@ -1,6 +1,8 @@ package gitlab import ( + "fmt" + "github.com/xanzy/go-gitlab" "github.com/devstream-io/devstream/pkg/util/log" @@ -72,8 +74,8 @@ func (c *Client) UpdateSingleFile(project, branch, commitMessage, filename, cont } func (c *Client) CommitMultipleFiles(project, branch, commitMessage string, files map[string][]byte) error { - var commitActionsOptions = make([]*gitlab.CommitActionOptions, 0) - + var commitActionsOptions = make([]*gitlab.CommitActionOptions, len(files)) + fmt.Println("---> ", len(commitActionsOptions)) for fileName, content := range files { commitActionsOptions = append(commitActionsOptions, &gitlab.CommitActionOptions{ Action: gitlab.FileAction(gitlab.FileCreate), diff --git a/pkg/util/gitlab/commits_test.go b/pkg/util/gitlab/commits_test.go new file mode 100644 index 000000000..ccb9009b6 --- /dev/null +++ b/pkg/util/gitlab/commits_test.go @@ -0,0 +1,133 @@ +package gitlab + +import ( + "os" + "testing" +) + +func TestClient_CommitSingleFile(t *testing.T) { + os.Setenv("GITLAB_TOKEN", fake_gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + client, err := NewClient(WithBaseURL(baseURL)) + if err != nil { + t.Error(err) + } + tests := []struct { + name string + client *Client + project string + branch string + commitMessage string + filename string + content string + wantErr bool + }{ + // TODO: Add test cases. + {"base", client, "", "", "", "", "", true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := tt.client.CommitSingleFile(tt.project, tt.branch, tt.commitMessage, tt.filename, tt.content); (err != nil) != tt.wantErr { + t.Errorf("Client.CommitSingleFile() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestClient_DeleteSingleFile(t *testing.T) { + os.Setenv("GITLAB_TOKEN", fake_gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + client, err := NewClient(WithBaseURL(baseURL)) + if err != nil { + t.Error(err) + } + tests := []struct { + name string + client *Client + project string + branch string + commitMessage string + filename string + wantErr bool + }{ + // TODO: Add test cases. + {"base", client, "", "", "", "", true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := tt.client.DeleteSingleFile(tt.project, tt.branch, tt.commitMessage, tt.filename); (err != nil) != tt.wantErr { + t.Errorf("Client.DeleteSingleFile() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestClient_UpdateSingleFile(t *testing.T) { + os.Setenv("GITLAB_TOKEN", fake_gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + client, err := NewClient(WithBaseURL(baseURL)) + if err != nil { + t.Error(err) + } + tests := []struct { + name string + client *Client + project string + branch string + commitMessage string + filename string + content string + wantErr bool + }{ + // TODO: Add test cases. + {"base", client, "", "", "", "", "", true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := tt.client.UpdateSingleFile(tt.project, tt.branch, tt.commitMessage, tt.filename, tt.content); (err != nil) != tt.wantErr { + t.Errorf("Client.UpdateSingleFile() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestClient_CommitMultipleFiles(t *testing.T) { + m := map[string][]byte{ + "a.txt": []byte("a.txt"), + "b.txt": []byte("b.txt"), + "c.txt": []byte("c.txt"), + } + os.Setenv("GITLAB_TOKEN", fake_gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + client, err := NewClient(WithBaseURL(baseURL)) + if err != nil { + t.Error(err) + } + tests := []struct { + name string + client *Client + project string + branch string + commitMessage string + files map[string][]byte + wantErr bool + }{ + // TODO: Add test cases. + {"base", client, "", "", "", m, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := tt.client.CommitMultipleFiles(tt.project, tt.branch, tt.commitMessage, tt.files); (err != nil) != tt.wantErr { + t.Errorf("Client.CommitMultipleFiles() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} diff --git a/pkg/util/gitlab/gitlab.go b/pkg/util/gitlab/gitlab.go index 17c053f7d..44506ae93 100644 --- a/pkg/util/gitlab/gitlab.go +++ b/pkg/util/gitlab/gitlab.go @@ -5,12 +5,8 @@ import ( "os" "github.com/xanzy/go-gitlab" - - "github.com/devstream-io/devstream/pkg/util/log" ) -var client *Client - const ( DefaultGitlabHost = "https://gitlab.com" ) @@ -29,11 +25,6 @@ type Client struct { } func NewClient(opts ...OptionFunc) (*Client, error) { - if client != nil { - log.Debug("Use a cached client.") - return client, nil - } - token := os.Getenv("GITLAB_TOKEN") if token == "" { return nil, errors.New("failed to read GITLAB_TOKEN from environment variable") @@ -51,7 +42,6 @@ func NewClient(opts ...OptionFunc) (*Client, error) { c.Client, err = gitlab.NewClient(token) } else { c.Client, err = gitlab.NewClient(token, gitlab.WithBaseURL(c.baseURL)) - } if err != nil { diff --git a/pkg/util/gitlab/gitlab_test.go b/pkg/util/gitlab/gitlab_test.go new file mode 100644 index 000000000..87a2ba273 --- /dev/null +++ b/pkg/util/gitlab/gitlab_test.go @@ -0,0 +1,69 @@ +package gitlab + +import ( + "os" + "testing" +) + +var fake_gitlab_token = "FAKE_GITLAB_TOKEN" +var baseURL = "" + +func TestWithBaseURL(t *testing.T) { + os.Setenv("GITLAB_TOKEN", fake_gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + got := WithBaseURL(baseURL) + if got == nil { + t.Error("got must not be nil\n") + } + client, err := NewClient(got) + if err != nil { + t.Error(err) + } + if client.baseURL != baseURL { + t.Errorf("client.baseURL = %s\n, want = %s\n", client.baseURL, baseURL) + } +} + +func TestNewClient(t *testing.T) { + os.Setenv("GITLAB_TOKEN", fake_gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + + baseURL := "" + opts := []OptionFunc{ + WithBaseURL(baseURL), + } + opts2 := []OptionFunc{ + WithBaseURL(DefaultGitlabHost), + } + testDataName := "last case: empty token" + tests := []struct { + name string + opts []OptionFunc + isNilClient bool + wantErr bool + }{ + // TODO: Add test cases. + {"base", opts, false, false}, + {"base not empty baseUrl", opts2, false, false}, + {testDataName, opts, true, true}, + } + for _, tt := range tests { + if tt.name == testDataName { + os.Setenv("GITLAB_TOKEN", "") + } + t.Run(tt.name, func(t *testing.T) { + got, err := NewClient(tt.opts...) + if (err != nil) != tt.wantErr { + t.Errorf("NewClient() error = %v, wantErr %v", err, tt.wantErr) + return + } + if (got != nil) == tt.isNilClient { + t.Errorf("NewClient() = %+v\n, want %+v\n", got, tt.isNilClient) + } + }) + } +} diff --git a/pkg/util/gitlab/project_test.go b/pkg/util/gitlab/project_test.go new file mode 100644 index 000000000..18a1b1901 --- /dev/null +++ b/pkg/util/gitlab/project_test.go @@ -0,0 +1,109 @@ +package gitlab + +import ( + "os" + "reflect" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/xanzy/go-gitlab" +) + +func TestClient_CreateProject(t *testing.T) { + os.Setenv("GITLAB_TOKEN", fake_gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + client, err := NewClient(WithBaseURL(baseURL)) + if err != nil { + t.Error(err) + } + tests := []struct { + name string + baseURL string + Client *Client + opts *CreateProjectOptions + wantErr bool + }{ + // TODO: Add test cases. + {"base", baseURL, client, + &CreateProjectOptions{ + Namespace: "", + }, true}, + {"base Namespace is not empty", baseURL, client, + &CreateProjectOptions{ + Namespace: "test", + }, true}, + {"base Visibility is `public`", baseURL, client, + &CreateProjectOptions{ + Visibility: "public", + }, true}, + {"base Visibility is `internal`", baseURL, client, + &CreateProjectOptions{ + Visibility: "internal", + }, true}, + {"base Visibility is `private`", baseURL, client, + &CreateProjectOptions{ + Visibility: "private", + }, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if err := tt.Client.CreateProject(tt.opts); (err != nil) != tt.wantErr { + t.Errorf("Client.CreateProject() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +} + +func TestClient_DeleteProject(t *testing.T) { + os.Setenv("GITLAB_TOKEN", fake_gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + client, err := NewClient(WithBaseURL(baseURL)) + if err != nil { + t.Error(err) + } + + err = client.DeleteProject("") + assert.NotNil(t, err) + + err = client.DeleteProject("test") + assert.NotNil(t, err) + +} + +func TestClient_DescribeProject(t *testing.T) { + os.Setenv("GITLAB_TOKEN", fake_gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + client, err := NewClient(WithBaseURL(baseURL)) + if err != nil { + t.Error(err) + } + tests := []struct { + name string + Client *Client + project string + want *gitlab.Project + wantErr bool + }{ + // TODO: Add test cases. + {"base", client, "", nil, true}, + {"base", client, "test", nil, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.Client.DescribeProject(tt.project) + if (err != nil) != tt.wantErr { + t.Errorf("Client.DescribeProject() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Client.DescribeProject() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/util/gitlab/repository_files.go b/pkg/util/gitlab/repository_files.go index 3501ce266..2f2366f25 100644 --- a/pkg/util/gitlab/repository_files.go +++ b/pkg/util/gitlab/repository_files.go @@ -1,6 +1,8 @@ package gitlab import ( + "net/http" + "github.com/xanzy/go-gitlab" ) @@ -13,8 +15,10 @@ func (c *Client) FileExists(project, branch, filename string) (bool, error) { } _, response, err := c.RepositoryFiles.GetFile(project, filename, getFileOptions) - if response.StatusCode == 404 { - return false, nil + for _, v := range []int{http.StatusBadRequest, http.StatusUnauthorized, http.StatusNotFound} { + if response.StatusCode == v { + return false, nil + } } if err != nil { diff --git a/pkg/util/gitlab/repository_files_test.go b/pkg/util/gitlab/repository_files_test.go new file mode 100644 index 000000000..cf2594a6c --- /dev/null +++ b/pkg/util/gitlab/repository_files_test.go @@ -0,0 +1,43 @@ +package gitlab + +import ( + "os" + "testing" +) + +func TestClient_FileExists(t *testing.T) { + os.Setenv("GITLAB_TOKEN", fake_gitlab_token) + defer func() { + os.Unsetenv("GITLAB_TOKEN") + }() + client, err := NewClient(WithBaseURL(baseURL)) + if err != nil { + t.Error(err) + } + tests := []struct { + name string + client *Client + project string + branch string + filename string + getFile bool + wantErr bool + }{ + // TODO: Add test cases. + {"base 404", client, "", "", "", false, false}, + {"base ref is empty", client, "yrdy", "", "sfdf", false, false}, + {"base branch is Unauthorized", client, "yrdy", "yrdy", "sfdf", false, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := client.FileExists(tt.project, tt.branch, tt.filename) + if (err != nil) != tt.wantErr { + t.Errorf("Client.FileExists() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.getFile { + t.Errorf("Client.FileExists() = %v, want %v", got, tt.getFile) + } + }) + } +} From fefc34681ad49761c78008ec5d5354f55daf52ce Mon Sep 17 00:00:00 2001 From: hxcGit Date: Fri, 22 Jul 2022 00:55:10 +0800 Subject: [PATCH 2/2] chore: remove fmt output Signed-off-by: hxcGit --- go.mod | 1 - pkg/util/gitlab/commits.go | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 170171a70..157843c10 100644 --- a/go.mod +++ b/go.mod @@ -173,7 +173,6 @@ require ( github.com/spf13/cast v1.4.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.2.0 // indirect github.com/subosito/gotenv v1.2.0 // indirect github.com/vmihailenco/go-tinylfu v0.2.1 // indirect github.com/vmihailenco/msgpack/v5 v5.3.4 // indirect diff --git a/pkg/util/gitlab/commits.go b/pkg/util/gitlab/commits.go index 69c7d575a..8b17061d3 100644 --- a/pkg/util/gitlab/commits.go +++ b/pkg/util/gitlab/commits.go @@ -1,8 +1,6 @@ package gitlab import ( - "fmt" - "github.com/xanzy/go-gitlab" "github.com/devstream-io/devstream/pkg/util/log" @@ -75,7 +73,7 @@ func (c *Client) UpdateSingleFile(project, branch, commitMessage, filename, cont func (c *Client) CommitMultipleFiles(project, branch, commitMessage string, files map[string][]byte) error { var commitActionsOptions = make([]*gitlab.CommitActionOptions, len(files)) - fmt.Println("---> ", len(commitActionsOptions)) + for fileName, content := range files { commitActionsOptions = append(commitActionsOptions, &gitlab.CommitActionOptions{ Action: gitlab.FileAction(gitlab.FileCreate),