diff options
Diffstat (limited to 'bug')
-rw-r--r-- | bug/comment.go | 7 | ||||
-rw-r--r-- | bug/label.go | 9 | ||||
-rw-r--r-- | bug/op_add_comment.go | 5 | ||||
-rw-r--r-- | bug/op_create.go | 13 | ||||
-rw-r--r-- | bug/op_create_test.go | 6 | ||||
-rw-r--r-- | bug/op_edit_comment.go | 16 | ||||
-rw-r--r-- | bug/op_edit_comment_test.go | 15 | ||||
-rw-r--r-- | bug/op_set_metadata.go | 11 | ||||
-rw-r--r-- | bug/op_set_title.go | 17 | ||||
-rw-r--r-- | bug/snapshot.go | 5 | ||||
-rw-r--r-- | bug/timeline.go | 5 |
11 files changed, 51 insertions, 58 deletions
diff --git a/bug/comment.go b/bug/comment.go index 4c9d118e..c1cfc7e5 100644 --- a/bug/comment.go +++ b/bug/comment.go @@ -11,6 +11,8 @@ import ( // Comment represent a comment in a Bug type Comment struct { + // id should be the result of entity.CombineIds with the Bug id and the id + // of the Operation that created the comment id entity.Id Author identity.Interface Message string @@ -24,9 +26,8 @@ type Comment struct { // Id return the Comment identifier func (c Comment) Id() entity.Id { if c.id == "" { - // simply panic as it would be a coding error - // (using an id of an identity not stored yet) - panic("no id yet") + // simply panic as it would be a coding error (no id provided at construction) + panic("no id") } return c.id } diff --git a/bug/label.go b/bug/label.go index 9d1e99a7..79b5f591 100644 --- a/bug/label.go +++ b/bug/label.go @@ -4,7 +4,6 @@ import ( "crypto/sha256" "fmt" "image/color" - "strings" fcolor "github.com/fatih/color" @@ -58,12 +57,8 @@ func (l Label) Validate() error { return fmt.Errorf("empty") } - if strings.Contains(str, "\n") { - return fmt.Errorf("should be a single line") - } - - if !text.Safe(str) { - return fmt.Errorf("not fully printable") + if !text.SafeOneLine(str) { + return fmt.Errorf("label has unsafe characters") } return nil diff --git a/bug/op_add_comment.go b/bug/op_add_comment.go index f835866b..15e62226 100644 --- a/bug/op_add_comment.go +++ b/bug/op_add_comment.go @@ -31,9 +31,8 @@ func (op *AddCommentOperation) Apply(snapshot *Snapshot) { snapshot.addActor(op.Author_) snapshot.addParticipant(op.Author_) - commentId := entity.CombineIds(snapshot.Id(), op.Id()) comment := Comment{ - id: commentId, + id: entity.CombineIds(snapshot.Id(), op.Id()), Message: op.Message, Author: op.Author_, Files: op.Files, @@ -43,7 +42,7 @@ func (op *AddCommentOperation) Apply(snapshot *Snapshot) { snapshot.Comments = append(snapshot.Comments, comment) item := &AddCommentTimelineItem{ - CommentTimelineItem: NewCommentTimelineItem(commentId, comment), + CommentTimelineItem: NewCommentTimelineItem(comment), } snapshot.Timeline = append(snapshot.Timeline, item) diff --git a/bug/op_create.go b/bug/op_create.go index 75b60bd8..9c972195 100644 --- a/bug/op_create.go +++ b/bug/op_create.go @@ -3,7 +3,6 @@ package bug import ( "encoding/json" "fmt" - "strings" "github.com/MichaelMure/git-bug/entity" "github.com/MichaelMure/git-bug/entity/dag" @@ -56,9 +55,8 @@ func (op *CreateOperation) Apply(snapshot *Snapshot) { snapshot.Title = op.Title - commentId := entity.CombineIds(snapshot.Id(), op.Id()) comment := Comment{ - id: commentId, + id: entity.CombineIds(snapshot.Id(), op.Id()), Message: op.Message, Author: op.Author_, UnixTime: timestamp.Timestamp(op.UnixTime), @@ -70,7 +68,7 @@ func (op *CreateOperation) Apply(snapshot *Snapshot) { snapshot.Timeline = []TimelineItem{ &CreateTimelineItem{ - CommentTimelineItem: NewCommentTimelineItem(commentId, comment), + CommentTimelineItem: NewCommentTimelineItem(comment), }, } } @@ -94,11 +92,8 @@ func (op *CreateOperation) Validate() error { if text.Empty(op.Title) { return fmt.Errorf("title is empty") } - if strings.Contains(op.Title, "\n") { - return fmt.Errorf("title should be a single line") - } - if !text.Safe(op.Title) { - return fmt.Errorf("title is not fully printable") + if !text.SafeOneLine(op.Title) { + return fmt.Errorf("title has unsafe characters") } if !text.Safe(op.Message) { diff --git a/bug/op_create_test.go b/bug/op_create_test.go index 1b359dee..25b87cfe 100644 --- a/bug/op_create_test.go +++ b/bug/op_create_test.go @@ -30,10 +30,8 @@ func TestCreate(t *testing.T) { id := create.Id() require.NoError(t, id.Validate()) - commentId := entity.CombineIds(create.Id(), create.Id()) - comment := Comment{ - id: commentId, + id: entity.CombineIds(create.Id(), create.Id()), Author: rene, Message: "message", UnixTime: timestamp.Timestamp(create.UnixTime), @@ -51,7 +49,7 @@ func TestCreate(t *testing.T) { CreateTime: create.Time(), Timeline: []TimelineItem{ &CreateTimelineItem{ - CommentTimelineItem: NewCommentTimelineItem(commentId, comment), + CommentTimelineItem: NewCommentTimelineItem(comment), }, }, } diff --git a/bug/op_edit_comment.go b/bug/op_edit_comment.go index 3e6634e4..a69cb599 100644 --- a/bug/op_edit_comment.go +++ b/bug/op_edit_comment.go @@ -34,12 +34,12 @@ func (op *EditCommentOperation) Apply(snapshot *Snapshot) { // Todo: currently any message can be edited, even by a different author // crypto signature are needed. - snapshot.addActor(op.Author_) + // Recreate the Comment Id to match on + commentId := entity.CombineIds(snapshot.Id(), op.Target) var target TimelineItem - for i, item := range snapshot.Timeline { - if item.Id() == op.Target { + if item.Id() == commentId { target = snapshot.Timeline[i] break } @@ -51,7 +51,7 @@ func (op *EditCommentOperation) Apply(snapshot *Snapshot) { } comment := Comment{ - id: op.Target, + id: commentId, Message: op.Message, Files: op.Files, UnixTime: timestamp.Timestamp(op.UnixTime), @@ -62,12 +62,18 @@ func (op *EditCommentOperation) Apply(snapshot *Snapshot) { target.Append(comment) case *AddCommentTimelineItem: target.Append(comment) + default: + // somehow, the target matched on something that is not a comment + // we make the op a no-op + return } + snapshot.addActor(op.Author_) + // Updating the corresponding comment for i := range snapshot.Comments { - if snapshot.Comments[i].Id() == op.Target { + if snapshot.Comments[i].Id() == commentId { snapshot.Comments[i].Message = op.Message snapshot.Comments[i].Files = op.Files break diff --git a/bug/op_edit_comment_test.go b/bug/op_edit_comment_test.go index 777f5f87..5ba94706 100644 --- a/bug/op_edit_comment_test.go +++ b/bug/op_edit_comment_test.go @@ -24,14 +24,12 @@ func TestEdit(t *testing.T) { create := NewCreateOp(rene, unix, "title", "create", nil) create.Apply(&snapshot) - id1 := create.Id() - require.NoError(t, id1.Validate()) + require.NoError(t, create.Id().Validate()) comment1 := NewAddCommentOp(rene, unix, "comment 1", nil) comment1.Apply(&snapshot) - id2 := comment1.Id() - require.NoError(t, id2.Validate()) + require.NoError(t, comment1.Id().Validate()) // add another unrelated op in between setTitle := NewSetTitleOp(rene, unix, "edited title", "title") @@ -40,10 +38,9 @@ func TestEdit(t *testing.T) { comment2 := NewAddCommentOp(rene, unix, "comment 2", nil) comment2.Apply(&snapshot) - id3 := comment2.Id() - require.NoError(t, id3.Validate()) + require.NoError(t, comment2.Id().Validate()) - edit := NewEditCommentOp(rene, unix, snapshot.Comments[0].Id(), "create edited", nil) + edit := NewEditCommentOp(rene, unix, create.Id(), "create edited", nil) edit.Apply(&snapshot) require.Len(t, snapshot.Timeline, 4) @@ -54,7 +51,7 @@ func TestEdit(t *testing.T) { require.Equal(t, snapshot.Comments[1].Message, "comment 1") require.Equal(t, snapshot.Comments[2].Message, "comment 2") - edit2 := NewEditCommentOp(rene, unix, snapshot.Comments[1].Id(), "comment 1 edited", nil) + edit2 := NewEditCommentOp(rene, unix, comment1.Id(), "comment 1 edited", nil) edit2.Apply(&snapshot) require.Len(t, snapshot.Timeline, 4) @@ -65,7 +62,7 @@ func TestEdit(t *testing.T) { require.Equal(t, snapshot.Comments[1].Message, "comment 1 edited") require.Equal(t, snapshot.Comments[2].Message, "comment 2") - edit3 := NewEditCommentOp(rene, unix, snapshot.Comments[2].Id(), "comment 2 edited", nil) + edit3 := NewEditCommentOp(rene, unix, comment2.Id(), "comment 2 edited", nil) edit3.Apply(&snapshot) require.Len(t, snapshot.Timeline, 4) diff --git a/bug/op_set_metadata.go b/bug/op_set_metadata.go index ca19a838..28496fd8 100644 --- a/bug/op_set_metadata.go +++ b/bug/op_set_metadata.go @@ -2,11 +2,13 @@ package bug import ( "encoding/json" + "fmt" "github.com/pkg/errors" "github.com/MichaelMure/git-bug/entity" "github.com/MichaelMure/git-bug/identity" + "github.com/MichaelMure/git-bug/util/text" ) var _ Operation = &SetMetadataOperation{} @@ -43,6 +45,15 @@ func (op *SetMetadataOperation) Validate() error { return errors.Wrap(err, "target invalid") } + for key, val := range op.NewMetadata { + if !text.SafeOneLine(key) { + return fmt.Errorf("metadata key is unsafe") + } + if !text.Safe(val) { + return fmt.Errorf("metadata value is not fully printable") + } + } + return nil } diff --git a/bug/op_set_title.go b/bug/op_set_title.go index c6a26746..badd192c 100644 --- a/bug/op_set_title.go +++ b/bug/op_set_title.go @@ -3,7 +3,6 @@ package bug import ( "encoding/json" "fmt" - "strings" "github.com/MichaelMure/git-bug/entity" "github.com/MichaelMure/git-bug/identity" @@ -49,20 +48,12 @@ func (op *SetTitleOperation) Validate() error { return fmt.Errorf("title is empty") } - if strings.Contains(op.Title, "\n") { - return fmt.Errorf("title should be a single line") + if !text.SafeOneLine(op.Title) { + return fmt.Errorf("title has unsafe characters") } - if !text.Safe(op.Title) { - return fmt.Errorf("title should be fully printable") - } - - if strings.Contains(op.Was, "\n") { - return fmt.Errorf("previous title should be a single line") - } - - if !text.Safe(op.Was) { - return fmt.Errorf("previous title should be fully printable") + if !text.SafeOneLine(op.Was) { + return fmt.Errorf("previous title has unsafe characters") } return nil diff --git a/bug/snapshot.go b/bug/snapshot.go index 0005b930..ce84cce1 100644 --- a/bug/snapshot.go +++ b/bug/snapshot.go @@ -29,9 +29,8 @@ type Snapshot struct { // Return the Bug identifier func (snap *Snapshot) Id() entity.Id { if snap.id == "" { - // simply panic as it would be a coding error - // (using an id of a bug not stored yet) - panic("no id yet") + // simply panic as it would be a coding error (no id provided at construction) + panic("no id") } return snap.id } diff --git a/bug/timeline.go b/bug/timeline.go index 5a51f516..a5ca4da5 100644 --- a/bug/timeline.go +++ b/bug/timeline.go @@ -26,6 +26,7 @@ type CommentHistoryStep struct { // CommentTimelineItem is a TimelineItem that holds a Comment and its edition history type CommentTimelineItem struct { + // id should be the same as in Comment id entity.Id Author identity.Interface Message string @@ -35,9 +36,9 @@ type CommentTimelineItem struct { History []CommentHistoryStep } -func NewCommentTimelineItem(ID entity.Id, comment Comment) CommentTimelineItem { +func NewCommentTimelineItem(comment Comment) CommentTimelineItem { return CommentTimelineItem{ - id: ID, + id: comment.id, Author: comment.Author, Message: comment.Message, Files: comment.Files, |