github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/label/list.go (about) 1 package label 2 3 import ( 4 "fmt" 5 "net/http" 6 7 "github.com/MakeNowJust/heredoc" 8 "github.com/ungtb10d/cli/v2/internal/browser" 9 "github.com/ungtb10d/cli/v2/internal/ghrepo" 10 "github.com/ungtb10d/cli/v2/internal/text" 11 "github.com/ungtb10d/cli/v2/pkg/cmdutil" 12 "github.com/ungtb10d/cli/v2/pkg/iostreams" 13 "github.com/ungtb10d/cli/v2/utils" 14 "github.com/spf13/cobra" 15 ) 16 17 type listOptions struct { 18 BaseRepo func() (ghrepo.Interface, error) 19 Browser browser.Browser 20 HttpClient func() (*http.Client, error) 21 IO *iostreams.IOStreams 22 23 Exporter cmdutil.Exporter 24 Query listQueryOptions 25 WebMode bool 26 } 27 28 func newCmdList(f *cmdutil.Factory, runF func(*listOptions) error) *cobra.Command { 29 opts := listOptions{ 30 Browser: f.Browser, 31 HttpClient: f.HttpClient, 32 IO: f.IOStreams, 33 } 34 35 cmd := &cobra.Command{ 36 Use: "list", 37 Short: "List labels in a repository", 38 Long: heredoc.Docf(` 39 Display labels in a GitHub repository. 40 41 When using the %[1]s--search%[1]s flag results are sorted by best match of the query. 42 This behavior cannot be configured with the %[1]s--order%[1]s or %[1]s--sort%[1]s flags. 43 `, "`"), 44 Example: heredoc.Doc(` 45 # sort labels by name 46 $ gh label list --sort name 47 48 # find labels with "bug" in the name or description 49 $ gh label list --search bug 50 `), 51 Args: cobra.NoArgs, 52 Aliases: []string{"ls"}, 53 RunE: func(c *cobra.Command, args []string) error { 54 // support `-R, --repo` override 55 opts.BaseRepo = f.BaseRepo 56 57 if opts.Query.Limit < 1 { 58 return cmdutil.FlagErrorf("invalid limit: %v", opts.Query.Limit) 59 } 60 61 if opts.Query.Query != "" && 62 (c.Flags().Changed("order") || c.Flags().Changed("sort")) { 63 return cmdutil.FlagErrorf("cannot specify `--order` or `--sort` with `--search`") 64 } 65 66 if runF != nil { 67 return runF(&opts) 68 } 69 return listRun(&opts) 70 }, 71 } 72 73 cmd.Flags().BoolVarP(&opts.WebMode, "web", "w", false, "List labels in the web browser") 74 cmd.Flags().IntVarP(&opts.Query.Limit, "limit", "L", 30, "Maximum number of labels to fetch") 75 cmd.Flags().StringVarP(&opts.Query.Query, "search", "S", "", "Search label names and descriptions") 76 cmdutil.StringEnumFlag(cmd, &opts.Query.Order, "order", "", defaultOrder, []string{"asc", "desc"}, "Order of labels returned") 77 cmdutil.StringEnumFlag(cmd, &opts.Query.Sort, "sort", "", defaultSort, []string{"created", "name"}, "Sort fetched labels") 78 79 cmdutil.AddJSONFlags(cmd, &opts.Exporter, labelFields) 80 81 return cmd 82 } 83 84 func listRun(opts *listOptions) error { 85 httpClient, err := opts.HttpClient() 86 if err != nil { 87 return err 88 } 89 90 baseRepo, err := opts.BaseRepo() 91 if err != nil { 92 return err 93 } 94 95 if opts.WebMode { 96 labelListURL := ghrepo.GenerateRepoURL(baseRepo, "labels") 97 98 if opts.IO.IsStdoutTTY() { 99 fmt.Fprintf(opts.IO.ErrOut, "Opening %s in your browser.\n", text.DisplayURL(labelListURL)) 100 } 101 102 return opts.Browser.Browse(labelListURL) 103 } 104 105 if opts.Exporter != nil { 106 opts.Query.fields = opts.Exporter.Fields() 107 } 108 109 opts.IO.StartProgressIndicator() 110 labels, totalCount, err := listLabels(httpClient, baseRepo, opts.Query) 111 opts.IO.StopProgressIndicator() 112 if err != nil { 113 return err 114 } 115 116 if len(labels) == 0 { 117 if opts.Query.Query != "" { 118 return cmdutil.NewNoResultsError(fmt.Sprintf("no labels in %s matched your search", ghrepo.FullName(baseRepo))) 119 } 120 return cmdutil.NewNoResultsError(fmt.Sprintf("no labels found in %s", ghrepo.FullName(baseRepo))) 121 } 122 123 if opts.Exporter != nil { 124 return opts.Exporter.Write(opts.IO, labels) 125 } 126 127 if opts.IO.IsStdoutTTY() { 128 title := listHeader(ghrepo.FullName(baseRepo), len(labels), totalCount) 129 fmt.Fprintf(opts.IO.Out, "\n%s\n\n", title) 130 } 131 132 return printLabels(opts.IO, labels) 133 } 134 135 func printLabels(io *iostreams.IOStreams, labels []label) error { 136 cs := io.ColorScheme() 137 //nolint:staticcheck // SA1019: utils.NewTablePrinter is deprecated: use internal/tableprinter 138 table := utils.NewTablePrinter(io) 139 140 for _, label := range labels { 141 table.AddField(label.Name, nil, cs.ColorFromRGB(label.Color)) 142 table.AddField(label.Description, text.Truncate, nil) 143 table.AddField("#"+label.Color, nil, nil) 144 145 table.EndRow() 146 } 147 148 return table.Render() 149 } 150 151 func listHeader(repoName string, count int, totalCount int) string { 152 return fmt.Sprintf("Showing %d of %s in %s", count, text.Pluralize(totalCount, "label"), repoName) 153 }