gh gist list
This commit is contained in:
parent
b34fe8123a
commit
f7c4a0cf3f
4 changed files with 228 additions and 0 deletions
|
|
@ -2,6 +2,7 @@ package gist
|
|||
|
||||
import (
|
||||
gistCreateCmd "github.com/cli/cli/pkg/cmd/gist/create"
|
||||
gistListCmd "github.com/cli/cli/pkg/cmd/gist/list"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
@ -14,6 +15,7 @@ func NewCmdGist(f *cmdutil.Factory) *cobra.Command {
|
|||
}
|
||||
|
||||
cmd.AddCommand(gistCreateCmd.NewCmdCreate(f, nil))
|
||||
cmd.AddCommand(gistListCmd.NewCmdList(f, nil))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
|
|||
52
pkg/cmd/gist/list/http.go
Normal file
52
pkg/cmd/gist/list/http.go
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
package list
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/cli/cli/api"
|
||||
)
|
||||
|
||||
type Gist struct {
|
||||
Description string `json:"description"`
|
||||
HTMLURL string `json:"html_url"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Public bool
|
||||
}
|
||||
|
||||
func listGists(client *http.Client, hostname string, limit int, visibility string) ([]Gist, error) {
|
||||
result := []Gist{}
|
||||
|
||||
query := url.Values{}
|
||||
if visibility == "all" {
|
||||
query.Add("per_page", fmt.Sprintf("%d", limit))
|
||||
} else {
|
||||
query.Add("per_page", "100")
|
||||
}
|
||||
|
||||
apiClient := api.NewClientFromHTTP(client)
|
||||
err := apiClient.REST(hostname, "GET", "gists?"+query.Encode(), nil, &result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
gists := []Gist{}
|
||||
|
||||
for _, gist := range result {
|
||||
if len(gists) == limit {
|
||||
break
|
||||
}
|
||||
if visibility == "all" || (visibility == "private" && !gist.Public) || (visibility == "public" && gist.Public) {
|
||||
gists = append(gists, gist)
|
||||
}
|
||||
}
|
||||
|
||||
sort.SliceStable(gists, func(i, j int) bool {
|
||||
return gists[i].UpdatedAt.After(gists[j].UpdatedAt)
|
||||
})
|
||||
|
||||
return gists, nil
|
||||
}
|
||||
90
pkg/cmd/gist/list/list.go
Normal file
90
pkg/cmd/gist/list/list.go
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
package list
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/cli/cli/internal/ghinstance"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/cli/cli/utils"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type ListOptions struct {
|
||||
IO *iostreams.IOStreams
|
||||
HttpClient func() (*http.Client, error)
|
||||
|
||||
Limit int
|
||||
Visibility string // all, secret, public
|
||||
}
|
||||
|
||||
func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command {
|
||||
opts := &ListOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List your gists",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if opts.Limit < 1 {
|
||||
return &cmdutil.FlagError{Err: fmt.Errorf("invalid limit: %v", opts.Limit)}
|
||||
}
|
||||
|
||||
pub := cmd.Flags().Changed("public")
|
||||
priv := cmd.Flags().Changed("private")
|
||||
|
||||
opts.Visibility = "all"
|
||||
if pub && !priv {
|
||||
opts.Visibility = "public"
|
||||
} else if priv && !pub {
|
||||
opts.Visibility = "private"
|
||||
}
|
||||
|
||||
if runF != nil {
|
||||
return runF(opts)
|
||||
}
|
||||
|
||||
return listRun(opts)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().IntVarP(&opts.Limit, "limit", "L", 10, "Maximum number of gists to fetch")
|
||||
cmd.Flags().Bool("public", false, "Show only public gists")
|
||||
cmd.Flags().Bool("private", false, "Show only private gists")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func listRun(opts *ListOptions) error {
|
||||
client, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gists, err := listGists(client, ghinstance.OverridableDefault(), opts.Limit, opts.Visibility)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
|
||||
tp := utils.NewTablePrinter(opts.IO)
|
||||
|
||||
for _, gist := range gists {
|
||||
// TODO i was getting confusing results with table printer's truncation
|
||||
description := gist.Description
|
||||
if len(description) > 40 {
|
||||
description = description[0:37] + "..."
|
||||
}
|
||||
|
||||
tp.AddField(description, nil, cs.Bold)
|
||||
tp.AddField(gist.HTMLURL, nil, nil)
|
||||
tp.EndRow()
|
||||
}
|
||||
|
||||
return tp.Render()
|
||||
}
|
||||
84
pkg/cmd/gist/list/list_test.go
Normal file
84
pkg/cmd/gist/list/list_test.go
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
package list
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/google/shlex"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewCmdList(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cli string
|
||||
wants ListOptions
|
||||
}{
|
||||
{
|
||||
name: "no arguments",
|
||||
cli: "",
|
||||
wants: ListOptions{
|
||||
Limit: 10,
|
||||
Visibility: "all",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "public",
|
||||
cli: "--public",
|
||||
wants: ListOptions{
|
||||
Limit: 10,
|
||||
Visibility: "public",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "private",
|
||||
cli: "--private",
|
||||
wants: ListOptions{
|
||||
Limit: 10,
|
||||
Visibility: "private",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "public and private",
|
||||
cli: "--private --public",
|
||||
wants: ListOptions{
|
||||
Limit: 10,
|
||||
Visibility: "all",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "limit",
|
||||
cli: "--limit 30",
|
||||
wants: ListOptions{
|
||||
Limit: 30,
|
||||
Visibility: "all",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
f := &cmdutil.Factory{}
|
||||
|
||||
argv, err := shlex.Split(tt.cli)
|
||||
assert.NoError(t, err)
|
||||
|
||||
var gotOpts *ListOptions
|
||||
cmd := NewCmdList(f, func(opts *ListOptions) error {
|
||||
gotOpts = opts
|
||||
return nil
|
||||
})
|
||||
cmd.SetArgs(argv)
|
||||
cmd.SetIn(&bytes.Buffer{})
|
||||
cmd.SetOut(&bytes.Buffer{})
|
||||
cmd.SetErr(&bytes.Buffer{})
|
||||
|
||||
_, err = cmd.ExecuteC()
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tt.wants.Visibility, gotOpts.Visibility)
|
||||
assert.Equal(t, tt.wants.Limit, gotOpts.Limit)
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue