diff options
-rw-r--r-- | bug/bug.go | 94 | ||||
-rw-r--r-- | bug/comment_test.go | 12 | ||||
-rw-r--r-- | bug/operation.go (renamed from bug/operations/operation.go) | 8 | ||||
-rw-r--r-- | bug/operation_pack.go | 20 | ||||
-rw-r--r-- | bug/operations/create.go | 6 | ||||
-rw-r--r-- | bug/operations/operation_test.go | 16 | ||||
-rw-r--r-- | bug/operations/set_title.go | 6 | ||||
-rw-r--r-- | bug/person.go | 2 | ||||
-rw-r--r-- | bug/snapshot.go | 8 | ||||
-rw-r--r-- | commands/commands.go | 12 | ||||
-rw-r--r-- | commands/new.go | 23 | ||||
-rw-r--r-- | notes | 1 |
12 files changed, 136 insertions, 72 deletions
@@ -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/operations/operation.go b/bug/operation.go index a9cf806f..f36e9e39 100644 --- a/bug/operations/operation.go +++ b/bug/operation.go @@ -1,8 +1,4 @@ -package operations - -import ( - "github.com/MichaelMure/git-bug/bug" -) +package bug type OperationType int @@ -15,5 +11,5 @@ const ( type Operation interface { OpType() OperationType - Apply(snapshot bug.Snapshot) bug.Snapshot + 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_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 +} diff --git a/commands/commands.go b/commands/commands.go index 64b2cbc1..2cc16380 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -27,16 +27,4 @@ var CommandMap = map[string]*Command{ "new": newCmd, "pull": pullCmd, "push": pushCmd, - - /*"abandon": abandonCmd, - "accept": acceptCmd, - "comment": commentCmd, - "list": listCmd, - "pull": pullCmd, - "push": pushCmd, - "rebase": rebaseCmd, - "reject": rejectCmd, - "request": requestCmd, - "show": showCmd, - "submit": submitCmd,*/ } diff --git a/commands/new.go b/commands/new.go index 6dd19508..f3127fc6 100644 --- a/commands/new.go +++ b/commands/new.go @@ -1,12 +1,13 @@ package commands import ( + "errors" "flag" "fmt" "github.com/MichaelMure/git-bug/bug" + "github.com/MichaelMure/git-bug/bug/operations" "github.com/MichaelMure/git-bug/commands/input" "github.com/MichaelMure/git-bug/repository" - "github.com/pkg/errors" ) var newFlagSet = flag.NewFlagSet("new", flag.ExitOnError) @@ -16,7 +17,7 @@ var ( newMessage = newFlagSet.String("m", "", "Provide a message to describe the issue") ) -func newBug(repo repository.Repo, args []string) error { +func RunNewBug(repo repository.Repo, args []string) error { newFlagSet.Parse(args) args = newFlagSet.Args() @@ -50,19 +51,15 @@ func newBug(repo repository.Repo, args []string) error { return err } - comment := bug.Comment{ - Author: author, - Message: *newMessage, - } - - bug := bug.Snapshot{ - Title: title, - Comments: []bug.Comment{comment}, + newbug, err := bug.NewBug() + if err != nil { + return err } - fmt.Println(bug) + createOp := operations.NewCreateOp(author, title, *newMessage) - author.Store(repo) + newbug.Append(createOp) + newbug.Commit() return nil @@ -73,5 +70,5 @@ var newCmd = &Command{ fmt.Printf("Usage: %s new <title> [<option>...]\n\nOptions:\n", arg0) newFlagSet.PrintDefaults() }, - RunMethod: newBug, + RunMethod: RunNewBug, } @@ -14,6 +14,7 @@ git push origin "refs/bug/*" git fetch origin "refs/bug/*:refs/bug/*" +git show-ref refs/bug |