This defines an AutolinkClient interface with a Get method used for fetching the autolinks lists from the api. Then, the http client for autolinks implements this interface with the AutolinkGetter struct. This allows for dependency injection of the AutolinkGetter struct into the listOptions, enabling mocking of the AutolinkGetter for testing. The result of this is simpler tests that are easier to maintain, because the interface for the table tests now allow for defining autolink structs as the response instead of large mocked api calls. This also allows for bespoke testing of the http file, which I'll follow up with in the next commit.
127 lines
3 KiB
Go
127 lines
3 KiB
Go
package autolink
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
|
|
"github.com/MakeNowJust/heredoc"
|
|
"github.com/cli/cli/v2/internal/browser"
|
|
"github.com/cli/cli/v2/internal/ghrepo"
|
|
"github.com/cli/cli/v2/internal/tableprinter"
|
|
"github.com/cli/cli/v2/internal/text"
|
|
"github.com/cli/cli/v2/pkg/cmdutil"
|
|
"github.com/cli/cli/v2/pkg/iostreams"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var autolinkFields = []string{
|
|
"id",
|
|
"isAlphanumeric",
|
|
"keyPrefix",
|
|
"urlTemplate",
|
|
}
|
|
|
|
type listOptions struct {
|
|
BaseRepo func() (ghrepo.Interface, error)
|
|
Browser browser.Browser
|
|
AutolinkClient AutolinkClient
|
|
IO *iostreams.IOStreams
|
|
|
|
Exporter cmdutil.Exporter
|
|
WebMode bool
|
|
}
|
|
|
|
type AutolinkClient interface {
|
|
Get(repo ghrepo.Interface) ([]autolink, error)
|
|
}
|
|
|
|
func newCmdList(f *cmdutil.Factory, runF func(*listOptions) error) *cobra.Command {
|
|
opts := &listOptions{
|
|
Browser: f.Browser,
|
|
IO: f.IOStreams,
|
|
}
|
|
|
|
cmd := &cobra.Command{
|
|
Use: "list",
|
|
Short: "List autolink references for a GitHub repository",
|
|
Long: heredoc.Doc(`
|
|
Gets all autolink references that are configured for a repository.
|
|
|
|
Information about autolinks is only available to repository administrators.
|
|
`),
|
|
Aliases: []string{"ls"},
|
|
Args: cobra.NoArgs,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
opts.BaseRepo = f.BaseRepo
|
|
|
|
httpClient, err := f.HttpClient()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
opts.AutolinkClient = NewAutolinkGetter(httpClient)
|
|
|
|
if runF != nil {
|
|
return runF(opts)
|
|
}
|
|
|
|
return listRun(opts)
|
|
},
|
|
}
|
|
|
|
cmd.Flags().BoolVarP(&opts.WebMode, "web", "w", false, "List autolink references in the web browser")
|
|
cmdutil.AddJSONFlags(cmd, &opts.Exporter, autolinkFields)
|
|
|
|
return cmd
|
|
}
|
|
|
|
func listRun(opts *listOptions) error {
|
|
|
|
repo, err := opts.BaseRepo()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if opts.WebMode {
|
|
autolinksListURL := ghrepo.GenerateRepoURL(repo, "settings/key_links")
|
|
|
|
if opts.IO.IsStdoutTTY() {
|
|
fmt.Fprintf(opts.IO.ErrOut, "Opening %s in your browser.\n", text.DisplayURL(autolinksListURL))
|
|
}
|
|
|
|
return opts.Browser.Browse(autolinksListURL)
|
|
}
|
|
|
|
autolinks, err := opts.AutolinkClient.Get(repo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(autolinks) == 0 {
|
|
return cmdutil.NewNoResultsError(fmt.Sprintf("no autolinks found in %s", ghrepo.FullName(repo)))
|
|
}
|
|
|
|
if opts.Exporter != nil {
|
|
return opts.Exporter.Write(opts.IO, autolinks)
|
|
}
|
|
|
|
if opts.IO.IsStdoutTTY() {
|
|
title := listHeader(ghrepo.FullName(repo), len(autolinks))
|
|
fmt.Fprintf(opts.IO.Out, "\n%s\n\n", title)
|
|
}
|
|
|
|
tp := tableprinter.New(opts.IO, tableprinter.WithHeader("ID", "KEY PREFIX", "URL TEMPLATE", "ALPHANUMERIC"))
|
|
|
|
for _, autolink := range autolinks {
|
|
tp.AddField(fmt.Sprintf("%d", autolink.ID))
|
|
tp.AddField(autolink.KeyPrefix)
|
|
tp.AddField(autolink.URLTemplate)
|
|
tp.AddField(strconv.FormatBool(autolink.IsAlphanumeric))
|
|
tp.EndRow()
|
|
}
|
|
|
|
return tp.Render()
|
|
}
|
|
|
|
func listHeader(repoName string, count int) string {
|
|
return fmt.Sprintf("Showing %s in %s", text.Pluralize(count, "autolink reference"), repoName)
|
|
}
|