aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Muré <batolettre@gmail.com>2019-01-19 19:23:31 +0100
committerMichael Muré <batolettre@gmail.com>2019-03-01 22:40:21 +0100
commitd10c76469d40f13e27739fd363145e89bf74c3e0 (patch)
treeff613ef1ce9400f8c208d3381bd703b186958aa3
parent844616baf8dc628360942d57fd69f24e298e08da (diff)
downloadgit-bug-d10c76469d40f13e27739fd363145e89bf74c3e0.tar.gz
identity: somewhat getting closer !
-rw-r--r--bug/bug_actions_test.go149
-rw-r--r--bug/bug_test.go6
-rw-r--r--bug/op_add_comment.go54
-rw-r--r--bug/op_add_comment_test.go25
-rw-r--r--bug/op_create.go59
-rw-r--r--bug/op_create_test.go17
-rw-r--r--bug/op_edit_comment.go58
-rw-r--r--bug/op_edit_comment_test.go18
-rw-r--r--bug/op_label_change.go53
-rw-r--r--bug/op_label_change_test.go25
-rw-r--r--bug/op_noop.go42
-rw-r--r--bug/op_noop_test.go25
-rw-r--r--bug/op_set_metadata.go54
-rw-r--r--bug/op_set_metadata_test.go19
-rw-r--r--bug/op_set_status.go49
-rw-r--r--bug/op_set_status_test.go25
-rw-r--r--bug/op_set_title.go53
-rw-r--r--bug/op_set_title_test.go25
-rw-r--r--bug/operation.go36
-rw-r--r--bug/operation_iterator_test.go8
-rw-r--r--bug/operation_pack.go8
-rw-r--r--identity/bare.go55
-rw-r--r--identity/bare_test.go13
-rw-r--r--identity/common.go53
-rw-r--r--identity/identity.go16
-rw-r--r--identity/interface.go5
-rw-r--r--util/git/hash.go2
27 files changed, 813 insertions, 139 deletions
diff --git a/bug/bug_actions_test.go b/bug/bug_actions_test.go
index 4327ae58..95ca01c9 100644
--- a/bug/bug_actions_test.go
+++ b/bug/bug_actions_test.go
@@ -77,17 +77,20 @@ func TestPushPull(t *testing.T) {
repoA, repoB, remote := setupRepos(t)
defer cleanupRepos(repoA, repoB, remote)
+ err := rene.Commit(repoA)
+ assert.NoError(t, err)
+
bug1, _, err := Create(rene, unix, "bug1", "message")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug1.Commit(repoA)
- assert.Nil(t, err)
+ assert.NoError(t, err)
// A --> remote --> B
_, err = Push(repoA, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = Pull(repoB, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
bugs := allBugs(t, ReadAllLocalBugs(repoB))
@@ -97,15 +100,15 @@ func TestPushPull(t *testing.T) {
// B --> remote --> A
bug2, _, err := Create(rene, unix, "bug2", "message")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug2.Commit(repoB)
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = Push(repoB, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = Pull(repoA, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
bugs = allBugs(t, ReadAllLocalBugs(repoA))
@@ -140,37 +143,37 @@ func _RebaseTheirs(t testing.TB) {
defer cleanupRepos(repoA, repoB, remote)
bug1, _, err := Create(rene, unix, "bug1", "message")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug1.Commit(repoA)
- assert.Nil(t, err)
+ assert.NoError(t, err)
// A --> remote
_, err = Push(repoA, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
// remote --> B
err = Pull(repoB, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
bug2, err := ReadLocalBug(repoB, bug1.Id())
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message2")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message3")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message4")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug2.Commit(repoB)
- assert.Nil(t, err)
+ assert.NoError(t, err)
// B --> remote
_, err = Push(repoB, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
// remote --> A
err = Pull(repoA, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
bugs := allBugs(t, ReadAllLocalBugs(repoB))
@@ -179,7 +182,7 @@ func _RebaseTheirs(t testing.TB) {
}
bug3, err := ReadLocalBug(repoA, bug1.Id())
- assert.Nil(t, err)
+ assert.NoError(t, err)
if nbOps(bug3) != 4 {
t.Fatal("Unexpected number of operations")
@@ -201,48 +204,48 @@ func _RebaseOurs(t testing.TB) {
defer cleanupRepos(repoA, repoB, remote)
bug1, _, err := Create(rene, unix, "bug1", "message")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug1.Commit(repoA)
- assert.Nil(t, err)
+ assert.NoError(t, err)
// A --> remote
_, err = Push(repoA, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
// remote --> B
err = Pull(repoB, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message2")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message3")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message4")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug1.Commit(repoA)
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message5")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message6")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message7")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug1.Commit(repoA)
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message8")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message9")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message10")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug1.Commit(repoA)
- assert.Nil(t, err)
+ assert.NoError(t, err)
// remote --> A
err = Pull(repoA, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
bugs := allBugs(t, ReadAllLocalBugs(repoA))
@@ -251,7 +254,7 @@ func _RebaseOurs(t testing.TB) {
}
bug2, err := ReadLocalBug(repoA, bug1.Id())
- assert.Nil(t, err)
+ assert.NoError(t, err)
if nbOps(bug2) != 10 {
t.Fatal("Unexpected number of operations")
@@ -282,82 +285,82 @@ func _RebaseConflict(t testing.TB) {
defer cleanupRepos(repoA, repoB, remote)
bug1, _, err := Create(rene, unix, "bug1", "message")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug1.Commit(repoA)
- assert.Nil(t, err)
+ assert.NoError(t, err)
// A --> remote
_, err = Push(repoA, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
// remote --> B
err = Pull(repoB, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message2")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message3")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message4")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug1.Commit(repoA)
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message5")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message6")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message7")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug1.Commit(repoA)
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message8")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message9")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug1, rene, unix, "message10")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug1.Commit(repoA)
- assert.Nil(t, err)
+ assert.NoError(t, err)
bug2, err := ReadLocalBug(repoB, bug1.Id())
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message11")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message12")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message13")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug2.Commit(repoB)
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message14")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message15")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message16")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug2.Commit(repoB)
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message17")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message18")
- assert.Nil(t, err)
+ assert.NoError(t, err)
_, err = AddComment(bug2, rene, unix, "message19")
- assert.Nil(t, err)
+ assert.NoError(t, err)
err = bug2.Commit(repoB)
- assert.Nil(t, err)
+ assert.NoError(t, err)
// A --> remote
_, err = Push(repoA, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
// remote --> B
err = Pull(repoB, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
bugs := allBugs(t, ReadAllLocalBugs(repoB))
@@ -366,7 +369,7 @@ func _RebaseConflict(t testing.TB) {
}
bug3, err := ReadLocalBug(repoB, bug1.Id())
- assert.Nil(t, err)
+ assert.NoError(t, err)
if nbOps(bug3) != 19 {
t.Fatal("Unexpected number of operations")
@@ -374,11 +377,11 @@ func _RebaseConflict(t testing.TB) {
// B --> remote
_, err = Push(repoB, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
// remote --> A
err = Pull(repoA, "origin")
- assert.Nil(t, err)
+ assert.NoError(t, err)
bugs = allBugs(t, ReadAllLocalBugs(repoA))
@@ -387,7 +390,7 @@ func _RebaseConflict(t testing.TB) {
}
bug4, err := ReadLocalBug(repoA, bug1.Id())
- assert.Nil(t, err)
+ assert.NoError(t, err)
if nbOps(bug4) != 19 {
t.Fatal("Unexpected number of operations")
diff --git a/bug/bug_test.go b/bug/bug_test.go
index 0fd373d5..41a5b03d 100644
--- a/bug/bug_test.go
+++ b/bug/bug_test.go
@@ -2,7 +2,6 @@ package bug
import (
"github.com/MichaelMure/git-bug/repository"
- "github.com/go-test/deep"
"github.com/stretchr/testify/assert"
"testing"
@@ -87,8 +86,5 @@ func TestBugSerialisation(t *testing.T) {
}
}
- deep.CompareUnexportedFields = true
- if diff := deep.Equal(bug1, bug2); diff != nil {
- t.Fatal(diff)
- }
+ assert.Equal(t, bug1, bug2)
}
diff --git a/bug/op_add_comment.go b/bug/op_add_comment.go
index 23a10419..ba5d611e 100644
--- a/bug/op_add_comment.go
+++ b/bug/op_add_comment.go
@@ -1,10 +1,10 @@
package bug
import (
+ "encoding/json"
"fmt"
"github.com/MichaelMure/git-bug/identity"
-
"github.com/MichaelMure/git-bug/util/git"
"github.com/MichaelMure/git-bug/util/text"
)
@@ -14,9 +14,9 @@ var _ Operation = &AddCommentOperation{}
// AddCommentOperation will add a new comment in the bug
type AddCommentOperation struct {
OpBase
- Message string `json:"message"`
+ Message string
// TODO: change for a map[string]util.hash to store the filename ?
- Files []git.Hash `json:"files"`
+ Files []git.Hash
}
func (op *AddCommentOperation) base() *OpBase {
@@ -67,6 +67,54 @@ func (op *AddCommentOperation) Validate() error {
return nil
}
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *AddCommentOperation) MarshalJSON() ([]byte, error) {
+ base, err := json.Marshal(op.OpBase)
+ if err != nil {
+ return nil, err
+ }
+
+ // revert back to a flat map to be able to add our own fields
+ var data map[string]interface{}
+ if err := json.Unmarshal(base, &data); err != nil {
+ return nil, err
+ }
+
+ data["message"] = op.Message
+ data["files"] = op.Files
+
+ return json.Marshal(data)
+}
+
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *AddCommentOperation) UnmarshalJSON(data []byte) error {
+ // Unmarshal OpBase and the op separately
+
+ base := OpBase{}
+ err := json.Unmarshal(data, &base)
+ if err != nil {
+ return err
+ }
+
+ aux := struct {
+ Message string `json:"message"`
+ Files []git.Hash `json:"files"`
+ }{}
+
+ err = json.Unmarshal(data, &aux)
+ if err != nil {
+ return err
+ }
+
+ op.OpBase = base
+ op.Message = aux.Message
+ op.Files = aux.Files
+
+ return nil
+}
+
// Sign post method for gqlgen
func (op *AddCommentOperation) IsAuthored() {}
diff --git a/bug/op_add_comment_test.go b/bug/op_add_comment_test.go
new file mode 100644
index 00000000..a38d0228
--- /dev/null
+++ b/bug/op_add_comment_test.go
@@ -0,0 +1,25 @@
+package bug
+
+import (
+ "encoding/json"
+ "testing"
+ "time"
+
+ "github.com/MichaelMure/git-bug/identity"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAddCommentSerialize(t *testing.T) {
+ var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
+ unix := time.Now().Unix()
+ before := NewAddCommentOp(rene, unix, "message", nil)
+
+ data, err := json.Marshal(before)
+ assert.NoError(t, err)
+
+ var after AddCommentOperation
+ err = json.Unmarshal(data, &after)
+ assert.NoError(t, err)
+
+ assert.Equal(t, before, &after)
+}
diff --git a/bug/op_create.go b/bug/op_create.go
index 01b2bf03..1d157e67 100644
--- a/bug/op_create.go
+++ b/bug/op_create.go
@@ -1,11 +1,11 @@
package bug
import (
+ "encoding/json"
"fmt"
"strings"
"github.com/MichaelMure/git-bug/identity"
-
"github.com/MichaelMure/git-bug/util/git"
"github.com/MichaelMure/git-bug/util/text"
)
@@ -15,9 +15,9 @@ var _ Operation = &CreateOperation{}
// CreateOperation define the initial creation of a bug
type CreateOperation struct {
OpBase
- Title string `json:"title"`
- Message string `json:"message"`
- Files []git.Hash `json:"files"`
+ Title string
+ Message string
+ Files []git.Hash
}
func (op *CreateOperation) base() *OpBase {
@@ -83,6 +83,57 @@ func (op *CreateOperation) Validate() error {
return nil
}
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *CreateOperation) MarshalJSON() ([]byte, error) {
+ base, err := json.Marshal(op.OpBase)
+ if err != nil {
+ return nil, err
+ }
+
+ // revert back to a flat map to be able to add our own fields
+ var data map[string]interface{}
+ if err := json.Unmarshal(base, &data); err != nil {
+ return nil, err
+ }
+
+ data["title"] = op.Title
+ data["message"] = op.Message
+ data["files"] = op.Files
+
+ return json.Marshal(data)
+}
+
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *CreateOperation) UnmarshalJSON(data []byte) error {
+ // Unmarshal OpBase and the op separately
+
+ base := OpBase{}
+ err := json.Unmarshal(data, &base)
+ if err != nil {
+ return err
+ }
+
+ aux := struct {
+ Title string `json:"title"`
+ Message string `json:"message"`
+ Files []git.Hash `json:"files"`
+ }{}
+
+ err = json.Unmarshal(data, &aux)
+ if err != nil {
+ return err
+ }
+
+ op.OpBase = base
+ op.Title = aux.Title
+ op.Message = aux.Message
+ op.Files = aux.Files
+
+ return nil
+}
+
// Sign post method for gqlgen
func (op *CreateOperation) IsAuthored() {}
diff --git a/bug/op_create_test.go b/bug/op_create_test.go
index aff58acc..31693a4a 100644
--- a/bug/op_create_test.go
+++ b/bug/op_create_test.go
@@ -1,11 +1,13 @@
package bug
import (
+ "encoding/json"
"testing"
"time"
"github.com/MichaelMure/git-bug/identity"
"github.com/go-test/deep"
+ "github.com/stretchr/testify/assert"
)
func TestCreate(t *testing.T) {
@@ -45,3 +47,18 @@ func TestCreate(t *testing.T) {
t.Fatal(diff)
}
}
+
+func TestCreateSerialize(t *testing.T) {
+ var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
+ unix := time.Now().Unix()
+ before := NewCreateOp(rene, unix, "title", "message", nil)
+
+ data, err := json.Marshal(before)
+ assert.NoError(t, err)
+
+ var after CreateOperation
+ err = json.Unmarshal(data, &after)
+ assert.NoError(t, err)
+
+ assert.Equal(t, before, &after)
+}
diff --git a/bug/op_edit_comment.go b/bug/op_edit_comment.go
index 9e0afc02..3ff16653 100644
--- a/bug/op_edit_comment.go
+++ b/bug/op_edit_comment.go
@@ -1,6 +1,7 @@
package bug
import (
+ "encoding/json"
"fmt"
"github.com/MichaelMure/git-bug/identity"
@@ -14,9 +15,9 @@ var _ Operation = &EditCommentOperation{}
// EditCommentOperation will change a comment in the bug
type EditCommentOperation struct {
OpBase
- Target git.Hash `json:"target"`
- Message string `json:"message"`
- Files []git.Hash `json:"files"`
+ Target git.Hash
+ Message string
+ Files []git.Hash
}
func (op *EditCommentOperation) base() *OpBase {
@@ -94,6 +95,57 @@ func (op *EditCommentOperation) Validate() error {
return nil
}
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *EditCommentOperation) MarshalJSON() ([]byte, error) {
+ base, err := json.Marshal(op.OpBase)
+ if err != nil {
+ return nil, err
+ }
+
+ // revert back to a flat map to be able to add our own fields
+ var data map[string]interface{}
+ if err := json.Unmarshal(base, &data); err != nil {
+ return nil, err
+ }
+
+ data["target"] = op.Target
+ data["message"] = op.Message
+ data["files"] = op.Files
+
+ return json.Marshal(data)
+}
+
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *EditCommentOperation) UnmarshalJSON(data []byte) error {
+ // Unmarshal OpBase and the op separately
+
+ base := OpBase{}
+ err := json.Unmarshal(data, &base)
+ if err != nil {
+ return err
+ }
+
+ aux := struct {
+ Target git.Hash `json:"target"`
+ Message string `json:"message"`
+ Files []git.Hash `json:"files"`
+ }{}
+
+ err = json.Unmarshal(data, &aux)
+ if err != nil {
+ return err
+ }
+
+ op.OpBase = base
+ op.Target = aux.Target
+ op.Message = aux.Message
+ op.Files = aux.Files
+
+ return nil
+}
+
// Sign post method for gqlgen
func (op *EditCommentOperation) IsAuthored() {}
diff --git a/bug/op_edit_comment_test.go b/bug/op_edit_comment_test.go
index 7eee2fc1..dbdf341d 100644
--- a/bug/op_edit_comment_test.go
+++ b/bug/op_edit_comment_test.go
@@ -1,11 +1,12 @@
package bug
import (
+ "encoding/json"
"testing"
"time"
"github.com/MichaelMure/git-bug/identity"
- "gotest.tools/assert"
+ "github.com/stretchr/testify/assert"
)
func TestEdit(t *testing.T) {
@@ -49,3 +50,18 @@ func TestEdit(t *testing.T) {
assert.Equal(t, snapshot.Comments[0].Message, "create edited")
assert.Equal(t, snapshot.Comments[1].Message, "comment edited")
}
+
+func TestEditCommentSerialize(t *testing.T) {
+ var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
+ unix := time.Now().Unix()
+ before := NewEditCommentOp(rene, unix, "target", "message", nil)
+
+ data, err := json.Marshal(before)
+ assert.NoError(t, err)
+
+ var after EditCommentOperation
+ err = json.Unmarshal(data, &after)
+ assert.NoError(t, err)
+
+ assert.Equal(t, before, &after)
+}
diff --git a/bug/op_label_change.go b/bug/op_label_change.go
index 5d0b6a78..b0dd2c33 100644
--- a/bug/op_label_change.go
+++ b/bug/op_label_change.go
@@ -1,6 +1,7 @@
package bug
import (
+ "encoding/json"
"fmt"
"sort"
@@ -15,8 +16,8 @@ var _ Operation = &LabelChangeOperation{}
// LabelChangeOperation define a Bug operation to add or remove labels
type LabelChangeOperation struct {
OpBase
- Added []Label `json:"added"`
- Removed []Label `json:"removed"`
+ Added []Label
+ Removed []Label
}
func (op *LabelChangeOperation) base() *OpBase {
@@ -99,6 +100,54 @@ func (op *LabelChangeOperation) Validate() error {
return nil
}
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *LabelChangeOperation) MarshalJSON() ([]byte, error) {
+ base, err := json.Marshal(op.OpBase)
+ if err != nil {
+ return nil, err
+ }
+
+ // revert back to a flat map to be able to add our own fields
+ var data map[string]interface{}
+ if err := json.Unmarshal(base, &data); err != nil {
+ return nil, err
+ }
+
+ data["added"] = op.Added
+ data["removed"] = op.Removed
+
+ return json.Marshal(data)
+}
+
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *LabelChangeOperation) UnmarshalJSON(data []byte) error {
+ // Unmarshal OpBase and the op separately
+
+ base := OpBase{}
+ err := json.Unmarshal(data, &base)
+ if err != nil {
+ return err
+ }
+
+ aux := struct {
+ Added []Label `json:"added"`
+ Removed []Label `json:"removed"`
+ }{}
+
+ err = json.Unmarshal(data, &aux)
+ if err != nil {
+ return err
+ }
+
+ op.OpBase = base
+ op.Added = aux.Added
+ op.Removed = aux.Removed
+
+ return nil
+}
+
// Sign post method for gqlgen
func (op *LabelChangeOperation) IsAuthored() {}
diff --git a/bug/op_label_change_test.go b/bug/op_label_change_test.go
new file mode 100644
index 00000000..f5550b72
--- /dev/null
+++ b/bug/op_label_change_test.go
@@ -0,0 +1,25 @@
+package bug
+
+import (
+ "encoding/json"
+ "testing"
+ "time"
+
+ "github.com/MichaelMure/git-bug/identity"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestLabelChangeSerialize(t *testing.T) {
+ var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
+ unix := time.Now().Unix()
+ before := NewLabelChangeOperation(rene, unix, []Label{"added"}, []Label{"removed"})
+
+ data, err := json.Marshal(before)
+ assert.NoError(t, err)
+
+ var after LabelChangeOperation
+ err = json.Unmarshal(data, &after)
+ assert.NoError(t, err)
+
+ assert.Equal(t, before, &after)
+}
diff --git a/bug/op_noop.go b/bug/op_noop.go
index 410799b3..fbc112a8 100644
--- a/bug/op_noop.go
+++ b/bug/op_noop.go
@@ -1,6 +1,8 @@
package bug
import (
+ "encoding/json"
+
"github.com/MichaelMure/git-bug/identity"
"github.com/MichaelMure/git-bug/util/git"
)
@@ -30,6 +32,46 @@ func (op *NoOpOperation) Validate() error {
return opBaseValidate(op, NoOpOp)
}
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *NoOpOperation) MarshalJSON() ([]byte, error) {
+ base, err := json.Marshal(op.OpBase)
+ if err != nil {
+ return nil, err
+ }
+
+ // revert back to a flat map to be able to add our own fields
+ var data map[string]interface{}
+ if err := json.Unmarshal(base, &data); err != nil {
+ return nil, err
+ }
+
+ return json.Marshal(data)
+}
+
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *NoOpOperation) UnmarshalJSON(data []byte) error {
+ // Unmarshal OpBase and the op separately
+
+ base := OpBase{}
+ err := json.Unmarshal(data, &base)
+ if err != nil {
+ return err
+ }
+
+ aux := struct{}{}
+
+ err = json.Unmarshal(data, &aux)
+ if err != nil {
+ return err
+ }
+
+ op.OpBase = base
+
+ return nil
+}
+
// Sign post method for gqlgen
func (op *NoOpOperation) IsAuthored() {}
diff --git a/bug/op_noop_test.go b/bug/op_noop_test.go
new file mode 100644
index 00000000..385bc914
--- /dev/null
+++ b/bug/op_noop_test.go
@@ -0,0 +1,25 @@
+package bug
+
+import (
+ "encoding/json"
+ "testing"
+ "time"
+
+ "github.com/MichaelMure/git-bug/identity"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestNoopSerialize(t *testing.T) {
+ var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
+ unix := time.Now().Unix()
+ before := NewNoOpOp(rene, unix)
+
+ data, err := json.Marshal(before)
+ assert.NoError(t, err)
+
+ var after NoOpOperation
+ err = json.Unmarshal(data, &after)
+ assert.NoError(t, err)
+
+ assert.Equal(t, before, &after)
+}
diff --git a/bug/op_set_metadata.go b/bug/op_set_metadata.go
index e18f1cb6..57b78667 100644
--- a/bug/op_set_metadata.go
+++ b/bug/op_set_metadata.go
@@ -1,6 +1,8 @@
package bug
import (
+ "encoding/json"
+
"github.com/MichaelMure/git-bug/identity"
"github.com/MichaelMure/git-bug/util/git"
)
@@ -9,8 +11,8 @@ var _ Operation = &SetMetadataOperation{}
type SetMetadataOperation struct {
OpBase
- Target git.Hash `json:"target"`
- NewMetadata map[string]string `json:"new_metadata"`
+ Target git.Hash
+ NewMetadata map[string]string
}
func (op *SetMetadataOperation) base() *OpBase {
@@ -56,6 +58,54 @@ func (op *SetMetadataOperation) Validate() error {
return nil
}
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *SetMetadataOperation) MarshalJSON() ([]byte, error) {
+ base, err := json.Marshal(op.OpBase)
+ if err != nil {
+ return nil, err
+ }
+
+ // revert back to a flat map to be able to add our own fields
+ var data map[string]interface{}
+ if err := json.Unmarshal(base, &data); err != nil {
+ return nil, err
+ }
+
+ data["target"] = op.Target
+ data["new_metadata"] = op.NewMetadata
+
+ return json.Marshal(data)
+}
+
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *SetMetadataOperation) UnmarshalJSON(data []byte) error {
+ // Unmarshal OpBase and the op separately
+
+ base := OpBase{}
+ err := json.Unmarshal(data, &base)
+ if err != nil {
+ return err
+ }
+
+ aux := struct {
+ Target git.Hash `json:"target"`
+ NewMetadata map[string]string `json:"new_metadata"`
+ }{}
+
+ err = json.Unmarshal(data, &aux)
+ if err != nil {
+ return err
+ }
+
+ op.OpBase = base
+ op.Target = aux.Target
+ op.NewMetadata = aux.NewMetadata
+
+ return nil
+}
+
// Sign post method for gqlgen
func (op *SetMetadataOperation) IsAuthored() {}
diff --git a/bug/op_set_metadata_test.go b/bug/op_set_metadata_test.go
index 6e62c9a3..847164f3 100644
--- a/bug/op_set_metadata_test.go
+++ b/bug/op_set_metadata_test.go
@@ -1,6 +1,7 @@
package bug
import (
+ "encoding/json"
"testing"
"time"
@@ -94,3 +95,21 @@ func TestSetMetadata(t *testing.T) {
assert.Equal(t, commentMetadata["key2"], "value2")
assert.Equal(t, commentMetadata["key3"], "value3")
}
+
+func TestSetMetadataSerialize(t *testing.T) {
+ var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
+ unix := time.Now().Unix()
+ before := NewSetMetadataOp(rene, unix, "message", map[string]string{
+ "key1": "value1",
+ "key2": "value2",
+ })
+
+ data, err := json.Marshal(before)
+ assert.NoError(t, err)
+
+ var after SetMetadataOperation
+ err = json.Unmarshal(data, &after)
+ assert.NoError(t, err)
+
+ assert.Equal(t, before, &after)
+}
diff --git a/bug/op_set_status.go b/bug/op_set_status.go
index 9fc64e52..6deb1675 100644
--- a/bug/op_set_status.go
+++ b/bug/op_set_status.go
@@ -1,6 +1,8 @@
package bug
import (
+ "encoding/json"
+
"github.com/MichaelMure/git-bug/identity"
"github.com/MichaelMure/git-bug/util/git"
"github.com/pkg/errors"
@@ -11,7 +13,7 @@ var _ Operation = &SetStatusOperation{}
// SetStatusOperation will change the status of a bug
type SetStatusOperation struct {
OpBase
- Status Status `json:"status"`
+ Status Status
}
func (op *SetStatusOperation) base() *OpBase {
@@ -54,6 +56,51 @@ func (op *SetStatusOperation) Validate() error {
return nil
}
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *SetStatusOperation) MarshalJSON() ([]byte, error) {
+ base, err := json.Marshal(op.OpBase)
+ if err != nil {
+ return nil, err
+ }
+
+ // revert back to a flat map to be able to add our own fields
+ var data map[string]interface{}
+ if err := json.Unmarshal(base, &data); err != nil {
+ return nil, err
+ }
+
+ data["status"] = op.Status
+
+ return json.Marshal(data)
+}
+
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *SetStatusOperation) UnmarshalJSON(data []byte) error {
+ // Unmarshal OpBase and the op separately
+
+ base := OpBase{}
+ err := json.Unmarshal(data, &base)
+ if err != nil {
+ return err
+ }
+
+ aux := struct {
+ Status Status `json:"status"`
+ }{}
+
+ err = json.Unmarshal(data, &aux)
+ if err != nil {
+ return err
+ }
+
+ op.OpBase = base
+ op.Status = aux.Status
+
+ return nil
+}
+
// Sign post method for gqlgen
func (op *SetStatusOperation) IsAuthored() {}
diff --git a/bug/op_set_status_test.go b/bug/op_set_status_test.go
new file mode 100644
index 00000000..2506b947
--- /dev/null
+++ b/bug/op_set_status_test.go
@@ -0,0 +1,25 @@
+package bug
+
+import (
+ "encoding/json"
+ "testing"
+ "time"
+
+ "github.com/MichaelMure/git-bug/identity"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestSetStatusSerialize(t *testing.T) {
+ var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
+ unix := time.Now().Unix()
+ before := NewSetStatusOp(rene, unix, ClosedStatus)
+
+ data, err := json.Marshal(before)
+ assert.NoError(t, err)
+
+ var after SetStatusOperation
+ err = json.Unmarshal(data, &after)
+ assert.NoError(t, err)
+
+ assert.Equal(t, before, &after)
+}
diff --git a/bug/op_set_title.go b/bug/op_set_title.go
index 3b253c06..ae6484c6 100644
--- a/bug/op_set_title.go
+++ b/bug/op_set_title.go
@@ -1,6 +1,7 @@
package bug
import (
+ "encoding/json"
"fmt"
"strings"
@@ -15,8 +16,8 @@ var _ Operation = &SetTitleOperation{}
// SetTitleOperation will change the title of a bug
type SetTitleOperation struct {
OpBase
- Title string `json:"title"`
- Was string `json:"was"`
+ Title string
+ Was string
}
func (op *SetTitleOperation) base() *OpBase {
@@ -76,6 +77,54 @@ func (op *SetTitleOperation) Validate() error {
return nil
}
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *SetTitleOperation) MarshalJSON() ([]byte, error) {
+ base, err := json.Marshal(op.OpBase)
+ if err != nil {
+ return nil, err
+ }
+
+ // revert back to a flat map to be able to add our own fields
+ var data map[string]interface{}
+ if err := json.Unmarshal(base, &data); err != nil {
+ return nil, err
+ }
+
+ data["title"] = op.Title
+ data["was"] = op.Was
+
+ return json.Marshal(data)
+}
+
+// Workaround to avoid the inner OpBase.MarshalJSON overriding the outer op
+// MarshalJSON
+func (op *SetTitleOperation) UnmarshalJSON(data []byte) error {
+ // Unmarshal OpBase and the op separately
+
+ base := OpBase{}
+ err := json.Unmarshal(data, &base)
+ if err != nil {
+ return err
+ }
+
+ aux := struct {
+ Title string `json:"title"`
+ Was string `json:"was"`
+ }{}
+
+ err = json.Unmarshal(data, &aux)
+ if err != nil {
+ return err
+ }
+
+ op.OpBase = base
+ op.Title = aux.Title
+ op.Was = aux.Was
+
+ return nil
+}
+
// Sign post method for gqlgen
func (op *SetTitleOperation) IsAuthored() {}
diff --git a/bug/op_set_title_test.go b/bug/op_set_title_test.go
new file mode 100644
index 00000000..1f730596
--- /dev/null
+++ b/bug/op_set_title_test.go
@@ -0,0 +1,25 @@
+package bug
+
+import (
+ "encoding/json"
+ "testing"
+ "time"
+
+ "github.com/MichaelMure/git-bug/identity"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestSetTitleSerialize(t *testing.T) {
+ var rene = identity.NewBare("René Descartes", "rene@descartes.fr")
+ unix := time.Now().Unix()
+ before := NewSetTitleOp(rene, unix, "title", "was")
+
+ data, err := json.Marshal(before)
+ assert.NoError(t, err)
+
+ var after SetTitleOperation
+ err = json.Unmarshal(data, &after)
+ assert.NoError(t, err)
+
+ assert.Equal(t, before, &after)
+}
diff --git a/bug/operation.go b/bug/operation.go
index 8dec5644..cc5b0007 100644
--- a/bug/operation.go
+++ b/bug/operation.go
@@ -76,8 +76,6 @@ func hashOperation(op Operation) (git.Hash, error) {
return base.hash, nil
}
-// TODO: serialization with identity
-
// OpBase implement the common code for all operations
type OpBase struct {
OperationType OperationType
@@ -100,28 +98,40 @@ func newOpBase(opType OperationType, author identity.Interface, unixTime int64)
}
}
-type opBaseJson struct {
- OperationType OperationType `json:"type"`
- UnixTime int64 `json:"timestamp"`
- Metadata map[string]string `json:"metadata,omitempty"`
-}
-
-func (op *OpBase) MarshalJSON() ([]byte, error) {
- return json.Marshal(opBaseJson{
+func (op OpBase) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ OperationType OperationType `json:"type"`
+ Author identity.Interface `json:"author"`
+ UnixTime int64 `json:"timestamp"`
+ Metadata map[string]string `json:"metadata,omitempty"`
+ }{
OperationType: op.OperationType,
+ Author: op.Author,
UnixTime: op.UnixTime,
Metadata: op.Metadata,
})
}
func (op *OpBase) UnmarshalJSON(data []byte) error {
- aux := opBaseJson{}
+ aux := struct {
+ OperationType OperationType `json:"type"`
+ Author json.RawMessage `json:"author"`
+ UnixTime int64 `json:"timestamp"`
+ Metadata map[string]string `json:"metadata,omitempty"`
+ }{}
if err := json.Unmarshal(data, &aux); err != nil {
return err
}
+ // delegate the decoding of the identity
+ author, err := identity.UnmarshalJSON(aux.Author)
+ if err != nil {
+ return err
+ }
+
op.OperationType = aux.OperationType
+ op.Author = author
op.UnixTime = aux.UnixTime
op.Metadata = aux.Metadata
@@ -149,10 +159,6 @@ func opBaseValidate(op Operation, opType OperationType) error {
return fmt.Errorf("incorrect operation type (expected: %v, actual: %v)", opType, op.base().OperationType)
}
- if _, err := op.Hash(); err != nil {
- return errors.Wrap(err, "op is not serializable")
- }
-
if op.GetUnixTime() == 0 {
return fmt.Errorf("time not set")
}
diff --git a/bug/operation_iterator_test.go b/bug/operation_iterator_test.go
index b8e1bf09..e1aa8911 100644
--- a/bug/operation_iterator_test.go
+++ b/bug/operation_iterator_test.go
@@ -3,6 +3,8 @@ package bug
import (
"github.com/MichaelMure/git-bug/identity"
"github.com/MichaelMure/git-bug/repository"
+ "github.com/stretchr/testify/assert"
+
"testing"
"time"
)
@@ -29,13 +31,15 @@ func TestOpIterator(t *testing.T) {
bug1.Append(addCommentOp)
bug1.Append(setStatusOp)
bug1.Append(labelChangeOp)
- bug1.Commit(mockRepo)
+ err := bug1.Commit(mockRepo)
+ assert.NoError(t, err)
// second pack
bug1.Append(setTitleOp)
bug1.Append(setTitleOp)
bug1.Append(setTitleOp)
- bug1.Commit(mockRepo)
+ err = bug1.Commit(mockRepo)
+ assert.NoError(t, err)
// staging
bug1.Append(setTitleOp)
diff --git a/bug/operation_pack.go b/bug/operation_pack.go
index fc395d90..18b2a478 100644
--- a/bug/operation_pack.go
+++ b/bug/operation_pack.go
@@ -139,6 +139,14 @@ func (opp *OperationPack) Validate() error {
// Write will serialize and store the OperationPack as a git blob and return
// its hash
func (opp *OperationPack) Write(repo repository.Repo) (git.Hash, error) {
+ // First, make sure that all the identities are properly Commit as well
+ for _, op := range opp.Operations {
+ err := op.base().Author.Commit(repo)
+ if err != nil {
+ return "", err
+ }
+ }
+
data, err := json.Marshal(opp)
if err != nil {
diff --git a/identity/bare.go b/identity/bare.go
index 24f30f9f..729dc2e0 100644
--- a/identity/bare.go
+++ b/identity/bare.go
@@ -1,20 +1,25 @@
package identity
import (
+ "crypto/sha256"
"encoding/json"
"fmt"
"strings"
+ "github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/util/lamport"
"github.com/MichaelMure/git-bug/util/text"
)
+var _ Interface = &Bare{}
+
// Bare is a very minimal identity, designed to be fully embedded directly along
// other data.
//
// in particular, this identity is designed to be compatible with the handling of
// identities in the early version of git-bug.
type Bare struct {
+ id string
name string
email string
login string
@@ -36,7 +41,7 @@ type bareIdentityJson struct {
AvatarUrl string `json:"avatar_url,omitempty"`
}
-func (i Bare) MarshalJSON() ([]byte, error) {
+func (i *Bare) MarshalJSON() ([]byte, error) {
return json.Marshal(bareIdentityJson{
Name: i.name,
Email: i.email,
@@ -45,7 +50,7 @@ func (i Bare) MarshalJSON() ([]byte, error) {
})
}
-func (i Bare) UnmarshalJSON(data []byte) error {
+func (i *Bare) UnmarshalJSON(data []byte) error {
aux := bareIdentityJson{}
if err := json.Unmarshal(data, &aux); err != nil {
@@ -60,35 +65,54 @@ func (i Bare) UnmarshalJSON(data []byte) error {
return nil
}
-func (i Bare) Name() string {
+func (i *Bare) Id() string {
+ // We don't have a proper ID at hand, so let's hash all the data to get one.
+ // Hopefully the
+
+ if i.id != "" {
+ return i.id
+ }
+
+ data, err := json.Marshal(i)
+ if err != nil {
+ panic(err)
+ }
+
+ h := fmt.Sprintf("%x", sha256.New().Sum(data)[:16])
+ i.id = string(h)
+
+ return i.id
+}
+
+func (i *Bare) Name() string {
return i.name
}
-func (i Bare) Email() string {
+func (i *Bare) Email() string {
return i.email
}
-func (i Bare) Login() string {
+func (i *Bare) Login() string {
return i.login
}
-func (i Bare) AvatarUrl() string {
+func (i *Bare) AvatarUrl() string {
return i.avatarUrl
}
// Keys return the last version of the valid keys
-func (i Bare) Keys() []Key {
+func (i *Bare) Keys() []Key {
return []Key{}
}
// ValidKeysAtTime return the set of keys valid at a given lamport time
-func (i Bare) ValidKeysAtTime(time lamport.Time) []Key {
+func (i *Bare) ValidKeysAtTime(time lamport.Time) []Key {
return []Key{}
}
// DisplayName return a non-empty string to display, representing the
// identity, based on the non-empty values.
-func (i Bare) DisplayName() string {
+func (i *Bare) DisplayName() string {
switch {
case i.name == "" && i.login != "":
return i.login
@@ -102,7 +126,7 @@ func (i Bare) DisplayName() string {
}
// Match tell is the Person match the given query string
-func (i Bare) Match(query string) bool {
+func (i *Bare) Match(query string) bool {
query = strings.ToLower(query)
return strings.Contains(strings.ToLower(i.name), query) ||
@@ -110,7 +134,7 @@ func (i Bare) Match(query string) bool {
}
// Validate check if the Identity data is valid
-func (i Bare) Validate() error {
+func (i *Bare) Validate() error {
if text.Empty(i.name) && text.Empty(i.login) {
return fmt.Errorf("either name or login should be set")
}
@@ -146,8 +170,15 @@ func (i Bare) Validate() error {
return nil
}
+// Write the identity into the Repository. In particular, this ensure that
+// the Id is properly set.
+func (i *Bare) Commit(repo repository.Repo) error {
+ // Nothing to do, everything is directly embedded
+ return nil
+}
+
// IsProtected return true if the chain of git commits started to be signed.
// If that's the case, only signed commit with a valid key for this identity can be added.
-func (i Bare) IsProtected() bool {
+func (i *Bare) IsProtected() bool {
return false
}
diff --git a/identity/bare_test.go b/identity/bare_test.go
new file mode 100644
index 00000000..1458107a
--- /dev/null
+++ b/identity/bare_test.go
@@ -0,0 +1,13 @@
+package identity
+
+import (
+ "testing"
+
+ "github.com/magiconair/properties/assert"
+)
+
+func TestBare_Id(t *testing.T) {
+ i := NewBare("name", "email")
+ id := i.Id()
+ assert.Equal(t, "7b226e616d65223a226e616d65222c22", id)
+}
diff --git a/identity/common.go b/identity/common.go
new file mode 100644
index 00000000..32dd3d9e
--- /dev/null
+++ b/identity/common.go
@@ -0,0 +1,53 @@
+package identity
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "strings"
+)
+
+var ErrIdentityNotExist = errors.New("identity doesn't exist")
+
+type ErrMultipleMatch struct {
+ Matching []string
+}
+
+func (e ErrMultipleMatch) Error() string {
+ return fmt.Sprintf("Multiple matching identities found:\n%s", strings.Join(e.Matching, "\n"))
+}
+
+// Custom unmarshaling function to allow package user to delegate
+// the decoding of an Identity and distinguish between an Identity
+// and a Bare.
+//
+// If the given message has a "id" field, it's considered being a proper Identity.
+func UnmarshalJSON(raw json.RawMessage) (Interface, error) {
+ // First try to decode as a normal Identity
+ var i Identity
+
+ err := json.Unmarshal(raw, &i)
+ if err == nil && i.id != "" {
+ return &i, nil
+ }
+
+ // abort if we have an error other than the wrong type
+ if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok {
+ return nil, err
+ }
+
+ // Fallback on a legacy Bare identity
+ var b Bare
+
+ err = json.Unmarshal(raw, &b)
+ if err == nil && (b.name != "" || b.login != "") {
+ return &b, nil
+ }
+
+ // abort if we have an error other than the wrong type
+ if _, ok := err.(*json.UnmarshalTypeError); err != nil && !ok {
+ return nil, err
+ }
+
+ return nil, fmt.Errorf("unknown identity type")
+}
diff --git a/identity/identity.go b/identity/identity.go
index 313e3fd7..38729e37 100644
--- a/identity/identity.go
+++ b/identity/identity.go
@@ -16,16 +16,6 @@ const identityRefPattern = "refs/identities/"
const versionEntryName = "version"
const identityConfigKey = "git-bug.identity"
-var ErrIdentityNotExist = errors.New("identity doesn't exist")
-
-type ErrMultipleMatch struct {
- Matching []string
-}
-
-func (e ErrMultipleMatch) Error() string {
- return fmt.Sprintf("Multiple matching identities found:\n%s", strings.Join(e.Matching, "\n"))
-}
-
var _ Interface = &Identity{}
type Identity struct {
@@ -85,8 +75,6 @@ func (i *Identity) UnmarshalJSON(data []byte) error {
return nil
}
-// TODO: load/write from OpBase
-
// Read load an Identity from the identities data available in git
func Read(repo repository.Repo, id string) (*Identity, error) {
i := &Identity{
@@ -230,7 +218,9 @@ func (i *Identity) AddVersion(version *Version) {
i.Versions = append(i.Versions, version)
}
-func (i *Identity) Commit(repo repository.ClockedRepo) error {
+// Write the identity into the Repository. In particular, this ensure that
+// the Id is properly set.
+func (i *Identity) Commit(repo repository.Repo) error {
// Todo: check for mismatch between memory and commited data
var lastCommit git.Hash = ""
diff --git a/identity/interface.go b/identity/interface.go
index 6489efbe..c784a7a6 100644
--- a/identity/interface.go
+++ b/identity/interface.go
@@ -1,6 +1,7 @@
package identity
import (
+ "github.com/MichaelMure/git-bug/repository"
"github.com/MichaelMure/git-bug/util/lamport"
)
@@ -28,6 +29,10 @@ type Interface interface {
// Validate check if the Identity data is valid
Validate() error
+ // Write the identity into the Repository. In particular, this ensure that
+ // the Id is properly set.
+ Commit(repo repository.Repo) error
+
// IsProtected return true if the chain of git commits started to be signed.
// If that's the case, only signed commit with a valid key for this identity can be added.
IsProtected() bool
diff --git a/util/git/hash.go b/util/git/hash.go
index 401e6edc..d9160d75 100644
--- a/util/git/hash.go
+++ b/util/git/hash.go
@@ -30,7 +30,7 @@ func (h *Hash) UnmarshalGQL(v interface{}) error {
// MarshalGQL implement the Marshaler interface for gqlgen
func (h Hash) MarshalGQL(w io.Writer) {
- w.Write([]byte(`"` + h.String() + `"`))
+ _, _ = w.Write([]byte(`"` + h.String() + `"`))
}
// IsValid tell if the hash is valid