diff options
Diffstat (limited to 'bug')
-rw-r--r-- | bug/bug_test.go | 3 | ||||
-rw-r--r-- | bug/op_add_comment.go | 4 | ||||
-rw-r--r-- | bug/op_create.go | 4 | ||||
-rw-r--r-- | bug/op_label_change.go | 5 | ||||
-rw-r--r-- | bug/op_set_status.go | 5 | ||||
-rw-r--r-- | bug/op_set_title.go | 5 | ||||
-rw-r--r-- | bug/operation.go | 40 | ||||
-rw-r--r-- | bug/operation_pack.go | 3 |
8 files changed, 63 insertions, 6 deletions
diff --git a/bug/bug_test.go b/bug/bug_test.go index d85db6d2..6504da1a 100644 --- a/bug/bug_test.go +++ b/bug/bug_test.go @@ -74,6 +74,9 @@ func TestBugSerialisation(t *testing.T) { // ignore some fields bug2.packs[0].commitHash = bug1.packs[0].commitHash + for i := range bug1.packs[0].Operations { + bug2.packs[0].Operations[i].base().hash = bug1.packs[0].Operations[i].base().hash + } deep.CompareUnexportedFields = true if diff := deep.Equal(bug1, bug2); diff != nil { diff --git a/bug/op_add_comment.go b/bug/op_add_comment.go index 0a3a5a37..300609fb 100644 --- a/bug/op_add_comment.go +++ b/bug/op_add_comment.go @@ -22,6 +22,10 @@ func (op AddCommentOperation) base() *OpBase { return op.OpBase } +func (op AddCommentOperation) Hash() (git.Hash, error) { + return hashOperation(op) +} + func (op AddCommentOperation) Apply(snapshot Snapshot) Snapshot { comment := Comment{ Message: op.Message, diff --git a/bug/op_create.go b/bug/op_create.go index 2852a519..c65b3bd8 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -23,6 +23,10 @@ func (op CreateOperation) base() *OpBase { return op.OpBase } +func (op CreateOperation) Hash() (git.Hash, error) { + return hashOperation(op) +} + func (op CreateOperation) Apply(snapshot Snapshot) Snapshot { snapshot.Title = op.Title snapshot.Comments = []Comment{ diff --git a/bug/op_label_change.go b/bug/op_label_change.go index 120671fb..c245d1a5 100644 --- a/bug/op_label_change.go +++ b/bug/op_label_change.go @@ -4,6 +4,7 @@ import ( "fmt" "sort" + "github.com/MichaelMure/git-bug/util/git" "github.com/pkg/errors" ) @@ -20,6 +21,10 @@ func (op LabelChangeOperation) base() *OpBase { return op.OpBase } +func (op LabelChangeOperation) Hash() (git.Hash, error) { + return hashOperation(op) +} + // Apply apply the operation func (op LabelChangeOperation) Apply(snapshot Snapshot) Snapshot { // Add in the set diff --git a/bug/op_set_status.go b/bug/op_set_status.go index d6df3da4..19af46c2 100644 --- a/bug/op_set_status.go +++ b/bug/op_set_status.go @@ -1,6 +1,7 @@ package bug import ( + "github.com/MichaelMure/git-bug/util/git" "github.com/pkg/errors" ) @@ -17,6 +18,10 @@ func (op SetStatusOperation) base() *OpBase { return op.OpBase } +func (op SetStatusOperation) Hash() (git.Hash, error) { + return hashOperation(op) +} + func (op SetStatusOperation) Apply(snapshot Snapshot) Snapshot { snapshot.Status = op.Status diff --git a/bug/op_set_title.go b/bug/op_set_title.go index e8c5caf8..a4912143 100644 --- a/bug/op_set_title.go +++ b/bug/op_set_title.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" + "github.com/MichaelMure/git-bug/util/git" "github.com/MichaelMure/git-bug/util/text" ) @@ -21,6 +22,10 @@ func (op SetTitleOperation) base() *OpBase { return op.OpBase } +func (op SetTitleOperation) Hash() (git.Hash, error) { + return hashOperation(op) +} + func (op SetTitleOperation) Apply(snapshot Snapshot) Snapshot { snapshot.Title = op.Title diff --git a/bug/operation.go b/bug/operation.go index cd4094dc..4c6f2e5a 100644 --- a/bug/operation.go +++ b/bug/operation.go @@ -1,11 +1,13 @@ package bug import ( - "github.com/MichaelMure/git-bug/util/git" - "github.com/pkg/errors" - + "crypto/sha256" + "encoding/json" "fmt" "time" + + "github.com/MichaelMure/git-bug/util/git" + "github.com/pkg/errors" ) // OperationType is an operation type identifier @@ -24,6 +26,8 @@ const ( type Operation interface { // base return the OpBase of the Operation, for package internal use base() *OpBase + // Hash return the hash of the operation + Hash() (git.Hash, error) // Time return the time when the operation was added Time() time.Time // GetUnixTime return the unix timestamp when the operation was added @@ -40,11 +44,35 @@ type Operation interface { GetMetadata(key string) (string, bool) } +func hashRaw(data []byte) git.Hash { + hasher := sha256.New() + return git.Hash(fmt.Sprintf("%x", hasher.Sum(data))) +} + +// hash compute the hash of the serialized operation +func hashOperation(op Operation) (git.Hash, error) { + base := op.base() + + if base.hash != "" { + return base.hash, nil + } + + data, err := json.Marshal(op) + if err != nil { + return "", err + } + + base.hash = hashRaw(data) + + return base.hash, nil +} + // OpBase implement the common code for all operations type OpBase struct { - OperationType OperationType `json:"type"` - Author Person `json:"author"` - UnixTime int64 `json:"timestamp"` + OperationType OperationType `json:"type"` + Author Person `json:"author"` + UnixTime int64 `json:"timestamp"` + hash git.Hash Metadata map[string]string `json:"metadata,omitempty"` } diff --git a/bug/operation_pack.go b/bug/operation_pack.go index 2da8bee0..5238ea60 100644 --- a/bug/operation_pack.go +++ b/bug/operation_pack.go @@ -62,6 +62,9 @@ func (opp *OperationPack) UnmarshalJSON(data []byte) error { return err } + // Compute the hash of the operation + op.base().hash = hashRaw(raw) + opp.Operations = append(opp.Operations, op) } |