From c46d01f8c10e6363b680fa6876e91bd8eaf3bb3e Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sat, 29 Sep 2018 20:41:19 +0200 Subject: bug: implement comment edition - add a new operation - add a new "timeline" in the snapshot that hold a processed version of the operations --- bug/op_edit_comment.go | 123 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 bug/op_edit_comment.go (limited to 'bug/op_edit_comment.go') diff --git a/bug/op_edit_comment.go b/bug/op_edit_comment.go new file mode 100644 index 00000000..c6cfab2b --- /dev/null +++ b/bug/op_edit_comment.go @@ -0,0 +1,123 @@ +package bug + +import ( + "fmt" + + "github.com/MichaelMure/git-bug/util/git" + "github.com/MichaelMure/git-bug/util/text" +) + +var _ Operation = &EditCommentOperation{} + +// EditCommentOperation will change a comment in the bug +type EditCommentOperation struct { + *OpBase + Target git.Hash `json:"target"` + Message string `json:"message"` + Files []git.Hash `json:"files"` +} + +func (op *EditCommentOperation) base() *OpBase { + return op.OpBase +} + +func (op *EditCommentOperation) Hash() (git.Hash, error) { + return hashOperation(op) +} + +func (op *EditCommentOperation) Apply(snapshot *Snapshot) { + // Todo: currently any message can be edited, even by a different author + // crypto signature are needed. + + var target TimelineItem + var commentIndex int + + for i, item := range snapshot.Timeline { + h, err := item.Hash() + + if err != nil { + // Should never happen, we control what goes into the timeline + panic(err) + } + + if h == op.Target { + target = snapshot.Timeline[i] + break + } + + // Track the index in the []Comment + switch item.(type) { + case *CreateTimelineItem, *CommentTimelineItem: + commentIndex++ + } + } + + if target == nil { + // Target not found, edit is a no-op + return + } + + switch target.(type) { + case *CreateTimelineItem: + item := target.(*CreateTimelineItem) + newComment := item.LastState() + newComment.Message = op.Message + item.History = append(item.History, newComment) + + case *CommentTimelineItem: + item := target.(*CommentTimelineItem) + newComment := item.LastState() + newComment.Message = op.Message + item.History = append(item.History, newComment) + } + + snapshot.Comments[commentIndex].Message = op.Message + snapshot.Comments[commentIndex].Files = op.Files +} + +func (op *EditCommentOperation) GetFiles() []git.Hash { + return op.Files +} + +func (op *EditCommentOperation) Validate() error { + if err := opBaseValidate(op, EditCommentOp); err != nil { + return err + } + + if !op.Target.IsValid() { + return fmt.Errorf("target hash is invalid") + } + + if text.Empty(op.Message) { + return fmt.Errorf("message is empty") + } + + if !text.Safe(op.Message) { + return fmt.Errorf("message is not fully printable") + } + + return nil +} + +func NewEditCommentOp(author Person, unixTime int64, target git.Hash, message string, files []git.Hash) *EditCommentOperation { + return &EditCommentOperation{ + OpBase: newOpBase(EditCommentOp, author, unixTime), + Target: target, + Message: message, + Files: files, + } +} + +// Convenience function to apply the operation +func EditComment(b Interface, author Person, unixTime int64, target git.Hash, message string) error { + return EditCommentWithFiles(b, author, unixTime, target, message, nil) +} + +func EditCommentWithFiles(b Interface, author Person, unixTime int64, target git.Hash, message string, files []git.Hash) error { + editCommentOp := NewEditCommentOp(author, unixTime, target, message, files) + if err := editCommentOp.Validate(); err != nil { + return err + } + b.Append(editCommentOp) + return nil +} -- cgit From 037f5bf50b2bb2b020620413d186b6acf47a0b61 Mon Sep 17 00:00:00 2001 From: Michael Muré Date: Sun, 30 Sep 2018 11:00:39 +0200 Subject: timeline: various minor improvements --- bug/op_edit_comment.go | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'bug/op_edit_comment.go') diff --git a/bug/op_edit_comment.go b/bug/op_edit_comment.go index c6cfab2b..cb4a2216 100644 --- a/bug/op_edit_comment.go +++ b/bug/op_edit_comment.go @@ -57,18 +57,20 @@ func (op *EditCommentOperation) Apply(snapshot *Snapshot) { return } + comment := Comment{ + Message: op.Message, + Files: op.Files, + UnixTime: Timestamp(op.UnixTime), + } + switch target.(type) { case *CreateTimelineItem: item := target.(*CreateTimelineItem) - newComment := item.LastState() - newComment.Message = op.Message - item.History = append(item.History, newComment) + item.Append(comment) case *CommentTimelineItem: item := target.(*CommentTimelineItem) - newComment := item.LastState() - newComment.Message = op.Message - item.History = append(item.History, newComment) + item.Append(comment) } snapshot.Comments[commentIndex].Message = op.Message -- cgit