diff --git a/.mockery.yaml b/.mockery.yaml new file mode 100644 index 0000000..5822662 --- /dev/null +++ b/.mockery.yaml @@ -0,0 +1,6 @@ +--- +all: True +dir: "{{.PackageName}}/mocks" +outpkg: "mocks" +packages: + github.com/thegeeklab/wp-gitea-release/gitea: diff --git a/Makefile b/Makefile index 8ccd76e..2a100a3 100644 --- a/Makefile +++ b/Makefile @@ -11,13 +11,14 @@ IMPORT := github.com/thegeeklab/$(EXECUTABLE) GO ?= go CWD ?= $(shell pwd) -PACKAGES ?= $(shell go list ./...) +PACKAGES ?= $(shell go list ./... | grep -Ev '/mocks$$') SOURCES ?= $(shell find . -name "*.go" -type f) GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@$(GOFUMPT_PACKAGE_VERSION) GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_PACKAGE_VERSION) XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest GOTESTSUM_PACKAGE ?= gotest.tools/gotestsum@latest +MOCKERY_PACKAGE ?= github.com/vektra/mockery/v2@latest XGO_VERSION := go-1.22.x XGO_TARGETS ?= linux/amd64,linux/arm-6,linux/arm-7,linux/arm64 @@ -65,6 +66,7 @@ lint: golangci-lint .PHONY: generate generate: $(GO) generate $(PACKAGES) + $(GO) run $(MOCKERY_PACKAGE) .PHONY: test test: diff --git a/gitea/api.go b/gitea/api.go new file mode 100644 index 0000000..d69e52b --- /dev/null +++ b/gitea/api.go @@ -0,0 +1,16 @@ +package gitea + +import ( + "io" + + "code.gitea.io/sdk/gitea" +) + +//nolint:lll +type APIClient interface { + ListReleases(owner, repo string, opt gitea.ListReleasesOptions) ([]*gitea.Release, *gitea.Response, error) + CreateRelease(owner, repo string, opt gitea.CreateReleaseOption) (*gitea.Release, *gitea.Response, error) + ListReleaseAttachments(user, repo string, release int64, opt gitea.ListReleaseAttachmentsOptions) ([]*gitea.Attachment, *gitea.Response, error) + CreateReleaseAttachment(user, repo string, release int64, file io.Reader, filename string) (*gitea.Attachment, *gitea.Response, error) + DeleteReleaseAttachment(user, repo string, release, id int64) (*gitea.Response, error) +} diff --git a/plugin/release.go b/gitea/gitea.go similarity index 82% rename from plugin/release.go rename to gitea/gitea.go index 2d0ca14..c1c87dd 100644 --- a/plugin/release.go +++ b/gitea/gitea.go @@ -1,8 +1,9 @@ -package plugin +package gitea import ( "errors" "fmt" + "net/http" "os" "path" @@ -15,17 +16,23 @@ var ( ErrFileExists = errors.New("asset file already exist") ) -type GiteaClient struct { - client *gitea.Client - Release *GiteaRelease +const ( + FileExistsOverwrite FileExists = "overwrite" + FileExistsFail FileExists = "fail" + FileExistsSkip FileExists = "skip" +) + +type Client struct { + client APIClient + Release *Release } -type GiteaRelease struct { - client *gitea.Client - Opt GiteaReleaseOpt +type Release struct { + client APIClient + Opt ReleaseOpt } -type GiteaReleaseOpt struct { +type ReleaseOpt struct { Owner string Repo string Tag string @@ -38,26 +45,25 @@ type GiteaReleaseOpt struct { type FileExists string -const ( - FileExistsOverwrite FileExists = "overwrite" - FileExistsFail FileExists = "fail" - FileExistsSkip FileExists = "skip" -) - -// NewGiteaClient creates a new GiteaClient instance with the provided Gitea client. -func NewGiteaClient(client *gitea.Client) *GiteaClient { - return &GiteaClient{ - client: client, - Release: &GiteaRelease{ - client: client, - Opt: GiteaReleaseOpt{}, - }, +// NewClient creates a new Client instance with the provided Gitea client. +func NewClient(url, key string, client *http.Client) (*Client, error) { + c, err := gitea.NewClient(url, gitea.SetToken(key), gitea.SetHTTPClient(client)) + if err != nil { + return nil, err } + + return &Client{ + client: c, + Release: &Release{ + client: c, + Opt: ReleaseOpt{}, + }, + }, nil } // Find retrieves the release with the specified tag name from the repository. // If the release is not found, it returns an ErrReleaseNotFound error. -func (r *GiteaRelease) Find() (*gitea.Release, error) { +func (r *Release) Find() (*gitea.Release, error) { releases, _, err := r.client.ListReleases(r.Opt.Owner, r.Opt.Repo, gitea.ListReleasesOptions{}) if err != nil { return nil, err @@ -76,7 +82,7 @@ func (r *GiteaRelease) Find() (*gitea.Release, error) { // Create creates a new release on the Gitea repository with the specified options. // It returns the created release or an error if the creation failed. -func (r *GiteaRelease) Create() (*gitea.Release, error) { +func (r *Release) Create() (*gitea.Release, error) { opts := gitea.CreateReleaseOption{ TagName: r.Opt.Tag, IsDraft: r.Opt.Draft, @@ -104,7 +110,7 @@ func (r *GiteaRelease) Create() (*gitea.Release, error) { // - "skip": skips uploading the file and logs a warning // // If there are no conflicts, it uploads the new files as attachments to the release. -func (r *GiteaRelease) AddAttachments(releaseID int64, files []string) error { +func (r *Release) AddAttachments(releaseID int64, files []string) error { attachments, _, err := r.client.ListReleaseAttachments( r.Opt.Owner, r.Opt.Repo, @@ -151,7 +157,7 @@ func (r *GiteaRelease) AddAttachments(releaseID int64, files []string) error { return nil } -func (r *GiteaRelease) uploadFile(releaseID int64, file string) error { +func (r *Release) uploadFile(releaseID int64, file string) error { handle, err := os.Open(file) if err != nil { return fmt.Errorf("failed to read artifact: %s: %w", file, err) diff --git a/plugin/release_test.go b/gitea/gitea_test.go similarity index 62% rename from plugin/release_test.go rename to gitea/gitea_test.go index 17e766d..3bc042a 100644 --- a/plugin/release_test.go +++ b/gitea/gitea_test.go @@ -1,98 +1,30 @@ -package plugin +package gitea import ( "bytes" "errors" - "fmt" - "io" - "net/http" - "net/http/httptest" "os" "path/filepath" "testing" - "github.com/rs/zerolog/log" - "code.gitea.io/sdk/gitea" "github.com/rs/zerolog" + "github.com/rs/zerolog/log" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "github.com/thegeeklab/wp-gitea-release/gitea/mocks" ) -func giteaMockHandler(t *testing.T, opt GiteaReleaseOpt) func(http.ResponseWriter, *http.Request) { - t.Helper() - - return func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/json") - fmt.Println(r.RequestURI) - - switch r.RequestURI { - case "/api/v1/version": - _, err := io.WriteString(w, `{"version":"1.21.0"}`) - if err != nil { - t.Fail() - } - case "/api/v1/repos/test-owner/test-repo/releases?limit=0&page=1": - _, err := io.WriteString(w, `[{ - "id": 1, - "tag_name": "v1.0.0", - "name": "Release v1.0.0", - "body": "This is the release notes for v1.0.0", - "draft": false, - "prerelease": false, - "created_at": "2023-05-01T12:00:00Z", - "published_at": "2023-05-01T12:30:00Z" - }]`) - if err != nil { - t.Fail() - } - case "/api/v1/repos/test-owner/test-repo/releases": - _, err := io.WriteString(w, fmt.Sprintf(`{ - "id": 1, - "tag_name": "%s", - "name": "Release %s", - "body": "This is the release notes for %s", - "draft": %t, - "prerelease": %t, - "created_at": "2023-05-01T12:00:00Z", - "published_at": "2023-05-01T12:30:00Z" - }`, opt.Tag, opt.Tag, opt.Tag, opt.Draft, opt.Prerelease)) - if err != nil { - t.Fail() - } - case "/api/v1/repos/test-owner/test-repo/releases/1/assets?limit=0&page=1": - _, err := io.WriteString(w, `[{ - "id": 1, - "name": "file1.txt", - "size": 1024, - "created_at": "2023-05-01T12:30:00Z" - }]`) - if err != nil { - t.Fail() - } - case "/api/v1/repos/test-owner/test-repo/releases/1/assets": - _, err := io.WriteString(w, `{ - "id": 1, - "name": "file1.txt", - "size": 1024, - "created_at": "2023-05-01T12:30:00Z" - }`) - if err != nil { - t.Fail() - } - } - } -} - -func TestGiteaReleaseFind(t *testing.T) { +func TestReleaseFind(t *testing.T) { tests := []struct { name string - opt GiteaReleaseOpt + opt ReleaseOpt want *gitea.Release wantErr error }{ { name: "find release by tag", - opt: GiteaReleaseOpt{ + opt: ReleaseOpt{ Owner: "test-owner", Repo: "test-repo", Tag: "v1.0.0", @@ -103,7 +35,7 @@ func TestGiteaReleaseFind(t *testing.T) { }, { name: "release not found", - opt: GiteaReleaseOpt{ + opt: ReleaseOpt{ Owner: "test-owner", Repo: "test-repo", Tag: "v1.1.0", @@ -114,19 +46,29 @@ func TestGiteaReleaseFind(t *testing.T) { } for _, tt := range tests { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - giteaMockHandler(t, tt.opt)(w, r) - })) - defer ts.Close() + mockClient := mocks.NewMockAPIClient(t) + r := &Release{ + Opt: tt.opt, + client: mockClient, + } - g, _ := gitea.NewClient(ts.URL) - client := NewGiteaClient(g) + mockClient. + On("ListReleases", mock.Anything, mock.Anything, mock.Anything). + Return([]*gitea.Release{ + { + ID: 1, + TagName: "v1.0.0", + Title: "Release v1.0.0", + Note: "This is the release notes for v1.0.0", + IsDraft: false, + IsPrerelease: false, + }, + }, nil, nil) t.Run(tt.name, func(t *testing.T) { - client.Release.Opt = tt.opt - release, err := client.Release.Find() + release, err := r.Find() - if tt.want == nil { + if tt.wantErr != nil { assert.Error(t, err) assert.Nil(t, release) @@ -139,16 +81,16 @@ func TestGiteaReleaseFind(t *testing.T) { } } -func TestGiteaReleaseCreate(t *testing.T) { +func TestReleaseCreate(t *testing.T) { tests := []struct { name string - opt GiteaReleaseOpt + opt ReleaseOpt want *gitea.Release wantErr error }{ { name: "create release", - opt: GiteaReleaseOpt{ + opt: ReleaseOpt{ Owner: "test-owner", Repo: "test-repo", Tag: "v1.1.0", @@ -167,7 +109,7 @@ func TestGiteaReleaseCreate(t *testing.T) { }, { name: "create draft release", - opt: GiteaReleaseOpt{ + opt: ReleaseOpt{ Owner: "test-owner", Repo: "test-repo", Tag: "v1.2.0", @@ -186,7 +128,7 @@ func TestGiteaReleaseCreate(t *testing.T) { }, { name: "create prerelease", - opt: GiteaReleaseOpt{ + opt: ReleaseOpt{ Owner: "test-owner", Repo: "test-repo", Tag: "v1.3.0-rc1", @@ -206,17 +148,25 @@ func TestGiteaReleaseCreate(t *testing.T) { } for _, tt := range tests { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - giteaMockHandler(t, tt.opt)(w, r) - })) - defer ts.Close() + mockClient := mocks.NewMockAPIClient(t) + r := &Release{ + Opt: tt.opt, + client: mockClient, + } - g, _ := gitea.NewClient(ts.URL) - client := NewGiteaClient(g) + mockClient. + On("CreateRelease", mock.Anything, mock.Anything, mock.Anything). + Return(&gitea.Release{ + ID: 1, + TagName: tt.opt.Tag, + Title: tt.opt.Title, + Note: tt.opt.Note, + IsDraft: tt.opt.Draft, + IsPrerelease: tt.opt.Prerelease, + }, nil, nil) t.Run(tt.name, func(t *testing.T) { - client.Release.Opt = tt.opt - release, err := client.Release.Create() + release, err := r.Create() if tt.wantErr != nil { assert.Error(t, err) @@ -235,14 +185,14 @@ func TestGiteaReleaseCreate(t *testing.T) { } } -func TestGiteaReleaseAddAttachments(t *testing.T) { +func TestReleaseAddAttachments(t *testing.T) { logBuffer := &bytes.Buffer{} logger := zerolog.New(logBuffer) log.Logger = logger tests := []struct { name string - opt GiteaReleaseOpt + opt ReleaseOpt files []string fileExists string wantErr error @@ -250,7 +200,7 @@ func TestGiteaReleaseAddAttachments(t *testing.T) { }{ { name: "add new attachments", - opt: GiteaReleaseOpt{ + opt: ReleaseOpt{ Owner: "test-owner", Repo: "test-repo", Tag: "v2.0.0", @@ -262,7 +212,7 @@ func TestGiteaReleaseAddAttachments(t *testing.T) { }, { name: "fail on existing attachments", - opt: GiteaReleaseOpt{ + opt: ReleaseOpt{ Owner: "test-owner", Repo: "test-repo", Tag: "v2.0.0", @@ -274,7 +224,7 @@ func TestGiteaReleaseAddAttachments(t *testing.T) { }, { name: "overwrite on existing attachments", - opt: GiteaReleaseOpt{ + opt: ReleaseOpt{ Owner: "test-owner", Repo: "test-repo", Tag: "v2.0.0", @@ -282,12 +232,11 @@ func TestGiteaReleaseAddAttachments(t *testing.T) { FileExists: "overwrite", }, files: []string{createTempFile(t, "file1.txt"), createTempFile(t, "file2.txt")}, - wantErr: nil, wantLogs: []string{"deleted artifact: file1.txt", "uploaded artifact: file1.txt"}, }, { name: "skip on existing attachments", - opt: GiteaReleaseOpt{ + opt: ReleaseOpt{ Owner: "test-owner", Repo: "test-repo", Tag: "v2.0.0", @@ -295,12 +244,11 @@ func TestGiteaReleaseAddAttachments(t *testing.T) { FileExists: "skip", }, files: []string{createTempFile(t, "file1.txt"), createTempFile(t, "file2.txt")}, - wantErr: nil, wantLogs: []string{"skip existing artifact: file1"}, }, { name: "fail on invalid file", - opt: GiteaReleaseOpt{ + opt: ReleaseOpt{ Owner: "test-owner", Repo: "test-repo", Tag: "v2.0.0", @@ -313,21 +261,36 @@ func TestGiteaReleaseAddAttachments(t *testing.T) { } for _, tt := range tests { - ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - giteaMockHandler(t, tt.opt)(w, r) - })) - defer ts.Close() - logBuffer.Reset() - g, _ := gitea.NewClient(ts.URL) - client := NewGiteaClient(g) + mockClient := mocks.NewMockAPIClient(t) + r := &Release{ + Opt: tt.opt, + client: mockClient, + } + + mockClient. + On("ListReleaseAttachments", mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return([]*gitea.Attachment{ + { + Name: "file1.txt", + }, + }, nil, nil) + + if FileExists(tt.opt.FileExists) == FileExistsOverwrite { + mockClient. + On("DeleteReleaseAttachment", mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil, nil) + } + + if tt.wantErr == nil { + mockClient. + On("CreateReleaseAttachment", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything). + Return(nil, nil, nil) + } t.Run(tt.name, func(t *testing.T) { - client.Release.Opt = tt.opt - release, _ := client.Release.Create() - - err := client.Release.AddAttachments(release.ID, tt.files) + err := r.AddAttachments(1, tt.files) // Assert log output. for _, l := range tt.wantLogs { diff --git a/gitea/mocks/mock_APIClient.go b/gitea/mocks/mock_APIClient.go new file mode 100644 index 0000000..93c1634 --- /dev/null +++ b/gitea/mocks/mock_APIClient.go @@ -0,0 +1,378 @@ +// Code generated by mockery v2.43.0. DO NOT EDIT. + +package mocks + +import ( + io "io" + + gitea "code.gitea.io/sdk/gitea" + + mock "github.com/stretchr/testify/mock" +) + +// MockAPIClient is an autogenerated mock type for the APIClient type +type MockAPIClient struct { + mock.Mock +} + +type MockAPIClient_Expecter struct { + mock *mock.Mock +} + +func (_m *MockAPIClient) EXPECT() *MockAPIClient_Expecter { + return &MockAPIClient_Expecter{mock: &_m.Mock} +} + +// CreateRelease provides a mock function with given fields: owner, repo, opt +func (_m *MockAPIClient) CreateRelease(owner string, repo string, opt gitea.CreateReleaseOption) (*gitea.Release, *gitea.Response, error) { + ret := _m.Called(owner, repo, opt) + + if len(ret) == 0 { + panic("no return value specified for CreateRelease") + } + + var r0 *gitea.Release + var r1 *gitea.Response + var r2 error + if rf, ok := ret.Get(0).(func(string, string, gitea.CreateReleaseOption) (*gitea.Release, *gitea.Response, error)); ok { + return rf(owner, repo, opt) + } + if rf, ok := ret.Get(0).(func(string, string, gitea.CreateReleaseOption) *gitea.Release); ok { + r0 = rf(owner, repo, opt) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*gitea.Release) + } + } + + if rf, ok := ret.Get(1).(func(string, string, gitea.CreateReleaseOption) *gitea.Response); ok { + r1 = rf(owner, repo, opt) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*gitea.Response) + } + } + + if rf, ok := ret.Get(2).(func(string, string, gitea.CreateReleaseOption) error); ok { + r2 = rf(owner, repo, opt) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockAPIClient_CreateRelease_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateRelease' +type MockAPIClient_CreateRelease_Call struct { + *mock.Call +} + +// CreateRelease is a helper method to define mock.On call +// - owner string +// - repo string +// - opt gitea.CreateReleaseOption +func (_e *MockAPIClient_Expecter) CreateRelease(owner interface{}, repo interface{}, opt interface{}) *MockAPIClient_CreateRelease_Call { + return &MockAPIClient_CreateRelease_Call{Call: _e.mock.On("CreateRelease", owner, repo, opt)} +} + +func (_c *MockAPIClient_CreateRelease_Call) Run(run func(owner string, repo string, opt gitea.CreateReleaseOption)) *MockAPIClient_CreateRelease_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string), args[2].(gitea.CreateReleaseOption)) + }) + return _c +} + +func (_c *MockAPIClient_CreateRelease_Call) Return(_a0 *gitea.Release, _a1 *gitea.Response, _a2 error) *MockAPIClient_CreateRelease_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *MockAPIClient_CreateRelease_Call) RunAndReturn(run func(string, string, gitea.CreateReleaseOption) (*gitea.Release, *gitea.Response, error)) *MockAPIClient_CreateRelease_Call { + _c.Call.Return(run) + return _c +} + +// CreateReleaseAttachment provides a mock function with given fields: user, repo, release, file, filename +func (_m *MockAPIClient) CreateReleaseAttachment(user string, repo string, release int64, file io.Reader, filename string) (*gitea.Attachment, *gitea.Response, error) { + ret := _m.Called(user, repo, release, file, filename) + + if len(ret) == 0 { + panic("no return value specified for CreateReleaseAttachment") + } + + var r0 *gitea.Attachment + var r1 *gitea.Response + var r2 error + if rf, ok := ret.Get(0).(func(string, string, int64, io.Reader, string) (*gitea.Attachment, *gitea.Response, error)); ok { + return rf(user, repo, release, file, filename) + } + if rf, ok := ret.Get(0).(func(string, string, int64, io.Reader, string) *gitea.Attachment); ok { + r0 = rf(user, repo, release, file, filename) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*gitea.Attachment) + } + } + + if rf, ok := ret.Get(1).(func(string, string, int64, io.Reader, string) *gitea.Response); ok { + r1 = rf(user, repo, release, file, filename) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*gitea.Response) + } + } + + if rf, ok := ret.Get(2).(func(string, string, int64, io.Reader, string) error); ok { + r2 = rf(user, repo, release, file, filename) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockAPIClient_CreateReleaseAttachment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CreateReleaseAttachment' +type MockAPIClient_CreateReleaseAttachment_Call struct { + *mock.Call +} + +// CreateReleaseAttachment is a helper method to define mock.On call +// - user string +// - repo string +// - release int64 +// - file io.Reader +// - filename string +func (_e *MockAPIClient_Expecter) CreateReleaseAttachment(user interface{}, repo interface{}, release interface{}, file interface{}, filename interface{}) *MockAPIClient_CreateReleaseAttachment_Call { + return &MockAPIClient_CreateReleaseAttachment_Call{Call: _e.mock.On("CreateReleaseAttachment", user, repo, release, file, filename)} +} + +func (_c *MockAPIClient_CreateReleaseAttachment_Call) Run(run func(user string, repo string, release int64, file io.Reader, filename string)) *MockAPIClient_CreateReleaseAttachment_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string), args[2].(int64), args[3].(io.Reader), args[4].(string)) + }) + return _c +} + +func (_c *MockAPIClient_CreateReleaseAttachment_Call) Return(_a0 *gitea.Attachment, _a1 *gitea.Response, _a2 error) *MockAPIClient_CreateReleaseAttachment_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *MockAPIClient_CreateReleaseAttachment_Call) RunAndReturn(run func(string, string, int64, io.Reader, string) (*gitea.Attachment, *gitea.Response, error)) *MockAPIClient_CreateReleaseAttachment_Call { + _c.Call.Return(run) + return _c +} + +// DeleteReleaseAttachment provides a mock function with given fields: user, repo, release, id +func (_m *MockAPIClient) DeleteReleaseAttachment(user string, repo string, release int64, id int64) (*gitea.Response, error) { + ret := _m.Called(user, repo, release, id) + + if len(ret) == 0 { + panic("no return value specified for DeleteReleaseAttachment") + } + + var r0 *gitea.Response + var r1 error + if rf, ok := ret.Get(0).(func(string, string, int64, int64) (*gitea.Response, error)); ok { + return rf(user, repo, release, id) + } + if rf, ok := ret.Get(0).(func(string, string, int64, int64) *gitea.Response); ok { + r0 = rf(user, repo, release, id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*gitea.Response) + } + } + + if rf, ok := ret.Get(1).(func(string, string, int64, int64) error); ok { + r1 = rf(user, repo, release, id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// MockAPIClient_DeleteReleaseAttachment_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteReleaseAttachment' +type MockAPIClient_DeleteReleaseAttachment_Call struct { + *mock.Call +} + +// DeleteReleaseAttachment is a helper method to define mock.On call +// - user string +// - repo string +// - release int64 +// - id int64 +func (_e *MockAPIClient_Expecter) DeleteReleaseAttachment(user interface{}, repo interface{}, release interface{}, id interface{}) *MockAPIClient_DeleteReleaseAttachment_Call { + return &MockAPIClient_DeleteReleaseAttachment_Call{Call: _e.mock.On("DeleteReleaseAttachment", user, repo, release, id)} +} + +func (_c *MockAPIClient_DeleteReleaseAttachment_Call) Run(run func(user string, repo string, release int64, id int64)) *MockAPIClient_DeleteReleaseAttachment_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string), args[2].(int64), args[3].(int64)) + }) + return _c +} + +func (_c *MockAPIClient_DeleteReleaseAttachment_Call) Return(_a0 *gitea.Response, _a1 error) *MockAPIClient_DeleteReleaseAttachment_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *MockAPIClient_DeleteReleaseAttachment_Call) RunAndReturn(run func(string, string, int64, int64) (*gitea.Response, error)) *MockAPIClient_DeleteReleaseAttachment_Call { + _c.Call.Return(run) + return _c +} + +// ListReleaseAttachments provides a mock function with given fields: user, repo, release, opt +func (_m *MockAPIClient) ListReleaseAttachments(user string, repo string, release int64, opt gitea.ListReleaseAttachmentsOptions) ([]*gitea.Attachment, *gitea.Response, error) { + ret := _m.Called(user, repo, release, opt) + + if len(ret) == 0 { + panic("no return value specified for ListReleaseAttachments") + } + + var r0 []*gitea.Attachment + var r1 *gitea.Response + var r2 error + if rf, ok := ret.Get(0).(func(string, string, int64, gitea.ListReleaseAttachmentsOptions) ([]*gitea.Attachment, *gitea.Response, error)); ok { + return rf(user, repo, release, opt) + } + if rf, ok := ret.Get(0).(func(string, string, int64, gitea.ListReleaseAttachmentsOptions) []*gitea.Attachment); ok { + r0 = rf(user, repo, release, opt) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*gitea.Attachment) + } + } + + if rf, ok := ret.Get(1).(func(string, string, int64, gitea.ListReleaseAttachmentsOptions) *gitea.Response); ok { + r1 = rf(user, repo, release, opt) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*gitea.Response) + } + } + + if rf, ok := ret.Get(2).(func(string, string, int64, gitea.ListReleaseAttachmentsOptions) error); ok { + r2 = rf(user, repo, release, opt) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockAPIClient_ListReleaseAttachments_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListReleaseAttachments' +type MockAPIClient_ListReleaseAttachments_Call struct { + *mock.Call +} + +// ListReleaseAttachments is a helper method to define mock.On call +// - user string +// - repo string +// - release int64 +// - opt gitea.ListReleaseAttachmentsOptions +func (_e *MockAPIClient_Expecter) ListReleaseAttachments(user interface{}, repo interface{}, release interface{}, opt interface{}) *MockAPIClient_ListReleaseAttachments_Call { + return &MockAPIClient_ListReleaseAttachments_Call{Call: _e.mock.On("ListReleaseAttachments", user, repo, release, opt)} +} + +func (_c *MockAPIClient_ListReleaseAttachments_Call) Run(run func(user string, repo string, release int64, opt gitea.ListReleaseAttachmentsOptions)) *MockAPIClient_ListReleaseAttachments_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string), args[2].(int64), args[3].(gitea.ListReleaseAttachmentsOptions)) + }) + return _c +} + +func (_c *MockAPIClient_ListReleaseAttachments_Call) Return(_a0 []*gitea.Attachment, _a1 *gitea.Response, _a2 error) *MockAPIClient_ListReleaseAttachments_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *MockAPIClient_ListReleaseAttachments_Call) RunAndReturn(run func(string, string, int64, gitea.ListReleaseAttachmentsOptions) ([]*gitea.Attachment, *gitea.Response, error)) *MockAPIClient_ListReleaseAttachments_Call { + _c.Call.Return(run) + return _c +} + +// ListReleases provides a mock function with given fields: owner, repo, opt +func (_m *MockAPIClient) ListReleases(owner string, repo string, opt gitea.ListReleasesOptions) ([]*gitea.Release, *gitea.Response, error) { + ret := _m.Called(owner, repo, opt) + + if len(ret) == 0 { + panic("no return value specified for ListReleases") + } + + var r0 []*gitea.Release + var r1 *gitea.Response + var r2 error + if rf, ok := ret.Get(0).(func(string, string, gitea.ListReleasesOptions) ([]*gitea.Release, *gitea.Response, error)); ok { + return rf(owner, repo, opt) + } + if rf, ok := ret.Get(0).(func(string, string, gitea.ListReleasesOptions) []*gitea.Release); ok { + r0 = rf(owner, repo, opt) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*gitea.Release) + } + } + + if rf, ok := ret.Get(1).(func(string, string, gitea.ListReleasesOptions) *gitea.Response); ok { + r1 = rf(owner, repo, opt) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).(*gitea.Response) + } + } + + if rf, ok := ret.Get(2).(func(string, string, gitea.ListReleasesOptions) error); ok { + r2 = rf(owner, repo, opt) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// MockAPIClient_ListReleases_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ListReleases' +type MockAPIClient_ListReleases_Call struct { + *mock.Call +} + +// ListReleases is a helper method to define mock.On call +// - owner string +// - repo string +// - opt gitea.ListReleasesOptions +func (_e *MockAPIClient_Expecter) ListReleases(owner interface{}, repo interface{}, opt interface{}) *MockAPIClient_ListReleases_Call { + return &MockAPIClient_ListReleases_Call{Call: _e.mock.On("ListReleases", owner, repo, opt)} +} + +func (_c *MockAPIClient_ListReleases_Call) Run(run func(owner string, repo string, opt gitea.ListReleasesOptions)) *MockAPIClient_ListReleases_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(string), args[1].(string), args[2].(gitea.ListReleasesOptions)) + }) + return _c +} + +func (_c *MockAPIClient_ListReleases_Call) Return(_a0 []*gitea.Release, _a1 *gitea.Response, _a2 error) *MockAPIClient_ListReleases_Call { + _c.Call.Return(_a0, _a1, _a2) + return _c +} + +func (_c *MockAPIClient_ListReleases_Call) RunAndReturn(run func(string, string, gitea.ListReleasesOptions) ([]*gitea.Release, *gitea.Response, error)) *MockAPIClient_ListReleases_Call { + _c.Call.Return(run) + return _c +} + +// NewMockAPIClient creates a new instance of MockAPIClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewMockAPIClient(t interface { + mock.TestingT + Cleanup(func()) +}) *MockAPIClient { + mock := &MockAPIClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/go.mod b/go.mod index 1a4d2e7..d369ae0 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shopspring/decimal v1.2.0 // indirect github.com/spf13/cast v1.3.1 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect golang.org/x/net v0.25.0 // indirect golang.org/x/sys v0.20.0 // indirect diff --git a/go.sum b/go.sum index b5b7d64..83f6016 100644 --- a/go.sum +++ b/go.sum @@ -50,6 +50,8 @@ github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= diff --git a/plugin/impl.go b/plugin/impl.go index 7cefe63..1bcda52 100644 --- a/plugin/impl.go +++ b/plugin/impl.go @@ -8,7 +8,7 @@ import ( "path/filepath" "strings" - "code.gitea.io/sdk/gitea" + "github.com/thegeeklab/wp-gitea-release/gitea" "github.com/thegeeklab/wp-plugin-go/v2/file" ) @@ -69,17 +69,12 @@ func (p *Plugin) Validate() error { // Execute provides the implementation of the plugin. func (p *Plugin) Execute() error { - gitea, err := gitea.NewClient( - p.Settings.baseURL.String(), - gitea.SetToken(p.Settings.APIKey), - gitea.SetHTTPClient(p.Network.Client), - ) + client, err := gitea.NewClient(p.Settings.baseURL.String(), p.Settings.APIKey, p.Network.Client) if err != nil { - return err + return fmt.Errorf("failed to create Gitea client: %w", err) } - client := NewGiteaClient(gitea) - client.Release.Opt = GiteaReleaseOpt{ + client.Release.Opt = gitea.ReleaseOpt{ Owner: p.Metadata.Repository.Owner, Repo: p.Metadata.Repository.Name, Tag: strings.TrimPrefix(p.Settings.CommitRef, "refs/tags/"), @@ -91,7 +86,7 @@ func (p *Plugin) Execute() error { } release, err := client.Release.Find() - if err != nil && !errors.Is(err, ErrReleaseNotFound) { + if err != nil && !errors.Is(err, gitea.ErrReleaseNotFound) { return fmt.Errorf("failed to retrieve release: %w", err) }