Upgrade to Go 1.27 (#1407)

This commit is contained in:
Abhinav Gupta
2026-08-22 13:57:32 -04:00
committed by GitHub
parent e2af58995a
commit 699d5ded0d
49 changed files with 206 additions and 277 deletions
+1 -1
View File
@@ -2,7 +2,7 @@ module go.abhg.dev/gs/doc
go 1.24.0
toolchain go1.26.3
toolchain go1.27.0
require github.com/charmbracelet/freeze v0.2.2
+1 -1
View File
@@ -1,6 +1,6 @@
module go.abhg.dev/gs
go 1.26.0
go 1.27.0
require (
charm.land/bubbles/v2 v2.1.0
+1 -1
View File
@@ -181,7 +181,7 @@ func TestDefinition_New_rejectsMismatchedConfiguredURL(t *testing.T) {
{
name: "ShamHub",
def: &shamhub.Definition{
Options: shamhub.Options{URL: "https://shamhub.example.com"},
URL: "https://shamhub.example.com",
},
},
}
+2 -4
View File
@@ -25,10 +25,8 @@ func (r *Repository) FindChangesByBranch(
listOptions := &forgejo.PullRequestListOptions{
State: pullRequestListState(opts.State),
Sort: "recentupdate",
ListOptions: forgejo.ListOptions{
Page: 1,
Limit: 50,
},
Page: 1,
Limit: 50,
}
var changes []*forge.FindChangeItem
+7 -9
View File
@@ -166,15 +166,13 @@ func testConfig(
config := forgetest.Config(t).Forgejo
cfg = forgetest.ForgejoConfig{
URL: cmp.Or(os.Getenv("FORGEJO_URL"), config.URL, canonical.URL),
ForgeConfig: forgetest.ForgeConfig{
Owner: config.Owner,
Repo: config.Repo,
ForkOwner: config.ForkOwner,
ForkRepo: config.ForkRepo,
Reviewer: config.Reviewer,
Assignee: config.Assignee,
},
URL: cmp.Or(os.Getenv("FORGEJO_URL"), config.URL, canonical.URL),
Owner: config.Owner,
Repo: config.Repo,
ForkOwner: config.ForkOwner,
ForkRepo: config.ForkRepo,
Reviewer: config.Reviewer,
Assignee: config.Assignee,
}
return cfg, forgetest.ForgejoConfigSanitizers(cfg, canonical)
+14 -18
View File
@@ -146,30 +146,26 @@ func CanonicalBitbucketConfig() ForgeConfig {
// a single Gitea user account can serve all three roles in tests.
func CanonicalGiteaConfig() GiteaConfig {
return GiteaConfig{
URL: "http://localhost:3000",
ForgeConfig: ForgeConfig{
Owner: CanonicalOwner,
Repo: CanonicalRepo,
ForkOwner: "test-reviewer",
ForkRepo: "test-fork-repo",
Reviewer: "test-reviewer",
Assignee: "test-reviewer",
},
URL: "http://localhost:3000",
Owner: CanonicalOwner,
Repo: CanonicalRepo,
ForkOwner: "test-reviewer",
ForkRepo: "test-fork-repo",
Reviewer: "test-reviewer",
Assignee: "test-reviewer",
}
}
// CanonicalForgejoConfig returns canonical placeholders for Forgejo fixtures.
func CanonicalForgejoConfig() ForgejoConfig {
return ForgejoConfig{
URL: "https://codeberg.org",
ForgeConfig: ForgeConfig{
Owner: CanonicalOwner,
Repo: CanonicalRepo,
ForkOwner: "test-fork-owner",
ForkRepo: CanonicalRepo,
Reviewer: "test-reviewer",
Assignee: "test-assignee",
},
URL: "https://codeberg.org",
Owner: CanonicalOwner,
Repo: CanonicalRepo,
ForkOwner: "test-fork-owner",
ForkRepo: CanonicalRepo,
Reviewer: "test-reviewer",
Assignee: "test-assignee",
}
}
+3 -5
View File
@@ -29,11 +29,9 @@ func TestConfigSanitizers_GitHubRoleCollisions(t *testing.T) {
func TestGiteaConfigSanitizers_URLCollision(t *testing.T) {
cfg := GiteaConfig{
URL: "https://forge.example.com/alice/widgets",
ForgeConfig: ForgeConfig{
Owner: "alice",
Repo: "widgets",
},
URL: "https://forge.example.com/alice/widgets",
Owner: "alice",
Repo: "widgets",
}
got := applyTestSanitizers(
+1 -1
View File
@@ -25,7 +25,7 @@ func (r *Repository) ChangeChecks(
var statuses []*giteagw.CommitStatus
opt := &giteagw.ListCommitStatusOptions{
ListOptions: giteagw.ListOptions{Limit: 100},
Limit: 100,
}
for {
page, resp, err := r.client.CommitStatusList(
+1 -3
View File
@@ -89,9 +89,7 @@ func (r *Repository) ListChangeComments(
return func(yield func(*forge.ListChangeCommentItem, error) bool) {
opts := &giteagw.ListIssueCommentsOptions{
ListOptions: giteagw.ListOptions{
Limit: int64(_listChangeCommentsPageSize),
},
Limit: int64(_listChangeCommentsPageSize),
}
for pageNum := 1; true; pageNum++ {
+1 -3
View File
@@ -40,9 +40,7 @@ func (r *Repository) reviewCommentCounts(
) (*forge.CommentCounts, error) {
var total int
opts := &giteagw.ListPullReviewsOptions{
ListOptions: giteagw.ListOptions{
Limit: _commentCountsReviewPageSize,
},
Limit: _commentCountsReviewPageSize,
}
for {
+2 -4
View File
@@ -34,10 +34,8 @@ func (r *Repository) FindChangesByBranch(ctx context.Context, branch string, opt
for {
prs, resp, err := r.client.PullList(ctx, r.owner, r.repo, &giteagw.ListPullRequestsOptions{
ListOptions: giteagw.ListOptions{
Limit: 50,
Page: page,
},
Limit: 50,
Page: page,
State: state,
Sort: "recentupdate",
})
+7 -9
View File
@@ -46,15 +46,13 @@ func testConfig(t *testing.T) (cfg forgetest.GiteaConfig, sanitizers []forgetest
config := forgetest.Config(t).Gitea
cfg = forgetest.GiteaConfig{
URL: envOr("GITEA_URL", config.URL),
ForgeConfig: forgetest.ForgeConfig{
Owner: envOr("GITEA_TEST_OWNER", config.Owner),
Repo: envOr("GITEA_TEST_REPO", config.Repo),
ForkOwner: envOr("GITEA_TEST_FORK_OWNER", config.ForkOwner),
ForkRepo: envOr("GITEA_TEST_FORK_REPO", config.ForkRepo),
Reviewer: envOr("GITEA_TEST_REVIEWER", config.Reviewer),
Assignee: envOr("GITEA_TEST_ASSIGNEE", config.Assignee),
},
URL: envOr("GITEA_URL", config.URL),
Owner: envOr("GITEA_TEST_OWNER", config.Owner),
Repo: envOr("GITEA_TEST_REPO", config.Repo),
ForkOwner: envOr("GITEA_TEST_FORK_OWNER", config.ForkOwner),
ForkRepo: envOr("GITEA_TEST_FORK_REPO", config.ForkRepo),
Reviewer: envOr("GITEA_TEST_REVIEWER", config.Reviewer),
Assignee: envOr("GITEA_TEST_ASSIGNEE", config.Assignee),
}
return cfg, forgetest.GiteaConfigSanitizers(cfg, canonical)
+1 -1
View File
@@ -46,7 +46,7 @@ func (r *Repository) labelIDs(ctx context.Context) (map[string]int64, error) {
page := int64(1)
for {
labels, resp, err := r.client.LabelList(ctx, r.owner, r.repo, &giteagw.ListLabelsOptions{
ListOptions: giteagw.ListOptions{Page: page, Limit: 50},
Page: page, Limit: 50,
})
if err != nil {
return nil, fmt.Errorf("list labels: %w", err)
+4 -4
View File
@@ -50,9 +50,9 @@ func (r *Repository) fetchTemplate(ctx context.Context, path string) (string, er
}
func templateFilename(path string) string {
idx := strings.LastIndexByte(path, '/')
if idx < 0 {
return path
_, filename, ok := strings.CutLast(path, "/")
if ok {
return filename
}
return path[idx+1:]
return path
}
+1 -2
View File
@@ -552,8 +552,7 @@ type CLIAuthenticator struct {
func (a *CLIAuthenticator) Authenticate(ctx context.Context, _ ui.View) (*AuthenticationToken, error) {
cmd := xec.Command(ctx, nil, a.GH, "auth", "token").WithExecer(a.execer)
if err := cmd.Run(); err != nil {
var exitErr *xec.ExitError
if errors.As(err, &exitErr) {
if exitErr, ok := errors.AsType[*xec.ExitError](err); ok {
return nil, errors.Join(
errors.New("gh is not authenticated"),
fmt.Errorf("stderr: %s", exitErr.Stderr),
+2 -4
View File
@@ -507,8 +507,7 @@ func (gc *glabCLI) Status(ctx context.Context, host string) (ok bool, err error)
cmd := xec.Command(ctx, nil, gc.GL, "auth", "status", "--hostname", host).
WithExecer(gc.execer)
if err := cmd.Run(); err != nil {
var exitErr *xec.ExitError
if errors.As(err, &exitErr) {
if _, ok := errors.AsType[*xec.ExitError](err); ok {
return false, nil
}
@@ -529,8 +528,7 @@ func (gc *glabCLI) Token(ctx context.Context, host string) (string, error) {
WithExecer(gc.execer).
WithStderr(&stderr)
if err := cmd.Run(); err != nil {
var exitErr *xec.ExitError
if errors.As(err, &exitErr) {
if _, ok := errors.AsType[*xec.ExitError](err); ok {
return "", errors.Join(
errors.New("glab is not authenticated"),
fmt.Errorf("stderr: %s", stderr.String()),
+1 -1
View File
@@ -26,7 +26,7 @@ func (r *Repository) ChangeChecks(
var checks []forge.ChangeCheck
opt := &gitlab.ListCommitStatusesOptions{
ListOptions: gitlab.ListOptions{PerPage: 100},
PerPage: 100,
}
if mr.SourceBranch != "" {
opt.Ref = &mr.SourceBranch
+4 -8
View File
@@ -20,10 +20,8 @@ func TestRepository_ChangeChecks(t *testing.T) {
case "/api/v4/projects/42/merge_requests/55":
assert.Empty(t, r.URL.RawQuery)
writeJSON(t, w, gitlab.MergeRequest{
BasicMergeRequest: gitlab.BasicMergeRequest{
SHA: "abc123",
SourceBranch: "feature/refit",
},
SHA: "abc123",
SourceBranch: "feature/refit",
})
case "/api/v4/projects/42/repository/commits/abc123/statuses":
assert.Equal(t, "100", r.URL.Query().Get("per_page"))
@@ -99,10 +97,8 @@ func TestRepository_ChangeChecks_readsCommitStatusesWithoutHeadPipeline(t *testi
case "/api/v4/projects/42/merge_requests/55":
assert.Empty(t, r.URL.RawQuery)
writeJSON(t, w, gitlab.MergeRequest{
BasicMergeRequest: gitlab.BasicMergeRequest{
SHA: "abc123",
SourceBranch: "feature/refit",
},
SHA: "abc123",
SourceBranch: "feature/refit",
})
case "/api/v4/projects/42/repository/commits/abc123/statuses":
assert.Equal(t, "feature/refit", r.URL.Query().Get("ref"))
+2 -4
View File
@@ -162,10 +162,8 @@ func (r *Repository) ListChangeComments(
return func(yield func(*forge.ListChangeCommentItem, error) bool) {
notesOptions := gitlab.ListMergeRequestNotesOptions{
Sort: new("asc"),
ListOptions: gitlab.ListOptions{
PerPage: int64(_listChangeCommentsPageSize),
},
Sort: new("asc"),
PerPage: int64(_listChangeCommentsPageSize),
}
for pageNum := 1; true; pageNum++ {
+1 -1
View File
@@ -36,7 +36,7 @@ func (r *Repository) discussionCounts(
var total, resolved int
opts := &gitlab.ListMergeRequestDiscussionsOptions{
ListOptions: gitlab.ListOptions{PerPage: 100},
PerPage: 100,
}
for {
+1 -3
View File
@@ -131,9 +131,7 @@ func (r *Repository) FindChangesByBranch(ctx context.Context, branch string, opt
opt := &gitlab.ListProjectMergeRequestsOptions{
OrderBy: new("updated_at"),
SourceBranch: new(branch),
ListOptions: gitlab.ListOptions{
PerPage: int64(opts.Limit),
},
PerPage: int64(opts.Limit),
}
if opts.State != 0 {
+2 -4
View File
@@ -56,10 +56,8 @@ func TestRepository_MergeChange_method(t *testing.T) {
}
writeGitLabJSON(t, w, http.StatusOK, gatewaygitlab.MergeRequest{
BasicMergeRequest: gatewaygitlab.BasicMergeRequest{
IID: 55,
State: "merged",
},
IID: 55,
State: "merged",
})
}))
defer srv.Close()
+2 -4
View File
@@ -64,10 +64,8 @@ func TestRepository_ChangeMergeability(t *testing.T) {
assert.Empty(t, r.URL.RawQuery)
writeJSON(t, w, gitlab.MergeRequest{
BasicMergeRequest: gitlab.BasicMergeRequest{
DetailedMergeStatus: tt.status,
HasConflicts: tt.hasConflicts,
},
DetailedMergeStatus: tt.status,
HasConflicts: tt.hasConflicts,
})
},
))
+3 -5
View File
@@ -29,11 +29,9 @@ func (r *Repository) ChangeStatuses(ctx context.Context, ids []forge.ChangeID) (
page := int64(0)
for {
opts := &gitlab.ListProjectMergeRequestsOptions{
ListOptions: gitlab.ListOptions{
PerPage: maxMergeRequestsPerPage,
Page: page,
},
IIDs: &batch,
PerPage: maxMergeRequestsPerPage,
Page: page,
IIDs: &batch,
}
mergeRequests, resp, err := r.client.MergeRequestList(ctx, r.repoID, opts)
if err != nil {
+2 -4
View File
@@ -35,10 +35,8 @@ func TestRepository_SubmitChange_fromPushRepository(t *testing.T) {
assert.NotContains(t, body, "source_project_id")
writeGitLabJSON(t, w, http.StatusCreated, gatewaygitlab.MergeRequest{
BasicMergeRequest: gatewaygitlab.BasicMergeRequest{
IID: 55,
WebURL: "https://gitlab.example.com/test-owner/test-repo/-/merge_requests/55",
},
IID: 55,
WebURL: "https://gitlab.example.com/test-owner/test-repo/-/merge_requests/55",
})
default:
+1 -1
View File
@@ -9,7 +9,7 @@ import (
)
func TestForge_ParseRepositoryPath_knownForge(t *testing.T) {
f := &Forge{Options: Options{URL: "https://shamhub.example"}}
f := &Forge{URL: "https://shamhub.example"}
remoteURL, err := giturl.Parse("git@shamhub-alias:example/repo.git")
require.NoError(t, err)
+1 -2
View File
@@ -174,8 +174,7 @@ func buildRESTHandler[State, Req, Res any](state State, handler func(State, cont
res, err := handler(state, r.Context(), req.(Req))
if err != nil {
var httpErr *httpError
if errors.As(err, &httpErr) {
if httpErr, ok := errors.AsType[*httpError](err); ok {
http.Error(w, httpErr.Error(), httpErr.code)
} else {
http.Error(w, fmt.Sprintf("error: %v", err), http.StatusInternalServerError)
+3 -5
View File
@@ -130,11 +130,9 @@ func TestIntegration(t *testing.T) {
token := tokenFixture.Get(t)
shamForge := &Forge{
Options: Options{
URL: gitURL,
APIURL: apiURL,
},
Log: silogtest.New(t),
URL: gitURL,
APIURL: apiURL,
Log: silogtest.New(t),
}
forgetest.RunIntegration(t, forgetest.IntegrationConfig{
+3 -5
View File
@@ -410,11 +410,9 @@ func newMergeabilityTestRepository(t *testing.T) (*ShamHub, *forgeRepository) {
repository, err := newRepository(
&Forge{
Options: Options{
URL: sh.GitURL(),
APIURL: sh.APIURL(),
},
Log: silog.Nop(),
URL: sh.GitURL(),
APIURL: sh.APIURL(),
Log: silog.Nop(),
},
&AuthenticationToken{tok: token},
&RepositoryID{
+3 -5
View File
@@ -54,11 +54,9 @@ func TestForgeRepository_MergeChange_mergeMethod(t *testing.T) {
repo, err := newRepository(
&Forge{
Options: Options{
URL: "https://example.com",
APIURL: srv.URL,
},
Log: silog.Nop(),
URL: "https://example.com",
APIURL: srv.URL,
Log: silog.Nop(),
},
&AuthenticationToken{tok: "token"},
&RepositoryID{
+5 -5
View File
@@ -100,9 +100,9 @@ func TestClient_PullRequestList(t *testing.T) {
"owner",
"repo",
&PullRequestListOptions{
ListOptions: ListOptions{Limit: 20},
State: "open",
Sort: "recentupdate",
Limit: 20,
State: "open",
Sort: "recentupdate",
},
)
require.NoError(t, err)
@@ -303,8 +303,8 @@ func TestClient_UserSearch(t *testing.T) {
client := newTestClient(t, srv)
users, _, err := client.UserSearch(t.Context(), &UserSearchOptions{
ListOptions: ListOptions{Page: 1},
Query: "reviewer",
Page: 1,
Query: "reviewer",
})
require.NoError(t, err)
require.Len(t, users.Data, 1)
+9 -9
View File
@@ -177,10 +177,10 @@ func TestClient_PullList(t *testing.T) {
client := newTestClient(t, srv)
prs, resp, err := client.PullList(t.Context(), "captain", "warp-core", &ListPullRequestsOptions{
ListOptions: ListOptions{Limit: 10},
State: "open",
Sort: "recentupdate",
Head: "scotty/fix",
Limit: 10,
State: "open",
Sort: "recentupdate",
Head: "scotty/fix",
})
require.NoError(t, err)
require.Len(t, prs, 2)
@@ -230,7 +230,7 @@ func TestClient_PullReviewList(t *testing.T) {
"warp-core",
42,
&ListPullReviewsOptions{
ListOptions: ListOptions{Page: 2, Limit: 20},
Page: 2, Limit: 20,
},
)
require.NoError(t, err)
@@ -335,7 +335,7 @@ func TestClient_CommentList(t *testing.T) {
client := newTestClient(t, srv)
comments, resp, err := client.CommentList(t.Context(), "captain", "warp-core", 42,
&ListIssueCommentsOptions{
ListOptions: ListOptions{Page: 2, Limit: 20},
Page: 2, Limit: 20,
},
)
require.NoError(t, err)
@@ -379,7 +379,7 @@ func TestClient_CommitStatusList(t *testing.T) {
"warp-core",
"abc123",
&ListCommitStatusOptions{
ListOptions: ListOptions{Page: 2, Limit: 20},
Page: 2, Limit: 20,
},
)
require.NoError(t, err)
@@ -401,7 +401,7 @@ func TestClient_LabelList(t *testing.T) {
client := newTestClient(t, srv)
labels, _, err := client.LabelList(t.Context(), "captain", "warp-core",
&ListLabelsOptions{ListOptions: ListOptions{Limit: 50}},
&ListLabelsOptions{Limit: 50},
)
require.NoError(t, err)
require.Len(t, labels, 2)
@@ -484,7 +484,7 @@ func TestClient_PullList_paginated(t *testing.T) {
var all []*PullRequest
opts := &ListPullRequestsOptions{
ListOptions: ListOptions{Limit: 2},
Limit: 2,
}
for {
page, resp, err := client.PullList(t.Context(), "captain", "warp-core", opts)
+28 -46
View File
@@ -92,10 +92,8 @@ func TestClient_MergeRequestCreate(t *testing.T) {
"remove_source_branch":true
}`)
writeJSON(t, w, http.StatusCreated, MergeRequest{
BasicMergeRequest: BasicMergeRequest{
IID: 55,
WebURL: "https://gitlab.example.com/captain/warp-core/-/merge_requests/55",
},
IID: 55,
WebURL: "https://gitlab.example.com/captain/warp-core/-/merge_requests/55",
})
}))
defer srv.Close()
@@ -125,15 +123,13 @@ func TestClient_MergeRequestGet(t *testing.T) {
assert.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, "/api/v4/projects/42/merge_requests/55", r.URL.Path)
writeJSON(t, w, http.StatusOK, MergeRequest{
BasicMergeRequest: BasicMergeRequest{
IID: 55,
Title: "Stabilize nacelles",
TargetBranch: "main",
Labels: []string{"engineering"},
DetailedMergeStatus: DetailedMergeStatusMergeable,
Reviewers: []*BasicUser{
{ID: 12, Username: "spock"},
},
IID: 55,
Title: "Stabilize nacelles",
TargetBranch: "main",
Labels: []string{"engineering"},
DetailedMergeStatus: DetailedMergeStatusMergeable,
Reviewers: []*BasicUser{
{ID: 12, Username: "spock"},
},
})
}))
@@ -161,11 +157,9 @@ func TestClient_MergeRequestUpdate(t *testing.T) {
"state_event":"close"
}`)
writeJSON(t, w, http.StatusOK, MergeRequest{
BasicMergeRequest: BasicMergeRequest{
IID: 55,
Title: "Draft: Stabilize nacelles",
TargetBranch: "release",
},
IID: 55,
Title: "Draft: Stabilize nacelles",
TargetBranch: "release",
})
}))
defer srv.Close()
@@ -204,7 +198,7 @@ func TestClient_MergeRequestList(t *testing.T) {
t.Context(),
int64(42),
&ListProjectMergeRequestsOptions{
ListOptions: ListOptions{PerPage: 20},
PerPage: 20,
IIDs: &[]int64{55, 56},
OrderBy: new("updated_at"),
State: new("opened"),
@@ -245,7 +239,7 @@ func TestClient_MergeRequestList_paginated(t *testing.T) {
var all []*BasicMergeRequest
opts := &ListProjectMergeRequestsOptions{
ListOptions: ListOptions{PerPage: 2},
PerPage: 2,
}
for {
page, resp, err := client.MergeRequestList(t.Context(), int64(42), opts)
@@ -268,10 +262,8 @@ func TestClient_MergeRequestAccept(t *testing.T) {
assert.Equal(t, "/api/v4/projects/42/merge_requests/55/merge", r.URL.Path)
assertJSONBody(t, r, `{"should_remove_source_branch":true}`)
writeJSON(t, w, http.StatusOK, MergeRequest{
BasicMergeRequest: BasicMergeRequest{
IID: 55,
State: "merged",
},
IID: 55,
State: "merged",
})
}))
defer srv.Close()
@@ -295,10 +287,8 @@ func TestClient_MergeRequestAccept_withSHA(t *testing.T) {
assert.Equal(t, "/api/v4/projects/42/merge_requests/55/merge", r.URL.Path)
assertJSONBody(t, r, `{"sha":"abc123"}`)
writeJSON(t, w, http.StatusOK, MergeRequest{
BasicMergeRequest: BasicMergeRequest{
IID: 55,
State: "merged",
},
IID: 55,
State: "merged",
})
}))
defer srv.Close()
@@ -322,10 +312,8 @@ func TestClient_MergeRequestAccept_withSquash(t *testing.T) {
assert.Equal(t, "/api/v4/projects/42/merge_requests/55/merge", r.URL.Path)
assertJSONBody(t, r, `{"squash":true}`)
writeJSON(t, w, http.StatusOK, MergeRequest{
BasicMergeRequest: BasicMergeRequest{
IID: 55,
State: "merged",
},
IID: 55,
State: "merged",
})
}))
defer srv.Close()
@@ -423,11 +411,9 @@ func TestClient_CommitStatusList(t *testing.T) {
int64(42),
"abc123",
&ListCommitStatusesOptions{
Ref: &ref,
ListOptions: ListOptions{
PerPage: 100,
Page: 2,
},
Ref: &ref,
PerPage: 100,
Page: 2,
},
)
require.NoError(t, err)
@@ -541,11 +527,9 @@ func TestClient_MergeRequestNoteList(t *testing.T) {
int64(42),
55,
&ListMergeRequestNotesOptions{
ListOptions: ListOptions{
PerPage: 20,
Page: 2,
},
Sort: new("asc"),
PerPage: 20,
Page: 2,
Sort: new("asc"),
},
)
require.NoError(t, err)
@@ -604,10 +588,8 @@ func TestClient_MergeRequestDiscussionList(t *testing.T) {
int64(42),
55,
&ListMergeRequestDiscussionsOptions{
ListOptions: ListOptions{
PerPage: 100,
Page: 2,
},
PerPage: 100,
Page: 2,
},
)
require.NoError(t, err)
+4 -5
View File
@@ -69,16 +69,15 @@ type ConfigKey string
// Split splits the key into its three parts:
// section, subsection, and name.
func (k ConfigKey) Split() (section, subsection, name string) {
idx := strings.LastIndex(string(k), ".")
if idx == -1 {
prefix, name, ok := strings.CutLast(string(k), ".")
if !ok {
// "foo" => "", "", "foo"
return "", "", string(k)
}
name = string(k[idx+1:])
k = k[:idx]
k = ConfigKey(prefix)
idx = strings.Index(string(k), ".")
idx := strings.Index(string(k), ".")
if idx == -1 {
// "foo.bar" => "foo", "", "bar"
return string(k), "", name
-3
View File
@@ -57,9 +57,6 @@ func InitWorktree(ctx context.Context, dir string, opts InitOptions) (*Worktree,
exec: opts.exec,
indexLockTimeout: _defaultIndexLockTimeout,
}
if opts.IndexLockTimeout != nil {
commonOpts.indexLockTimeout = max(*opts.IndexLockTimeout, 0)
}
if opts.Log != nil {
opts.Log.Debug("Initializing repository", "path", dir)
+1 -2
View File
@@ -261,8 +261,7 @@ func (h *Handler) ListBranches(ctx context.Context, req *BranchesRequest) (*Bran
// reconciled value so this invocation does not render stale commits.
baseHash, err := h.Service.CheckRestacked(ctx, branch.Name)
if err != nil {
var needsRestack *spice.BranchNeedsRestackError
if errors.As(err, &needsRestack) {
if needsRestack, ok := errors.AsType[*spice.BranchNeedsRestackError](err); ok {
item.NeedsRestack = true
baseHash = needsRestack.Upstream
} else {
+1 -2
View File
@@ -756,8 +756,7 @@ func (e *mergePlanExecutor) prepareForMerge(
item *mergeItem,
) error {
if err := e.Service.VerifyRestacked(ctx, item.branch); err != nil {
var restackErr *spice.BranchNeedsRestackError
if !errors.As(err, &restackErr) {
if _, ok := errors.AsType[*spice.BranchNeedsRestackError](err); !ok {
return fmt.Errorf("verify restacked: %w", err)
}
+6 -6
View File
@@ -81,18 +81,18 @@ func (b *Point) Decode(ctx *kong.DecodeContext) error {
return err
}
idx := strings.LastIndex(spec, ":")
commit, name, ok := strings.CutLast(spec, ":")
switch {
case idx == -1:
case !ok:
return fmt.Errorf("expected COMMIT:NAME, got %q", spec)
case len(spec[:idx]) == 0:
case commit == "":
return fmt.Errorf("part before : cannot be empty: %q", spec)
case len(spec[idx+1:]) == 0:
case name == "":
return fmt.Errorf("part after : cannot be empty: %q", spec)
}
b.Commit = spec[:idx]
b.Name = spec[idx+1:]
b.Commit = commit
b.Name = name
return nil
}
+1 -2
View File
@@ -92,8 +92,7 @@ func (h *Handler) SquashBranch(ctx context.Context, branchName string, opts *Opt
}
if err := h.Service.VerifyRestacked(ctx, branchName); err != nil {
var restackErr *spice.BranchNeedsRestackError
if errors.As(err, &restackErr) {
if _, ok := errors.AsType[*spice.BranchNeedsRestackError](err); ok {
return fmt.Errorf("branch %v needs to be restacked before it can be squashed", branchName)
}
return fmt.Errorf("verify restacked: %w", err)
+1 -2
View File
@@ -70,8 +70,7 @@ func (h *Handler) TrackBranch(ctx context.Context, req *BranchRequest) error {
log.Infof("%v: tracking with base %v", req.Branch, req.Base)
if err := h.Service.VerifyRestacked(ctx, req.Branch); err != nil {
var restackErr *spice.BranchNeedsRestackError
if errors.As(err, &restackErr) {
if _, ok := errors.AsType[*spice.BranchNeedsRestackError](err); ok {
log.Infof("%v: branch is behind its base and needs to be restacked.", req.Branch)
log.Infof("%v: run '%s branch restack --branch=%v' to restack it", req.Branch, cli.Name(), req.Branch)
} else {
+1 -1
View File
@@ -5,7 +5,7 @@ import "log/slog"
// Level is a log level.
type Level slog.Level
var _ slog.Leveler = (Level)(0)
var _ slog.Leveler = Level(0)
// Supported log levels.
const (
+3 -5
View File
@@ -47,11 +47,9 @@ func TestService_LookupBranch_changeAssociation(t *testing.T) {
t.Cleanup(shamhubServer.Close)
shamhubForge := &shamhub.Definition{
Log: silogtest.New(t),
Options: shamhub.Options{
URL: shamhubServer.URL,
APIURL: shamhubServer.URL,
},
Log: silogtest.New(t),
URL: shamhubServer.URL,
APIURL: shamhubServer.URL,
}
var forgeReg forge.Registry
+1 -1
View File
@@ -13,7 +13,7 @@ import (
// This is NOT thread safe. Use [SyncBackend] to make it so.
type MapBackend map[string][]byte
var _ Backend = (MapBackend)(nil)
var _ Backend = MapBackend(nil)
// Get retrieves a value from the store.
func (m MapBackend) Get(_ context.Context, key string, dst any) error {
+4 -6
View File
@@ -215,12 +215,10 @@ func (b *BranchTreeSelect) Init() tea.Cmd {
// but it still needs to be shown
// for the tree to render correctly.
base = &branchInfo{
Index: len(b.all),
Visible: true,
BranchTreeItem: BranchTreeItem{
Branch: bi.Base,
Disabled: true,
},
Index: len(b.all),
Visible: true,
Branch: bi.Base,
Disabled: true,
}
b.all = append(b.all, base)
b.idxByName[base.Branch] = base.Index
+1 -2
View File
@@ -46,8 +46,7 @@ func (*logCmd) AfterApply(kctx *kong.Context) error {
Service: svc,
ResolveRepository: func(ctx context.Context, remote string) (forge.Forge, forge.RepositoryID, error) {
f, repoID, err := remoteResolver.Resolve(ctx, remote)
var unsupported *unsupportedForgeError
if errors.As(err, &unsupported) {
if _, ok := errors.AsType[*unsupportedForgeError](err); ok {
return nil, nil, nil
}
return f, repoID, err
+1 -2
View File
@@ -630,8 +630,7 @@ func (cmd *mainCmd) AfterApply(
remoteRepo, err := remoteResolver.Open(ctx, secretStash, remote.Upstream)
if err != nil {
var unsupported *unsupportedForgeError
if !errors.As(err, &unsupported) {
if _, ok := errors.AsType[*unsupportedForgeError](err); !ok {
return nil, err
}
remoteRepo = nil
Generated
+59 -52
View File
@@ -125,113 +125,120 @@ url = "https://github.com/abhinav/gotestsum/releases/download/v1.14.0-beta.1%2Bg
url_api = "https://api.github.com/repos/abhinav/gotestsum/releases/assets/428166818"
[[tools."github:abhinav/requiredfield"]]
version = "0.9.0"
version = "0.10.0"
backend = "github:abhinav/requiredfield"
[tools."github:abhinav/requiredfield"."platforms.linux-arm64"]
checksum = "sha256:1bad25e1570b0df22f551c0ebec3fdb41fed7fb4fdd654ccc36f4fc844c44ec4"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.9.0/requiredfield.Linux-aarch64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/357740555"
checksum = "sha256:67963080de1311c9978c865dd16519139af2b92ff235f562ea9ccaefba730f16"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.10.0/requiredfield.Linux-aarch64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/522684647"
[tools."github:abhinav/requiredfield"."platforms.linux-arm64-musl"]
checksum = "sha256:1bad25e1570b0df22f551c0ebec3fdb41fed7fb4fdd654ccc36f4fc844c44ec4"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.9.0/requiredfield.Linux-aarch64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/357740555"
checksum = "sha256:67963080de1311c9978c865dd16519139af2b92ff235f562ea9ccaefba730f16"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.10.0/requiredfield.Linux-aarch64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/522684647"
[tools."github:abhinav/requiredfield"."platforms.linux-x64"]
checksum = "sha256:46f82f7a552c0fd61dbe3ca7ffa165de85b6d5ed1e97a833fe7d154dfb331bcf"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.9.0/requiredfield.Linux-x86_64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/357740554"
checksum = "sha256:33cf4d87eb1b540ca3efec4d21a070f750557c638da83e29ffbe84eb48b162de"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.10.0/requiredfield.Linux-x86_64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/522684648"
[tools."github:abhinav/requiredfield"."platforms.linux-x64-musl"]
checksum = "sha256:46f82f7a552c0fd61dbe3ca7ffa165de85b6d5ed1e97a833fe7d154dfb331bcf"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.9.0/requiredfield.Linux-x86_64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/357740554"
checksum = "sha256:33cf4d87eb1b540ca3efec4d21a070f750557c638da83e29ffbe84eb48b162de"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.10.0/requiredfield.Linux-x86_64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/522684648"
[tools."github:abhinav/requiredfield"."platforms.macos-arm64"]
checksum = "sha256:a9924eeb3161db4962466f3d2172d998f8719d8afebed5ef4e41c7b6287b9581"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.9.0/requiredfield.Darwin-arm64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/357740565"
checksum = "sha256:01918d9178c2b5d8f12a7d2725b5d89fd672ae69112a5210e9dbb54d106f4c73"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.10.0/requiredfield.Darwin-arm64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/522684668"
[tools."github:abhinav/requiredfield"."platforms.macos-x64"]
checksum = "sha256:3e0c8c89d2b2c9340807b659d76ba5aaaa15a38d178f92d5d59d1a3a4a453d2f"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.9.0/requiredfield.Darwin-x86_64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/357740567"
checksum = "sha256:ec9d06e71a947e5676aede10b67d084be177731f8464173b488efe011f474930"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.10.0/requiredfield.Darwin-x86_64.tar.gz"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/522684670"
[tools."github:abhinav/requiredfield"."platforms.windows-x64"]
checksum = "sha256:d431d9086678669e49a2d609ab77a07ecb1a09d676aa7907c8fa2e39fedd5a29"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.9.0/requiredfield.Windows-x86_64.zip"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/357740550"
checksum = "sha256:66a5af92e063fb84b735b346911799530d521d4b6bdfef7c9fa657f3d41a1d5d"
url = "https://github.com/abhinav/requiredfield/releases/download/v0.10.0/requiredfield.Windows-x86_64.zip"
url_api = "https://api.github.com/repos/abhinav/requiredfield/releases/assets/522684646"
[[tools.go]]
version = "1.26.5"
version = "1.27.0"
backend = "core:go"
[tools.go."platforms.linux-arm64"]
checksum = "sha256:fe4789e92b1f33358680864bbe8704289e7bb5fc207d80623c308935bd696d49"
url = "https://dl.google.com/go/go1.26.5.linux-arm64.tar.gz"
checksum = "sha256:51798d2c42d0e1c6ed7fd9f48728b4193abac9e8aad6dbac2fe96a81f5909bda"
url = "https://dl.google.com/go/go1.27.0.linux-arm64.tar.gz"
[tools.go."platforms.linux-arm64-musl"]
checksum = "sha256:fe4789e92b1f33358680864bbe8704289e7bb5fc207d80623c308935bd696d49"
url = "https://dl.google.com/go/go1.26.5.linux-arm64.tar.gz"
checksum = "sha256:51798d2c42d0e1c6ed7fd9f48728b4193abac9e8aad6dbac2fe96a81f5909bda"
url = "https://dl.google.com/go/go1.27.0.linux-arm64.tar.gz"
[tools.go."platforms.linux-x64"]
checksum = "sha256:5c2c3b16caefa1d968a94c1daca04a7ca301a496d9b086e17ad77bb81393f053"
url = "https://dl.google.com/go/go1.26.5.linux-amd64.tar.gz"
checksum = "sha256:675c26c449cbb18fc24b74650de1eabbae6e16f64326fd85a283fb3b58280685"
url = "https://dl.google.com/go/go1.27.0.linux-amd64.tar.gz"
[tools.go."platforms.linux-x64-musl"]
checksum = "sha256:5c2c3b16caefa1d968a94c1daca04a7ca301a496d9b086e17ad77bb81393f053"
url = "https://dl.google.com/go/go1.26.5.linux-amd64.tar.gz"
checksum = "sha256:675c26c449cbb18fc24b74650de1eabbae6e16f64326fd85a283fb3b58280685"
url = "https://dl.google.com/go/go1.27.0.linux-amd64.tar.gz"
[tools.go."platforms.macos-arm64"]
checksum = "sha256:efb87ff28af9a188d0536ef5d42e63dd52ba8263cd7344a993cc48dd11dedb6a"
url = "https://dl.google.com/go/go1.26.5.darwin-arm64.tar.gz"
checksum = "sha256:90493b3bbd5e10f91d12153198bf1994fd756399b4fec93b49b0c6e2acdeeb3e"
url = "https://dl.google.com/go/go1.27.0.darwin-arm64.tar.gz"
[tools.go."platforms.macos-x64"]
checksum = "sha256:6231d8d3b8f5552ec6cbf6d685bdd5482e1e703214b120e89b3bf0d7bf1ef725"
url = "https://dl.google.com/go/go1.26.5.darwin-amd64.tar.gz"
checksum = "sha256:d3314e25496e4381d71a5c51d2907e7af655d199f6780b549f015bd85fef4986"
url = "https://dl.google.com/go/go1.27.0.darwin-amd64.tar.gz"
[tools.go."platforms.windows-x64"]
checksum = "sha256:97e6b2a833b6d89f9ff17d25419ac0a7e3b482a044e9ab18cdef834bd834fd38"
url = "https://dl.google.com/go/go1.26.5.windows-amd64.zip"
checksum = "sha256:f0c0a0d33ba94f4d2c5dbc887334ce678b21813504ddb3aafcb06e60a5a667c4"
url = "https://dl.google.com/go/go1.27.0.windows-amd64.zip"
[[tools.golangci-lint]]
version = "2.12.2"
version = "2.13.1"
backend = "aqua:golangci/golangci-lint"
[tools.golangci-lint."platforms.linux-arm64"]
checksum = "sha256:44cd40a8c76c86755375adfeea52cfd3533cb43d7bd647771e0ae065e166df3a"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-arm64.tar.gz"
checksum = "sha256:908317c23db18448f924e853b3d8a659fd919614cd438f224810a4053daa2607"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.13.1/golangci-lint-2.13.1-linux-arm64.tar.gz"
url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/522396912"
provenance = "github-attestations"
[tools.golangci-lint."platforms.linux-arm64-musl"]
checksum = "sha256:44cd40a8c76c86755375adfeea52cfd3533cb43d7bd647771e0ae065e166df3a"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-arm64.tar.gz"
checksum = "sha256:908317c23db18448f924e853b3d8a659fd919614cd438f224810a4053daa2607"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.13.1/golangci-lint-2.13.1-linux-arm64.tar.gz"
url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/522396912"
provenance = "github-attestations"
[tools.golangci-lint."platforms.linux-x64"]
checksum = "sha256:8df580d2670fed8fa984aac0507099af8df275e665215f5c7a2ae3943893a553"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-amd64.tar.gz"
checksum = "sha256:b17bfbc9d4aaa48be7f4f1ce3240bc3d8200c870c072bacf15c26219e2cfb9cc"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.13.1/golangci-lint-2.13.1-linux-amd64.tar.gz"
url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/522396872"
provenance = "github-attestations"
[tools.golangci-lint."platforms.linux-x64-musl"]
checksum = "sha256:8df580d2670fed8fa984aac0507099af8df275e665215f5c7a2ae3943893a553"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-linux-amd64.tar.gz"
checksum = "sha256:b17bfbc9d4aaa48be7f4f1ce3240bc3d8200c870c072bacf15c26219e2cfb9cc"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.13.1/golangci-lint-2.13.1-linux-amd64.tar.gz"
url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/522396872"
provenance = "github-attestations"
[tools.golangci-lint."platforms.macos-arm64"]
checksum = "sha256:a9c54498731b3128f79e090be6110f3e5fffccc617b08142ed244d4126c73f29"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-darwin-arm64.tar.gz"
checksum = "sha256:0c9818baf6fb8ad26c6d2ef51b68d5a1e260ef07727036b1431647cc44637c7c"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.13.1/golangci-lint-2.13.1-darwin-arm64.tar.gz"
url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/522396798"
provenance = "github-attestations"
[tools.golangci-lint."platforms.macos-x64"]
checksum = "sha256:f6f06d94b6241521c53d15450c5209b028270bf966f842afb11c030c79f5bc16"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-darwin-amd64.tar.gz"
checksum = "sha256:2c373363953e4e0bee2a03b7fe864a5eb6a3822927cb077d9ca33f2ae3cb2da2"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.13.1/golangci-lint-2.13.1-darwin-amd64.tar.gz"
url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/522396867"
provenance = "github-attestations"
[tools.golangci-lint."platforms.windows-x64"]
checksum = "sha256:bd42e3ebc8cb4ececb86941983baaf1dc221bbb04d838e94ce63b49cc91e02bb"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.12.2/golangci-lint-2.12.2-windows-amd64.zip"
checksum = "sha256:cc119bdd57d2b35ce36fbc174b54949e1a1e45f2cadaf64372cc799cabaf88a9"
url = "https://github.com/golangci/golangci-lint/releases/download/v2.13.1/golangci-lint-2.13.1-windows-amd64.zip"
url_api = "https://api.github.com/repos/golangci/golangci-lint/releases/assets/522396821"
provenance = "github-attestations"
[[tools.requiredfield]]
+1 -2
View File
@@ -58,8 +58,7 @@ func (cmd *rebaseContinueCmd) Run(
// Finish the ongoing rebase.
if err := wt.RebaseContinue(ctx, &opts); err != nil {
var rebaseErr *git.RebaseInterruptError
if errors.As(err, &rebaseErr) {
if _, ok := errors.AsType[*git.RebaseInterruptError](err); ok {
var msg strings.Builder
fmt.Fprintf(&msg, "There are more conflicts to resolve.\n")
fmt.Fprintf(&msg, "Resolve them and run the following command again:\n")
+1 -2
View File
@@ -59,8 +59,7 @@ func (cmd *stackEditCmd) Run(
stack, err := svc.ListStackLinear(ctx, cmd.Branch)
if err != nil {
var nonLinearErr *spice.NonLinearStackError
if errors.As(err, &nonLinearErr) {
if nonLinearErr, ok := errors.AsType[*spice.NonLinearStackError](err); ok {
// TODO: We could provide a prompt here to select a linear stack to edit from.
log.Errorf("%v is part of a stack with a divergent upstack.", cmd.Branch)
log.Errorf("%v has multiple branches above it: %s", nonLinearErr.Branch, strings.Join(nonLinearErr.Aboves, ", "))