start on gist view
This commit is contained in:
parent
f7c4a0cf3f
commit
b17124157c
5 changed files with 201 additions and 0 deletions
|
|
@ -3,6 +3,7 @@ package gist
|
|||
import (
|
||||
gistCreateCmd "github.com/cli/cli/pkg/cmd/gist/create"
|
||||
gistListCmd "github.com/cli/cli/pkg/cmd/gist/list"
|
||||
gistViewCmd "github.com/cli/cli/pkg/cmd/gist/view"
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
@ -16,6 +17,7 @@ func NewCmdGist(f *cmdutil.Factory) *cobra.Command {
|
|||
|
||||
cmd.AddCommand(gistCreateCmd.NewCmdCreate(f, nil))
|
||||
cmd.AddCommand(gistListCmd.NewCmdList(f, nil))
|
||||
cmd.AddCommand(gistViewCmd.NewCmdView(f, nil))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,3 +82,5 @@ func TestNewCmdList(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO execution tests
|
||||
|
|
|
|||
33
pkg/cmd/gist/view/http.go
Normal file
33
pkg/cmd/gist/view/http.go
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
package view
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/cli/cli/api"
|
||||
)
|
||||
|
||||
type GistFile struct {
|
||||
Filename string
|
||||
Type string
|
||||
Language string
|
||||
Content string
|
||||
}
|
||||
|
||||
type Gist struct {
|
||||
Description string
|
||||
Files map[string]GistFile
|
||||
}
|
||||
|
||||
func getGist(client *http.Client, hostname, gistID string) (*Gist, error) {
|
||||
gist := Gist{}
|
||||
path := fmt.Sprintf("gists/%s", gistID)
|
||||
|
||||
apiClient := api.NewClientFromHTTP(client)
|
||||
err := apiClient.REST(hostname, "GET", path, nil, &gist)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &gist, nil
|
||||
}
|
||||
94
pkg/cmd/gist/view/view.go
Normal file
94
pkg/cmd/gist/view/view.go
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
package view
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"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 ViewOptions struct {
|
||||
IO *iostreams.IOStreams
|
||||
HttpClient func() (*http.Client, error)
|
||||
|
||||
Selector string
|
||||
Raw bool
|
||||
}
|
||||
|
||||
func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Command {
|
||||
opts := &ViewOptions{
|
||||
IO: f.IOStreams,
|
||||
HttpClient: f.HttpClient,
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "view {<gist id> | <gist url>}",
|
||||
Short: "View a gist",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
opts.Selector = args[0]
|
||||
|
||||
if !opts.IO.IsStdoutTTY() {
|
||||
opts.Raw = true
|
||||
}
|
||||
|
||||
if runF != nil {
|
||||
return runF(opts)
|
||||
}
|
||||
return viewRun(opts)
|
||||
},
|
||||
}
|
||||
|
||||
cmd.Flags().BoolVarP(&opts.Raw, "raw", "r", false, "do not try and render markdown")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func viewRun(opts *ViewOptions) error {
|
||||
gistID := opts.Selector
|
||||
|
||||
u, err := url.Parse(opts.Selector)
|
||||
if err == nil {
|
||||
if strings.HasPrefix(u.Path, "/") {
|
||||
gistID = u.Path[1:]
|
||||
}
|
||||
}
|
||||
|
||||
client, err := opts.HttpClient()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
gist, err := getGist(client, ghinstance.OverridableDefault(), gistID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cs := opts.IO.ColorScheme()
|
||||
if gist.Description != "" {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s\n", cs.Bold(gist.Description))
|
||||
}
|
||||
|
||||
for filename, gistFile := range gist.Files {
|
||||
fmt.Fprintf(opts.IO.ErrOut, "%s\n", cs.Gray(filename))
|
||||
fmt.Fprintln(opts.IO.ErrOut)
|
||||
content := gistFile.Content
|
||||
if strings.Contains(gistFile.Type, "markdown") && !opts.Raw {
|
||||
rendered, err := utils.RenderMarkdown(gistFile.Content)
|
||||
if err == nil {
|
||||
content = rendered
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(opts.IO.Out, "%s\n", content)
|
||||
fmt.Fprintln(opts.IO.Out)
|
||||
}
|
||||
|
||||
// TODO print gist files, possibly with rendered markdown
|
||||
return nil
|
||||
}
|
||||
70
pkg/cmd/gist/view/view_test.go
Normal file
70
pkg/cmd/gist/view/view_test.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package view
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"github.com/cli/cli/pkg/cmdutil"
|
||||
"github.com/cli/cli/pkg/iostreams"
|
||||
"github.com/google/shlex"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestNewCmdView(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
cli string
|
||||
wants ViewOptions
|
||||
tty bool
|
||||
}{
|
||||
{
|
||||
name: "tty no arguments",
|
||||
tty: true,
|
||||
cli: "123",
|
||||
wants: ViewOptions{
|
||||
Raw: false,
|
||||
Selector: "123",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "nontty no arguments",
|
||||
cli: "123",
|
||||
wants: ViewOptions{
|
||||
Raw: true,
|
||||
Selector: "123",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
io, _, _, _ := iostreams.Test()
|
||||
io.SetStdoutTTY(tt.tty)
|
||||
|
||||
f := &cmdutil.Factory{
|
||||
IOStreams: io,
|
||||
}
|
||||
|
||||
argv, err := shlex.Split(tt.cli)
|
||||
assert.NoError(t, err)
|
||||
|
||||
var gotOpts *ViewOptions
|
||||
cmd := NewCmdView(f, func(opts *ViewOptions) 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.Raw, gotOpts.Raw)
|
||||
assert.Equal(t, tt.wants.Selector, gotOpts.Selector)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO execution tests
|
||||
Loading…
Add table
Add a link
Reference in a new issue