1package bug
2
3import (
4 "fmt"
5
6 "github.com/MichaelMure/git-bug/entity"
7 "github.com/MichaelMure/git-bug/entity/dag"
8 "github.com/MichaelMure/git-bug/repository"
9 "github.com/MichaelMure/git-bug/util/text"
10 "github.com/MichaelMure/git-bug/util/timestamp"
11)
12
13var _ Operation = &AddCommentOperation{}
14var _ entity.OperationWithFiles = &AddCommentOperation{}
15
16// AddCommentOperation will add a new comment in the bug
17type AddCommentOperation struct {
18 dag.OpBase
19 Message string `json:"message"`
20 // TODO: change for a map[string]util.hash to store the filename ?
21 Files []repository.Hash `json:"files"`
22}
23
24func (op *AddCommentOperation) Id() entity.Id {
25 return dag.IdOperation(op, &op.OpBase)
26}
27
28func (op *AddCommentOperation) Apply(snapshot *Snapshot) {
29 snapshot.addActor(op.Author())
30 snapshot.addParticipant(op.Author())
31
32 opId := op.Id()
33
34 comment := Comment{
35 combinedId: entity.CombineIds(snapshot.Id(), opId),
36 targetId: opId,
37 Message: op.Message,
38 Author: op.Author(),
39 Files: op.Files,
40 unixTime: timestamp.Timestamp(op.UnixTime),
41 }
42
43 snapshot.Comments = append(snapshot.Comments, comment)
44
45 item := &AddCommentTimelineItem{
46 CommentTimelineItem: NewCommentTimelineItem(comment),
47 }
48
49 snapshot.Timeline = append(snapshot.Timeline, item)
50}
51
52func (op *AddCommentOperation) GetFiles() []repository.Hash {
53 return op.Files
54}
55
56func (op *AddCommentOperation) Validate() error {
57 if err := op.OpBase.Validate(op, AddCommentOp); err != nil {
58 return err
59 }
60
61 if !text.Safe(op.Message) {
62 return fmt.Errorf("message is not fully printable")
63 }
64
65 for _, file := range op.Files {
66 if !file.IsValid() {
67 return fmt.Errorf("invalid file hash")
68 }
69 }
70
71 return nil
72}
73
74func NewAddCommentOp(author entity.Identity, unixTime int64, message string, files []repository.Hash) *AddCommentOperation {
75 return &AddCommentOperation{
76 OpBase: dag.NewOpBase(AddCommentOp, author, unixTime),
77 Message: message,
78 Files: files,
79 }
80}
81
82// AddCommentTimelineItem replace a AddComment operation in the Timeline and hold its edition history
83type AddCommentTimelineItem struct {
84 CommentTimelineItem
85}
86
87// IsAuthored is a sign post method for gqlgen
88func (a *AddCommentTimelineItem) IsAuthored() {}
89
90// AddComment is a convenience function to add a comment to a bug
91func AddComment(b Interface, author entity.Identity, unixTime int64, message string, files []repository.Hash, metadata map[string]string) (entity.CombinedId, *AddCommentOperation, error) {
92 op := NewAddCommentOp(author, unixTime, message, files)
93 for key, val := range metadata {
94 op.SetMetadata(key, val)
95 }
96 if err := op.Validate(); err != nil {
97 return entity.UnsetCombinedId, nil, err
98 }
99 b.Append(op)
100 return entity.CombineIds(b.Id(), op.Id()), op, nil
101}