From 5b88bc75ab6e43dbdd83365e156d285707efe601 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Wed, 12 Jul 2023 23:43:32 +0200 Subject: [PATCH] Allow gitea dev version (#914) (#1988) Backport #914 Close #1987 * update gitea sdk to latest * As before try to autodetect gitea version, if this does not work, assume it's latest version (v1.17.0 atm) --- go.mod | 4 +- go.sum | 10 +- server/remote/gitea/gitea.go | 11 +- vendor/code.gitea.io/sdk/gitea/attachment.go | 6 +- vendor/code.gitea.io/sdk/gitea/client.go | 110 +++++++++-------- vendor/code.gitea.io/sdk/gitea/fork.go | 4 +- .../code.gitea.io/sdk/gitea/hook_validate.go | 59 +++++++++ vendor/code.gitea.io/sdk/gitea/issue.go | 10 ++ .../sdk/gitea/issue_milestone.go | 14 +-- .../code.gitea.io/sdk/gitea/list_options.go | 18 ++- .../code.gitea.io/sdk/gitea/notifications.go | 18 ++- vendor/code.gitea.io/sdk/gitea/org_team.go | 47 +++++++- vendor/code.gitea.io/sdk/gitea/pull.go | 49 ++++++-- vendor/code.gitea.io/sdk/gitea/pull_review.go | 2 +- vendor/code.gitea.io/sdk/gitea/release.go | 8 +- vendor/code.gitea.io/sdk/gitea/repo.go | 11 +- .../sdk/gitea/repo_collaborator.go | 4 +- vendor/code.gitea.io/sdk/gitea/repo_commit.go | 28 +++-- .../code.gitea.io/sdk/gitea/repo_migrate.go | 2 +- .../code.gitea.io/sdk/gitea/repo_transfer.go | 26 ++++ vendor/code.gitea.io/sdk/gitea/repo_tree.go | 2 +- vendor/code.gitea.io/sdk/gitea/repo_watch.go | 2 +- vendor/code.gitea.io/sdk/gitea/user.go | 1 - vendor/code.gitea.io/sdk/gitea/user_app.go | 4 +- vendor/code.gitea.io/sdk/gitea/version.go | 38 ++++-- .../hashicorp/go-version/CHANGELOG.md | 45 +++++++ .../github.com/hashicorp/go-version/README.md | 2 +- .../hashicorp/go-version/constraint.go | 114 ++++++++++++++++-- .../hashicorp/go-version/version.go | 31 ++++- vendor/modules.txt | 4 +- 30 files changed, 531 insertions(+), 153 deletions(-) create mode 100644 vendor/code.gitea.io/sdk/gitea/hook_validate.go create mode 100644 vendor/github.com/hashicorp/go-version/CHANGELOG.md diff --git a/go.mod b/go.mod index 8e2757784..4dca50a4f 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/woodpecker-ci/woodpecker go 1.18 require ( - code.gitea.io/sdk/gitea v0.15.0 + code.gitea.io/sdk/gitea v0.15.1-0.20220501190934-319a978c6c71 codeberg.org/6543/go-yaml2json v1.0.0 github.com/bmatcuk/doublestar/v4 v4.0.2 github.com/docker/cli v20.10.12+incompatible @@ -123,7 +123,7 @@ require ( github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-retryablehttp v0.7.0 // indirect - github.com/hashicorp/go-version v1.2.1 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect diff --git a/go.sum b/go.sum index 1ca077987..46755a47f 100644 --- a/go.sum +++ b/go.sum @@ -52,9 +52,8 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= -code.gitea.io/sdk/gitea v0.15.0 h1:tsNhxDM/2N1Ohv1Xq5UWrht/esg0WmtRj4wsHVHriTg= -code.gitea.io/sdk/gitea v0.15.0/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA= +code.gitea.io/sdk/gitea v0.15.1-0.20220501190934-319a978c6c71 h1:+ZqwhfAftVOAd7AcLpfh4LBdTeJIyt60vGU39zhQPyA= +code.gitea.io/sdk/gitea v0.15.1-0.20220501190934-319a978c6c71/go.mod h1:MuMGvUxT8BmFHa0gHhHsrnz91QfmziXuFffm9AuhMCo= codeberg.org/6543/go-yaml2json v1.0.0 h1:heGqo9VEi7gY2yNqjj7X4ADs5nzlFIbGsJtgYDLrnig= codeberg.org/6543/go-yaml2json v1.0.0/go.mod h1:mz61q14LWF4ZABrgMEDMmk3t9dPi6zgR1uBh2VKV2RQ= contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= @@ -531,8 +530,10 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI= github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -1506,7 +1507,6 @@ golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= diff --git a/server/remote/gitea/gitea.go b/server/remote/gitea/gitea.go index ceebd86d7..c94bcb1d3 100644 --- a/server/remote/gitea/gitea.go +++ b/server/remote/gitea/gitea.go @@ -26,9 +26,11 @@ import ( "net/url" "path" "path/filepath" + "strings" "time" "code.gitea.io/sdk/gitea" + "github.com/rs/zerolog/log" "golang.org/x/oauth2" "github.com/woodpecker-ci/woodpecker/server" @@ -41,6 +43,7 @@ const ( authorizeTokenURL = "%s/login/oauth/authorize" accessTokenURL = "%s/login/oauth/access_token" perPage = 50 + giteaDevVersion = "v1.17.0" ) type Gitea struct { @@ -467,7 +470,13 @@ func (c *Gitea) newClientToken(ctx context.Context, token string) (*gitea.Client TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } } - return gitea.NewClient(c.URL, gitea.SetToken(token), gitea.SetHTTPClient(httpClient), gitea.SetContext(ctx)) + client, err := gitea.NewClient(c.URL, gitea.SetToken(token), gitea.SetHTTPClient(httpClient), gitea.SetContext(ctx)) + if err != nil && strings.Contains(err.Error(), "Malformed version") { + // we guess it's a dev gitea version + log.Error().Err(err).Msgf("could not detect gitea version, assume dev version %s", giteaDevVersion) + client, err = gitea.NewClient(c.URL, gitea.SetGiteaVersion(giteaDevVersion), gitea.SetToken(token), gitea.SetHTTPClient(httpClient), gitea.SetContext(ctx)) + } + return client, err } // getStatus is a helper function that converts a Woodpecker diff --git a/vendor/code.gitea.io/sdk/gitea/attachment.go b/vendor/code.gitea.io/sdk/gitea/attachment.go index 24c57baf4..f02c72141 100644 --- a/vendor/code.gitea.io/sdk/gitea/attachment.go +++ b/vendor/code.gitea.io/sdk/gitea/attachment.go @@ -43,7 +43,7 @@ func (c *Client) ListReleaseAttachments(user, repo string, release int64, opt Li } // GetReleaseAttachment returns the requested attachment -func (c *Client) GetReleaseAttachment(user, repo string, release int64, id int64) (*Attachment, *Response, error) { +func (c *Client) GetReleaseAttachment(user, repo string, release, id int64) (*Attachment, *Response, error) { if err := escapeValidatePathSegments(&user, &repo); err != nil { return nil, nil, err } @@ -88,7 +88,7 @@ type EditAttachmentOptions struct { } // EditReleaseAttachment updates the given attachment with the given options -func (c *Client) EditReleaseAttachment(user, repo string, release int64, attachment int64, form EditAttachmentOptions) (*Attachment, *Response, error) { +func (c *Client) EditReleaseAttachment(user, repo string, release, attachment int64, form EditAttachmentOptions) (*Attachment, *Response, error) { if err := escapeValidatePathSegments(&user, &repo); err != nil { return nil, nil, err } @@ -102,7 +102,7 @@ func (c *Client) EditReleaseAttachment(user, repo string, release int64, attachm } // DeleteReleaseAttachment deletes the given attachment including the uploaded file -func (c *Client) DeleteReleaseAttachment(user, repo string, release int64, id int64) (*Response, error) { +func (c *Client) DeleteReleaseAttachment(user, repo string, release, id int64) (*Response, error) { if err := escapeValidatePathSegments(&user, &repo); err != nil { return nil, err } diff --git a/vendor/code.gitea.io/sdk/gitea/client.go b/vendor/code.gitea.io/sdk/gitea/client.go index 9f857f85a..a821ddb47 100644 --- a/vendor/code.gitea.io/sdk/gitea/client.go +++ b/vendor/code.gitea.io/sdk/gitea/client.go @@ -6,9 +6,9 @@ package gitea import ( + "bytes" "context" "encoding/json" - "errors" "fmt" "io" "io/ioutil" @@ -24,23 +24,25 @@ var jsonHeader = http.Header{"content-type": []string{"application/json"}} // Version return the library version func Version() string { - return "0.14.0" + return "0.16.0" } // Client represents a thread-safe Gitea API client. type Client struct { - url string - accessToken string - username string - password string - otp string - sudo string - debug bool - client *http.Client - ctx context.Context - mutex sync.RWMutex + url string + accessToken string + username string + password string + otp string + sudo string + debug bool + client *http.Client + ctx context.Context + mutex sync.RWMutex + serverVersion *version.Version getVersionOnce sync.Once + ignoreVersion bool // only set by SetGiteaVersion so don't need a mutex lock } // Response represents the gitea response @@ -48,16 +50,21 @@ type Response struct { *http.Response } +// ClientOption are functions used to init a new client +type ClientOption func(*Client) error + // NewClient initializes and returns a API client. // Usage of all gitea.Client methods is concurrency-safe. -func NewClient(url string, options ...func(*Client)) (*Client, error) { +func NewClient(url string, options ...ClientOption) (*Client, error) { client := &Client{ url: strings.TrimSuffix(url, "/"), client: &http.Client{}, ctx: context.Background(), } for _, opt := range options { - opt(client) + if err := opt(client); err != nil { + return nil, err + } } if err := client.checkServerVersionGreaterThanOrEqual(version1_11_0); err != nil { return nil, err @@ -73,9 +80,10 @@ func NewClientWithHTTP(url string, httpClient *http.Client) *Client { } // SetHTTPClient is an option for NewClient to set custom http client -func SetHTTPClient(httpClient *http.Client) func(client *Client) { - return func(client *Client) { +func SetHTTPClient(httpClient *http.Client) ClientOption { + return func(client *Client) error { client.SetHTTPClient(httpClient) + return nil } } @@ -87,18 +95,20 @@ func (c *Client) SetHTTPClient(client *http.Client) { } // SetToken is an option for NewClient to set token -func SetToken(token string) func(client *Client) { - return func(client *Client) { +func SetToken(token string) ClientOption { + return func(client *Client) error { client.mutex.Lock() client.accessToken = token client.mutex.Unlock() + return nil } } // SetBasicAuth is an option for NewClient to set username and password -func SetBasicAuth(username, password string) func(client *Client) { - return func(client *Client) { +func SetBasicAuth(username, password string) ClientOption { + return func(client *Client) error { client.SetBasicAuth(username, password) + return nil } } @@ -110,9 +120,10 @@ func (c *Client) SetBasicAuth(username, password string) { } // SetOTP is an option for NewClient to set OTP for 2FA -func SetOTP(otp string) func(client *Client) { - return func(client *Client) { +func SetOTP(otp string) ClientOption { + return func(client *Client) error { client.SetOTP(otp) + return nil } } @@ -123,14 +134,15 @@ func (c *Client) SetOTP(otp string) { c.mutex.Unlock() } -// SetContext is an option for NewClient to set context -func SetContext(ctx context.Context) func(client *Client) { - return func(client *Client) { +// SetContext is an option for NewClient to set the default context +func SetContext(ctx context.Context) ClientOption { + return func(client *Client) error { client.SetContext(ctx) + return nil } } -// SetContext set context witch is used for http requests +// SetContext set default context witch is used for http requests func (c *Client) SetContext(ctx context.Context) { c.mutex.Lock() c.ctx = ctx @@ -138,9 +150,10 @@ func (c *Client) SetContext(ctx context.Context) { } // SetSudo is an option for NewClient to set sudo header -func SetSudo(sudo string) func(client *Client) { - return func(client *Client) { +func SetSudo(sudo string) ClientOption { + return func(client *Client) error { client.SetSudo(sudo) + return nil } } @@ -152,11 +165,12 @@ func (c *Client) SetSudo(sudo string) { } // SetDebugMode is an option for NewClient to enable debug mode -func SetDebugMode() func(client *Client) { - return func(client *Client) { +func SetDebugMode() ClientOption { + return func(client *Client) error { client.mutex.Lock() client.debug = true client.mutex.Unlock() + return nil } } @@ -185,14 +199,20 @@ func (c *Client) getWebResponse(method, path string, body io.Reader) ([]byte, *R if debug { fmt.Printf("Response: %v\n\n", resp) } - return data, &Response{resp}, nil + return data, &Response{resp}, err } func (c *Client) doRequest(method, path string, header http.Header, body io.Reader) (*Response, error) { c.mutex.RLock() debug := c.debug if debug { - fmt.Printf("%s: %s\nHeader: %v\nBody: %s\n", method, c.url+"/api/v1"+path, header, body) + var bodyStr string + if body != nil { + bs, _ := ioutil.ReadAll(body) + body = bytes.NewReader(bs) + bodyStr = string(bs) + } + fmt.Printf("%s: %s\nHeader: %v\nBody: %s\n", method, c.url+"/api/v1"+path, header, bodyStr) } req, err := http.NewRequestWithContext(c.ctx, method, c.url+"/api/v1"+path, body) if err != nil { @@ -248,27 +268,23 @@ func statusCodeToErr(resp *Response) (body []byte, err error) { return nil, fmt.Errorf("body read on HTTP error %d: %v", resp.StatusCode, err) } - switch resp.StatusCode { - case 403: - return data, errors.New("403 Forbidden") - case 404: - return data, errors.New("404 Not Found") - case 409: - return data, errors.New("409 Conflict") - case 422: - return data, fmt.Errorf("422 Unprocessable Entity: %s", string(data)) - } - - path := resp.Request.URL.Path - method := resp.Request.Method - header := resp.Request.Header + // Try to unmarshal and get an error message errMap := make(map[string]interface{}) if err = json.Unmarshal(data, &errMap); err != nil { // when the JSON can't be parsed, data was probably empty or a // plain string, so we try to return a helpful error anyway + path := resp.Request.URL.Path + method := resp.Request.Method + header := resp.Request.Header return data, fmt.Errorf("Unknown API Error: %d\nRequest: '%s' with '%s' method '%s' header and '%s' body", resp.StatusCode, path, method, header, string(data)) } - return data, errors.New(errMap["message"].(string)) + + if msg, ok := errMap["message"]; ok { + return data, fmt.Errorf("%v", msg) + } + + // If no error message, at least give status and data + return data, fmt.Errorf("%s: %s", resp.Status, string(data)) } func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, *Response, error) { diff --git a/vendor/code.gitea.io/sdk/gitea/fork.go b/vendor/code.gitea.io/sdk/gitea/fork.go index c8e5323bc..0373c352b 100644 --- a/vendor/code.gitea.io/sdk/gitea/fork.go +++ b/vendor/code.gitea.io/sdk/gitea/fork.go @@ -16,7 +16,7 @@ type ListForksOptions struct { } // ListForks list a repository's forks -func (c *Client) ListForks(user string, repo string, opt ListForksOptions) ([]*Repository, *Response, error) { +func (c *Client) ListForks(user, repo string, opt ListForksOptions) ([]*Repository, *Response, error) { if err := escapeValidatePathSegments(&user, &repo); err != nil { return nil, nil, err } @@ -32,6 +32,8 @@ func (c *Client) ListForks(user string, repo string, opt ListForksOptions) ([]*R type CreateForkOption struct { // organization name, if forking into an organization Organization *string `json:"organization"` + // name of the forked repository + Name *string `json:"name"` } // CreateFork create a fork of a repository diff --git a/vendor/code.gitea.io/sdk/gitea/hook_validate.go b/vendor/code.gitea.io/sdk/gitea/hook_validate.go new file mode 100644 index 000000000..5ef614938 --- /dev/null +++ b/vendor/code.gitea.io/sdk/gitea/hook_validate.go @@ -0,0 +1,59 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package gitea + +import ( + "bytes" + "crypto/hmac" + "crypto/sha256" + "encoding/hex" + "io" + "net/http" +) + +// VerifyWebhookSignature verifies that a payload matches the X-Gitea-Signature based on a secret +func VerifyWebhookSignature(secret, expected string, payload []byte) (bool, error) { + hash := hmac.New(sha256.New, []byte(secret)) + if _, err := hash.Write(payload); err != nil { + return false, err + } + expectedSum, err := hex.DecodeString(expected) + if err != nil { + return false, err + } + return hmac.Equal(hash.Sum(nil), expectedSum), nil +} + +// VerifyWebhookSignatureMiddleware is a http.Handler for verifying X-Gitea-Signature on incoming webhooks +func VerifyWebhookSignatureMiddleware(secret string) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var b bytes.Buffer + if _, err := io.Copy(&b, r.Body); err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + expected := r.Header.Get("X-Gitea-Signature") + if expected == "" { + http.Error(w, "no signature found", http.StatusBadRequest) + return + } + + ok, err := VerifyWebhookSignature(secret, expected, b.Bytes()) + if err != nil { + http.Error(w, err.Error(), http.StatusUnauthorized) + return + } + if !ok { + http.Error(w, "invalid payload", http.StatusUnauthorized) + return + } + + r.Body = io.NopCloser(&b) + next.ServeHTTP(w, r) + }) + } +} diff --git a/vendor/code.gitea.io/sdk/gitea/issue.go b/vendor/code.gitea.io/sdk/gitea/issue.go index c33856a4d..660e7c513 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue.go +++ b/vendor/code.gitea.io/sdk/gitea/issue.go @@ -71,6 +71,10 @@ type ListIssueOption struct { AssignedBy string // filter by username mentioned MentionedBy string + // filter by owner (only works on ListIssues on User) + Owner string + // filter by team (requires organization owner parameter to be provided and only works on ListIssues on User) + Team string } // StateType issue state type @@ -135,6 +139,12 @@ func (opt *ListIssueOption) QueryEncode() string { if len(opt.MentionedBy) > 0 { query.Add("mentioned_by", opt.MentionedBy) } + if len(opt.Owner) > 0 { + query.Add("owner", opt.Owner) + } + if len(opt.Team) > 0 { + query.Add("team", opt.MentionedBy) + } return query.Encode() } diff --git a/vendor/code.gitea.io/sdk/gitea/issue_milestone.go b/vendor/code.gitea.io/sdk/gitea/issue_milestone.go index a865a4583..4e0d79a9f 100644 --- a/vendor/code.gitea.io/sdk/gitea/issue_milestone.go +++ b/vendor/code.gitea.io/sdk/gitea/issue_milestone.go @@ -72,8 +72,8 @@ func (c *Client) GetMilestone(owner, repo string, id int64) (*Milestone, *Respon } // GetMilestoneByName get one milestone by repo and milestone name -func (c *Client) GetMilestoneByName(owner, repo string, name string) (*Milestone, *Response, error) { - if c.CheckServerVersionConstraint(">=1.13") != nil { +func (c *Client) GetMilestoneByName(owner, repo, name string) (*Milestone, *Response, error) { + if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil { // backwards compatibility mode m, resp, err := c.resolveMilestoneByName(owner, repo, name) return m, resp, err @@ -163,8 +163,8 @@ func (c *Client) EditMilestone(owner, repo string, id int64, opt EditMilestoneOp } // EditMilestoneByName modify milestone with options -func (c *Client) EditMilestoneByName(owner, repo string, name string, opt EditMilestoneOption) (*Milestone, *Response, error) { - if c.CheckServerVersionConstraint(">=1.13") != nil { +func (c *Client) EditMilestoneByName(owner, repo, name string, opt EditMilestoneOption) (*Milestone, *Response, error) { + if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil { // backwards compatibility mode m, _, err := c.resolveMilestoneByName(owner, repo, name) if err != nil { @@ -197,8 +197,8 @@ func (c *Client) DeleteMilestone(owner, repo string, id int64) (*Response, error } // DeleteMilestoneByName delete one milestone by name -func (c *Client) DeleteMilestoneByName(owner, repo string, name string) (*Response, error) { - if c.CheckServerVersionConstraint(">=1.13") != nil { +func (c *Client) DeleteMilestoneByName(owner, repo, name string) (*Response, error) { + if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil { // backwards compatibility mode m, _, err := c.resolveMilestoneByName(owner, repo, name) if err != nil { @@ -229,7 +229,7 @@ func (c *Client) resolveMilestoneByName(owner, repo, name string) (*Milestone, * return nil, nil, fmt.Errorf("milestone '%s' do not exist", name) } for _, m := range miles { - if strings.ToLower(strings.TrimSpace(m.Title)) == strings.ToLower(strings.TrimSpace(name)) { + if strings.EqualFold(strings.TrimSpace(m.Title), strings.TrimSpace(name)) { return m, resp, nil } } diff --git a/vendor/code.gitea.io/sdk/gitea/list_options.go b/vendor/code.gitea.io/sdk/gitea/list_options.go index 6f3ffb231..fb1aff4e8 100644 --- a/vendor/code.gitea.io/sdk/gitea/list_options.go +++ b/vendor/code.gitea.io/sdk/gitea/list_options.go @@ -9,12 +9,13 @@ import ( "net/url" ) -const defaultPageSize = 10 -const maxPageSize = 50 - // ListOptions options for using Gitea's API pagination type ListOptions struct { - Page int + // Setting Page to -1 disables pagination on endpoints that support it. + // Page numbering starts at 1. + Page int + // The default value depends on the server config DEFAULT_PAGING_NUM + // The highest valid value depends on the server config MAX_RESPONSE_ITEMS PageSize int } @@ -26,8 +27,9 @@ func (o ListOptions) getURLQuery() url.Values { return query } -// setDefaults set default pagination options if none or wrong are set -// if you set -1 as page it will set all to 0 +// setDefaults applies default pagination options. +// If .Page is set to -1, it will disable pagination. +// WARNING: This function is not idempotent, make sure to never call this method twice! func (o *ListOptions) setDefaults() { if o.Page < 0 { o.Page, o.PageSize = 0, 0 @@ -35,8 +37,4 @@ func (o *ListOptions) setDefaults() { } else if o.Page == 0 { o.Page = 1 } - - if o.PageSize < 0 || o.PageSize > maxPageSize { - o.PageSize = defaultPageSize - } } diff --git a/vendor/code.gitea.io/sdk/gitea/notifications.go b/vendor/code.gitea.io/sdk/gitea/notifications.go index 8b1ffa7ba..bb77bb81f 100644 --- a/vendor/code.gitea.io/sdk/gitea/notifications.go +++ b/vendor/code.gitea.io/sdk/gitea/notifications.go @@ -8,12 +8,6 @@ import ( "fmt" "net/url" "time" - - "github.com/hashicorp/go-version" -) - -var ( - version1_12_3, _ = version.NewVersion("1.12.3") ) // NotificationThread expose Notification on API @@ -29,11 +23,13 @@ type NotificationThread struct { // NotificationSubject contains the notification subject (Issue/Pull/Commit) type NotificationSubject struct { - Title string `json:"title"` - URL string `json:"url"` - LatestCommentURL string `json:"latest_comment_url"` - Type NotifySubjectType `json:"type"` - State NotifySubjectState `json:"state"` + Title string `json:"title"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + LatestCommentURL string `json:"latest_comment_url"` + LatestCommentHTMLURL string `json:"latest_comment_html_url"` + Type NotifySubjectType `json:"type"` + State NotifySubjectState `json:"state"` } // NotifyStatus notification status type diff --git a/vendor/code.gitea.io/sdk/gitea/org_team.go b/vendor/code.gitea.io/sdk/gitea/org_team.go index 4b1b27b4b..e4de31e05 100644 --- a/vendor/code.gitea.io/sdk/gitea/org_team.go +++ b/vendor/code.gitea.io/sdk/gitea/org_team.go @@ -8,6 +8,7 @@ import ( "bytes" "encoding/json" "fmt" + "net/url" ) // Team represents a team in an organization @@ -75,6 +76,44 @@ func (c *Client) GetTeam(id int64) (*Team, *Response, error) { return t, resp, err } +// SearchTeamsOptions options for searching teams. +type SearchTeamsOptions struct { + ListOptions + Query string + IncludeDescription bool +} + +func (o SearchTeamsOptions) getURLQuery() url.Values { + query := make(url.Values) + query.Add("page", fmt.Sprintf("%d", o.Page)) + query.Add("limit", fmt.Sprintf("%d", o.PageSize)) + query.Add("q", o.Query) + query.Add("include_desc", fmt.Sprintf("%t", o.IncludeDescription)) + + return query +} + +// TeamSearchResults is the JSON struct that is returned from Team search API. +type TeamSearchResults struct { + OK bool `json:"ok"` + Error string `json:"error"` + Data []*Team `json:"data"` +} + +// SearchOrgTeams search for teams in a org. +func (c *Client) SearchOrgTeams(org string, opt *SearchTeamsOptions) ([]*Team, *Response, error) { + responseBody := TeamSearchResults{} + opt.setDefaults() + resp, err := c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s/teams/search?%s", org, opt.getURLQuery().Encode()), nil, nil, &responseBody) + if err != nil { + return nil, resp, err + } + if !responseBody.OK { + return nil, resp, fmt.Errorf("gitea error: %v", responseBody.Error) + } + return responseBody.Data, resp, err +} + // CreateTeamOption options for creating a team type CreateTeamOption struct { Name string `json:"name"` @@ -86,7 +125,7 @@ type CreateTeamOption struct { } // Validate the CreateTeamOption struct -func (opt CreateTeamOption) Validate() error { +func (opt *CreateTeamOption) Validate() error { if opt.Permission == AccessModeOwner { opt.Permission = AccessModeAdmin } else if opt.Permission != AccessModeRead && opt.Permission != AccessModeWrite && opt.Permission != AccessModeAdmin { @@ -109,7 +148,7 @@ func (c *Client) CreateTeam(org string, opt CreateTeamOption) (*Team, *Response, if err := escapeValidatePathSegments(&org); err != nil { return nil, nil, err } - if err := opt.Validate(); err != nil { + if err := (&opt).Validate(); err != nil { return nil, nil, err } body, err := json.Marshal(&opt) @@ -132,7 +171,7 @@ type EditTeamOption struct { } // Validate the EditTeamOption struct -func (opt EditTeamOption) Validate() error { +func (opt *EditTeamOption) Validate() error { if opt.Permission == AccessModeOwner { opt.Permission = AccessModeAdmin } else if opt.Permission != AccessModeRead && opt.Permission != AccessModeWrite && opt.Permission != AccessModeAdmin { @@ -152,7 +191,7 @@ func (opt EditTeamOption) Validate() error { // EditTeam edits a team of an organization func (c *Client) EditTeam(id int64, opt EditTeamOption) (*Response, error) { - if err := opt.Validate(); err != nil { + if err := (&opt).Validate(); err != nil { return nil, err } body, err := json.Marshal(&opt) diff --git a/vendor/code.gitea.io/sdk/gitea/pull.go b/vendor/code.gitea.io/sdk/gitea/pull.go index 9528762bf..e27784797 100644 --- a/vendor/code.gitea.io/sdk/gitea/pull.go +++ b/vendor/code.gitea.io/sdk/gitea/pull.go @@ -209,15 +209,18 @@ func (c *Client) EditPullRequest(owner, repo string, index int64, opt EditPullRe // MergePullRequestOption options when merging a pull request type MergePullRequestOption struct { - Style MergeStyle `json:"Do"` - Title string `json:"MergeTitleField"` - Message string `json:"MergeMessageField"` + Style MergeStyle `json:"Do"` + MergeCommitID string `json:"MergeCommitID"` + Title string `json:"MergeTitleField"` + Message string `json:"MergeMessageField"` + DeleteBranchAfterMerge bool `json:"delete_branch_after_merge"` + ForceMerge bool `json:"force_merge"` } // Validate the MergePullRequestOption struct func (opt MergePullRequestOption) Validate(c *Client) error { if opt.Style == MergeStyleSquash { - if err := c.CheckServerVersionConstraint(">=1.11.5"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_11_5); err != nil { return err } } @@ -249,7 +252,6 @@ func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, *Re return false, nil, err } status, resp, err := c.getStatusCode("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d/merge", owner, repo, index), nil, nil) - if err != nil { return false, resp, err } @@ -257,9 +259,29 @@ func (c *Client) IsPullRequestMerged(owner, repo string, index int64) (bool, *Re return status == 204, resp, nil } +// PullRequestDiffOptions options for GET /repos///pulls/.[diff|patch] +type PullRequestDiffOptions struct { + // Include binary file changes when requesting a .diff + Binary bool +} + +// QueryEncode converts the options to a query string +func (o PullRequestDiffOptions) QueryEncode() string { + query := make(url.Values) + query.Add("binary", fmt.Sprintf("%v", o.Binary)) + return query.Encode() +} + +type pullRequestDiffType string + +const ( + pullRequestDiffTypeDiff pullRequestDiffType = "diff" + pullRequestDiffTypePatch pullRequestDiffType = "patch" +) + // getPullRequestDiffOrPatch gets the patch or diff file as bytes for a PR -func (c *Client) getPullRequestDiffOrPatch(owner, repo, kind string, index int64) ([]byte, *Response, error) { - if err := escapeValidatePathSegments(&owner, &repo, &kind); err != nil { +func (c *Client) getPullRequestDiffOrPatch(owner, repo string, kind pullRequestDiffType, index int64, opts PullRequestDiffOptions) ([]byte, *Response, error) { + if err := escapeValidatePathSegments(&owner, &repo); err != nil { return nil, nil, err } if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { @@ -270,19 +292,20 @@ func (c *Client) getPullRequestDiffOrPatch(owner, repo, kind string, index int64 if r.Private { return nil, nil, err } - return c.getWebResponse("GET", fmt.Sprintf("/%s/%s/pulls/%d.%s", owner, repo, index, kind), nil) + url := fmt.Sprintf("/%s/%s/pulls/%d.%s?%s", owner, repo, index, kind, opts.QueryEncode()) + return c.getWebResponse("GET", url, nil) } return c.getResponse("GET", fmt.Sprintf("/repos/%s/%s/pulls/%d.%s", owner, repo, index, kind), nil, nil) } -// GetPullRequestPatch gets the .patch file as bytes for a PR +// GetPullRequestPatch gets the git patchset of a PR func (c *Client) GetPullRequestPatch(owner, repo string, index int64) ([]byte, *Response, error) { - return c.getPullRequestDiffOrPatch(owner, repo, "patch", index) + return c.getPullRequestDiffOrPatch(owner, repo, pullRequestDiffTypePatch, index, PullRequestDiffOptions{}) } -// GetPullRequestDiff gets the .diff file as bytes for a PR -func (c *Client) GetPullRequestDiff(owner, repo string, index int64) ([]byte, *Response, error) { - return c.getPullRequestDiffOrPatch(owner, repo, "diff", index) +// GetPullRequestDiff gets the diff of a PR. For Gitea >= 1.16, you must set includeBinary to get an applicable diff +func (c *Client) GetPullRequestDiff(owner, repo string, index int64, opts PullRequestDiffOptions) ([]byte, *Response, error) { + return c.getPullRequestDiffOrPatch(owner, repo, pullRequestDiffTypeDiff, index, opts) } // ListPullRequestCommitsOptions options for listing pull requests diff --git a/vendor/code.gitea.io/sdk/gitea/pull_review.go b/vendor/code.gitea.io/sdk/gitea/pull_review.go index a484dfdd9..6d32c4f12 100644 --- a/vendor/code.gitea.io/sdk/gitea/pull_review.go +++ b/vendor/code.gitea.io/sdk/gitea/pull_review.go @@ -116,7 +116,7 @@ type ListPullReviewsOptions struct { // Validate the CreatePullReviewOptions struct func (opt CreatePullReviewOptions) Validate() error { - if opt.State != ReviewStateApproved && len(strings.TrimSpace(opt.Body)) == 0 { + if opt.State != ReviewStateApproved && len(opt.Comments) == 0 && len(strings.TrimSpace(opt.Body)) == 0 { return fmt.Errorf("body is empty") } for i := range opt.Comments { diff --git a/vendor/code.gitea.io/sdk/gitea/release.go b/vendor/code.gitea.io/sdk/gitea/release.go index c8e7681d0..3200f2034 100644 --- a/vendor/code.gitea.io/sdk/gitea/release.go +++ b/vendor/code.gitea.io/sdk/gitea/release.go @@ -47,7 +47,7 @@ func (opt *ListReleasesOptions) QueryEncode() string { query.Add("draft", fmt.Sprintf("%t", *opt.IsDraft)) } if opt.IsPreRelease != nil { - query.Add("draft", fmt.Sprintf("%t", *opt.IsPreRelease)) + query.Add("pre-release", fmt.Sprintf("%t", *opt.IsPreRelease)) } return query.Encode() @@ -79,7 +79,7 @@ func (c *Client) GetRelease(owner, repo string, id int64) (*Release, *Response, } // GetReleaseByTag get a release of a repository by tag -func (c *Client) GetReleaseByTag(owner, repo string, tag string) (*Release, *Response, error) { +func (c *Client) GetReleaseByTag(owner, repo, tag string) (*Release, *Response, error) { if c.checkServerVersionGreaterThanOrEqual(version1_13_0) != nil { return c.fallbackGetReleaseByTag(owner, repo, tag) } @@ -168,7 +168,7 @@ func (c *Client) DeleteRelease(user, repo string, id int64) (*Response, error) { } // DeleteReleaseByTag deletes a release frm a repository by tag -func (c *Client) DeleteReleaseByTag(user, repo string, tag string) (*Response, error) { +func (c *Client) DeleteReleaseByTag(user, repo, tag string) (*Response, error) { if err := escapeValidatePathSegments(&user, &repo, &tag); err != nil { return nil, err } @@ -182,7 +182,7 @@ func (c *Client) DeleteReleaseByTag(user, repo string, tag string) (*Response, e } // fallbackGetReleaseByTag is fallback for old gitea installations ( < 1.13.0 ) -func (c *Client) fallbackGetReleaseByTag(owner, repo string, tag string) (*Release, *Response, error) { +func (c *Client) fallbackGetReleaseByTag(owner, repo, tag string) (*Release, *Response, error) { for i := 1; ; i++ { rl, resp, err := c.ListReleases(owner, repo, ListReleasesOptions{ListOptions: ListOptions{Page: i}}) if err != nil { diff --git a/vendor/code.gitea.io/sdk/gitea/repo.go b/vendor/code.gitea.io/sdk/gitea/repo.go index 9c669ae9b..8f0e346ab 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo.go +++ b/vendor/code.gitea.io/sdk/gitea/repo.go @@ -93,6 +93,7 @@ type Repository struct { AvatarURL string `json:"avatar_url"` Internal bool `json:"internal"` MirrorInterval string `json:"mirror_interval"` + MirrorUpdated time.Time `json:"mirror_updated,omitempty"` DefaultMergeStyle MergeStyle `json:"default_merge_style"` } @@ -286,7 +287,9 @@ func (c *Client) SearchRepos(opt SearchRepoOptions) ([]*Repository, *Response, e // private repos only not supported on gitea <= 1.11.x return nil, nil, err } - link.Query().Add("private", "false") + newQuery := link.Query() + newQuery.Add("private", "false") + link.RawQuery = newQuery.Encode() } } @@ -329,13 +332,13 @@ func (opt CreateRepoOption) Validate(c *Client) error { return fmt.Errorf("name has more than 100 chars") } if len(opt.Description) > 255 { - return fmt.Errorf("name has more than 255 chars") + return fmt.Errorf("description has more than 255 chars") } if len(opt.DefaultBranch) > 100 { - return fmt.Errorf("name has more than 100 chars") + return fmt.Errorf("default branch name has more than 100 chars") } if len(opt.TrustModel) != 0 { - if err := c.CheckServerVersionConstraint(">=1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return err } } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go b/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go index c766250f4..ab730df16 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_collaborator.go @@ -66,7 +66,7 @@ const ( ) // Validate the AddCollaboratorOption struct -func (opt AddCollaboratorOption) Validate() error { +func (opt *AddCollaboratorOption) Validate() error { if opt.Permission != nil { if *opt.Permission == AccessModeOwner { *opt.Permission = AccessModeAdmin @@ -88,7 +88,7 @@ func (c *Client) AddCollaborator(user, repo, collaborator string, opt AddCollabo if err := escapeValidatePathSegments(&user, &repo, &collaborator); err != nil { return nil, err } - if err := opt.Validate(); err != nil { + if err := (&opt).Validate(); err != nil { return nil, err } body, err := json.Marshal(&opt) diff --git a/vendor/code.gitea.io/sdk/gitea/repo_commit.go b/vendor/code.gitea.io/sdk/gitea/repo_commit.go index 9bb65b3b1..72bb28cbb 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_commit.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_commit.go @@ -32,11 +32,19 @@ type CommitUser struct { // RepoCommit contains information of a commit in the context of a repository. type RepoCommit struct { - URL string `json:"url"` - Author *CommitUser `json:"author"` - Committer *CommitUser `json:"committer"` - Message string `json:"message"` - Tree *CommitMeta `json:"tree"` + URL string `json:"url"` + Author *CommitUser `json:"author"` + Committer *CommitUser `json:"committer"` + Message string `json:"message"` + Tree *CommitMeta `json:"tree"` + Verification *PayloadCommitVerification `json:"verification"` +} + +// CommitStats contains stats from a Git commit +type CommitStats struct { + Total int `json:"total"` + Additions int `json:"additions"` + Deletions int `json:"deletions"` } // Commit contains information generated from a Git commit. @@ -48,6 +56,7 @@ type Commit struct { Committer *User `json:"committer"` Parents []*CommitMeta `json:"parents"` Files []*CommitAffectedFiles `json:"files"` + Stats *CommitStats `json:"stats"` } // CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE @@ -74,16 +83,21 @@ func (c *Client) GetSingleCommit(user, repo, commitID string) (*Commit, *Respons // ListCommitOptions list commit options type ListCommitOptions struct { ListOptions - //SHA or branch to start listing commits from (usually 'master') + // SHA or branch to start listing commits from (usually 'master') SHA string + // Path indicates that only commits that include the path's file/dir should be returned. + Path string } // QueryEncode turns options into querystring argument func (opt *ListCommitOptions) QueryEncode() string { - query := opt.ListOptions.getURLQuery() + query := opt.getURLQuery() if opt.SHA != "" { query.Add("sha", opt.SHA) } + if opt.Path != "" { + query.Add("path", opt.Path) + } return query.Encode() } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_migrate.go b/vendor/code.gitea.io/sdk/gitea/repo_migrate.go index cd0fe44c8..3ab690e53 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_migrate.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_migrate.go @@ -16,7 +16,7 @@ type GitServiceType string const ( // GitServicePlain represents a plain git service GitServicePlain GitServiceType = "git" - //GitServiceGithub represents github.com + // GitServiceGithub represents github.com GitServiceGithub GitServiceType = "github" // GitServiceGitlab represents a gitlab service GitServiceGitlab GitServiceType = "gitlab" diff --git a/vendor/code.gitea.io/sdk/gitea/repo_transfer.go b/vendor/code.gitea.io/sdk/gitea/repo_transfer.go index be06010a7..534a6e42c 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_transfer.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_transfer.go @@ -34,3 +34,29 @@ func (c *Client) TransferRepo(owner, reponame string, opt TransferRepoOption) (* resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/transfer", owner, reponame), jsonHeader, bytes.NewReader(body), repo) return repo, resp, err } + +// AcceptRepoTransfer accepts a repo transfer. +func (c *Client) AcceptRepoTransfer(owner, reponame string) (*Repository, *Response, error) { + if err := escapeValidatePathSegments(&owner, &reponame); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_16_0); err != nil { + return nil, nil, err + } + repo := new(Repository) + resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/transfer/accept", owner, reponame), jsonHeader, nil, repo) + return repo, resp, err +} + +// RejectRepoTransfer rejects a repo transfer. +func (c *Client) RejectRepoTransfer(owner, reponame string) (*Repository, *Response, error) { + if err := escapeValidatePathSegments(&owner, &reponame); err != nil { + return nil, nil, err + } + if err := c.checkServerVersionGreaterThanOrEqual(version1_16_0); err != nil { + return nil, nil, err + } + repo := new(Repository) + resp, err := c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/transfer/reject", owner, reponame), jsonHeader, nil, repo) + return repo, resp, err +} diff --git a/vendor/code.gitea.io/sdk/gitea/repo_tree.go b/vendor/code.gitea.io/sdk/gitea/repo_tree.go index 452394a3c..c9ffc55e3 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_tree.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_tree.go @@ -35,7 +35,7 @@ func (c *Client) GetTrees(user, repo, ref string, recursive bool) (*GitTreeRespo return nil, nil, err } trees := new(GitTreeResponse) - var path = fmt.Sprintf("/repos/%s/%s/git/trees/%s", user, repo, ref) + path := fmt.Sprintf("/repos/%s/%s/git/trees/%s", user, repo, ref) if recursive { path += "?recursive=1" } diff --git a/vendor/code.gitea.io/sdk/gitea/repo_watch.go b/vendor/code.gitea.io/sdk/gitea/repo_watch.go index f499aff22..c36ca6403 100644 --- a/vendor/code.gitea.io/sdk/gitea/repo_watch.go +++ b/vendor/code.gitea.io/sdk/gitea/repo_watch.go @@ -33,7 +33,7 @@ func (c *Client) GetWatchedRepos(user string) ([]*Repository, *Response, error) // GetMyWatchedRepos list repositories watched by the authenticated user func (c *Client) GetMyWatchedRepos() ([]*Repository, *Response, error) { repos := make([]*Repository, 0, 10) - resp, err := c.getParsedResponse("GET", fmt.Sprintf("/user/subscriptions"), nil, nil, &repos) + resp, err := c.getParsedResponse("GET", "/user/subscriptions", nil, nil, &repos) return repos, resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/user.go b/vendor/code.gitea.io/sdk/gitea/user.go index c37627bfa..67208fb06 100644 --- a/vendor/code.gitea.io/sdk/gitea/user.go +++ b/vendor/code.gitea.io/sdk/gitea/user.go @@ -77,7 +77,6 @@ func (c *Client) GetUserByID(id int64) (*User, *Response, error) { query := make(url.Values) query.Add("uid", strconv.FormatInt(id, 10)) users, resp, err := c.searchUsers(query.Encode()) - if err != nil { return nil, resp, err } diff --git a/vendor/code.gitea.io/sdk/gitea/user_app.go b/vendor/code.gitea.io/sdk/gitea/user_app.go index 2921eea7d..eb3ef21c6 100644 --- a/vendor/code.gitea.io/sdk/gitea/user_app.go +++ b/vendor/code.gitea.io/sdk/gitea/user_app.go @@ -71,13 +71,13 @@ func (c *Client) DeleteAccessToken(value interface{}) (*Response, error) { return nil, fmt.Errorf("\"username\" not set: only BasicAuth allowed") } - var token = "" + token := "" switch reflect.ValueOf(value).Kind() { case reflect.Int64: token = fmt.Sprintf("%d", value.(int64)) case reflect.String: - if err := c.CheckServerVersionConstraint(">= 1.13.0"); err != nil { + if err := c.checkServerVersionGreaterThanOrEqual(version1_13_0); err != nil { return nil, err } token = value.(string) diff --git a/vendor/code.gitea.io/sdk/gitea/version.go b/vendor/code.gitea.io/sdk/gitea/version.go index 449ad97f2..83f6df9fe 100644 --- a/vendor/code.gitea.io/sdk/gitea/version.go +++ b/vendor/code.gitea.io/sdk/gitea/version.go @@ -12,7 +12,7 @@ import ( // ServerVersion returns the version of the server func (c *Client) ServerVersion() (string, *Response, error) { - var v = struct { + v := struct { Version string `json:"version"` }{} resp, err := c.getParsedResponse("GET", "/version", nil, nil, &v) @@ -39,17 +39,41 @@ func (c *Client) CheckServerVersionConstraint(constraint string) error { return nil } +// SetGiteaVersion configures the Client to assume the given version of the +// Gitea server, instead of querying the server for it when initializing. +// Use "" to skip all canonical ways in the SDK to check for versions +func SetGiteaVersion(v string) ClientOption { + if v == "" { + return func(c *Client) error { + c.ignoreVersion = true + return nil + } + } + return func(c *Client) (err error) { + c.getVersionOnce.Do(func() { + c.serverVersion, err = version.NewVersion(v) + }) + return + } +} + // predefined versions only have to be parsed by library once var ( - version1_11_0, _ = version.NewVersion("1.11.0") - version1_12_0, _ = version.NewVersion("1.12.0") - version1_13_0, _ = version.NewVersion("1.13.0") - version1_14_0, _ = version.NewVersion("1.14.0") - version1_15_0, _ = version.NewVersion("1.15.0") + version1_11_0 = version.Must(version.NewVersion("1.11.0")) + version1_11_5 = version.Must(version.NewVersion("1.11.5")) + version1_12_0 = version.Must(version.NewVersion("1.12.0")) + version1_12_3 = version.Must(version.NewVersion("1.12.3")) + version1_13_0 = version.Must(version.NewVersion("1.13.0")) + version1_14_0 = version.Must(version.NewVersion("1.14.0")) + version1_15_0 = version.Must(version.NewVersion("1.15.0")) + version1_16_0 = version.Must(version.NewVersion("1.16.0")) ) -// checkServerVersionGreaterThanOrEqual is internally used to speed up things and ignore issues with prerelease +// checkServerVersionGreaterThanOrEqual is the canonical way in the SDK to check for versions for API compatibility reasons func (c *Client) checkServerVersionGreaterThanOrEqual(v *version.Version) error { + if c.ignoreVersion { + return nil + } if err := c.loadServerVersion(); err != nil { return err } diff --git a/vendor/github.com/hashicorp/go-version/CHANGELOG.md b/vendor/github.com/hashicorp/go-version/CHANGELOG.md new file mode 100644 index 000000000..5f16dd140 --- /dev/null +++ b/vendor/github.com/hashicorp/go-version/CHANGELOG.md @@ -0,0 +1,45 @@ +# 1.6.0 (June 28, 2022) + +FEATURES: + +- Add `Prerelease` function to `Constraint` to return true if the version includes a prerelease field ([#100](https://github.com/hashicorp/go-version/pull/100)) + +# 1.5.0 (May 18, 2022) + +FEATURES: + +- Use `encoding` `TextMarshaler` & `TextUnmarshaler` instead of JSON equivalents ([#95](https://github.com/hashicorp/go-version/pull/95)) +- Add JSON handlers to allow parsing from/to JSON ([#93](https://github.com/hashicorp/go-version/pull/93)) + +# 1.4.0 (January 5, 2022) + +FEATURES: + + - Introduce `MustConstraints()` ([#87](https://github.com/hashicorp/go-version/pull/87)) + - `Constraints`: Introduce `Equals()` and `sort.Interface` methods ([#88](https://github.com/hashicorp/go-version/pull/88)) + +# 1.3.0 (March 31, 2021) + +Please note that CHANGELOG.md does not exist in the source code prior to this release. + +FEATURES: + - Add `Core` function to return a version without prerelease or metadata ([#85](https://github.com/hashicorp/go-version/pull/85)) + +# 1.2.1 (June 17, 2020) + +BUG FIXES: + - Prevent `Version.Equal` method from panicking on `nil` encounter ([#73](https://github.com/hashicorp/go-version/pull/73)) + +# 1.2.0 (April 23, 2019) + +FEATURES: + - Add `GreaterThanOrEqual` and `LessThanOrEqual` helper methods ([#53](https://github.com/hashicorp/go-version/pull/53)) + +# 1.1.0 (Jan 07, 2019) + +FEATURES: + - Add `NewSemver` constructor ([#45](https://github.com/hashicorp/go-version/pull/45)) + +# 1.0.0 (August 24, 2018) + +Initial release. diff --git a/vendor/github.com/hashicorp/go-version/README.md b/vendor/github.com/hashicorp/go-version/README.md index 851a337be..4d2505090 100644 --- a/vendor/github.com/hashicorp/go-version/README.md +++ b/vendor/github.com/hashicorp/go-version/README.md @@ -1,5 +1,5 @@ # Versioning Library for Go -[![Build Status](https://circleci.com/gh/hashicorp/go-version/tree/master.svg?style=svg)](https://circleci.com/gh/hashicorp/go-version/tree/master) +[![Build Status](https://circleci.com/gh/hashicorp/go-version/tree/main.svg?style=svg)](https://circleci.com/gh/hashicorp/go-version/tree/main) [![GoDoc](https://godoc.org/github.com/hashicorp/go-version?status.svg)](https://godoc.org/github.com/hashicorp/go-version) go-version is a library for parsing versions and version constraints, diff --git a/vendor/github.com/hashicorp/go-version/constraint.go b/vendor/github.com/hashicorp/go-version/constraint.go index d05575961..da5d1aca1 100644 --- a/vendor/github.com/hashicorp/go-version/constraint.go +++ b/vendor/github.com/hashicorp/go-version/constraint.go @@ -4,6 +4,7 @@ import ( "fmt" "reflect" "regexp" + "sort" "strings" ) @@ -11,30 +12,40 @@ import ( // ">= 1.0". type Constraint struct { f constraintFunc + op operator check *Version original string } +func (c *Constraint) Equals(con *Constraint) bool { + return c.op == con.op && c.check.Equal(con.check) +} + // Constraints is a slice of constraints. We make a custom type so that // we can add methods to it. type Constraints []*Constraint type constraintFunc func(v, c *Version) bool -var constraintOperators map[string]constraintFunc +var constraintOperators map[string]constraintOperation + +type constraintOperation struct { + op operator + f constraintFunc +} var constraintRegexp *regexp.Regexp func init() { - constraintOperators = map[string]constraintFunc{ - "": constraintEqual, - "=": constraintEqual, - "!=": constraintNotEqual, - ">": constraintGreaterThan, - "<": constraintLessThan, - ">=": constraintGreaterThanEqual, - "<=": constraintLessThanEqual, - "~>": constraintPessimistic, + constraintOperators = map[string]constraintOperation{ + "": {op: equal, f: constraintEqual}, + "=": {op: equal, f: constraintEqual}, + "!=": {op: notEqual, f: constraintNotEqual}, + ">": {op: greaterThan, f: constraintGreaterThan}, + "<": {op: lessThan, f: constraintLessThan}, + ">=": {op: greaterThanEqual, f: constraintGreaterThanEqual}, + "<=": {op: lessThanEqual, f: constraintLessThanEqual}, + "~>": {op: pessimistic, f: constraintPessimistic}, } ops := make([]string, 0, len(constraintOperators)) @@ -66,6 +77,16 @@ func NewConstraint(v string) (Constraints, error) { return Constraints(result), nil } +// MustConstraints is a helper that wraps a call to a function +// returning (Constraints, error) and panics if error is non-nil. +func MustConstraints(c Constraints, err error) Constraints { + if err != nil { + panic(err) + } + + return c +} + // Check tests if a version satisfies all the constraints. func (cs Constraints) Check(v *Version) bool { for _, c := range cs { @@ -77,6 +98,56 @@ func (cs Constraints) Check(v *Version) bool { return true } +// Equals compares Constraints with other Constraints +// for equality. This may not represent logical equivalence +// of compared constraints. +// e.g. even though '>0.1,>0.2' is logically equivalent +// to '>0.2' it is *NOT* treated as equal. +// +// Missing operator is treated as equal to '=', whitespaces +// are ignored and constraints are sorted before comaparison. +func (cs Constraints) Equals(c Constraints) bool { + if len(cs) != len(c) { + return false + } + + // make copies to retain order of the original slices + left := make(Constraints, len(cs)) + copy(left, cs) + sort.Stable(left) + right := make(Constraints, len(c)) + copy(right, c) + sort.Stable(right) + + // compare sorted slices + for i, con := range left { + if !con.Equals(right[i]) { + return false + } + } + + return true +} + +func (cs Constraints) Len() int { + return len(cs) +} + +func (cs Constraints) Less(i, j int) bool { + if cs[i].op < cs[j].op { + return true + } + if cs[i].op > cs[j].op { + return false + } + + return cs[i].check.LessThan(cs[j].check) +} + +func (cs Constraints) Swap(i, j int) { + cs[i], cs[j] = cs[j], cs[i] +} + // Returns the string format of the constraints func (cs Constraints) String() string { csStr := make([]string, len(cs)) @@ -92,6 +163,12 @@ func (c *Constraint) Check(v *Version) bool { return c.f(v, c.check) } +// Prerelease returns true if the version underlying this constraint +// contains a prerelease field. +func (c *Constraint) Prerelease() bool { + return len(c.check.Prerelease()) > 0 +} + func (c *Constraint) String() string { return c.original } @@ -107,8 +184,11 @@ func parseSingle(v string) (*Constraint, error) { return nil, err } + cop := constraintOperators[matches[1]] + return &Constraint{ - f: constraintOperators[matches[1]], + f: cop.f, + op: cop.op, check: check, original: v, }, nil @@ -138,6 +218,18 @@ func prereleaseCheck(v, c *Version) bool { // Constraint functions //------------------------------------------------------------------- +type operator rune + +const ( + equal operator = '=' + notEqual operator = '≠' + greaterThan operator = '>' + lessThan operator = '<' + greaterThanEqual operator = '≥' + lessThanEqual operator = '≤' + pessimistic operator = '~' +) + func constraintEqual(v, c *Version) bool { return v.Equal(c) } diff --git a/vendor/github.com/hashicorp/go-version/version.go b/vendor/github.com/hashicorp/go-version/version.go index 09703e8e6..e87df6990 100644 --- a/vendor/github.com/hashicorp/go-version/version.go +++ b/vendor/github.com/hashicorp/go-version/version.go @@ -64,7 +64,6 @@ func newVersion(v string, pattern *regexp.Regexp) (*Version, error) { } segmentsStr := strings.Split(matches[1], ".") segments := make([]int64, len(segmentsStr)) - si := 0 for i, str := range segmentsStr { val, err := strconv.ParseInt(str, 10, 64) if err != nil { @@ -72,8 +71,7 @@ func newVersion(v string, pattern *regexp.Regexp) (*Version, error) { "Error parsing version: %s", err) } - segments[i] = int64(val) - si++ + segments[i] = val } // Even though we could support more than three segments, if we @@ -92,7 +90,7 @@ func newVersion(v string, pattern *regexp.Regexp) (*Version, error) { metadata: matches[10], pre: pre, segments: segments, - si: si, + si: len(segmentsStr), original: v, }, nil } @@ -278,6 +276,14 @@ func comparePrereleases(v string, other string) int { return 0 } +// Core returns a new version constructed from only the MAJOR.MINOR.PATCH +// segments of the version, without prerelease or metadata. +func (v *Version) Core() *Version { + segments := v.Segments64() + segmentsOnly := fmt.Sprintf("%d.%d.%d", segments[0], segments[1], segments[2]) + return Must(NewVersion(segmentsOnly)) +} + // Equal tests if two versions are equal. func (v *Version) Equal(o *Version) bool { if v == nil || o == nil { @@ -382,3 +388,20 @@ func (v *Version) String() string { func (v *Version) Original() string { return v.original } + +// UnmarshalText implements encoding.TextUnmarshaler interface. +func (v *Version) UnmarshalText(b []byte) error { + temp, err := NewVersion(string(b)) + if err != nil { + return err + } + + *v = *temp + + return nil +} + +// MarshalText implements encoding.TextMarshaler interface. +func (v *Version) MarshalText() ([]byte, error) { + return []byte(v.String()), nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index db7ab62ad..63a7c8d4e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,7 +1,7 @@ # 4d63.com/gochecknoglobals v0.1.0 ## explicit; go 1.15 4d63.com/gochecknoglobals/checknoglobals -# code.gitea.io/sdk/gitea v0.15.0 +# code.gitea.io/sdk/gitea v0.15.1-0.20220501190934-319a978c6c71 ## explicit; go 1.13 code.gitea.io/sdk/gitea # codeberg.org/6543/go-yaml2json v1.0.0 @@ -405,7 +405,7 @@ github.com/hashicorp/go-multierror # github.com/hashicorp/go-retryablehttp v0.7.0 ## explicit; go 1.13 github.com/hashicorp/go-retryablehttp -# github.com/hashicorp/go-version v1.2.1 +# github.com/hashicorp/go-version v1.6.0 ## explicit github.com/hashicorp/go-version # github.com/hashicorp/hcl v1.0.0