commands: share JSON creation

Michael Muré created

Change summary

commands/bug/bug.go             |  58 ---------------
commands/bug/bug_show.go        |  65 -----------------
commands/bug/bug_test.go        |   3 
commands/cmdjson/bug.go         | 123 +++++++++++++++++++++++++++++++++++
commands/execenv/env.go         |  11 +++
commands/execenv/env_testing.go |  10 ++
commands/user/user.go           |  12 +--
7 files changed, 156 insertions(+), 126 deletions(-)

Detailed changes

commands/bug/bug.go 🔗

@@ -1,7 +1,6 @@
 package bugcmd
 
 import (
-	"encoding/json"
 	"fmt"
 	"regexp"
 	"strings"
@@ -187,67 +186,16 @@ func repairQuery(args []string) string {
 	return strings.Join(args, " ")
 }
 
-type JSONBugExcerpt struct {
-	Id         string       `json:"id"`
-	HumanId    string       `json:"human_id"`
-	CreateTime cmdjson.Time `json:"create_time"`
-	EditTime   cmdjson.Time `json:"edit_time"`
-
-	Status       string             `json:"status"`
-	Labels       []bug.Label        `json:"labels"`
-	Title        string             `json:"title"`
-	Actors       []cmdjson.Identity `json:"actors"`
-	Participants []cmdjson.Identity `json:"participants"`
-	Author       cmdjson.Identity   `json:"author"`
-
-	Comments int               `json:"comments"`
-	Metadata map[string]string `json:"metadata"`
-}
-
 func bugsJsonFormatter(env *execenv.Env, bugExcerpts []*cache.BugExcerpt) error {
-	jsonBugs := make([]JSONBugExcerpt, len(bugExcerpts))
+	jsonBugs := make([]cmdjson.BugExcerpt, len(bugExcerpts))
 	for i, b := range bugExcerpts {
-		jsonBug := JSONBugExcerpt{
-			Id:         b.Id().String(),
-			HumanId:    b.Id().Human(),
-			CreateTime: cmdjson.NewTime(b.CreateTime(), b.CreateLamportTime),
-			EditTime:   cmdjson.NewTime(b.EditTime(), b.EditLamportTime),
-			Status:     b.Status.String(),
-			Labels:     b.Labels,
-			Title:      b.Title,
-			Comments:   b.LenComments,
-			Metadata:   b.CreateMetadata,
-		}
-
-		author, err := env.Backend.Identities().ResolveExcerpt(b.AuthorId)
+		jsonBug, err := cmdjson.NewBugExcerpt(env.Backend, b)
 		if err != nil {
 			return err
 		}
-		jsonBug.Author = cmdjson.NewIdentityFromExcerpt(author)
-
-		jsonBug.Actors = make([]cmdjson.Identity, len(b.Actors))
-		for i, element := range b.Actors {
-			actor, err := env.Backend.Identities().ResolveExcerpt(element)
-			if err != nil {
-				return err
-			}
-			jsonBug.Actors[i] = cmdjson.NewIdentityFromExcerpt(actor)
-		}
-
-		jsonBug.Participants = make([]cmdjson.Identity, len(b.Participants))
-		for i, element := range b.Participants {
-			participant, err := env.Backend.Identities().ResolveExcerpt(element)
-			if err != nil {
-				return err
-			}
-			jsonBug.Participants[i] = cmdjson.NewIdentityFromExcerpt(participant)
-		}
-
 		jsonBugs[i] = jsonBug
 	}
-	jsonObject, _ := json.MarshalIndent(jsonBugs, "", "    ")
-	env.Out.Printf("%s\n", jsonObject)
-	return nil
+	return env.Out.PrintJSON(jsonBugs)
 }
 
 func bugsCompactFormatter(env *execenv.Env, bugExcerpts []*cache.BugExcerpt) error {

commands/bug/bug_show.go 🔗

@@ -1,7 +1,6 @@
 package bugcmd
 
 import (
-	"encoding/json"
 	"errors"
 	"fmt"
 	"strings"
@@ -186,67 +185,9 @@ func showDefaultFormatter(env *execenv.Env, snapshot *bug.Snapshot) error {
 	return nil
 }
 
-type JSONBugSnapshot struct {
-	Id           string             `json:"id"`
-	HumanId      string             `json:"human_id"`
-	CreateTime   cmdjson.Time       `json:"create_time"`
-	EditTime     cmdjson.Time       `json:"edit_time"`
-	Status       string             `json:"status"`
-	Labels       []bug.Label        `json:"labels"`
-	Title        string             `json:"title"`
-	Author       cmdjson.Identity   `json:"author"`
-	Actors       []cmdjson.Identity `json:"actors"`
-	Participants []cmdjson.Identity `json:"participants"`
-	Comments     []JSONBugComment   `json:"comments"`
-}
-
-type JSONBugComment struct {
-	Id      string           `json:"id"`
-	HumanId string           `json:"human_id"`
-	Author  cmdjson.Identity `json:"author"`
-	Message string           `json:"message"`
-}
-
-func NewJSONComment(comment bug.Comment) JSONBugComment {
-	return JSONBugComment{
-		Id:      comment.CombinedId().String(),
-		HumanId: comment.CombinedId().Human(),
-		Author:  cmdjson.NewIdentity(comment.Author),
-		Message: comment.Message,
-	}
-}
-
-func showJsonFormatter(env *execenv.Env, snapshot *bug.Snapshot) error {
-	jsonBug := JSONBugSnapshot{
-		Id:         snapshot.Id().String(),
-		HumanId:    snapshot.Id().Human(),
-		CreateTime: cmdjson.NewTime(snapshot.CreateTime, 0),
-		EditTime:   cmdjson.NewTime(snapshot.EditTime(), 0),
-		Status:     snapshot.Status.String(),
-		Labels:     snapshot.Labels,
-		Title:      snapshot.Title,
-		Author:     cmdjson.NewIdentity(snapshot.Author),
-	}
-
-	jsonBug.Actors = make([]cmdjson.Identity, len(snapshot.Actors))
-	for i, element := range snapshot.Actors {
-		jsonBug.Actors[i] = cmdjson.NewIdentity(element)
-	}
-
-	jsonBug.Participants = make([]cmdjson.Identity, len(snapshot.Participants))
-	for i, element := range snapshot.Participants {
-		jsonBug.Participants[i] = cmdjson.NewIdentity(element)
-	}
-
-	jsonBug.Comments = make([]JSONBugComment, len(snapshot.Comments))
-	for i, comment := range snapshot.Comments {
-		jsonBug.Comments[i] = NewJSONComment(comment)
-	}
-
-	jsonObject, _ := json.MarshalIndent(jsonBug, "", "    ")
-	env.Out.Printf("%s\n", jsonObject)
-
-	return nil
+func showJsonFormatter(env *execenv.Env, snap *bug.Snapshot) error {
+	jsonBug := cmdjson.NewBugSnapshot(snap)
+	return env.Out.PrintJSON(jsonBug)
 }
 
 func showOrgModeFormatter(env *execenv.Env, snapshot *bug.Snapshot) error {

commands/bug/bug_test.go 🔗

@@ -8,6 +8,7 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"github.com/MichaelMure/git-bug/commands/bug/testenv"
+	"github.com/MichaelMure/git-bug/commands/cmdjson"
 )
 
 func Test_repairQuery(t *testing.T) {
@@ -95,7 +96,7 @@ $`
 
 		require.NoError(t, runBug(env, opts, []string{}))
 
-		var bugs []JSONBugExcerpt
+		var bugs []cmdjson.BugExcerpt
 		require.NoError(t, json.Unmarshal(env.Out.Bytes(), &bugs))
 
 		require.Len(t, bugs, 1)

commands/cmdjson/bug.go 🔗

@@ -0,0 +1,123 @@
+package cmdjson
+
+import (
+	"github.com/MichaelMure/git-bug/cache"
+	"github.com/MichaelMure/git-bug/entities/bug"
+)
+
+type BugSnapshot struct {
+	Id           string       `json:"id"`
+	HumanId      string       `json:"human_id"`
+	CreateTime   Time         `json:"create_time"`
+	EditTime     Time         `json:"edit_time"`
+	Status       string       `json:"status"`
+	Labels       []bug.Label  `json:"labels"`
+	Title        string       `json:"title"`
+	Author       Identity     `json:"author"`
+	Actors       []Identity   `json:"actors"`
+	Participants []Identity   `json:"participants"`
+	Comments     []BugComment `json:"comments"`
+}
+
+func NewBugSnapshot(snap *bug.Snapshot) BugSnapshot {
+	jsonBug := BugSnapshot{
+		Id:         snap.Id().String(),
+		HumanId:    snap.Id().Human(),
+		CreateTime: NewTime(snap.CreateTime, 0),
+		EditTime:   NewTime(snap.EditTime(), 0),
+		Status:     snap.Status.String(),
+		Labels:     snap.Labels,
+		Title:      snap.Title,
+		Author:     NewIdentity(snap.Author),
+	}
+
+	jsonBug.Actors = make([]Identity, len(snap.Actors))
+	for i, element := range snap.Actors {
+		jsonBug.Actors[i] = NewIdentity(element)
+	}
+
+	jsonBug.Participants = make([]Identity, len(snap.Participants))
+	for i, element := range snap.Participants {
+		jsonBug.Participants[i] = NewIdentity(element)
+	}
+
+	jsonBug.Comments = make([]BugComment, len(snap.Comments))
+	for i, comment := range snap.Comments {
+		jsonBug.Comments[i] = NewBugComment(comment)
+	}
+
+	return jsonBug
+}
+
+type BugComment struct {
+	Id      string   `json:"id"`
+	HumanId string   `json:"human_id"`
+	Author  Identity `json:"author"`
+	Message string   `json:"message"`
+}
+
+func NewBugComment(comment bug.Comment) BugComment {
+	return BugComment{
+		Id:      comment.CombinedId().String(),
+		HumanId: comment.CombinedId().Human(),
+		Author:  NewIdentity(comment.Author),
+		Message: comment.Message,
+	}
+}
+
+type BugExcerpt struct {
+	Id         string `json:"id"`
+	HumanId    string `json:"human_id"`
+	CreateTime Time   `json:"create_time"`
+	EditTime   Time   `json:"edit_time"`
+
+	Status       string      `json:"status"`
+	Labels       []bug.Label `json:"labels"`
+	Title        string      `json:"title"`
+	Actors       []Identity  `json:"actors"`
+	Participants []Identity  `json:"participants"`
+	Author       Identity    `json:"author"`
+
+	Comments int               `json:"comments"`
+	Metadata map[string]string `json:"metadata"`
+}
+
+func NewBugExcerpt(backend *cache.RepoCache, excerpt *cache.BugExcerpt) (BugExcerpt, error) {
+	jsonBug := BugExcerpt{
+		Id:         excerpt.Id().String(),
+		HumanId:    excerpt.Id().Human(),
+		CreateTime: NewTime(excerpt.CreateTime(), excerpt.CreateLamportTime),
+		EditTime:   NewTime(excerpt.EditTime(), excerpt.EditLamportTime),
+		Status:     excerpt.Status.String(),
+		Labels:     excerpt.Labels,
+		Title:      excerpt.Title,
+		Comments:   excerpt.LenComments,
+		Metadata:   excerpt.CreateMetadata,
+	}
+
+	author, err := backend.Identities().ResolveExcerpt(excerpt.AuthorId)
+	if err != nil {
+		return BugExcerpt{}, err
+	}
+	jsonBug.Author = NewIdentityFromExcerpt(author)
+
+	jsonBug.Actors = make([]Identity, len(excerpt.Actors))
+	for i, element := range excerpt.Actors {
+		actor, err := backend.Identities().ResolveExcerpt(element)
+		if err != nil {
+			return BugExcerpt{}, err
+		}
+		jsonBug.Actors[i] = NewIdentityFromExcerpt(actor)
+	}
+
+	jsonBug.Participants = make([]Identity, len(excerpt.Participants))
+	for i, element := range excerpt.Participants {
+		participant, err := backend.Identities().ResolveExcerpt(element)
+		if err != nil {
+			return BugExcerpt{}, err
+		}
+		jsonBug.Participants[i] = NewIdentityFromExcerpt(participant)
+	}
+
+	return jsonBug, nil
+}

commands/execenv/env.go 🔗

@@ -1,6 +1,7 @@
 package execenv
 
 import (
+	"encoding/json"
 	"fmt"
 	"io"
 	"os"
@@ -38,6 +39,7 @@ type Out interface {
 	Printf(format string, a ...interface{})
 	Print(a ...interface{})
 	Println(a ...interface{})
+	PrintJSON(v interface{}) error
 
 	// String returns what have been written in the output before, as a string.
 	// This only works in test scenario.
@@ -66,6 +68,15 @@ func (o out) Println(a ...interface{}) {
 	_, _ = fmt.Fprintln(o, a...)
 }
 
+func (o out) PrintJSON(v interface{}) error {
+	raw, err := json.MarshalIndent(v, "", "    ")
+	if err != nil {
+		return err
+	}
+	o.Println(string(raw))
+	return nil
+}
+
 func (o out) String() string {
 	panic("only work with a test env")
 }

commands/execenv/env_testing.go 🔗

@@ -2,6 +2,7 @@ package execenv
 
 import (
 	"bytes"
+	"encoding/json"
 	"fmt"
 	"testing"
 
@@ -27,6 +28,15 @@ func (te *TestOut) Println(a ...interface{}) {
 	_, _ = fmt.Fprintln(te.Buffer, a...)
 }
 
+func (te *TestOut) PrintJSON(v interface{}) error {
+	raw, err := json.MarshalIndent(v, "", "    ")
+	if err != nil {
+		return err
+	}
+	te.Println(string(raw))
+	return nil
+}
+
 func NewTestEnv(t *testing.T) *Env {
 	t.Helper()
 

commands/user/user.go 🔗

@@ -1,14 +1,12 @@
 package usercmd
 
 import (
-	"encoding/json"
 	"fmt"
 
 	"github.com/spf13/cobra"
 
-	json2 "github.com/MichaelMure/git-bug/commands/cmdjson"
-
 	"github.com/MichaelMure/git-bug/cache"
+	"github.com/MichaelMure/git-bug/commands/cmdjson"
 	"github.com/MichaelMure/git-bug/commands/completion"
 	"github.com/MichaelMure/git-bug/commands/execenv"
 	"github.com/MichaelMure/git-bug/util/colors"
@@ -78,12 +76,10 @@ func userDefaultFormatter(env *execenv.Env, users []*cache.IdentityExcerpt) erro
 }
 
 func userJsonFormatter(env *execenv.Env, users []*cache.IdentityExcerpt) error {
-	jsonUsers := make([]json2.Identity, len(users))
+	jsonUsers := make([]cmdjson.Identity, len(users))
 	for i, user := range users {
-		jsonUsers[i] = json2.NewIdentityFromExcerpt(user)
+		jsonUsers[i] = cmdjson.NewIdentityFromExcerpt(user)
 	}
 
-	jsonObject, _ := json.MarshalIndent(jsonUsers, "", "    ")
-	env.Out.Printf("%s\n", jsonObject)
-	return nil
+	return env.Out.PrintJSON(jsonUsers)
 }