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.Safe(op.Message) {
89 return fmt.Errorf("message is not fully printable")
90 }
91
92 return nil
93}
94
95func NewEditCommentOp(author Person, unixTime int64, target git.Hash, message string, files []git.Hash) *EditCommentOperation {
96 return &EditCommentOperation{
97 OpBase: newOpBase(EditCommentOp, author, unixTime),
98 Target: target,
99 Message: message,
100 Files: files,
101 }
102}
103
104// Convenience function to apply the operation
105func EditComment(b Interface, author Person, unixTime int64, target git.Hash, message string) (*EditCommentOperation, error) {
106 return EditCommentWithFiles(b, author, unixTime, target, message, nil)
107}
108
109func EditCommentWithFiles(b Interface, author Person, unixTime int64, target git.Hash, message string, files []git.Hash) (*EditCommentOperation, error) {
110 editCommentOp := NewEditCommentOp(author, unixTime, target, message, files)
111 if err := editCommentOp.Validate(); err != nil {
112 return nil, err
113 }
114 b.Append(editCommentOp)
115 return editCommentOp, nil
116}