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}