Skip to content

Commit

Permalink
Add --reviewer flag completion (cli#6873)
Browse files Browse the repository at this point in the history
Co-authored-by: Mislav Marohnić <[email protected]>
  • Loading branch information
benjlevesque and mislav authored Jan 25, 2023
1 parent 55053df commit fef4195
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 8 deletions.
53 changes: 45 additions & 8 deletions pkg/cmd/pr/create/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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?$")
18 changes: 18 additions & 0 deletions pkg/cmd/pr/edit/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
39 changes: 39 additions & 0 deletions pkg/cmd/pr/shared/completion.go
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit fef4195

Please sign in to comment.