diff options
author | Michael Muré <batolettre@gmail.com> | 2020-06-26 01:02:27 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-26 01:02:27 +0200 |
commit | 2dd0dbb1344ae9293aae05346f977b5d5907934b (patch) | |
tree | 610ff7e381ef99827dc1b1dbc9ae4ea137fe5e21 /commands | |
parent | f790083fb28ac0e68acddc9d5e7a709107a70bab (diff) | |
parent | c326007d01b623bcf883f74f31fc3e5ab3078396 (diff) | |
download | git-bug-2dd0dbb1344ae9293aae05346f977b5d5907934b.tar.gz |
Merge pull request #410 from MichaelMure/output-formatting-2
Add formatting options to the 'show' and 'user ls' commands
Diffstat (limited to 'commands')
-rw-r--r-- | commands/json_common.go | 55 | ||||
-rw-r--r-- | commands/ls.go | 152 | ||||
-rw-r--r-- | commands/show.go | 198 | ||||
-rw-r--r-- | commands/user_ls.go | 47 |
4 files changed, 380 insertions, 72 deletions
diff --git a/commands/json_common.go b/commands/json_common.go new file mode 100644 index 00000000..9a144a1e --- /dev/null +++ b/commands/json_common.go @@ -0,0 +1,55 @@ +package commands + +import ( + "time" + + "github.com/MichaelMure/git-bug/cache" + "github.com/MichaelMure/git-bug/identity" + "github.com/MichaelMure/git-bug/util/lamport" +) + +type JSONIdentity struct { + Id string `json:"id"` + HumanId string `json:"human_id"` + Name string `json:"name"` + Login string `json:"login"` +} + +func NewJSONIdentity(i identity.Interface) JSONIdentity { + return JSONIdentity{ + Id: i.Id().String(), + HumanId: i.Id().Human(), + Name: i.Name(), + Login: i.Login(), + } +} + +func NewJSONIdentityFromExcerpt(excerpt *cache.IdentityExcerpt) JSONIdentity { + return JSONIdentity{ + Id: excerpt.Id.String(), + HumanId: excerpt.Id.Human(), + Name: excerpt.Name, + Login: excerpt.Login, + } +} + +func NewJSONIdentityFromLegacyExcerpt(excerpt *cache.LegacyAuthorExcerpt) JSONIdentity { + return JSONIdentity{ + Name: excerpt.Name, + Login: excerpt.Login, + } +} + +type JSONTime struct { + Timestamp int64 `json:"timestamp"` + Time time.Time `json:"time"` + Lamport lamport.Time `json:"lamport,omitempty"` +} + +func NewJSONTime(t time.Time, l lamport.Time) JSONTime { + return JSONTime{ + Timestamp: t.Unix(), + Time: t, + Lamport: l, + } +} diff --git a/commands/ls.go b/commands/ls.go index 68cb0cfc..34f1f982 100644 --- a/commands/ls.go +++ b/commands/ls.go @@ -4,7 +4,6 @@ import ( "encoding/json" "fmt" "strings" - "time" text "github.com/MichaelMure/go-term-text" "github.com/spf13/cobra" @@ -61,6 +60,8 @@ func runLsBug(_ *cobra.Command, args []string) error { } switch lsOutputFormat { + case "org-mode": + return lsOrgmodeFormatter(backend, bugExcerpt) case "plain": return lsPlainFormatter(backend, bugExcerpt) case "json": @@ -72,11 +73,11 @@ func runLsBug(_ *cobra.Command, args []string) error { } } -type JSONBug struct { - Id string `json:"id"` - HumanId string `json:"human_id"` - CreationTime time.Time `json:"creation_time"` - LastEdited time.Time `json:"last_edited"` +type JSONBugExcerpt struct { + Id string `json:"id"` + HumanId string `json:"human_id"` + CreateTime JSONTime `json:"create_time"` + EditTime JSONTime `json:"edit_time"` Status string `json:"status"` Labels []bug.Label `json:"labels"` @@ -89,29 +90,19 @@ 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{ - b.Id.String(), - b.Id.Human(), - time.Unix(b.CreateUnixTime, 0), - time.Unix(b.EditUnixTime, 0), - b.Status.String(), - b.Labels, - b.Title, - []JSONIdentity{}, - []JSONIdentity{}, - JSONIdentity{}, - b.LenComments, - b.CreateMetadata, + jsonBug := JSONBugExcerpt{ + Id: b.Id.String(), + HumanId: b.Id.Human(), + CreateTime: NewJSONTime(b.CreateTime(), b.CreateLamportTime), + EditTime: NewJSONTime(b.EditTime(), b.EditLamportTime), + Status: b.Status.String(), + Labels: b.Labels, + Title: b.Title, + Comments: b.LenComments, + Metadata: b.CreateMetadata, } if b.AuthorId != "" { @@ -119,41 +110,27 @@ func lsJsonFormatter(backend *cache.RepoCache, bugExcerpts []*cache.BugExcerpt) if err != nil { return err } - - jsonBug.Author.Name = author.DisplayName() - jsonBug.Author.Login = author.Login - jsonBug.Author.Id = author.Id.String() - jsonBug.Author.HumanId = author.Id.Human() + jsonBug.Author = NewJSONIdentityFromExcerpt(author) } else { - jsonBug.Author.Name = b.LegacyAuthor.DisplayName() - jsonBug.Author.Login = b.LegacyAuthor.Login + jsonBug.Author = NewJSONIdentityFromLegacyExcerpt(&b.LegacyAuthor) } - for _, element := range b.Actors { + jsonBug.Actors = make([]JSONIdentity, len(b.Actors)) + for i, element := range b.Actors { actor, err := backend.ResolveIdentityExcerpt(element) if err != nil { return err } - - jsonBug.Actors = append(jsonBug.Actors, JSONIdentity{ - actor.Id.String(), - actor.Id.Human(), - actor.Name, - actor.Login, - }) + jsonBug.Actors[i] = NewJSONIdentityFromExcerpt(actor) } - for _, element := range b.Participants { + jsonBug.Participants = make([]JSONIdentity, len(b.Participants)) + for i, element := range b.Participants { participant, err := backend.ResolveIdentityExcerpt(element) if err != nil { return err } - jsonBug.Participants = append(jsonBug.Participants, JSONIdentity{ - participant.Id.String(), - participant.Id.Human(), - participant.DisplayName(), - participant.Login, - }) + jsonBug.Participants[i] = NewJSONIdentityFromExcerpt(participant) } jsonBugs[i] = jsonBug @@ -207,11 +184,84 @@ func lsDefaultFormatter(backend *cache.RepoCache, bugExcerpts []*cache.BugExcerp func lsPlainFormatter(_ *cache.RepoCache, bugExcerpts []*cache.BugExcerpt) error { for _, b := range bugExcerpts { - fmt.Printf("[%s] %s\n", b.Status, b.Title) + fmt.Printf("%s [%s] %s\n", b.Id.Human(), b.Status, b.Title) } return nil } +func lsOrgmodeFormatter(backend *cache.RepoCache, bugExcerpts []*cache.BugExcerpt) error { + fmt.Println("+TODO: OPEN | CLOSED") + + for _, b := range bugExcerpts { + status := strings.Title(b.Status.String()) + + var title string + if link, ok := b.CreateMetadata["github-url"]; ok { + title = fmt.Sprintf("[%s][%s]", link, b.Title) + } else { + title = b.Title + } + + var name string + if b.AuthorId != "" { + author, err := backend.ResolveIdentityExcerpt(b.AuthorId) + if err != nil { + return err + } + name = author.DisplayName() + } else { + name = b.LegacyAuthor.DisplayName() + } + + labels := b.Labels + var labelsString string + if len(labels) > 0 { + labelsString = fmt.Sprintf(":%s:", strings.Replace(fmt.Sprint(labels), " ", ":", -1)) + } else { + labelsString = "" + } + + fmt.Printf("* %s %s [%s] %s: %s %s\n", + b.Id.Human(), + status, + b.CreateTime(), + name, + title, + labelsString, + ) + + fmt.Printf("** Last Edited: %s\n", b.EditTime().String()) + + fmt.Printf("** Actors:\n") + for _, element := range b.Actors { + actor, err := backend.ResolveIdentityExcerpt(element) + if err != nil { + return err + } + + fmt.Printf(": %s %s\n", + actor.Id.Human(), + actor.DisplayName(), + ) + } + + fmt.Printf("** Participants:\n") + for _, element := range b.Participants { + participant, err := backend.ResolveIdentityExcerpt(element) + if err != nil { + return err + } + + fmt.Printf(": %s %s\n", + participant.Id.Human(), + participant.DisplayName(), + ) + } + } + + return nil +} + // Finish the command flags transformation into the query.Query func completeQuery() error { for _, str := range lsStatusQuery { @@ -294,5 +344,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,org-mode]") } diff --git a/commands/show.go b/commands/show.go index 0bb3dc4a..2f4e46ed 100644 --- a/commands/show.go +++ b/commands/show.go @@ -1,22 +1,26 @@ package commands import ( + "encoding/json" "errors" "fmt" "strings" + "github.com/spf13/cobra" + + "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" ) 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 +39,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.CreateTime.String()) + case "lastEdit": + fmt.Printf("%s\n", snapshot.EditTime().String()) case "humanId": fmt.Printf("%s\n", snapshot.Id().Human()) case "id": @@ -74,16 +78,33 @@ func runShowBug(cmd *cobra.Command, args []string) error { return nil } + switch showOutputFormat { + case "org-mode": + return showOrgmodeFormatter(snapshot) + case "json": + return showJsonFormatter(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), + fmt.Printf("%s [%s] %s\n\n", colors.Cyan(snapshot.Id().Human()), + colors.Yellow(snapshot.Status), 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.CreateTime.String(), + ) + + fmt.Printf("This was last edited at %s\n\n", + snapshot.EditTime().String(), ) // Labels @@ -143,6 +164,151 @@ func runShowBug(cmd *cobra.Command, args []string) error { return nil } +type JSONBugSnapshot struct { + Id string `json:"id"` + HumanId string `json:"human_id"` + CreateTime JSONTime `json:"create_time"` + EditTime JSONTime `json:"edit_time"` + 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 string `json:"id"` + HumanId string `json:"human_id"` + Author JSONIdentity `json:"author"` + Message string `json:"message"` +} + +func NewJSONComment(comment bug.Comment) JSONComment { + return JSONComment{ + Id: comment.Id().String(), + HumanId: comment.Id().Human(), + Author: NewJSONIdentity(comment.Author), + Message: comment.Message, + } +} + +func showJsonFormatter(snapshot *bug.Snapshot) error { + jsonBug := JSONBugSnapshot{ + Id: snapshot.Id().String(), + HumanId: snapshot.Id().Human(), + CreateTime: NewJSONTime(snapshot.CreateTime, 0), + EditTime: NewJSONTime(snapshot.EditTime(), 0), + Status: snapshot.Status.String(), + Labels: snapshot.Labels, + Title: snapshot.Title, + Author: NewJSONIdentity(snapshot.Author), + } + + jsonBug.Actors = make([]JSONIdentity, len(snapshot.Actors)) + for i, element := range snapshot.Actors { + jsonBug.Actors[i] = NewJSONIdentity(element) + } + + jsonBug.Participants = make([]JSONIdentity, len(snapshot.Participants)) + for i, element := range snapshot.Participants { + jsonBug.Participants[i] = NewJSONIdentity(element) + } + + jsonBug.Comments = make([]JSONComment, len(snapshot.Comments)) + for i, comment := range snapshot.Comments { + jsonBug.Comments[i] = NewJSONComment(comment) + } + + jsonObject, _ := json.MarshalIndent(jsonBug, "", " ") + fmt.Printf("%s\n", jsonObject) + + return nil +} + +func showOrgmodeFormatter(snapshot *bug.Snapshot) error { + // Header + fmt.Printf("%s [%s] %s\n", + snapshot.Id().Human(), + snapshot.Status, + snapshot.Title, + ) + + fmt.Printf("* Author: %s\n", + snapshot.Author.DisplayName(), + ) + + fmt.Printf("* Creation Time: %s\n", + snapshot.CreateTime.String(), + ) + + fmt.Printf("* Last Edit: %s\n", + snapshot.EditTime().String(), + ) + + // Labels + var labels = make([]string, len(snapshot.Labels)) + for i, label := range snapshot.Labels { + labels[i] = string(label) + } + + fmt.Printf("* Labels:\n") + if len(labels) > 0 { + fmt.Printf("** %s\n", + strings.Join(labels, "\n** "), + ) + } + + // Actors + var actors = make([]string, len(snapshot.Actors)) + for i, actor := range snapshot.Actors { + actors[i] = fmt.Sprintf("%s %s", + actor.Id().Human(), + actor.DisplayName(), + ) + } + + fmt.Printf("* Actors:\n** %s\n", + strings.Join(actors, "\n** "), + ) + + // Participants + var participants = make([]string, len(snapshot.Participants)) + for i, participant := range snapshot.Participants { + participants[i] = fmt.Sprintf("%s %s", + participant.Id().Human(), + participant.DisplayName(), + ) + } + + fmt.Printf("* Participants:\n** %s\n", + strings.Join(participants, "\n** "), + ) + + fmt.Printf("* Comments:\n") + + for i, comment := range snapshot.Comments { + var message string + fmt.Printf("** #%d %s\n", + i, + comment.Author.DisplayName(), + ) + + if comment.Message == "" { + message = "No description provided." + } else { + message = strings.ReplaceAll(comment.Message, "\n", "\n: ") + } + + fmt.Printf(": %s\n", + message, + ) + } + + return nil +} + var showCmd = &cobra.Command{ Use: "show [<id>]", Short: "Display the details of a bug.", @@ -152,6 +318,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,json,org-mode]") } diff --git a/commands/user_ls.go b/commands/user_ls.go index 609ff5a4..b3fb32e6 100644 --- a/commands/user_ls.go +++ b/commands/user_ls.go @@ -1,15 +1,21 @@ package commands import ( + "encoding/json" "fmt" + "github.com/spf13/cobra" + "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,21 +23,48 @@ func runUserLs(cmd *cobra.Command, args []string) error { defer backend.Close() interrupt.RegisterCleaner(backend.Close) - for _, id := range backend.AllIdentityIds() { - i, err := backend.ResolveIdentityExcerpt(id) + ids := backend.AllIdentityIds() + var users []*cache.IdentityExcerpt + for _, id := range ids { + user, err := backend.ResolveIdentityExcerpt(id) if err != nil { return err } + users = append(users, user) + } + + switch userLsOutputFormat { + case "json": + return userLsJsonFormatter(users) + case "default": + return userLsDefaultFormatter(users) + default: + return fmt.Errorf("unknown format %s", userLsOutputFormat) + } +} +func userLsDefaultFormatter(users []*cache.IdentityExcerpt) error { + for _, user := range users { fmt.Printf("%s %s\n", - colors.Cyan(i.Id.Human()), - i.DisplayName(), + colors.Cyan(user.Id.Human()), + user.DisplayName(), ) } return nil } +func userLsJsonFormatter(users []*cache.IdentityExcerpt) error { + jsonUsers := make([]JSONIdentity, len(users)) + for i, user := range users { + jsonUsers[i] = NewJSONIdentityFromExcerpt(user) + } + + jsonObject, _ := json.MarshalIndent(jsonUsers, "", " ") + fmt.Printf("%s\n", jsonObject) + return nil +} + var userLsCmd = &cobra.Command{ Use: "ls", Short: "List identities.", @@ -42,4 +75,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,json]") } |