From bbaf0103036d7c88c5cbca5a8dccbcee92360330 Mon Sep 17 00:00:00 2001 From: Hirad Pourtahmasbi Date: Tue, 10 May 2022 11:39:53 -0400 Subject: [PATCH] repo list: add `--visibility internal` filter (#5564) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Mislav Marohnić --- pkg/cmd/repo/list/fixtures/repoList.json | 9 +++++--- pkg/cmd/repo/list/http.go | 7 +++--- pkg/cmd/repo/list/list.go | 29 +++++++++++++----------- pkg/cmd/repo/list/list_test.go | 19 ++++++++-------- 4 files changed, 36 insertions(+), 28 deletions(-) diff --git a/pkg/cmd/repo/list/fixtures/repoList.json b/pkg/cmd/repo/list/fixtures/repoList.json index 18bb5eff8..0373a7892 100644 --- a/pkg/cmd/repo/list/fixtures/repoList.json +++ b/pkg/cmd/repo/list/fixtures/repoList.json @@ -11,7 +11,8 @@ "isFork": false, "isPrivate": false, "isArchived": false, - "pushedAt": "2021-02-19T06:34:58Z" + "pushedAt": "2021-02-19T06:34:58Z", + "visibility": "PUBLIC" }, { "nameWithOwner": "octocat/cli", @@ -19,7 +20,8 @@ "isFork": true, "isPrivate": false, "isArchived": false, - "pushedAt": "2021-02-19T06:06:06Z" + "pushedAt": "2021-02-19T06:06:06Z", + "visibility": "PUBLIC" }, { "nameWithOwner": "octocat/testing", @@ -27,7 +29,8 @@ "isFork": false, "isPrivate": true, "isArchived": false, - "pushedAt": "2021-02-11T22:32:05Z" + "pushedAt": "2021-02-11T22:32:05Z", + "visibility": "PRIVATE" } ], "pageInfo": { diff --git a/pkg/cmd/repo/list/http.go b/pkg/cmd/repo/list/http.go index c6f8844a9..e111b93ff 100644 --- a/pkg/cmd/repo/list/http.go +++ b/pkg/cmd/repo/list/http.go @@ -5,9 +5,10 @@ import ( "net/http" "strings" + "github.com/shurcooL/githubv4" + "github.com/cli/cli/v2/api" "github.com/cli/cli/v2/pkg/search" - "github.com/shurcooL/githubv4" ) type RepositoryList struct { @@ -18,7 +19,7 @@ type RepositoryList struct { } type FilterOptions struct { - Visibility string // private, public + Visibility string // private, public, internal Fork bool Source bool Language string @@ -29,7 +30,7 @@ type FilterOptions struct { } func listRepos(client *http.Client, hostname string, limit int, owner string, filter FilterOptions) (*RepositoryList, error) { - if filter.Language != "" || filter.Archived || filter.NonArchived || filter.Topic != "" { + if filter.Language != "" || filter.Archived || filter.NonArchived || filter.Topic != "" || filter.Visibility == "internal" { return searchRepos(client, hostname, limit, owner, filter) } diff --git a/pkg/cmd/repo/list/list.go b/pkg/cmd/repo/list/list.go index 16ca8d30c..321d753e8 100644 --- a/pkg/cmd/repo/list/list.go +++ b/pkg/cmd/repo/list/list.go @@ -6,13 +6,14 @@ import ( "strings" "time" + "github.com/spf13/cobra" + "github.com/cli/cli/v2/api" "github.com/cli/cli/v2/internal/config" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/iostreams" "github.com/cli/cli/v2/pkg/text" "github.com/cli/cli/v2/utils" - "github.com/spf13/cobra" ) type ListOptions struct { @@ -58,8 +59,8 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman return cmdutil.FlagErrorf("invalid limit: %v", opts.Limit) } - if flagPrivate && flagPublic { - return cmdutil.FlagErrorf("specify only one of `--public` or `--private`") + if err := cmdutil.MutuallyExclusive("specify only one of `--public`, `--private`, or `--visibility`", flagPublic, flagPrivate, opts.Visibility != ""); err != nil { + return err } if opts.Source && opts.Fork { return cmdutil.FlagErrorf("specify only one of `--source` or `--fork`") @@ -86,20 +87,24 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman } cmd.Flags().IntVarP(&opts.Limit, "limit", "L", 30, "Maximum number of repositories to list") - cmd.Flags().BoolVar(&flagPrivate, "private", false, "Show only private repositories") - cmd.Flags().BoolVar(&flagPublic, "public", false, "Show only public repositories") cmd.Flags().BoolVar(&opts.Source, "source", false, "Show only non-forks") cmd.Flags().BoolVar(&opts.Fork, "fork", false, "Show only forks") cmd.Flags().StringVarP(&opts.Language, "language", "l", "", "Filter by primary coding language") cmd.Flags().StringVar(&opts.Topic, "topic", "", "Filter by topic") + cmdutil.StringEnumFlag(cmd, &opts.Visibility, "visibility", "", "", []string{"public", "private", "internal"}, "Filter by repository visibility") cmd.Flags().BoolVar(&opts.Archived, "archived", false, "Show only archived repositories") cmd.Flags().BoolVar(&opts.NonArchived, "no-archived", false, "Omit archived repositories") cmdutil.AddJSONFlags(cmd, &opts.Exporter, api.RepositoryFields) + cmd.Flags().BoolVar(&flagPrivate, "private", false, "Show only private repositories") + cmd.Flags().BoolVar(&flagPublic, "public", false, "Show only public repositories") + _ = cmd.Flags().MarkDeprecated("public", "use `--visibility=public` instead") + _ = cmd.Flags().MarkDeprecated("private", "use `--visibility=private` instead") + return cmd } -var defaultFields = []string{"nameWithOwner", "description", "isPrivate", "isFork", "isArchived", "createdAt", "pushedAt"} +var defaultFields = []string{"nameWithOwner", "description", "isPrivate", "isFork", "isArchived", "createdAt", "pushedAt", "visibility"} func listRun(opts *ListOptions) error { httpClient, err := opts.HttpClient() @@ -152,7 +157,8 @@ func listRun(opts *ListOptions) error { for _, repo := range listResult.Repositories { info := repoInfo(repo) infoColor := cs.Gray - if repo.IsPrivate { + + if repo.Visibility != "PUBLIC" { infoColor = cs.Yellow } @@ -202,13 +208,10 @@ func listHeader(owner string, matchCount, totalMatchCount int, hasFilters bool) } func repoInfo(r api.Repository) string { - var tags []string - - if r.IsPrivate { - tags = append(tags, "private") - } else { - tags = append(tags, "public") + tags := []string{ + strings.ToLower(r.Visibility), } + if r.IsFork { tags = append(tags, "fork") } diff --git a/pkg/cmd/repo/list/list_test.go b/pkg/cmd/repo/list/list_test.go index 4df55f283..262ff6ffb 100644 --- a/pkg/cmd/repo/list/list_test.go +++ b/pkg/cmd/repo/list/list_test.go @@ -8,14 +8,15 @@ import ( "time" "github.com/MakeNowJust/heredoc" + "github.com/google/shlex" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/cli/cli/v2/internal/config" "github.com/cli/cli/v2/pkg/cmdutil" "github.com/cli/cli/v2/pkg/httpmock" "github.com/cli/cli/v2/pkg/iostreams" "github.com/cli/cli/v2/test" - "github.com/google/shlex" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func TestNewCmdList(t *testing.T) { @@ -72,7 +73,7 @@ func TestNewCmdList(t *testing.T) { }, { name: "only public", - cli: "--public", + cli: "--visibility=public", wants: ListOptions{ Limit: 30, Owner: "", @@ -87,7 +88,7 @@ func TestNewCmdList(t *testing.T) { }, { name: "only private", - cli: "--private", + cli: "--visibility=private", wants: ListOptions{ Limit: 30, Owner: "", @@ -191,9 +192,9 @@ func TestNewCmdList(t *testing.T) { }, }, { - name: "no public and private", - cli: "--public --private", - wantsErr: "specify only one of `--public` or `--private`", + name: "invalid visibility", + cli: "--visibility=bad", + wantsErr: "invalid argument \"bad\" for \"--visibility\" flag: valid values are {public|private|internal}", }, { name: "no forks with sources", @@ -385,7 +386,7 @@ func TestRepoList_filtering(t *testing.T) { }), ) - output, err := runCommand(http, true, `--private --limit 2 `) + output, err := runCommand(http, true, `--visibility=private --limit 2 `) if err != nil { t.Fatal(err) }