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, err := item.Hash()
 37
 38		if err != nil {
 39			// Should never happen, we control what goes into the timeline
 40			panic(err)
 41		}
 42
 43		if h == op.Target {
 44			target = snapshot.Timeline[i]
 45			break
 46		}
 47
 48		// Track the index in the []Comment
 49		switch item.(type) {
 50		case *CreateTimelineItem, *CommentTimelineItem:
 51			commentIndex++
 52		}
 53	}
 54
 55	if target == nil {
 56		// Target not found, edit is a no-op
 57		return
 58	}
 59
 60	switch target.(type) {
 61	case *CreateTimelineItem:
 62		item := target.(*CreateTimelineItem)
 63		newComment := item.LastState()
 64		newComment.Message = op.Message
 65		item.History = append(item.History, newComment)
 66
 67	case *CommentTimelineItem:
 68		item := target.(*CommentTimelineItem)
 69		newComment := item.LastState()
 70		newComment.Message = op.Message
 71		item.History = append(item.History, newComment)
 72	}
 73
 74	snapshot.Comments[commentIndex].Message = op.Message
 75	snapshot.Comments[commentIndex].Files = op.Files
 76}
 77
 78func (op *EditCommentOperation) GetFiles() []git.Hash {
 79	return op.Files
 80}
 81
 82func (op *EditCommentOperation) Validate() error {
 83	if err := opBaseValidate(op, EditCommentOp); err != nil {
 84		return err
 85	}
 86
 87	if !op.Target.IsValid() {
 88		return fmt.Errorf("target hash is invalid")
 89	}
 90
 91	if text.Empty(op.Message) {
 92		return fmt.Errorf("message is empty")
 93	}
 94
 95	if !text.Safe(op.Message) {
 96		return fmt.Errorf("message is not fully printable")
 97	}
 98
 99	return nil
100}
101
102func NewEditCommentOp(author Person, unixTime int64, target git.Hash, message string, files []git.Hash) *EditCommentOperation {
103	return &EditCommentOperation{
104		OpBase:  newOpBase(EditCommentOp, author, unixTime),
105		Target:  target,
106		Message: message,
107		Files:   files,
108	}
109}
110
111// Convenience function to apply the operation
112func EditComment(b Interface, author Person, unixTime int64, target git.Hash, message string) error {
113	return EditCommentWithFiles(b, author, unixTime, target, message, nil)
114}
115
116func EditCommentWithFiles(b Interface, author Person, unixTime int64, target git.Hash, message string, files []git.Hash) error {
117	editCommentOp := NewEditCommentOp(author, unixTime, target, message, files)
118	if err := editCommentOp.Validate(); err != nil {
119		return err
120	}
121	b.Append(editCommentOp)
122	return nil
123}