Add ability to filter by archived in repo list
Like `--language`, archived filters also use the Search API.
This commit is contained in:
parent
5da8301d5d
commit
e27a77fc99
4 changed files with 164 additions and 64 deletions
|
|
@ -44,17 +44,20 @@ type RepositoryList struct {
|
|||
Owner string
|
||||
Repositories []Repository
|
||||
TotalCount int
|
||||
FromSearch bool
|
||||
}
|
||||
|
||||
type FilterOptions struct {
|
||||
Visibility string // private, public
|
||||
Fork bool
|
||||
Source bool
|
||||
Language string
|
||||
Visibility string // private, public
|
||||
Fork bool
|
||||
Source bool
|
||||
Language string
|
||||
Archived bool
|
||||
NonArchived bool
|
||||
}
|
||||
|
||||
func listRepos(client *http.Client, hostname string, limit int, owner string, filter FilterOptions) (*RepositoryList, error) {
|
||||
if filter.Language != "" {
|
||||
if filter.Language != "" || filter.Archived || filter.NonArchived {
|
||||
return searchRepos(client, hostname, limit, owner, filter)
|
||||
}
|
||||
|
||||
|
|
@ -165,7 +168,7 @@ func searchRepos(client *http.Client, hostname string, limit int, owner string,
|
|||
}
|
||||
|
||||
gql := graphql.NewClient(ghinstance.GraphQLEndpoint(hostname), client)
|
||||
listResult := RepositoryList{}
|
||||
listResult := RepositoryList{FromSearch: true}
|
||||
pagination:
|
||||
for {
|
||||
var result query
|
||||
|
|
@ -222,5 +225,11 @@ func searchQuery(owner string, filter FilterOptions) string {
|
|||
queryParts = append(queryParts, "is:private")
|
||||
}
|
||||
|
||||
if filter.Archived {
|
||||
queryParts = append(queryParts, "archived:true")
|
||||
} else if filter.NonArchived {
|
||||
queryParts = append(queryParts, "archived:false")
|
||||
}
|
||||
|
||||
return strings.Join(queryParts, " ")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ func Test_listReposWithLanguage(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, 3, res.TotalCount)
|
||||
assert.Equal(t, true, res.FromSearch)
|
||||
assert.Equal(t, "octocat", res.Owner)
|
||||
assert.Equal(t, "octocat/hello-world", res.Repositories[0].NameWithOwner)
|
||||
|
||||
|
|
@ -130,6 +131,26 @@ func Test_searchQuery(t *testing.T) {
|
|||
},
|
||||
want: "sort:updated-desc user:@me fork:true language:\"ruby\"",
|
||||
},
|
||||
{
|
||||
name: "only archived",
|
||||
args: args{
|
||||
owner: "",
|
||||
filter: FilterOptions{
|
||||
Archived: true,
|
||||
},
|
||||
},
|
||||
want: "sort:updated-desc user:@me fork:true archived:true",
|
||||
},
|
||||
{
|
||||
name: "only non-archived",
|
||||
args: args{
|
||||
owner: "",
|
||||
filter: FilterOptions{
|
||||
NonArchived: true,
|
||||
},
|
||||
},
|
||||
want: "sort:updated-desc user:@me fork:true archived:false",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -20,10 +20,12 @@ type ListOptions struct {
|
|||
Limit int
|
||||
Owner string
|
||||
|
||||
Visibility string
|
||||
Fork bool
|
||||
Source bool
|
||||
Language string
|
||||
Visibility string
|
||||
Fork bool
|
||||
Source bool
|
||||
Language string
|
||||
Archived bool
|
||||
NonArchived bool
|
||||
|
||||
Now func() time.Time
|
||||
}
|
||||
|
|
@ -55,6 +57,9 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
|
|||
if opts.Source && opts.Fork {
|
||||
return &cmdutil.FlagError{Err: fmt.Errorf("specify only one of `--source` or `--fork`")}
|
||||
}
|
||||
if opts.Archived && opts.NonArchived {
|
||||
return &cmdutil.FlagError{Err: fmt.Errorf("specify only one of `--archived` or `--no-archived`")}
|
||||
}
|
||||
|
||||
if flagPrivate {
|
||||
opts.Visibility = "private"
|
||||
|
|
@ -79,6 +84,8 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
|
|||
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().BoolVar(&opts.Archived, "archived", false, "Show only archived repositories")
|
||||
cmd.Flags().BoolVar(&opts.NonArchived, "no-archived", false, "Omit archived repositories")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
@ -90,10 +97,12 @@ func listRun(opts *ListOptions) error {
|
|||
}
|
||||
|
||||
filter := FilterOptions{
|
||||
Visibility: opts.Visibility,
|
||||
Fork: opts.Fork,
|
||||
Source: opts.Source,
|
||||
Language: opts.Language,
|
||||
Visibility: opts.Visibility,
|
||||
Fork: opts.Fork,
|
||||
Source: opts.Source,
|
||||
Language: opts.Language,
|
||||
Archived: opts.Archived,
|
||||
NonArchived: opts.NonArchived,
|
||||
}
|
||||
|
||||
listResult, err := listRepos(httpClient, ghinstance.OverridableDefault(), opts.Limit, opts.Owner, filter)
|
||||
|
|
@ -117,13 +126,18 @@ func listRun(opts *ListOptions) error {
|
|||
infoColor = cs.Yellow
|
||||
}
|
||||
|
||||
t := repo.PushedAt
|
||||
// if listResult.FromSearch {
|
||||
// t = repo.UpdatedAt
|
||||
// }
|
||||
|
||||
tp.AddField(repo.NameWithOwner, nil, cs.Bold)
|
||||
tp.AddField(text.ReplaceExcessiveWhitespace(repo.Description), nil, nil)
|
||||
tp.AddField(info, nil, infoColor)
|
||||
if tp.IsTTY() {
|
||||
tp.AddField(utils.FuzzyAgoAbbr(now, repo.PushedAt), nil, cs.Gray)
|
||||
tp.AddField(utils.FuzzyAgoAbbr(now, t), nil, cs.Gray)
|
||||
} else {
|
||||
tp.AddField(repo.PushedAt.Format(time.RFC3339), nil, nil)
|
||||
tp.AddField(t.Format(time.RFC3339), nil, nil)
|
||||
}
|
||||
tp.EndRow()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,96 +28,140 @@ func TestNewCmdList(t *testing.T) {
|
|||
name: "no arguments",
|
||||
cli: "",
|
||||
wants: ListOptions{
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Archived: false,
|
||||
NonArchived: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with owner",
|
||||
cli: "monalisa",
|
||||
wants: ListOptions{
|
||||
Limit: 30,
|
||||
Owner: "monalisa",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Limit: 30,
|
||||
Owner: "monalisa",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Archived: false,
|
||||
NonArchived: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with limit",
|
||||
cli: "-L 101",
|
||||
wants: ListOptions{
|
||||
Limit: 101,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Limit: 101,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Archived: false,
|
||||
NonArchived: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only public",
|
||||
cli: "--public",
|
||||
wants: ListOptions{
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "public",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "public",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Archived: false,
|
||||
NonArchived: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only private",
|
||||
cli: "--private",
|
||||
wants: ListOptions{
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "private",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "private",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Archived: false,
|
||||
NonArchived: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only forks",
|
||||
cli: "--fork",
|
||||
wants: ListOptions{
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: true,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: true,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Archived: false,
|
||||
NonArchived: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only sources",
|
||||
cli: "--source",
|
||||
wants: ListOptions{
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: true,
|
||||
Language: "",
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: true,
|
||||
Language: "",
|
||||
Archived: false,
|
||||
NonArchived: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with language",
|
||||
cli: "-l go",
|
||||
wants: ListOptions{
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "go",
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "go",
|
||||
Archived: false,
|
||||
NonArchived: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only archived",
|
||||
cli: "--archived",
|
||||
wants: ListOptions{
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Archived: true,
|
||||
NonArchived: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "only non-archived",
|
||||
cli: "--no-archived",
|
||||
wants: ListOptions{
|
||||
Limit: 30,
|
||||
Owner: "",
|
||||
Visibility: "",
|
||||
Fork: false,
|
||||
Source: false,
|
||||
Language: "",
|
||||
Archived: false,
|
||||
NonArchived: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -130,11 +174,21 @@ func TestNewCmdList(t *testing.T) {
|
|||
cli: "--fork --source",
|
||||
wantsErr: "specify only one of `--source` or `--fork`",
|
||||
},
|
||||
{
|
||||
name: "conflicting archived",
|
||||
cli: "--archived --no-archived",
|
||||
wantsErr: "specify only one of `--archived` or `--no-archived`",
|
||||
},
|
||||
{
|
||||
name: "too many arguments",
|
||||
cli: "monalisa hubot",
|
||||
wantsErr: "accepts at most 1 arg(s), received 2",
|
||||
},
|
||||
{
|
||||
name: "invalid limit",
|
||||
cli: "-L 0",
|
||||
wantsErr: "invalid limit: 0",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
|
@ -166,6 +220,8 @@ func TestNewCmdList(t *testing.T) {
|
|||
assert.Equal(t, tt.wants.Visibility, gotOpts.Visibility)
|
||||
assert.Equal(t, tt.wants.Fork, gotOpts.Fork)
|
||||
assert.Equal(t, tt.wants.Source, gotOpts.Source)
|
||||
assert.Equal(t, tt.wants.Archived, gotOpts.Archived)
|
||||
assert.Equal(t, tt.wants.NonArchived, gotOpts.NonArchived)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue