Skip to content

Commit

Permalink
Refactor filtering into existing gist list
Browse files Browse the repository at this point in the history
Resolves feedback in issue cli#9704
  • Loading branch information
heaths committed Oct 9, 2024
1 parent 383d175 commit c04fa68
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 559 deletions.
2 changes: 0 additions & 2 deletions pkg/cmd/gist/gist.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
gistEditCmd "github.com/cli/cli/v2/pkg/cmd/gist/edit"
gistListCmd "github.com/cli/cli/v2/pkg/cmd/gist/list"
gistRenameCmd "github.com/cli/cli/v2/pkg/cmd/gist/rename"
gistSearchCmd "github.com/cli/cli/v2/pkg/cmd/gist/search"
gistViewCmd "github.com/cli/cli/v2/pkg/cmd/gist/view"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -36,7 +35,6 @@ func NewCmdGist(f *cmdutil.Factory) *cobra.Command {
cmd.AddCommand(gistEditCmd.NewCmdEdit(f, nil))
cmd.AddCommand(gistDeleteCmd.NewCmdDelete(f, nil))
cmd.AddCommand(gistRenameCmd.NewCmdRename(f, nil))
cmd.AddCommand(gistSearchCmd.NewCmdSearch(f, nil))

return cmd
}
65 changes: 61 additions & 4 deletions pkg/cmd/gist/list/list.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package list

import (
"fmt"
"net/http"
"regexp"
"strings"
"time"

"github.com/cli/cli/v2/internal/gh"
"github.com/cli/cli/v2/internal/tableprinter"
"github.com/cli/cli/v2/internal/text"
"github.com/cli/cli/v2/pkg/cmd/gist/shared"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
Expand All @@ -15,8 +21,10 @@ type ListOptions struct {
Config func() (gh.Config, error)
HttpClient func() (*http.Client, error)

Limit int
Visibility string // all, secret, public
Limit int
Filter *regexp.Regexp
IncludeContent bool
Visibility string // all, secret, public
}

func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command {
Expand All @@ -28,6 +36,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman

var flagPublic bool
var flagSecret bool
var flagFilter string

cmd := &cobra.Command{
Use: "list",
Expand All @@ -39,6 +48,12 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
return cmdutil.FlagErrorf("invalid limit: %v", opts.Limit)
}

if filter, err := regexp.CompilePOSIX(flagFilter); err != nil {
return err
} else {
opts.Filter = filter
}

opts.Visibility = "all"
if flagSecret {
opts.Visibility = "secret"
Expand All @@ -56,6 +71,8 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
cmd.Flags().IntVarP(&opts.Limit, "limit", "L", 10, "Maximum number of gists to fetch")
cmd.Flags().BoolVar(&flagPublic, "public", false, "Show only public gists")
cmd.Flags().BoolVar(&flagSecret, "secret", false, "Show only secret gists")
cmd.Flags().StringVar(&flagFilter, "filter", "", "Filter gists using a regular expression")
cmd.Flags().BoolVar(&opts.IncludeContent, "include-content", false, "Include gists' file content when filtering")

return cmd
}
Expand All @@ -73,7 +90,7 @@ func listRun(opts *ListOptions) error {

host, _ := cfg.Authentication().DefaultHost()

gists, err := shared.ListGists(client, host, opts.Limit, opts.Visibility, false, nil)
gists, err := shared.ListGists(client, host, opts.Limit, opts.Filter, opts.IncludeContent, opts.Visibility)
if err != nil {
return err
}
Expand All @@ -82,5 +99,45 @@ func listRun(opts *ListOptions) error {
return cmdutil.NewNoResultsError("no gists found")
}

return shared.PrintGists(opts.IO, gists)
if err := opts.IO.StartPager(); err == nil {
defer opts.IO.StopPager()
} else {
fmt.Fprintf(opts.IO.ErrOut, "failed to start pager: %v\n", err)
}

cs := opts.IO.ColorScheme()
tp := tableprinter.New(opts.IO, tableprinter.WithHeader("ID", "DESCRIPTION", "FILES", "VISIBILITY", "UPDATED"))

for _, gist := range gists {
fileCount := len(gist.Files)

visibility := "public"
visColor := cs.Green
if !gist.Public {
visibility = "secret"
visColor = cs.Red
}

description := gist.Description
if description == "" {
for filename := range gist.Files {
if !strings.HasPrefix(filename, "gistfile") {
description = filename
break
}
}
}

tp.AddField(gist.ID)
tp.AddField(
text.RemoveExcessiveWhitespace(description),
tableprinter.WithColor(cs.Bold),
)
tp.AddField(text.Pluralize(fileCount, "file"))
tp.AddField(visibility, tableprinter.WithColor(visColor))
tp.AddTimeField(time.Now(), gist.UpdatedAt, cs.Gray)
tp.EndRow()
}

return tp.Render()
}
84 changes: 81 additions & 3 deletions pkg/cmd/gist/list/list_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"net/http"
"regexp"
"testing"
"time"

Expand All @@ -19,9 +20,10 @@ import (

func TestNewCmdList(t *testing.T) {
tests := []struct {
name string
cli string
wants ListOptions
name string
cli string
wants ListOptions
wantsErr bool
}{
{
name: "no arguments",
Expand Down Expand Up @@ -70,6 +72,26 @@ func TestNewCmdList(t *testing.T) {
Visibility: "all",
},
},
{
name: "invalid limit",
cli: "--limit 0",
wantsErr: true,
},
{
name: "filter and include-content",
cli: "--filter octo --include-content",
wants: ListOptions{
Limit: 10,
Filter: regexp.MustCompilePOSIX("octo"),
IncludeContent: true,
Visibility: "all",
},
},
{
name: "invalid filter",
cli: "--filter octo(",
wantsErr: true,
},
}

for _, tt := range tests {
Expand All @@ -90,6 +112,10 @@ func TestNewCmdList(t *testing.T) {
cmd.SetErr(&bytes.Buffer{})

_, err = cmd.ExecuteC()
if tt.wantsErr {
assert.Error(t, err)
return
}
assert.NoError(t, err)

assert.Equal(t, tt.wants.Visibility, gotOpts.Visibility)
Expand Down Expand Up @@ -358,6 +384,58 @@ func Test_listRun(t *testing.T) {
`),
nontty: true,
},
{
name: "with content filter",
opts: &ListOptions{
Filter: regexp.MustCompile("octo"),
IncludeContent: true,
Visibility: "all",
},
stubs: func(reg *httpmock.Registry) {
reg.Register(
httpmock.GraphQL(query),
httpmock.StringResponse(fmt.Sprintf(
`{ "data": { "viewer": { "gists": { "nodes": [
{
"name": "1234",
"files": [
{ "name": "main.txt", "text": "foo" }
],
"description": "octo match in the description",
"updatedAt": "%[1]v",
"isPublic": true
},
{
"name": "2345",
"files": [
{ "name": "main.txt", "text": "foo" },
{ "name": "octo.txt", "text": "bar" }
],
"description": "match in the file name",
"updatedAt": "%[1]v",
"isPublic": false
},
{
"name": "3456",
"files": [
{ "name": "main.txt", "text": "octo in the text" }
],
"description": "match in the file text",
"updatedAt": "%[1]v",
"isPublic": true
}
] } } } }`,
sixHoursAgo.Format(time.RFC3339),
)),
)
},
wantOut: heredoc.Doc(`
ID DESCRIPTION FILES VISIBILITY UPDATED
1234 octo match in the description 1 file public about 6 hours ago
2345 match in the file name 2 files secret about 6 hours ago
3456 match in the file text 1 file public about 6 hours ago
`),
},
}

for _, tt := range tests {
Expand Down
126 changes: 0 additions & 126 deletions pkg/cmd/gist/search/search.go

This file was deleted.

Loading

0 comments on commit c04fa68

Please sign in to comment.