diff options
author | vince <vincetiu8@gmail.com> | 2020-06-21 13:51:48 +0800 |
---|---|---|
committer | vince <vincetiu8@gmail.com> | 2020-06-21 13:51:48 +0800 |
commit | cd8352edde7f4a26cb6b4dd922b05aa0bb23a70b (patch) | |
tree | 1ac2cf77cd24310350fe58cb358cb82d0b48da35 | |
parent | f790083fb28ac0e68acddc9d5e7a709107a70bab (diff) | |
download | git-bug-cd8352edde7f4a26cb6b4dd922b05aa0bb23a70b.tar.gz git-bug-cd8352edde7f4a26cb6b4dd922b05aa0bb23a70b.zip |
Add output formatting support to the 'show' and 'user ls' commands
This adds options to specify an output format for the commands in question. Supported formats are currently:
- 'plain': plaintext, stripped of all colors
- 'json': prints output as a json object
-rw-r--r-- | commands/ls.go | 15 | ||||
-rw-r--r-- | commands/show.go | 209 | ||||
-rw-r--r-- | commands/user_ls.go | 67 |
3 files changed, 264 insertions, 27 deletions
diff --git a/commands/ls.go b/commands/ls.go index 68cb0cfc..41f48f91 100644 --- a/commands/ls.go +++ b/commands/ls.go @@ -72,7 +72,7 @@ func runLsBug(_ *cobra.Command, args []string) error { } } -type JSONBug struct { +type JSONBugExcerpt struct { Id string `json:"id"` HumanId string `json:"human_id"` CreationTime time.Time `json:"creation_time"` @@ -89,17 +89,10 @@ type JSONBug struct { Metadata map[string]string `json:"metadata"` } -type JSONIdentity struct { - Id string `json:"id"` - HumanId string `json:"human_id"` - Name string `json:"name"` - Login string `json:"login"` -} - func lsJsonFormatter(backend *cache.RepoCache, bugExcerpts []*cache.BugExcerpt) error { - jsonBugs := make([]JSONBug, len(bugExcerpts)) + jsonBugs := make([]JSONBugExcerpt, len(bugExcerpts)) for i, b := range bugExcerpts { - jsonBug := JSONBug{ + jsonBug := JSONBugExcerpt{ b.Id.String(), b.Id.Human(), time.Unix(b.CreateUnixTime, 0), @@ -294,5 +287,5 @@ func init() { lsCmd.Flags().StringVarP(&lsSortDirection, "direction", "d", "asc", "Select the sorting direction. Valid values are [asc,desc]") lsCmd.Flags().StringVarP(&lsOutputFormat, "format", "f", "default", - "Select the output formatting style. Valid values are [default, plain(text), json]") + "Select the output formatting style. Valid values are [default,plain,json]") } diff --git a/commands/show.go b/commands/show.go index 0bb3dc4a..c484c97b 100644 --- a/commands/show.go +++ b/commands/show.go @@ -1,22 +1,25 @@ package commands import ( + "encoding/json" "errors" "fmt" - "strings" - + "github.com/MichaelMure/git-bug/bug" "github.com/MichaelMure/git-bug/cache" _select "github.com/MichaelMure/git-bug/commands/select" "github.com/MichaelMure/git-bug/util/colors" "github.com/MichaelMure/git-bug/util/interrupt" "github.com/spf13/cobra" + "strings" + "time" ) var ( - showFieldsQuery string + showFieldsQuery string + showOutputFormat string ) -func runShowBug(cmd *cobra.Command, args []string) error { +func runShowBug(_ *cobra.Command, args []string) error { backend, err := cache.NewRepoCache(repo) if err != nil { return err @@ -35,16 +38,16 @@ func runShowBug(cmd *cobra.Command, args []string) error { return errors.New("invalid bug: no comment") } - firstComment := snapshot.Comments[0] - if showFieldsQuery != "" { switch showFieldsQuery { case "author": - fmt.Printf("%s\n", firstComment.Author.DisplayName()) + fmt.Printf("%s\n", snapshot.Author.DisplayName()) case "authorEmail": - fmt.Printf("%s\n", firstComment.Author.Email()) + fmt.Printf("%s\n", snapshot.Author.Email()) case "createTime": - fmt.Printf("%s\n", firstComment.FormatTime()) + fmt.Printf("%s\n", snapshot.CreatedAt.String()) + case "lastEdit": + fmt.Printf("%s\n", snapshot.LastEditTime().String()) case "humanId": fmt.Printf("%s\n", snapshot.Id().Human()) case "id": @@ -74,6 +77,19 @@ func runShowBug(cmd *cobra.Command, args []string) error { return nil } + switch showOutputFormat { + case "json": + return showJsonFormatter(snapshot) + case "plain": + return showPlainFormatter(snapshot) + case "default": + return showDefaultFormatter(snapshot) + default: + return fmt.Errorf("unknown format %s", showOutputFormat) + } +} + +func showDefaultFormatter(snapshot *bug.Snapshot) error { // Header fmt.Printf("[%s] %s %s\n\n", colors.Yellow(snapshot.Status), @@ -81,9 +97,13 @@ func runShowBug(cmd *cobra.Command, args []string) error { snapshot.Title, ) - fmt.Printf("%s opened this issue %s\n\n", - colors.Magenta(firstComment.Author.DisplayName()), - firstComment.FormatTimeRel(), + fmt.Printf("%s opened this issue %s\n", + colors.Magenta(snapshot.Author.DisplayName()), + snapshot.CreatedAt.String(), + ) + + fmt.Printf("This was last edited at %s\n\n", + snapshot.LastEditTime().String(), ) // Labels @@ -143,6 +163,165 @@ func runShowBug(cmd *cobra.Command, args []string) error { return nil } +func showPlainFormatter(snapshot *bug.Snapshot) error { + // Header + fmt.Printf("[%s] %s %s\n", + snapshot.Status, + snapshot.Id().Human(), + snapshot.Title, + ) + + fmt.Printf("author: %s\n", + snapshot.Author.DisplayName(), + ) + + fmt.Printf("creation time: %s\n", + snapshot.CreatedAt.String(), + ) + + fmt.Printf("last edit: %s\n", + snapshot.LastEditTime().String(), + ) + + // Labels + var labels = make([]string, len(snapshot.Labels)) + for i := range snapshot.Labels { + labels[i] = string(snapshot.Labels[i]) + } + + fmt.Printf("labels: %s\n", + strings.Join(labels, ", "), + ) + + // Actors + var actors = make([]string, len(snapshot.Actors)) + for i := range snapshot.Actors { + actors[i] = snapshot.Actors[i].DisplayName() + } + + fmt.Printf("actors: %s\n", + strings.Join(actors, ", "), + ) + + // Participants + var participants = make([]string, len(snapshot.Participants)) + for i := range snapshot.Participants { + participants[i] = snapshot.Participants[i].DisplayName() + } + + fmt.Printf("participants: %s\n", + strings.Join(participants, ", "), + ) + + // Comments + indent := " " + + for i, comment := range snapshot.Comments { + var message string + fmt.Printf("%s#%d %s <%s>\n", + indent, + i, + comment.Author.DisplayName(), + comment.Author.Email(), + ) + + if comment.Message == "" { + message = "No description provided." + } else { + message = comment.Message + } + + fmt.Printf("%s%s\n", + indent, + message, + ) + } + + return nil +} + +type JSONBugSnapshot struct { + Id string `json:"id"` + HumanId string `json:"human_id"` + CreationTime time.Time `json:"creation_time"` + LastEdited time.Time `json:"last_edited"` + + Status string `json:"status"` + Labels []bug.Label `json:"labels"` + Title string `json:"title"` + Author JSONIdentity `json:"author"` + Actors []JSONIdentity `json:"actors"` + Participants []JSONIdentity `json:"participants"` + + Comments []JSONComment `json:"comments"` +} + +type JSONComment struct { + Id int `json:"id"` + AuthorName string `json:"author_name"` + AuthorLogin string `json:"author_login"` + Message string `json:"message"` +} + +func showJsonFormatter(snapshot *bug.Snapshot) error { + jsonBug := JSONBugSnapshot{ + snapshot.Id().String(), + snapshot.Id().Human(), + snapshot.CreatedAt, + snapshot.LastEditTime(), + snapshot.Status.String(), + snapshot.Labels, + snapshot.Title, + JSONIdentity{}, + []JSONIdentity{}, + []JSONIdentity{}, + []JSONComment{}, + } + + jsonBug.Author.Name = snapshot.Author.DisplayName() + jsonBug.Author.Login = snapshot.Author.Login() + jsonBug.Author.Id = snapshot.Author.Id().String() + jsonBug.Author.HumanId = snapshot.Author.Id().Human() + + for _, element := range snapshot.Actors { + jsonBug.Actors = append(jsonBug.Actors, JSONIdentity{ + element.Id().String(), + element.Id().Human(), + element.Name(), + element.Login(), + }) + } + + for _, element := range snapshot.Participants { + jsonBug.Actors = append(jsonBug.Actors, JSONIdentity{ + element.Id().String(), + element.Id().Human(), + element.Name(), + element.Login(), + }) + } + + for i, comment := range snapshot.Comments { + var message string + if comment.Message == "" { + message = "No description provided." + } else { + message = comment.Message + } + jsonBug.Comments = append(jsonBug.Comments, JSONComment{ + i, + comment.Author.Name(), + comment.Author.Login(), + message, + }) + } + + jsonObject, _ := json.MarshalIndent(jsonBug, "", " ") + fmt.Printf("%s\n", jsonObject) + + return nil +} + var showCmd = &cobra.Command{ Use: "show [<id>]", Short: "Display the details of a bug.", @@ -152,6 +331,8 @@ var showCmd = &cobra.Command{ func init() { RootCmd.AddCommand(showCmd) - showCmd.Flags().StringVarP(&showFieldsQuery, "field", "f", "", - "Select field to display. Valid values are [author,authorEmail,createTime,humanId,id,labels,shortId,status,title,actors,participants]") + showCmd.Flags().StringVarP(&showFieldsQuery, "field", "", "", + "Select field to display. Valid values are [author,authorEmail,createTime,lastEdit,humanId,id,labels,shortId,status,title,actors,participants]") + showCmd.Flags().StringVarP(&showOutputFormat, "format", "f", "default", + "Select the output formatting style. Valid values are [default,plain,json]") } diff --git a/commands/user_ls.go b/commands/user_ls.go index 609ff5a4..9d0eebf1 100644 --- a/commands/user_ls.go +++ b/commands/user_ls.go @@ -1,15 +1,19 @@ package commands import ( + "encoding/json" "fmt" - "github.com/MichaelMure/git-bug/cache" "github.com/MichaelMure/git-bug/util/colors" "github.com/MichaelMure/git-bug/util/interrupt" "github.com/spf13/cobra" ) -func runUserLs(cmd *cobra.Command, args []string) error { +var ( + userLsOutputFormat string +) + +func runUserLs(_ *cobra.Command, _ []string) error { backend, err := cache.NewRepoCache(repo) if err != nil { return err @@ -17,6 +21,42 @@ func runUserLs(cmd *cobra.Command, args []string) error { defer backend.Close() interrupt.RegisterCleaner(backend.Close) + switch userLsOutputFormat { + case "json": + return userLsJsonFormatter(backend) + case "plain": + return userLsPlainFormatter(backend) + case "default": + return userLsDefaultFormatter(backend) + default: + return fmt.Errorf("unknown format %s", userLsOutputFormat) + } +} + +type JSONIdentity struct { + Id string `json:"id"` + HumanId string `json:"human_id"` + Name string `json:"name"` + Login string `json:"login"` +} + +func userLsPlainFormatter(backend *cache.RepoCache) error { + for _, id := range backend.AllIdentityIds() { + i, err := backend.ResolveIdentityExcerpt(id) + if err != nil { + return err + } + + fmt.Printf("%s %s\n", + i.Id.Human(), + i.DisplayName(), + ) + } + + return nil +} + +func userLsDefaultFormatter(backend *cache.RepoCache) error { for _, id := range backend.AllIdentityIds() { i, err := backend.ResolveIdentityExcerpt(id) if err != nil { @@ -32,6 +72,27 @@ func runUserLs(cmd *cobra.Command, args []string) error { return nil } +func userLsJsonFormatter(backend *cache.RepoCache) error { + users := []JSONIdentity{} + for _, id := range backend.AllIdentityIds() { + i, err := backend.ResolveIdentityExcerpt(id) + if err != nil { + return err + } + + users = append(users, JSONIdentity{ + i.Id.String(), + i.Id.Human(), + i.Name, + i.Login, + }) + } + + jsonObject, _ := json.MarshalIndent(users, "", " ") + fmt.Printf("%s\n", jsonObject) + return nil +} + var userLsCmd = &cobra.Command{ Use: "ls", Short: "List identities.", @@ -42,4 +103,6 @@ var userLsCmd = &cobra.Command{ func init() { userCmd.AddCommand(userLsCmd) userLsCmd.Flags().SortFlags = false + userLsCmd.Flags().StringVarP(&userLsOutputFormat, "format", "f", "default", + "Select the output formatting style. Valid values are [default,plain,json]") } |