1package boardcmd
2
3import (
4 "fmt"
5 "strings"
6
7 text "github.com/MichaelMure/go-term-text"
8 "github.com/spf13/cobra"
9
10 "github.com/git-bug/git-bug/cache"
11 "github.com/git-bug/git-bug/commands/cmdjson"
12 "github.com/git-bug/git-bug/commands/completion"
13 "github.com/git-bug/git-bug/commands/execenv"
14 "github.com/git-bug/git-bug/util/colors"
15)
16
17type boardOptions struct {
18 metadataQuery []string
19 actorQuery []string
20 titleQuery []string
21 outputFormat string
22}
23
24func NewBoardCommand() *cobra.Command {
25 env := execenv.NewEnv()
26 options := boardOptions{}
27
28 cmd := &cobra.Command{
29 Use: "board",
30 Short: "List boards",
31 PreRunE: execenv.LoadBackend(env),
32 RunE: execenv.CloseBackend(env, func(cmd *cobra.Command, args []string) error {
33 return runBoard(env, options, args)
34 }),
35 }
36
37 flags := cmd.Flags()
38 flags.SortFlags = false
39
40 flags.StringSliceVarP(&options.metadataQuery, "metadata", "m", nil,
41 "Filter by metadata. Example: github-url=URL")
42 cmd.RegisterFlagCompletionFunc("author", completion.UserForQuery(env))
43 flags.StringSliceVarP(&options.actorQuery, "actor", "A", nil,
44 "Filter by actor")
45 cmd.RegisterFlagCompletionFunc("actor", completion.UserForQuery(env))
46 flags.StringSliceVarP(&options.titleQuery, "title", "t", nil,
47 "Filter by title")
48 flags.StringVarP(&options.outputFormat, "format", "f", "default",
49 "Select the output formatting style. Valid values are [default,plain,compact,id,json,org-mode]")
50 cmd.RegisterFlagCompletionFunc("format",
51 completion.From([]string{"default", "id", "json"}))
52
53 const selectGroup = "select"
54 cmd.AddGroup(&cobra.Group{ID: selectGroup, Title: "Implicit selection"})
55
56 addCmdWithGroup := func(child *cobra.Command, groupID string) {
57 cmd.AddCommand(child)
58 child.GroupID = groupID
59 }
60
61 addCmdWithGroup(newBoardDeselectCommand(), selectGroup)
62 addCmdWithGroup(newBoardSelectCommand(), selectGroup)
63
64 cmd.AddCommand(newBoardNewCommand())
65 cmd.AddCommand(newBoardRmCommand())
66 cmd.AddCommand(newBoardShowCommand())
67 cmd.AddCommand(newBoardDescriptionCommand())
68 cmd.AddCommand(newBoardTitleCommand())
69 cmd.AddCommand(newBoardAddDraftCommand())
70
71 return cmd
72}
73
74func runBoard(env *execenv.Env, opts boardOptions, args []string) error {
75 // TODO: query
76
77 allIds := env.Backend.Boards().AllIds()
78
79 excerpts := make([]*cache.BoardExcerpt, len(allIds))
80 for i, id := range allIds {
81 b, err := env.Backend.Boards().ResolveExcerpt(id)
82 if err != nil {
83 return err
84 }
85 excerpts[i] = b
86 }
87
88 switch opts.outputFormat {
89 case "json":
90 return boardJsonFormatter(env, excerpts)
91 case "id":
92 return boardIDFormatter(env, excerpts)
93 case "default":
94 return boardDefaultFormatter(env, excerpts)
95 default:
96 return fmt.Errorf("unknown format %s", opts.outputFormat)
97 }
98}
99
100func boardIDFormatter(env *execenv.Env, excerpts []*cache.BoardExcerpt) error {
101 for _, b := range excerpts {
102 env.Out.Println(b.Id().String())
103 }
104
105 return nil
106}
107
108func boardDefaultFormatter(env *execenv.Env, excerpts []*cache.BoardExcerpt) error {
109 for _, b := range excerpts {
110 // truncate + pad if needed
111 titleFmt := text.LeftPadMaxLine(strings.TrimSpace(b.Title), 50, 0)
112 descFmt := text.LeftPadMaxLine(strings.TrimSpace(b.Description), 50, 0)
113
114 var itemFmt string
115 switch {
116 case b.ItemCount < 1:
117 itemFmt = "empty"
118 case b.ItemCount < 1000:
119 itemFmt = fmt.Sprintf("%3d 📝", b.ItemCount)
120 default:
121 itemFmt = " ∞ 📝"
122
123 }
124
125 env.Out.Printf("%s\t%s\t%s\t%s\n",
126 colors.Cyan(b.Id().Human()),
127 titleFmt,
128 descFmt,
129 itemFmt,
130 )
131 }
132 return nil
133}
134
135func boardJsonFormatter(env *execenv.Env, excerpts []*cache.BoardExcerpt) error {
136 res := make([]cmdjson.BoardExcerpt, len(excerpts))
137 for i, b := range excerpts {
138 jsonBoard, err := cmdjson.NewBoardExcerpt(env.Backend, b)
139 if err != nil {
140 return err
141 }
142 res[i] = jsonBoard
143 }
144 return env.Out.PrintJSON(res)
145}