Add --reviewer flag completion (#6873)

Co-authored-by: Mislav Marohnić <mislav@github.com>
This commit is contained in:
Benjamin Levesque 2023-01-25 18:02:13 +01:00 committed by GitHub
parent 55053df592
commit fef4195004
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 102 additions and 8 deletions

View file

@ -182,6 +182,14 @@ func NewCmdCreate(f *cmdutil.Factory, runF func(*CreateOptions) error) *cobra.Co
fl.Bool("no-maintainer-edit", false, "Disable maintainer's ability to modify pull request")
fl.StringVar(&opts.RecoverFile, "recover", "", "Recover input from a failed run of create")
_ = cmd.RegisterFlagCompletionFunc("reviewer", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
results, err := requestableReviewersForCompletion(opts)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
return results, cobra.ShellCompDirectiveNoFileComp
})
return cmd
}
@ -472,16 +480,10 @@ func NewCreateContext(opts *CreateOptions) (*CreateContext, error) {
}
client := api.NewClientFromHTTP(httpClient)
// TODO: consider obtaining remotes from GitClient instead
remotes, err := opts.Remotes()
remotes, err := getRemotes(opts)
if err != nil {
// When a repo override value is given, ignore errors when fetching git remotes
// to support using this command outside of git repos.
if opts.RepoOverride == "" {
return nil, err
}
return nil, err
}
repoContext, err := ghContext.ResolveRemotesToRepos(remotes, client, opts.RepoOverride)
if err != nil {
return nil, err
@ -628,6 +630,19 @@ func NewCreateContext(opts *CreateOptions) (*CreateContext, error) {
}
func getRemotes(opts *CreateOptions) (ghContext.Remotes, error) {
// TODO: consider obtaining remotes from GitClient instead
remotes, err := opts.Remotes()
if err != nil {
// When a repo override value is given, ignore errors when fetching git remotes
// to support using this command outside of git repos.
if opts.RepoOverride == "" {
return nil, err
}
}
return remotes, nil
}
func submitPR(opts CreateOptions, ctx CreateContext, state shared.IssueMetadataState) error {
client := ctx.Client
@ -782,4 +797,26 @@ func humanize(s string) string {
return strings.Map(h, s)
}
func requestableReviewersForCompletion(opts *CreateOptions) ([]string, error) {
httpClient, err := opts.HttpClient()
if err != nil {
return nil, err
}
remotes, err := getRemotes(opts)
if err != nil {
return nil, err
}
repoContext, err := ghContext.ResolveRemotesToRepos(remotes, api.NewClientFromHTTP(httpClient), opts.RepoOverride)
if err != nil {
return nil, err
}
baseRepo, err := repoContext.BaseRepo(opts.IO)
if err != nil {
return nil, err
}
return shared.RequestableReviewersForCompletion(httpClient, baseRepo)
}
var gitPushRegexp = regexp.MustCompile("^remote: (Create a pull request.*by visiting|[[:space:]]*https://.*/pull/new/).*\n?$")

View file

@ -148,6 +148,24 @@ func NewCmdEdit(f *cmdutil.Factory, runF func(*EditOptions) error) *cobra.Comman
cmd.Flags().StringSliceVar(&opts.Editable.Projects.Remove, "remove-project", nil, "Remove the pull request from projects by `name`")
cmd.Flags().StringVarP(&opts.Editable.Milestone.Value, "milestone", "m", "", "Edit the milestone the pull request belongs to by `name`")
for _, flagName := range []string{"add-reviewer", "remove-reviewer"} {
_ = cmd.RegisterFlagCompletionFunc(flagName, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
baseRepo, err := f.BaseRepo()
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
httpClient, err := f.HttpClient()
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
results, err := shared.RequestableReviewersForCompletion(httpClient, baseRepo)
if err != nil {
return nil, cobra.ShellCompDirectiveError
}
return results, cobra.ShellCompDirectiveNoFileComp
})
}
return cmd
}

View file

@ -0,0 +1,39 @@
package shared
import (
"fmt"
"net/http"
"sort"
"strings"
"time"
"github.com/cli/cli/v2/api"
"github.com/cli/cli/v2/internal/ghrepo"
)
func RequestableReviewersForCompletion(httpClient *http.Client, repo ghrepo.Interface) ([]string, error) {
client := api.NewClientFromHTTP(api.NewCachedHTTPClient(httpClient, time.Minute*2))
metadata, err := api.RepoMetadata(client, repo, api.RepoMetadataInput{Reviewers: true})
if err != nil {
return nil, err
}
results := []string{}
for _, user := range metadata.AssignableUsers {
if strings.EqualFold(user.Login, metadata.CurrentLogin) {
continue
}
if user.Name != "" {
results = append(results, fmt.Sprintf("%s\t%s", user.Login, user.Name))
} else {
results = append(results, user.Login)
}
}
for _, team := range metadata.Teams {
results = append(results, fmt.Sprintf("%s/%s", repo.RepoOwner(), team.Slug))
}
sort.Strings(results)
return results, nil
}