1package commands
2
3import (
4 "fmt"
5
6 "github.com/MichaelMure/git-bug/bug"
7 "github.com/MichaelMure/git-bug/cache"
8 "github.com/MichaelMure/git-bug/util/colors"
9 "github.com/spf13/cobra"
10)
11
12var (
13 lsStatusQuery []string
14 lsAuthorQuery []string
15 lsLabelQuery []string
16 lsNoQuery []string
17 lsSortBy string
18 lsSortDirection string
19)
20
21func runLsBug(cmd *cobra.Command, args []string) error {
22 backend, err := cache.NewRepoCache(repo)
23 if err != nil {
24 return err
25 }
26 defer backend.Close()
27
28 var query *cache.Query
29 if len(args) >= 1 {
30 query, err = cache.ParseQuery(args[0])
31
32 if err != nil {
33 return err
34 }
35 } else {
36 query, err = lsQueryFromFlags()
37 if err != nil {
38 return err
39 }
40 }
41
42 allIds := backend.QueryBugs(query)
43
44 for _, id := range allIds {
45 b, err := backend.ResolveBug(id)
46 if err != nil {
47 return err
48 }
49
50 snapshot := b.Snapshot()
51
52 var author bug.Person
53
54 if len(snapshot.Comments) > 0 {
55 create := snapshot.Comments[0]
56 author = create.Author
57 }
58
59 // truncate + pad if needed
60 titleFmt := fmt.Sprintf("%-50.50s", snapshot.Title)
61 authorFmt := fmt.Sprintf("%-15.15s", author.Name)
62
63 fmt.Printf("%s %s\t%s\t%s\t%s\n",
64 colors.Cyan(b.HumanId()),
65 colors.Yellow(snapshot.Status),
66 titleFmt,
67 colors.Magenta(authorFmt),
68 snapshot.Summary(),
69 )
70 }
71
72 return nil
73}
74
75// Transform the command flags into a query
76func lsQueryFromFlags() (*cache.Query, error) {
77 query := cache.NewQuery()
78
79 for _, status := range lsStatusQuery {
80 f, err := cache.StatusFilter(status)
81 if err != nil {
82 return nil, err
83 }
84 query.Status = append(query.Status, f)
85 }
86
87 for _, author := range lsAuthorQuery {
88 f := cache.AuthorFilter(author)
89 query.Author = append(query.Author, f)
90 }
91
92 for _, label := range lsLabelQuery {
93 f := cache.LabelFilter(label)
94 query.Label = append(query.Label, f)
95 }
96
97 for _, no := range lsNoQuery {
98 switch no {
99 case "label":
100 query.NoFilters = append(query.NoFilters, cache.NoLabelFilter())
101 default:
102 return nil, fmt.Errorf("unknown \"no\" filter %s", no)
103 }
104 }
105
106 switch lsSortBy {
107 case "id":
108 query.OrderBy = cache.OrderById
109 case "creation":
110 query.OrderBy = cache.OrderByCreation
111 case "edit":
112 query.OrderBy = cache.OrderByEdit
113 default:
114 return nil, fmt.Errorf("unknown sort flag %s", lsSortBy)
115 }
116
117 switch lsSortDirection {
118 case "asc":
119 query.OrderDirection = cache.OrderAscending
120 case "desc":
121 query.OrderDirection = cache.OrderDescending
122 default:
123 return nil, fmt.Errorf("unknown sort direction %s", lsSortDirection)
124 }
125
126 return query, nil
127}
128
129var lsCmd = &cobra.Command{
130 Use: "ls [<query>]",
131 Short: "List bugs",
132 Long: `Display a summary of each bugs.
133
134You can pass an additional query to filter and order the list. This query can be expressed either with a simple query language or with flags.`,
135 Example: `List open bugs sorted by last edition with a query:
136git bug ls "status:open sort:edit-desc"
137
138List closed bugs sorted by creation with flags:
139git bug ls --status closed --by creation
140`,
141 RunE: runLsBug,
142}
143
144func init() {
145 RootCmd.AddCommand(lsCmd)
146
147 lsCmd.Flags().SortFlags = false
148
149 lsCmd.Flags().StringSliceVarP(&lsStatusQuery, "status", "s", nil,
150 "Filter by status. Valid values are [open,closed]")
151 lsCmd.Flags().StringSliceVarP(&lsAuthorQuery, "author", "a", nil,
152 "Filter by author")
153 lsCmd.Flags().StringSliceVarP(&lsLabelQuery, "label", "l", nil,
154 "Filter by label")
155 lsCmd.Flags().StringSliceVarP(&lsNoQuery, "no", "n", nil,
156 "Filter by absence of something. Valid values are [label]")
157 lsCmd.Flags().StringVarP(&lsSortBy, "by", "b", "creation",
158 "Sort the results by a characteristic. Valid values are [id,creation,edit]")
159 lsCmd.Flags().StringVarP(&lsSortDirection, "direction", "d", "asc",
160 "Select the sorting direction. Valid values are [asc,desc]")
161}