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