Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
e954245
Replace interface{} with any
BagToad Aug 26, 2026
abdea37
Use fmt.Appendf for byte formatting
BagToad Aug 26, 2026
4f0eb3d
Use maps helpers for map loops
BagToad Aug 26, 2026
aee884d
Use min and max built-ins
BagToad Aug 26, 2026
3f7bb81
Use new expression syntax
BagToad Aug 26, 2026
8a63c38
Use omitzero JSON tags
BagToad Aug 26, 2026
e26caf1
Use integer range loops
BagToad Aug 26, 2026
83c1649
Use reflect.TypeFor
BagToad Aug 26, 2026
6f844ce
Use slices.Contains helpers
BagToad Aug 26, 2026
fdd5a07
Use standard library iterators
BagToad Aug 26, 2026
fc68dc4
Use strings.Builder for concatenation
BagToad Aug 26, 2026
d190d6a
Use strings.Cut
BagToad Aug 26, 2026
4cf0c4e
Use strings.CutPrefix
BagToad Aug 26, 2026
f0f3646
Use string sequence iterators
BagToad Aug 26, 2026
556199d
Use testing context helper
BagToad Aug 26, 2026
ecb8c5a
Use WaitGroup.Go
BagToad Aug 26, 2026
0b23d8d
Inline duration pointer helper
BagToad Aug 26, 2026
b3846d7
Apply remaining strings.Builder fix
BagToad Aug 26, 2026
981de3e
Run go fix in lint workflow
BagToad Aug 26, 2026
6ba9230
Remove inlined pointer helpers
BagToad Aug 26, 2026
e86515a
Remove obsolete reflection helper
BagToad Aug 26, 2026
07fb593
Use native Go diff checks
BagToad Aug 27, 2026
10f0ee3
Simplify skill processing limit
BagToad Aug 27, 2026
a0b4ede
Simplify auth host validation
BagToad Aug 27, 2026
4c32c17
Inline codespace slice checks
BagToad Aug 27, 2026
88684c2
Inline pull request slice checks
BagToad Aug 27, 2026
2ea4611
Merge pull request #14278 from cli/bagtoad/go-fix-cleanup
BagToad Aug 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,10 @@ jobs:
with:
go-version-file: 'go.mod'

- name: Ensure go.mod and go.sum are up to date
- name: Ensure Go source and modules are up to date
run: |
STATUS=0
assert-nothing-changed() {
local diff
"$@" >/dev/null || return 1
if ! diff="$(git diff -U1 --color --exit-code)"; then
printf '\e[31mError: running `\e[1m%s\e[22m` results in modifications that you must check into version control:\e[0m\n%s\n\n' "$*" "$diff" >&2
git checkout -- .
STATUS=1
fi
}
assert-nothing-changed go mod tidy
exit $STATUS
go mod tidy -diff
go fix -diff ./...

