1package bug
2
3import (
4 "fmt"
5
6 "github.com/MichaelMure/git-bug/entities/identity"
7 "github.com/MichaelMure/git-bug/entity"
8 "github.com/MichaelMure/git-bug/entity/dag"
9 "github.com/MichaelMure/git-bug/util/timestamp"
10
11 "github.com/MichaelMure/git-bug/util/text"
12)
13
14var _ Operation = &SetTitleOperation{}
15
16// SetTitleOperation will change the title of a bug
17type SetTitleOperation struct {
18 dag.OpBase
19 Title string `json:"title"`
20 Was string `json:"was"`
21}
22
23func (op *SetTitleOperation) Id() entity.Id {
24 return dag.IdOperation(op, &op.OpBase)
25}
26
27func (op *SetTitleOperation) Apply(snapshot *Snapshot) {
28 snapshot.Title = op.Title
29 snapshot.addActor(op.Author())
30
31 id := op.Id()
32 item := &SetTitleTimelineItem{
33 id: id,
34 combinedId: entity.CombineIds(snapshot.Id(), id),
35 Author: op.Author(),
36 UnixTime: timestamp.Timestamp(op.UnixTime),
37 Title: op.Title,
38 Was: op.Was,
39 }
40
41 snapshot.Timeline = append(snapshot.Timeline, item)
42}
43
44func (op *SetTitleOperation) Validate() error {
45 if err := op.OpBase.Validate(op, SetTitleOp); err != nil {
46 return err
47 }
48
49 if text.Empty(op.Title) {
50 return fmt.Errorf("title is empty")
51 }
52
53 if !text.SafeOneLine(op.Title) {
54 return fmt.Errorf("title has unsafe characters")
55 }
56
57 if !text.SafeOneLine(op.Was) {
58 return fmt.Errorf("previous title has unsafe characters")
59 }
60
61 return nil
62}
63
64func NewSetTitleOp(author identity.Interface, unixTime int64, title string, was string) *SetTitleOperation {
65 return &SetTitleOperation{
66 OpBase: dag.NewOpBase(SetTitleOp, author, unixTime),
67 Title: title,
68 Was: was,
69 }
70}
71
72type SetTitleTimelineItem struct {
73 id entity.Id
74 combinedId entity.CombinedId
75 Author identity.Interface
76 UnixTime timestamp.Timestamp
77 Title string
78 Was string
79}
80
81func (s SetTitleTimelineItem) Id() entity.Id {
82 return s.id
83}
84
85func (s SetTitleTimelineItem) CombinedId() entity.CombinedId {
86 return s.combinedId
87}
88
89// IsAuthored is a sign post method for gqlgen
90func (s *SetTitleTimelineItem) IsAuthored() {}
91
92// SetTitle is a convenience function to change a bugs title
93func SetTitle(b Interface, author identity.Interface, unixTime int64, title string, metadata map[string]string) (*SetTitleOperation, error) {
94 var lastTitleOp *SetTitleOperation
95 for _, op := range b.Operations() {
96 switch op := op.(type) {
97 case *SetTitleOperation:
98 lastTitleOp = op
99 }
100 }
101
102 var was string
103 if lastTitleOp != nil {
104 was = lastTitleOp.Title
105 } else {
106 was = b.FirstOp().(*CreateOperation).Title
107 }
108
109 op := NewSetTitleOp(author, unixTime, title, was)
110 for key, value := range metadata {
111 op.SetMetadata(key, value)
112 }
113 if err := op.Validate(); err != nil {
114 return nil, err
115 }
116
117 b.Append(op)
118 return op, nil
119}