op_edit_comment.go

  1package bug
  2
  3import (
  4	"fmt"
  5
  6	"github.com/MichaelMure/git-bug/util/git"
  7	"github.com/MichaelMure/git-bug/util/text"
  8)
  9
 10var _ Operation = &EditCommentOperation{}
 11
 12// EditCommentOperation will change a comment in the bug
 13type EditCommentOperation struct {
 14	*OpBase
 15	Target  git.Hash   `json:"target"`
 16	Message string     `json:"message"`
 17	Files   []git.Hash `json:"files"`
 18}
 19
 20func (op *EditCommentOperation) base() *OpBase {
 21	return op.OpBase
 22}
 23
 24func (op *EditCommentOperation) Hash() (git.Hash, error) {
 25	return hashOperation(op)
 26}
 27
 28func (op *EditCommentOperation) Apply(snapshot *Snapshot) {
 29	// Todo: currently any message can be edited, even by a different author
 30	// crypto signature are needed.
 31
 32	var target TimelineItem
 33	var commentIndex int
 34
 35	for i, item := range snapshot.Timeline {
 36		h := item.Hash()
 37
 38		if h == op.Target {
 39			target = snapshot.Timeline[i]
 40			break
 41		}
 42
 43		// Track the index in the []Comment
 44		switch item.(type) {
 45		case *CreateTimelineItem, *CommentTimelineItem:
 46			commentIndex++
 47		}
 48	}
 49
 50	if target == nil {
 51		// Target not found, edit is a no-op
 52		return
 53	}
 54
 55	comment := Comment{
 56		Message:  op.Message,
 57		Files:    op.Files,
 58		UnixTime: Timestamp(op.UnixTime),
 59	}
 60
 61	switch target.(type) {
 62	case *CreateTimelineItem:
 63		item := target.(*CreateTimelineItem)
 64		item.Append(comment)
 65
 66	case *AddCommentTimelineItem:
 67		item := target.(*AddCommentTimelineItem)
 68		item.Append(comment)
 69	}
 70
 71	snapshot.Comments[commentIndex].Message = op.Message
 72	snapshot.Comments[commentIndex].Files = op.Files
 73}
 74
 75func (op *EditCommentOperation) GetFiles() []git.Hash {
 76	return op.Files
 77}
 78
 79func (op *EditCommentOperation) Validate() error {
 80	if err := opBaseValidate(op, EditCommentOp); err != nil {
 81		return err
 82	}
 83
 84	if !op.Target.IsValid() {
 85		return fmt.Errorf("target hash is invalid")
 86	}
 87
 88	if text.Empty(op.Message) {
 89		return fmt.Errorf("message is empty")
 90	}
 91
 92	if !text.Safe(op.Message) {
 93		return fmt.Errorf("message is not fully printable")
 94	}
 95
 96	return nil
 97}
 98
 99func NewEditCommentOp(author Person, unixTime int64, target git.Hash, message string, files []git.Hash) *EditCommentOperation {
100	return &EditCommentOperation{
101		OpBase:  newOpBase(EditCommentOp, author, unixTime),
102		Target:  target,
103		Message: message,
104		Files:   files,
105	}
106}
107
108// Convenience function to apply the operation
109func EditComment(b Interface, author Person, unixTime int64, target git.Hash, message string) error {
110	return EditCommentWithFiles(b, author, unixTime, target, message, nil)
111}
112
113func EditCommentWithFiles(b Interface, author Person, unixTime int64, target git.Hash, message string, files []git.Hash) error {
114	editCommentOp := NewEditCommentOp(author, unixTime, target, message, files)
115	if err := editCommentOp.Validate(); err != nil {
116		return err
117	}
118	b.Append(editCommentOp)
119	return nil
120}