- name: golangci-lint
uses: golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a # v9.3.0
Expand Down
24 changes: 12 additions & 12 deletions api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (err HTTPError) ScopesSuggestion() string {

// GraphQL performs a GraphQL request using the query string and parses the response into data receiver. If there are errors in the response,
// GraphQLError will be returned, but the receiver will also be partially populated.
func (c Client) GraphQL(hostname string, query string, variables map[string]interface{}, data interface{}) error {
func (c Client) GraphQL(hostname string, query string, variables map[string]any, data any) error {
opts := clientOptions(hostname, c.http.Transport)
opts.Headers[graphqlFeatures] = features
gqlClient, err := ghAPI.NewGraphQLClient(opts)
Expand All @@ -66,7 +66,7 @@ func (c Client) GraphQL(hostname string, query string, variables map[string]inte

// Mutate performs a GraphQL mutation based on a struct and parses the response with the same struct as the receiver. If there are errors in the response,
// GraphQLError will be returned, but the receiver will also be partially populated.
func (c Client) Mutate(hostname, name string, mutation interface{}, variables map[string]interface{}) error {
func (c Client) Mutate(hostname, name string, mutation any, variables map[string]any) error {
opts := clientOptions(hostname, c.http.Transport)
opts.Headers[graphqlFeatures] = features
gqlClient, err := ghAPI.NewGraphQLClient(opts)
Expand All @@ -78,7 +78,7 @@ func (c Client) Mutate(hostname, name string, mutation interface{}, variables ma

// Query performs a GraphQL query based on a struct and parses the response with the same struct as the receiver. If there are errors in the response,
// GraphQLError will be returned, but the receiver will also be partially populated.
func (c Client) Query(hostname, name string, query interface{}, variables map[string]interface{}) error {
func (c Client) Query(hostname, name string, query any, variables map[string]any) error {
opts := clientOptions(hostname, c.http.Transport)
opts.Headers[graphqlFeatures] = features
gqlClient, err := ghAPI.NewGraphQLClient(opts)
Expand All @@ -90,7 +90,7 @@ func (c Client) Query(hostname, name string, query interface{}, variables map[st

// QueryWithContext performs a GraphQL query based on a struct and parses the response with the same struct as the receiver. If there are errors in the response,
// GraphQLError will be returned, but the receiver will also be partially populated.
func (c Client) QueryWithContext(ctx context.Context, hostname, name string, query interface{}, variables map[string]interface{}) error {
func (c Client) QueryWithContext(ctx context.Context, hostname, name string, query any, variables map[string]any) error {
opts := clientOptions(hostname, c.http.Transport)
opts.Headers[graphqlFeatures] = features
gqlClient, err := ghAPI.NewGraphQLClient(opts)
Expand All @@ -101,7 +101,7 @@ func (c Client) QueryWithContext(ctx context.Context, hostname, name string, que
}

// REST performs a REST request and parses the response.
func (c Client) REST(hostname string, method string, p string, body io.Reader, data interface{}) error {
func (c Client) REST(hostname string, method string, p string, body io.Reader, data any) error {
opts := clientOptions(hostname, c.http.Transport)
restClient, err := ghAPI.NewRESTClient(opts)
if err != nil {
Expand All @@ -110,7 +110,7 @@ func (c Client) REST(hostname string, method string, p string, body io.Reader, d
return handleResponse(restClient.Do(method, p, body, data))
}

func (c Client) RESTWithNext(hostname string, method string, p string, body io.Reader, data interface{}) (string, error) {
func (c Client) RESTWithNext(hostname string, method string, p string, body io.Reader, data any) (string, error) {
opts := clientOptions(hostname, c.http.Transport)
restClient, err := ghAPI.NewRESTClient(opts)
if err != nil {
Expand Down Expand Up @@ -211,7 +211,7 @@ func generateScopesSuggestion(statusCode int, endpointNeedsScopes, tokenHasScope
}

gotScopes := map[string]struct{}{}
for _, s := range strings.Split(tokenHasScopes, ",") {
for s := range strings.SplitSeq(tokenHasScopes, ",") {
s = strings.TrimSpace(s)
gotScopes[s] = struct{}{}

Expand All @@ -230,15 +230,15 @@ func generateScopesSuggestion(statusCode int, endpointNeedsScopes, tokenHasScope
gotScopes["user:follow"] = struct{}{}
} else if s == "codespace" {
gotScopes["codespace:secrets"] = struct{}{}
} else if strings.HasPrefix(s, "admin:") {
gotScopes["read:"+strings.TrimPrefix(s, "admin:")] = struct{}{}
} else if after, ok := strings.CutPrefix(s, "admin:"); ok {
gotScopes["read:"+after] = struct{}{}
gotScopes["write:"+strings.TrimPrefix(s, "admin:")] = struct{}{}
} else if strings.HasPrefix(s, "write:") {
gotScopes["read:"+strings.TrimPrefix(s, "write:")] = struct{}{}
} else if after, ok := strings.CutPrefix(s, "write:"); ok {
gotScopes["read:"+after] = struct{}{}
}
}

for _, s := range strings.Split(endpointNeedsScopes, ",") {
for s := range strings.SplitSeq(endpointNeedsScopes, ",") {
s = strings.TrimSpace(s)
if _, gotScope := gotScopes[s]; s == "" || gotScope {
continue
Expand Down
2 changes: 1 addition & 1 deletion api/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestGraphQL(t *testing.T) {
http := &httpmock.Registry{}
client := newTestClient(http)

vars := map[string]interface{}{"name": "Mona"}
vars := map[string]any{"name": "Mona"}
response := struct {
Viewer struct {
Login string
Expand Down
70 changes: 35 additions & 35 deletions api/export_pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"strings"
)

func (issue *Issue) ExportData(fields []string) map[string]interface{} {
func (issue *Issue) ExportData(fields []string) map[string]any {
v := reflect.ValueOf(issue).Elem()
data := map[string]interface{}{}
data := map[string]any{}

for _, f := range fields {
switch f {
Expand All @@ -20,25 +20,25 @@ func (issue *Issue) ExportData(fields []string) map[string]interface{} {
case "projectCards":
data[f] = issue.ProjectCards.Nodes
case "projectItems":
items := make([]map[string]interface{}, 0, len(issue.ProjectItems.Nodes))
items := make([]map[string]any, 0, len(issue.ProjectItems.Nodes))
for _, n := range issue.ProjectItems.Nodes {
items = append(items, map[string]interface{}{
items = append(items, map[string]any{
"status": n.Status,
"title": n.Project.Title,
})
}
data[f] = items
case "closedByPullRequestsReferences":
items := make([]map[string]interface{}, 0, len(issue.ClosedByPullRequestsReferences.Nodes))
items := make([]map[string]any, 0, len(issue.ClosedByPullRequestsReferences.Nodes))
for _, n := range issue.ClosedByPullRequestsReferences.Nodes {
items = append(items, map[string]interface{}{
items = append(items, map[string]any{
"id": n.ID,
"number": n.Number,
"url": n.URL,
"repository": map[string]interface{}{
"repository": map[string]any{
"id": n.Repository.ID,
"name": n.Repository.Name,
"owner": map[string]interface{}{
"owner": map[string]any{
"id": n.Repository.Owner.ID,
"login": n.Repository.Owner.Login,
},
Expand All @@ -50,7 +50,7 @@ func (issue *Issue) ExportData(fields []string) map[string]interface{} {
data[f] = issue.IssueType
case "parent":
if issue.Parent != nil {
data[f] = map[string]interface{}{
data[f] = map[string]any{
"id": issue.Parent.ID,
"number": issue.Parent.Number,
"title": issue.Parent.Title,
Expand All @@ -61,53 +61,53 @@ func (issue *Issue) ExportData(fields []string) map[string]interface{} {
data[f] = nil
}
case "subIssues":
items := make([]map[string]interface{}, 0, len(issue.SubIssues.Nodes))
items := make([]map[string]any, 0, len(issue.SubIssues.Nodes))
for _, n := range issue.SubIssues.Nodes {
items = append(items, map[string]interface{}{
items = append(items, map[string]any{
"id": n.ID,
"number": n.Number,
"title": n.Title,
"url": n.URL,
"state": n.State,
})
}
data[f] = map[string]interface{}{
data[f] = map[string]any{
"nodes": items,
"totalCount": issue.SubIssues.TotalCount,
}
case "subIssuesSummary":
data[f] = map[string]interface{}{
data[f] = map[string]any{
"total": issue.SubIssuesSummary.Total,
"completed": issue.SubIssuesSummary.Completed,
"percentCompleted": issue.SubIssuesSummary.PercentCompleted,
}
case "blockedBy":
items := make([]map[string]interface{}, 0, len(issue.BlockedBy.Nodes))
items := make([]map[string]any, 0, len(issue.BlockedBy.Nodes))
for _, n := range issue.BlockedBy.Nodes {
items = append(items, map[string]interface{}{
items = append(items, map[string]any{
"id": n.ID,
"number": n.Number,
"title": n.Title,
"url": n.URL,
"state": n.State,
})
}
data[f] = map[string]interface{}{
data[f] = map[string]any{
"nodes": items,
"totalCount": issue.BlockedBy.TotalCount,
}
case "blocking":
items := make([]map[string]interface{}, 0, len(issue.Blocking.Nodes))
items := make([]map[string]any, 0, len(issue.Blocking.Nodes))
for _, n := range issue.Blocking.Nodes {
items = append(items, map[string]interface{}{
items = append(items, map[string]any{
"id": n.ID,
"number": n.Number,
"title": n.Title,
"url": n.URL,
"state": n.State,
})
}
data[f] = map[string]interface{}{
data[f] = map[string]any{
"nodes": items,
"totalCount": issue.Blocking.TotalCount,
}
Expand All @@ -120,20 +120,20 @@ func (issue *Issue) ExportData(fields []string) map[string]interface{} {
return data
}

func (pr *PullRequest) ExportData(fields []string) map[string]interface{} {
func (pr *PullRequest) ExportData(fields []string) map[string]any {
v := reflect.ValueOf(pr).Elem()
data := map[string]interface{}{}
data := map[string]any{}

for _, f := range fields {
switch f {
case "headRepository":
data[f] = pr.HeadRepository
case "statusCheckRollup":
if n := pr.StatusCheckRollup.Nodes; len(n) > 0 {
checks := make([]interface{}, 0, len(n[0].Commit.StatusCheckRollup.Contexts.Nodes))
checks := make([]any, 0, len(n[0].Commit.StatusCheckRollup.Contexts.Nodes))
for _, c := range n[0].Commit.StatusCheckRollup.Contexts.Nodes {
if c.TypeName == "CheckRun" {
checks = append(checks, map[string]interface{}{
checks = append(checks, map[string]any{
"__typename": c.TypeName,
"name": c.Name,
"workflowName": c.CheckSuite.WorkflowRun.Workflow.Name,
Expand All @@ -144,7 +144,7 @@ func (pr *PullRequest) ExportData(fields []string) map[string]interface{} {
"detailsUrl": c.DetailsURL,
})
} else {
checks = append(checks, map[string]interface{}{
checks = append(checks, map[string]any{
"__typename": c.TypeName,
"context": c.Context,
"state": c.State,
Expand All @@ -158,19 +158,19 @@ func (pr *PullRequest) ExportData(fields []string) map[string]interface{} {
data[f] = nil
}
case "commits":
commits := make([]interface{}, 0, len(pr.Commits.Nodes))
commits := make([]any, 0, len(pr.Commits.Nodes))
for _, c := range pr.Commits.Nodes {
commit := c.Commit
authors := make([]interface{}, 0, len(commit.Authors.Nodes))
authors := make([]any, 0, len(commit.Authors.Nodes))
for _, author := range commit.Authors.Nodes {
authors = append(authors, map[string]interface{}{
authors = append(authors, map[string]any{
"name": author.Name,
"email": author.Email,
"id": author.User.ID,
"login": author.User.Login,
})
}
commits = append(commits, map[string]interface{}{
commits = append(commits, map[string]any{
"oid": commit.OID,
"messageHeadline": commit.MessageHeadline,
"messageBody": commit.MessageBody,
Expand All @@ -189,9 +189,9 @@ func (pr *PullRequest) ExportData(fields []string) map[string]interface{} {
case "projectCards":
data[f] = pr.ProjectCards.Nodes
case "projectItems":
items := make([]map[string]interface{}, 0, len(pr.ProjectItems.Nodes))
items := make([]map[string]any, 0, len(pr.ProjectItems.Nodes))
for _, n := range pr.ProjectItems.Nodes {
items = append(items, map[string]interface{}{
items = append(items, map[string]any{
"status": n.Status,
"title": n.Project.Title,
})
Expand All @@ -204,7 +204,7 @@ func (pr *PullRequest) ExportData(fields []string) map[string]interface{} {
case "files":
data[f] = pr.Files.Nodes
case "reviewRequests":
requests := make([]interface{}, 0, len(pr.ReviewRequests.Nodes))
requests := make([]any, 0, len(pr.ReviewRequests.Nodes))
for _, req := range pr.ReviewRequests.Nodes {
r := req.RequestedReviewer
switch r.TypeName {
Expand All @@ -223,16 +223,16 @@ func (pr *PullRequest) ExportData(fields []string) map[string]interface{} {
}
data[f] = &requests
case "closingIssuesReferences":
items := make([]map[string]interface{}, 0, len(pr.ClosingIssuesReferences.Nodes))
items := make([]map[string]any, 0, len(pr.ClosingIssuesReferences.Nodes))
for _, n := range pr.ClosingIssuesReferences.Nodes {
items = append(items, map[string]interface{}{
items = append(items, map[string]any{
"id": n.ID,
"number": n.Number,
"url": n.URL,
"repository": map[string]interface{}{
"repository": map[string]any{
"id": n.Repository.ID,
"name": n.Repository.Name,
"owner": map[string]interface{}{
"owner": map[string]any{
"id": n.Repository.Owner.ID,
"login": n.Repository.Owner.Login,
},
Expand Down
8 changes: 4 additions & 4 deletions api/export_pr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,10 @@ func TestIssue_ExportData(t *testing.T) {
enc.SetIndent("", "\t")
require.NoError(t, enc.Encode(exported))

var gotData interface{}
var gotData any
dec = json.NewDecoder(&buf)
require.NoError(t, dec.Decode(&gotData))
var expectData interface{}
var expectData any
require.NoError(t, json.Unmarshal([]byte(tt.outputJSON), &expectData))

assert.Equal(t, expectData, gotData)
Expand Down Expand Up @@ -669,10 +669,10 @@ func TestPullRequest_ExportData(t *testing.T) {
enc.SetIndent("", "\t")
require.NoError(t, enc.Encode(exported))

var gotData interface{}
var gotData any
dec = json.NewDecoder(&buf)
require.NoError(t, dec.Decode(&gotData))
var expectData interface{}
var expectData any
require.NoError(t, json.Unmarshal([]byte(tt.outputJSON), &expectData))

assert.Equal(t, expectData, gotData)
Expand Down
8 changes: 4 additions & 4 deletions api/export_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import (
"reflect"
)

func (repo *Repository) ExportData(fields []string) map[string]interface{} {
func (repo *Repository) ExportData(fields []string) map[string]any {
v := reflect.ValueOf(repo).Elem()
data := map[string]interface{}{}
data := map[string]any{}

for _, f := range fields {
switch f {
Expand Down Expand Up @@ -41,11 +41,11 @@ func (repo *Repository) ExportData(fields []string) map[string]interface{} {
return data
}

func miniRepoExport(r *Repository) map[string]interface{} {
func miniRepoExport(r *Repository) map[string]any {
if r == nil {
return nil
}
return map[string]interface{}{
return map[string]any{
"id": r.ID,
"name": r.Name,
"owner": r.Owner,
Expand Down
Loading
Loading