diff --git a/github/github.go b/github/github.go index feb3382..2e777f5 100644 --- a/github/github.go +++ b/github/github.go @@ -14,8 +14,6 @@ // limitations under the License. // -//go:build go1.16 - package github import ( diff --git a/github/github_mocks.go b/github/github_mocks.go index 98dc727..d6ebe27 100644 --- a/github/github_mocks.go +++ b/github/github_mocks.go @@ -14,49 +14,63 @@ // limitations under the License. // -//go:build go1.16 - package github import ( "context" "net/http" "os" + "reflect" "testing" "github.com/google/go-github/v64/github" "github.com/stretchr/testify/assert" ) +type assertParams struct { + /* number of index/times the production function has been called by production code, zero based. */ + callIndex int + /* assertParameters is a slice of booleans that determine whether to assert the parameters passed to the function for + each call to the production function. If the value at the index of the callIndex is true, the actual parameters will be + asserted against the expected parameters. */ + assertParameters []bool + /* expectedParameters is a slice of any types of slices that contains the expected parameters that should be passed + to the production function during the running of test. */ + expectedParameters []any +} + +func (a *assertParams) doAssert(t assert.TestingT, actualParameters []any) { + for i, expParams := range a.expectedParameters { + refExpParams := reflect.ValueOf(expParams) + assert.Equal(t, reflect.Slice, refExpParams.Kind(), "expected parameters must be a slice") + epForThisCall := refExpParams.Index(a.callIndex).Interface() + assert.Equal(t, epForThisCall, actualParameters[i]) + } +} + // RepositoriesMock mocks RepositoriesService type RepositoriesMock struct { - t *testing.T - /* callCount is the number of times the CreateStatus function has been called by production code. */ - callCount int - /* assertParameters is a slice of booleans that determine whether to assert the parameters passed to the function for - each call to the CreateStatus function. If the value at the index of the callCount is true, the parameters will be - asserted. - */ - assertParameters []bool - expectedCtx []context.Context - expectedOwner, expectedRepo, expectedRef, expectedUser []string - // expectedOpts *github.ListOptions - expectedCreateStatusRepoStatus []*github.RepoStatus - createStatusRepoStatus []*github.RepoStatus - createStatusResponse []*github.Response - createStatusError []error - isCollaboratorResult bool - isCollaboratorResp *github.Response - isCollaboratorErr error + t *testing.T + assertParamsCreateStatus assertParams + createStatusRepoStatus []*github.RepoStatus + createStatusResponse []*github.Response + createStatusError []error + isCollaboratorResult bool + isCollaboratorResp *github.Response + isCollaboratorErr error } var _ RepositoriesService = (*RepositoriesMock)(nil) -func setupMockRepositoriesService(t *testing.T, assertParameters []bool) (mock *RepositoriesMock) { +func setupMockRepositoriesService(t *testing.T, assertParameters []bool, expectedParams []any) (mock *RepositoriesMock) { mock = &RepositoriesMock{ - t: t, - assertParameters: assertParameters, + t: t, + assertParamsCreateStatus: assertParams{ + assertParameters: assertParameters, + expectedParameters: expectedParams, + }, } + return mock } @@ -67,35 +81,22 @@ func (r *RepositoriesMock) ListStatuses(ctx context.Context, owner, repo, ref st } func (r *RepositoriesMock) CreateStatus(ctx context.Context, owner, repo, ref string, status *github.RepoStatus) (retRepoStatus *github.RepoStatus, createStatusResponse *github.Response, createStatusError error) { - defer func() { r.callCount++ }() - if r.assertParameters != nil && r.assertParameters[r.callCount] { - if r.expectedCtx != nil { - assert.Equal(r.t, r.expectedCtx[r.callCount], ctx) - } - if r.expectedOwner != nil { - assert.Equal(r.t, r.expectedOwner[r.callCount], owner) - } - if r.expectedRepo != nil { - assert.Equal(r.t, r.expectedRepo[r.callCount], repo) - } - if r.expectedRef != nil { - assert.Equal(r.t, r.expectedRef[r.callCount], ref) - } - if r.expectedCreateStatusRepoStatus != nil { - assert.Equal(r.t, r.expectedCreateStatusRepoStatus[r.callCount], status) - } + defer func() { r.assertParamsCreateStatus.callIndex++ }() + if r.assertParamsCreateStatus.assertParameters != nil && r.assertParamsCreateStatus.assertParameters[r.assertParamsCreateStatus.callIndex] { + actualParameters := []any{ctx, owner, repo, ref, status} + r.assertParamsCreateStatus.doAssert(r.t, actualParameters) } if r.createStatusRepoStatus != nil { - retRepoStatus = r.createStatusRepoStatus[r.callCount] + retRepoStatus = r.createStatusRepoStatus[r.assertParamsCreateStatus.callIndex] } if r.createStatusRepoStatus != nil { - createStatusResponse = r.createStatusResponse[r.callCount] + createStatusResponse = r.createStatusResponse[r.assertParamsCreateStatus.callIndex] } if r.createStatusError != nil { - createStatusError = r.createStatusError[r.callCount] + createStatusError = r.createStatusError[r.assertParamsCreateStatus.callIndex] } return } @@ -113,13 +114,8 @@ func (r *RepositoriesMock) Get(context.Context, string, string) (*github.Reposit }, nil, nil } +//goland:noinspection GoUnusedParameter func (r *RepositoriesMock) IsCollaborator(ctx context.Context, owner, repo, user string) (bool, *github.Response, error) { - if r.assertParameters != nil && r.assertParameters[r.callCount] { - assert.Equal(r.t, r.expectedCtx[r.callCount], ctx) - assert.Equal(r.t, r.expectedOwner[r.callCount], owner) - assert.Equal(r.t, r.expectedRepo[r.callCount], repo) - assert.Equal(r.t, r.expectedUser[r.callCount], user) - } return r.isCollaboratorResult, r.isCollaboratorResp, r.isCollaboratorErr } @@ -152,6 +148,8 @@ func (p *PullRequestsMock) ListCommits(ctx context.Context, owner string, repo s } type IssuesMock struct { + t *testing.T + assertParamsCreateComment assertParams mockGetLabel *github.Label MockGetLabelResponse *github.Response mockGetLabelError error @@ -203,6 +201,11 @@ func (i *IssuesMock) RemoveLabelForIssue(ctx context.Context, owner string, repo //goland:noinspection GoUnusedParameter func (i *IssuesMock) CreateComment(ctx context.Context, owner string, repo string, number int, comment *github.IssueComment) (*github.IssueComment, *github.Response, error) { + defer func() { i.assertParamsCreateComment.callIndex++ }() + if i.assertParamsCreateComment.assertParameters != nil && i.assertParamsCreateComment.assertParameters[i.assertParamsCreateComment.callIndex] { + actualParameters := []any{ctx, owner, repo, number, comment} + i.assertParamsCreateComment.doAssert(i.t, actualParameters) + } return i.mockComment, i.mockCreateCommentResponse, i.mockCreateCommentError } @@ -290,6 +293,8 @@ func (g *GHInterfaceMock) NewClient(httpClient *http.Client) GHClient { mockResponse: g.PullRequestsMock.mockResponse, }, Issues: &IssuesMock{ + t: g.IssuesMock.t, + assertParamsCreateComment: g.IssuesMock.assertParamsCreateComment, mockGetLabel: g.IssuesMock.mockGetLabel, MockGetLabelResponse: g.IssuesMock.MockGetLabelResponse, mockGetLabelError: g.IssuesMock.mockGetLabelError, diff --git a/github/github_test.go b/github/github_test.go index 7e13287..bc98655 100644 --- a/github/github_test.go +++ b/github/github_test.go @@ -14,8 +14,6 @@ // limitations under the License. // -//go:build go1.16 - package github import ( @@ -351,7 +349,7 @@ func TestWithFullEnvironment(t *testing.T) { t.Run("TestHandlePullRequestListCommitsError", func(t *testing.T) { forcedError := fmt.Errorf("forced ListCommits error") GHImpl = &GHInterfaceMock{ - RepositoriesMock: *setupMockRepositoriesService(t, []bool{false}), + RepositoriesMock: *setupMockRepositoriesService(t, []bool{false}, nil), PullRequestsMock: PullRequestsMock{ mockListCommitsError: forcedError, }, @@ -390,21 +388,26 @@ func TestWithFullEnvironment(t *testing.T) { t.Run("TestHandlePullRequestListCommitsUnsignedCommit", func(t *testing.T) { authors := []string{"john", "doe"} - repositoriesMock := *setupMockRepositoriesService(t, []bool{true, true}) - repositoriesMock.expectedCtx = []context.Context{context.Background(), context.Background()} - - repositoriesMock.expectedCreateStatusRepoStatus = []*github.RepoStatus{ - { - State: github.String("pending"), - Description: github.String("Paul Botsco, the CLA verifier is running"), - Context: &MockAppSlug, - }, - { - State: github.String("failure"), - Description: github.String("One or more commits haven't met our Quality requirements."), - Context: &MockAppSlug, - }, - } + repositoriesMock := *setupMockRepositoriesService(t, + []bool{true, true}, + []any{ + []context.Context{context.Background(), context.Background()}, // ctx + []string{"", ""}, // owner + []string{"", ""}, // repo + []string{"", ""}, // sha + []*github.RepoStatus{ + { + State: github.String("pending"), + Description: github.String("Paul Botsco, the CLA verifier is running"), + Context: &MockAppSlug, + }, + { + State: github.String("failure"), + Description: github.String("One or more commits haven't met our Quality requirements."), + Context: &MockAppSlug, + }, + }, + }) GHImpl = getGHMock(getMockRepositoryCommits(authors, false), nil, &repositoriesMock) mockDB, logger := setupMockDB(t, false) @@ -542,6 +545,27 @@ func TestHandlePullRequestListCommitsNoAuthor(t *testing.T) { mockRepositoryCommits: mockRepositoryCommits, }, IssuesMock: IssuesMock{ + t: t, + assertParamsCreateComment: assertParams{ + assertParameters: []bool{true}, + expectedParameters: []any{ + []context.Context{context.Background()}, // ctx + []string{""}, // owner + []string{""}, // repo + []int{0}, // number + []*github.IssueComment{ + {Body: github.String( + `Thanks for the contribution. Unfortunately some of your commits don't meet our standards. All commits must be signed and have author information set. + +The commits to review are: + +- johnSHA - missing author :cop: +- johnSHA - unsigned commit :key: +`, + )}, + }, // comment + }, + }, mockGetLabel: &github.Label{}, MockGetLabelResponse: &github.Response{ Response: &http.Response{}, diff --git a/go.mod b/go.mod index cd1853d..3f35d58 100644 --- a/go.mod +++ b/go.mod @@ -1,20 +1,20 @@ module github.com/sonatype-nexus-community/the-cla -go 1.21 +go 1.22.0 -toolchain go1.21.7 +toolchain go1.22.7 require ( github.com/DATA-DOG/go-sqlmock v1.5.2 github.com/bradleyfalzon/ghinstallation/v2 v2.11.0 - github.com/golang-migrate/migrate/v4 v4.17.1 + github.com/golang-migrate/migrate/v4 v4.18.1 github.com/google/go-github/v64 v64.0.0 github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.5.1 github.com/labstack/echo/v4 v4.12.0 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 - golang.org/x/oauth2 v0.21.0 + golang.org/x/oauth2 v0.23.0 gopkg.in/go-playground/webhooks.v5 v5.17.0 ) @@ -35,10 +35,10 @@ require ( github.com/valyala/fasttemplate v1.2.2 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.5.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect + golang.org/x/time v0.6.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 37d0f8a..6f0fc70 100644 --- a/go.sum +++ b/go.sum @@ -4,18 +4,22 @@ github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7Oputl github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/bradleyfalzon/ghinstallation/v2 v2.11.0 h1:R9d0v+iobRHSaE4wKUnXFiZp53AL4ED5MzgEMwGTZag= github.com/bradleyfalzon/ghinstallation/v2 v2.11.0/go.mod h1:0LWKQwOHewXO/1acI6TtyE0Xc4ObDb2rFN7eHBAG71M= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dhui/dktest v0.4.1 h1:/w+IWuDXVymg3IrRJCHHOkMK10m9aNVMOyD0X12YVTg= github.com/dhui/dktest v0.4.1/go.mod h1:DdOqcUpL7vgyP4GlF3X3w7HbSlz8cEQzwewPveYEQbA= +github.com/dhui/dktest v0.4.3 h1:wquqUxAFdcUgabAVLvSCOKOlag5cIZuaOjYIBOWdsR0= github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.2.0+incompatible h1:Rk9nIVdfH3+Vz4cyI/uhbINhEZ/oLmc+CBXmH6fbNk4= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -26,6 +30,8 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4= github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM= +github.com/golang-migrate/migrate/v4 v4.18.1 h1:JML/k+t4tpHCpQTCAD62Nu43NUFzHY4CV3uAuvHGC+Y= +github.com/golang-migrate/migrate/v4 v4.18.1/go.mod h1:HAX6m3sQgcdO81tdjn5exv20+3Kb13cmGli1hrD6hks= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -44,6 +50,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/sqlstruct v0.0.0-20201105191214-5f3e10d3ab46/go.mod h1:yyMNCyc/Ib3bDTKd379tNMpB/7/H5TjM2Y9QJ5THLbE= github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0= github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= @@ -64,6 +72,7 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -74,6 +83,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -82,27 +93,66 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= +golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/go-playground/webhooks.v5 v5.17.0 h1:truBced5ZmkiNKK47cM8bMe86wUSjNks7SFMuNKwzlc=