diff --git a/api/client.go b/api/client.go index 895f2969272..2eb3f3ff20d 100644 --- a/api/client.go +++ b/api/client.go @@ -203,7 +203,6 @@ func GenerateScopeErrorForGQL(gqlErr *ghAPI.GraphQLError) error { } if missing.Len() > 0 { s := missing.ToSlice() - // TODO: this duplicates parts of generateScopesSuggestion return fmt.Errorf( "error: your authentication token is missing required scopes %v\n"+ "To request it, run: gh auth refresh -s %s", diff --git a/pkg/cmd/project/shared/queries/queries.go b/pkg/cmd/project/shared/queries/queries.go index 9a3bd490902..1de42a4bd56 100644 --- a/pkg/cmd/project/shared/queries/queries.go +++ b/pkg/cmd/project/shared/queries/queries.go @@ -5,13 +5,11 @@ import ( "fmt" "net/http" "net/url" - "regexp" "strings" "github.com/cli/cli/v2/api" "github.com/cli/cli/v2/internal/prompter" "github.com/cli/cli/v2/pkg/iostreams" - "github.com/cli/cli/v2/pkg/set" "github.com/shurcooL/githubv4" ) @@ -1664,42 +1662,15 @@ func (c *Client) UnlinkProjectFromTeam(projectID string, teamID string) error { } func handleError(err error) error { - var gerr api.GraphQLError - if errors.As(err, &gerr) { - missing := set.NewStringSet() - for _, e := range gerr.Errors { - if e.Type != "INSUFFICIENT_SCOPES" { - continue - } - missing.AddValues(requiredScopesFromServerMessage(e.Message)) - } - if missing.Len() > 0 { - s := missing.ToSlice() - // TODO: this duplicates parts of generateScopesSuggestion - return fmt.Errorf( - "error: your authentication token is missing required scopes %v\n"+ - "To request it, run: gh auth refresh -s %s", - s, - strings.Join(s, ",")) + var gqlErr api.GraphQLError + if errors.As(err, &gqlErr) { + if scopeErr := api.GenerateScopeErrorForGQL(gqlErr.GraphQLError); scopeErr != nil { + return scopeErr } } return err } -var scopesRE = regexp.MustCompile(`one of the following scopes: \[(.+?)]`) - -func requiredScopesFromServerMessage(msg string) []string { - m := scopesRE.FindStringSubmatch(msg) - if m == nil { - return nil - } - var scopes []string - for _, mm := range strings.Split(m[1], ",") { - scopes = append(scopes, strings.Trim(mm, "' ")) - } - return scopes -} - func projectFieldValueData(v FieldValueNodes) interface{} { switch v.Type { case "ProjectV2ItemFieldDateValue": diff --git a/pkg/cmd/project/shared/queries/queries_test.go b/pkg/cmd/project/shared/queries/queries_test.go index cc4850d8620..dea5d13bb8f 100644 --- a/pkg/cmd/project/shared/queries/queries_test.go +++ b/pkg/cmd/project/shared/queries/queries_test.go @@ -3,7 +3,6 @@ package queries import ( "io" "net/http" - "reflect" "strings" "testing" @@ -564,37 +563,6 @@ func TestProjectFields_NoLimit(t *testing.T) { assert.Len(t, project.Fields.Nodes, 3) } -func Test_requiredScopesFromServerMessage(t *testing.T) { - tests := []struct { - name string - msg string - want []string - }{ - { - name: "no scopes", - msg: "SERVER OOPSIE", - want: []string(nil), - }, - { - name: "one scope", - msg: "Your token has not been granted the required scopes to execute this query. The 'dataType' field requires one of the following scopes: ['read:project'], but your token has only been granted the: ['codespace', repo'] scopes. Please modify your token's scopes at: https://github.com/settings/tokens.", - want: []string{"read:project"}, - }, - { - name: "multiple scopes", - msg: "Your token has not been granted the required scopes to execute this query. The 'dataType' field requires one of the following scopes: ['read:project', 'read:discussion', 'codespace'], but your token has only been granted the: [repo'] scopes. Please modify your token's scopes at: https://github.com/settings/tokens.", - want: []string{"read:project", "read:discussion", "codespace"}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := requiredScopesFromServerMessage(tt.msg); !reflect.DeepEqual(got, tt.want) { - t.Errorf("requiredScopesFromServerMessage() = %v, want %v", got, tt.want) - } - }) - } -} - func TestNewProject_nonTTY(t *testing.T) { client := NewTestClient() _, err := client.NewProject(false, &Owner{}, 0, false)