From bc12fee58e8bd86672793ae37d9f924158afb482 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Fri, 13 Jul 2018 16:13:40 +0200 Subject: create the Bug structure --- bug/bug.go | 94 ++++++++++++++++++++++++++++++++++------ bug/comment_test.go | 12 ----- bug/operation.go | 15 +++++++ bug/operation_pack.go | 20 +++++++++ bug/operations/create.go | 6 +-- bug/operations/operation.go | 19 -------- bug/operations/operation_test.go | 16 +++---- bug/operations/set_title.go | 6 +-- bug/person.go | 2 +- bug/snapshot.go | 8 ++++ 10 files changed, 138 insertions(+), 60 deletions(-) delete mode 100644 bug/comment_test.go create mode 100644 bug/operation.go create mode 100644 bug/operation_pack.go delete mode 100644 bug/operations/operation.go create mode 100644 bug/snapshot.go (limited to 'bug') diff --git a/bug/bug.go b/bug/bug.go index ac99c164..807f614f 100644 --- a/bug/bug.go +++ b/bug/bug.go @@ -1,18 +1,84 @@ package bug -// Snapshot is a compiled form of the Bug data structure used for storage and merge -type Snapshot struct { - Title string - Comments []Comment - Labels []Label +import ( + "github.com/kevinburke/go.uuid" +) + +// Bug hold the data of a bug thread, organized in a way close to +// how it will be persisted inside Git. This is the datastructure +// used for merge of two different version. +type Bug struct { + // Id used as unique identifier + Id uuid.UUID + + // TODO: need a way to order bugs + // Probably a Lamport clock + + Packs []OperationPack + + Staging OperationPack } -//func (bug Bug) Check() error { -// if bug.Operations.Len() == 0 { -// return "Empty operation log" -// } -// -// if bug.Operations.Elems() -// -// return true -//} +// Create a new Bug +func NewBug() (*Bug, error) { + + // Creating UUID Version 4 + id, err := uuid.ID4() + + if err != nil { + return nil, err + } + + return &Bug{ + Id: id, + }, nil +} + +// IsValid check if the Bug data is valid +func (bug *Bug) IsValid() bool { + // non-empty + if len(bug.Packs) == 0 { + return false + } + + // check if each pack is valid + for _, pack := range bug.Packs { + if !pack.IsValid() { + return false + } + } + + // The very first Op should be a CREATE + firstOp := bug.Packs[0].Operations[0] + if firstOp.OpType() != CREATE { + return false + } + + // Check that there is no more CREATE op + it := NewOperationIterator(bug) + createCount := 0 + for it.Next() { + if it.Value().OpType() == CREATE { + createCount++ + } + } + + if createCount != 1 { + return false + } + + return true +} + +func (bug *Bug) Append(op Operation) { + bug.Staging.Append(op) +} + +func (bug *Bug) Commit() { + bug.Packs = append(bug.Packs, bug.Staging) + bug.Staging = OperationPack{} +} + +func (bug *Bug) HumanId() string { + return bug.Id.String() +} diff --git a/bug/comment_test.go b/bug/comment_test.go deleted file mode 100644 index 7079f923..00000000 --- a/bug/comment_test.go +++ /dev/null @@ -1,12 +0,0 @@ -package bug - -import "testing" - -func TestCommentEquality(t *testing.T) { - c1 := Comment{} - c2 := Comment{} - - if c1 != c2 { - t.Fatal() - } -} diff --git a/bug/operation.go b/bug/operation.go new file mode 100644 index 00000000..f36e9e39 --- /dev/null +++ b/bug/operation.go @@ -0,0 +1,15 @@ +package bug + +type OperationType int + +const ( + UNKNOW OperationType = iota + CREATE + SET_TITLE + ADD_COMMENT +) + +type Operation interface { + OpType() OperationType + Apply(snapshot Snapshot) Snapshot +} diff --git a/bug/operation_pack.go b/bug/operation_pack.go new file mode 100644 index 00000000..e3d64e72 --- /dev/null +++ b/bug/operation_pack.go @@ -0,0 +1,20 @@ +package bug + +// OperationPack represent an ordered set of operation to apply +// to a Bug. These operations are stored in a single Git commit. +// +// These commits will be linked together in a linear chain of commits +// inside Git to form the complete ordered chain of operation to +// apply to get the final state of the Bug +type OperationPack struct { + Operations []Operation +} + +// Append a new operation to the pack +func (opp *OperationPack) Append(op Operation) { + opp.Operations = append(opp.Operations, op) +} + +func (opp *OperationPack) IsValid() bool { + return len(opp.Operations) > 0 +} diff --git a/bug/operations/create.go b/bug/operations/create.go index f004a12b..57cca907 100644 --- a/bug/operations/create.go +++ b/bug/operations/create.go @@ -7,7 +7,7 @@ import ( // CreateOperation define the initial creation of a bug -var _ Operation = CreateOperation{} +var _ bug.Operation = CreateOperation{} type CreateOperation struct { Title string @@ -23,8 +23,8 @@ func NewCreateOp(author bug.Person, title, message string) CreateOperation { } } -func (op CreateOperation) OpType() OperationType { - return CREATE +func (op CreateOperation) OpType() bug.OperationType { + return bug.CREATE } func (op CreateOperation) Apply(snapshot bug.Snapshot) bug.Snapshot { diff --git a/bug/operations/operation.go b/bug/operations/operation.go deleted file mode 100644 index a9cf806f..00000000 --- a/bug/operations/operation.go +++ /dev/null @@ -1,19 +0,0 @@ -package operations - -import ( - "github.com/MichaelMure/git-bug/bug" -) - -type OperationType int - -const ( - UNKNOW OperationType = iota - CREATE - SET_TITLE - ADD_COMMENT -) - -type Operation interface { - OpType() OperationType - Apply(snapshot bug.Snapshot) bug.Snapshot -} diff --git a/bug/operations/operation_test.go b/bug/operations/operation_test.go index 1bd15f78..e53e524b 100644 --- a/bug/operations/operation_test.go +++ b/bug/operations/operation_test.go @@ -11,8 +11,8 @@ type CreateOperation2 struct { Message string } -func (op CreateOperation2) OpType() OperationType { - return UNKNOW +func (op CreateOperation2) OpType() bug.OperationType { + return bug.UNKNOW } func (op CreateOperation2) Apply(snapshot bug.Snapshot) bug.Snapshot { @@ -26,16 +26,16 @@ func TestOperationsEquality(t *testing.T) { Email: "rene@descartes.fr", } - var A Operation = NewCreateOp(rene, "title", "message") - var B Operation = NewCreateOp(rene, "title", "message") - var C Operation = NewCreateOp(rene, "title", "different message") + var A bug.Operation = NewCreateOp(rene, "title", "message") + var B bug.Operation = NewCreateOp(rene, "title", "message") + var C bug.Operation = NewCreateOp(rene, "title", "different message") if A != B { - t.Fatal("Equal value operations should be tested equals") + t.Fatal("Equal value ops should be tested equals") } if A == C { - t.Fatal("Different value operations should be tested different") + t.Fatal("Different value ops should be tested different") } D := CreateOperation2{Title: "title", Message: "message"} @@ -49,7 +49,7 @@ func TestOperationsEquality(t *testing.T) { Email: "isaac@newton.uk", } - var E Operation = NewCreateOp(isaac, "title", "message") + var E bug.Operation = NewCreateOp(isaac, "title", "message") if A == E { t.Fatal("Operation equality should handle the author") diff --git a/bug/operations/set_title.go b/bug/operations/set_title.go index 0d935db6..1e2ef20a 100644 --- a/bug/operations/set_title.go +++ b/bug/operations/set_title.go @@ -2,7 +2,7 @@ package operations import "github.com/MichaelMure/git-bug/bug" -var _ Operation = SetTitleOperation{} +var _ bug.Operation = SetTitleOperation{} type SetTitleOperation struct { Title string @@ -14,8 +14,8 @@ func NewSetTitleOp(title string) SetTitleOperation { } } -func (op SetTitleOperation) OpType() OperationType { - return SET_TITLE +func (op SetTitleOperation) OpType() bug.OperationType { + return bug.SET_TITLE } func (op SetTitleOperation) Apply(snapshot bug.Snapshot) bug.Snapshot { diff --git a/bug/person.go b/bug/person.go index d47bc150..9541dbd8 100644 --- a/bug/person.go +++ b/bug/person.go @@ -2,9 +2,9 @@ package bug import ( "encoding/json" + "errors" "github.com/MichaelMure/git-bug/repository" "github.com/MichaelMure/git-bug/util" - "github.com/pkg/errors" ) type Person struct { diff --git a/bug/snapshot.go b/bug/snapshot.go new file mode 100644 index 00000000..8828c337 --- /dev/null +++ b/bug/snapshot.go @@ -0,0 +1,8 @@ +package bug + +// Snapshot is a compiled form of the Bug data structure used for storage and merge +type Snapshot struct { + Title string + Comments []Comment + Labels []Label +} -- cgit