show.go

  1package commands
  2
  3import (
  4	"encoding/json"
  5	"errors"
  6	"fmt"
  7	"github.com/MichaelMure/git-bug/bug"
  8	"github.com/MichaelMure/git-bug/cache"
  9	_select "github.com/MichaelMure/git-bug/commands/select"
 10	"github.com/MichaelMure/git-bug/util/colors"
 11	"github.com/MichaelMure/git-bug/util/interrupt"
 12	"github.com/spf13/cobra"
 13	"strings"
 14	"time"
 15)
 16
 17var (
 18	showFieldsQuery  string
 19	showOutputFormat string
 20)
 21
 22func runShowBug(_ *cobra.Command, args []string) error {
 23	backend, err := cache.NewRepoCache(repo)
 24	if err != nil {
 25		return err
 26	}
 27	defer backend.Close()
 28	interrupt.RegisterCleaner(backend.Close)
 29
 30	b, args, err := _select.ResolveBug(backend, args)
 31	if err != nil {
 32		return err
 33	}
 34
 35	snapshot := b.Snapshot()
 36
 37	if len(snapshot.Comments) == 0 {
 38		return errors.New("invalid bug: no comment")
 39	}
 40
 41	if showFieldsQuery != "" {
 42		switch showFieldsQuery {
 43		case "author":
 44			fmt.Printf("%s\n", snapshot.Author.DisplayName())
 45		case "authorEmail":
 46			fmt.Printf("%s\n", snapshot.Author.Email())
 47		case "createTime":
 48			fmt.Printf("%s\n", snapshot.CreatedAt.String())
 49		case "lastEdit":
 50			fmt.Printf("%s\n", snapshot.LastEditTime().String())
 51		case "humanId":
 52			fmt.Printf("%s\n", snapshot.Id().Human())
 53		case "id":
 54			fmt.Printf("%s\n", snapshot.Id())
 55		case "labels":
 56			for _, l := range snapshot.Labels {
 57				fmt.Printf("%s\n", l.String())
 58			}
 59		case "actors":
 60			for _, a := range snapshot.Actors {
 61				fmt.Printf("%s\n", a.DisplayName())
 62			}
 63		case "participants":
 64			for _, p := range snapshot.Participants {
 65				fmt.Printf("%s\n", p.DisplayName())
 66			}
 67		case "shortId":
 68			fmt.Printf("%s\n", snapshot.Id().Human())
 69		case "status":
 70			fmt.Printf("%s\n", snapshot.Status)
 71		case "title":
 72			fmt.Printf("%s\n", snapshot.Title)
 73		default:
 74			return fmt.Errorf("\nUnsupported field: %s\n", showFieldsQuery)
 75		}
 76
 77		return nil
 78	}
 79
 80	switch showOutputFormat {
 81	case "json":
 82		return showJsonFormatter(snapshot)
 83	case "plain":
 84		return showPlainFormatter(snapshot)
 85	case "default":
 86		return showDefaultFormatter(snapshot)
 87	default:
 88		return fmt.Errorf("unknown format %s", showOutputFormat)
 89	}
 90}
 91
 92func showDefaultFormatter(snapshot *bug.Snapshot) error {
 93	// Header
 94	fmt.Printf("[%s] %s %s\n\n",
 95		colors.Yellow(snapshot.Status),
 96		colors.Cyan(snapshot.Id().Human()),
 97		snapshot.Title,
 98	)
 99
100	fmt.Printf("%s opened this issue %s\n",
101		colors.Magenta(snapshot.Author.DisplayName()),
102		snapshot.CreatedAt.String(),
103	)
104
105	fmt.Printf("This was last edited at %s\n\n",
106		snapshot.LastEditTime().String(),
107	)
108
109	// Labels
110	var labels = make([]string, len(snapshot.Labels))
111	for i := range snapshot.Labels {
112		labels[i] = string(snapshot.Labels[i])
113	}
114
115	fmt.Printf("labels: %s\n",
116		strings.Join(labels, ", "),
117	)
118
119	// Actors
120	var actors = make([]string, len(snapshot.Actors))
121	for i := range snapshot.Actors {
122		actors[i] = snapshot.Actors[i].DisplayName()
123	}
124
125	fmt.Printf("actors: %s\n",
126		strings.Join(actors, ", "),
127	)
128
129	// Participants
130	var participants = make([]string, len(snapshot.Participants))
131	for i := range snapshot.Participants {
132		participants[i] = snapshot.Participants[i].DisplayName()
133	}
134
135	fmt.Printf("participants: %s\n\n",
136		strings.Join(participants, ", "),
137	)
138
139	// Comments
140	indent := "  "
141
142	for i, comment := range snapshot.Comments {
143		var message string
144		fmt.Printf("%s#%d %s <%s>\n\n",
145			indent,
146			i,
147			comment.Author.DisplayName(),
148			comment.Author.Email(),
149		)
150
151		if comment.Message == "" {
152			message = colors.GreyBold("No description provided.")
153		} else {
154			message = comment.Message
155		}
156
157		fmt.Printf("%s%s\n\n\n",
158			indent,
159			message,
160		)
161	}
162
163	return nil
164}
165
166func showPlainFormatter(snapshot *bug.Snapshot) error {
167	// Header
168	fmt.Printf("[%s] %s %s\n",
169		snapshot.Status,
170		snapshot.Id().Human(),
171		snapshot.Title,
172	)
173
174	fmt.Printf("author: %s\n",
175		snapshot.Author.DisplayName(),
176	)
177
178	fmt.Printf("creation time: %s\n",
179		snapshot.CreatedAt.String(),
180	)
181
182	fmt.Printf("last edit: %s\n",
183		snapshot.LastEditTime().String(),
184	)
185
186	// Labels
187	var labels = make([]string, len(snapshot.Labels))
188	for i := range snapshot.Labels {
189		labels[i] = string(snapshot.Labels[i])
190	}
191
192	fmt.Printf("labels: %s\n",
193		strings.Join(labels, ", "),
194	)
195
196	// Actors
197	var actors = make([]string, len(snapshot.Actors))
198	for i := range snapshot.Actors {
199		actors[i] = snapshot.Actors[i].DisplayName()
200	}
201
202	fmt.Printf("actors: %s\n",
203		strings.Join(actors, ", "),
204	)
205
206	// Participants
207	var participants = make([]string, len(snapshot.Participants))
208	for i := range snapshot.Participants {
209		participants[i] = snapshot.Participants[i].DisplayName()
210	}
211
212	fmt.Printf("participants: %s\n",
213		strings.Join(participants, ", "),
214	)
215
216	// Comments
217	indent := "  "
218
219	for i, comment := range snapshot.Comments {
220		var message string
221		fmt.Printf("%s#%d %s <%s>\n",
222			indent,
223			i,
224			comment.Author.DisplayName(),
225			comment.Author.Email(),
226		)
227
228		if comment.Message == "" {
229			message = "No description provided."
230		} else {
231			message = comment.Message
232		}
233
234		fmt.Printf("%s%s\n",
235			indent,
236			message,
237		)
238	}
239
240	return nil
241}
242
243type JSONBugSnapshot struct {
244	Id           string    `json:"id"`
245	HumanId      string    `json:"human_id"`
246	CreationTime time.Time `json:"creation_time"`
247	LastEdited   time.Time `json:"last_edited"`
248
249	Status       string         `json:"status"`
250	Labels       []bug.Label    `json:"labels"`
251	Title        string         `json:"title"`
252	Author       JSONIdentity   `json:"author"`
253	Actors       []JSONIdentity `json:"actors"`
254	Participants []JSONIdentity `json:"participants"`
255
256	Comments []JSONComment `json:"comments"`
257}
258
259type JSONComment struct {
260	Id          int    `json:"id"`
261	AuthorName  string `json:"author_name"`
262	AuthorLogin string `json:"author_login"`
263	Message     string `json:"message"`
264}
265
266func showJsonFormatter(snapshot *bug.Snapshot) error {
267	jsonBug := JSONBugSnapshot{
268		snapshot.Id().String(),
269		snapshot.Id().Human(),
270		snapshot.CreatedAt,
271		snapshot.LastEditTime(),
272		snapshot.Status.String(),
273		snapshot.Labels,
274		snapshot.Title,
275		JSONIdentity{},
276		[]JSONIdentity{},
277		[]JSONIdentity{},
278		[]JSONComment{},
279	}
280
281	jsonBug.Author.Name = snapshot.Author.DisplayName()
282	jsonBug.Author.Login = snapshot.Author.Login()
283	jsonBug.Author.Id = snapshot.Author.Id().String()
284	jsonBug.Author.HumanId = snapshot.Author.Id().Human()
285
286	for _, element := range snapshot.Actors {
287		jsonBug.Actors = append(jsonBug.Actors, JSONIdentity{
288			element.Id().String(),
289			element.Id().Human(),
290			element.Name(),
291			element.Login(),
292		})
293	}
294
295	for _, element := range snapshot.Participants {
296		jsonBug.Actors = append(jsonBug.Actors, JSONIdentity{
297			element.Id().String(),
298			element.Id().Human(),
299			element.Name(),
300			element.Login(),
301		})
302	}
303
304	for i, comment := range snapshot.Comments {
305		var message string
306		if comment.Message == "" {
307			message = "No description provided."
308		} else {
309			message = comment.Message
310		}
311		jsonBug.Comments = append(jsonBug.Comments, JSONComment{
312			i,
313			comment.Author.Name(),
314			comment.Author.Login(),
315			message,
316		})
317	}
318
319	jsonObject, _ := json.MarshalIndent(jsonBug, "", "    ")
320	fmt.Printf("%s\n", jsonObject)
321
322	return nil
323}
324
325var showCmd = &cobra.Command{
326	Use:     "show [<id>]",
327	Short:   "Display the details of a bug.",
328	PreRunE: loadRepo,
329	RunE:    runShowBug,
330}
331
332func init() {
333	RootCmd.AddCommand(showCmd)
334	showCmd.Flags().StringVarP(&showFieldsQuery, "field", "", "",
335		"Select field to display. Valid values are [author,authorEmail,createTime,lastEdit,humanId,id,labels,shortId,status,title,actors,participants]")
336	showCmd.Flags().StringVarP(&showOutputFormat, "format", "f", "default",
337		"Select the output formatting style. Valid values are [default,plain,json]")
338}