bug: add the ability to store arbitrary metadata on an operation

This commit is contained in:
Michael Muré 2018-09-24 20:19:16 +02:00
parent c4a207622a
commit a72ea453a9
No known key found for this signature in database
GPG Key ID: A4457C029293126F
9 changed files with 59 additions and 16 deletions

View File

@ -36,18 +36,23 @@ type Operation interface {
Apply(snapshot Snapshot) Snapshot
// Validate check if the operation is valid (ex: a title is a single line)
Validate() error
// SetMetadata store arbitrary metadata about the operation
SetMetadata(key string, value string)
// GetMetadata retrieve arbitrary metadata about the operation
GetMetadata(key string) (string, bool)
}
// 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"`
Metadata map[string]string `json:"metadata,omitempty"`
}
// NewOpBase is the constructor for an OpBase
func NewOpBase(opType OperationType, author Person) OpBase {
return OpBase{
func NewOpBase(opType OperationType, author Person) *OpBase {
return &OpBase{
OperationType: opType,
Author: author,
UnixTime: time.Now().Unix(),
@ -55,27 +60,27 @@ func NewOpBase(opType OperationType, author Person) OpBase {
}
// OpType return the type of operation
func (op OpBase) OpType() OperationType {
func (op *OpBase) OpType() OperationType {
return op.OperationType
}
// Time return the time when the operation was added
func (op OpBase) Time() time.Time {
func (op *OpBase) Time() time.Time {
return time.Unix(op.UnixTime, 0)
}
// GetUnixTime return the unix timestamp when the operation was added
func (op OpBase) GetUnixTime() int64 {
func (op *OpBase) GetUnixTime() int64 {
return op.UnixTime
}
// GetAuthor return the author of the operation
func (op OpBase) GetAuthor() Person {
func (op *OpBase) GetAuthor() Person {
return op.Author
}
// GetFiles return the files needed by this operation
func (op OpBase) GetFiles() []git.Hash {
func (op *OpBase) GetFiles() []git.Hash {
return nil
}
@ -101,3 +106,18 @@ func OpBaseValidate(op Operation, opType OperationType) error {
return nil
}
// SetMetadata store arbitrary metadata about the operation
func (op *OpBase) SetMetadata(key string, value string) {
if op.Metadata == nil {
op.Metadata = make(map[string]string)
}
op.Metadata[key] = value
}
// GetMetadata retrieve arbitrary metadata about the operation
func (op *OpBase) GetMetadata(key string) (string, bool) {
val, ok := op.Metadata[key]
return val, ok
}

View File

@ -13,7 +13,7 @@ import (
var _ bug.Operation = AddCommentOperation{}
type AddCommentOperation struct {
bug.OpBase
*bug.OpBase
Message string `json:"message"`
// TODO: change for a map[string]util.hash to store the filename ?
Files []git.Hash `json:"files"`

View File

@ -14,7 +14,7 @@ import (
var _ bug.Operation = CreateOperation{}
type CreateOperation struct {
bug.OpBase
*bug.OpBase
Title string `json:"title"`
Message string `json:"message"`
Files []git.Hash `json:"files"`

View File

@ -12,7 +12,7 @@ var _ bug.Operation = LabelChangeOperation{}
// LabelChangeOperation define a Bug operation to add or remove labels
type LabelChangeOperation struct {
bug.OpBase
*bug.OpBase
Added []bug.Label `json:"added"`
Removed []bug.Label `json:"removed"`
}

View File

@ -34,7 +34,7 @@ func TestValidate(t *testing.T) {
NewSetStatusOp(bug.Person{Name: "René Descartes", Email: "rene@descartes.fr\u001b"}, bug.ClosedStatus),
NewSetStatusOp(bug.Person{Name: "René \nDescartes", Email: "rene@descartes.fr"}, bug.ClosedStatus),
NewSetStatusOp(bug.Person{Name: "René Descartes", Email: "rene@\ndescartes.fr"}, bug.ClosedStatus),
CreateOperation{OpBase: bug.OpBase{
CreateOperation{OpBase: &bug.OpBase{
Author: rene,
UnixTime: 0,
OperationType: bug.CreateOp,

View File

@ -10,7 +10,7 @@ import (
var _ bug.Operation = SetStatusOperation{}
type SetStatusOperation struct {
bug.OpBase
*bug.OpBase
Status bug.Status `json:"status"`
}

View File

@ -13,7 +13,7 @@ import (
var _ bug.Operation = SetTitleOperation{}
type SetTitleOperation struct {
bug.OpBase
*bug.OpBase
Title string `json:"title"`
Was string `json:"was"`
}

View File

@ -25,6 +25,7 @@ func TestOpIterator(t *testing.T) {
bug1 := bug.NewBug()
// first pack
bug1.Append(createOp)
bug1.Append(setTitleOp)
bug1.Append(addCommentOp)
@ -32,11 +33,13 @@ func TestOpIterator(t *testing.T) {
bug1.Append(labelChangeOp)
bug1.Commit(mockRepo)
// second pack
bug1.Append(setTitleOp)
bug1.Append(setTitleOp)
bug1.Append(setTitleOp)
bug1.Commit(mockRepo)
// staging
bug1.Append(setTitleOp)
bug1.Append(setTitleOp)
bug1.Append(setTitleOp)

View File

@ -6,6 +6,8 @@ import (
"testing"
"github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/operations"
"github.com/MichaelMure/git-bug/util/git"
)
func TestOperationPackSerialize(t *testing.T) {
@ -17,6 +19,24 @@ func TestOperationPackSerialize(t *testing.T) {
opp.Append(setStatusOp)
opp.Append(labelChangeOp)
opMeta := operations.NewCreateOp(rene, "title", "message", nil)
opMeta.SetMetadata("key", "value")
opp.Append(opMeta)
if len(opMeta.Metadata) != 1 {
t.Fatal()
}
opFile := operations.NewCreateOp(rene, "title", "message", []git.Hash{
"abcdef",
"ghijkl",
})
opp.Append(opFile)
if len(opFile.Files) != 2 {
t.Fatal()
}
data, err := json.Marshal(opp)
if err != nil {
t.Fatal(err)