1package bug
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/MichaelMure/git-bug/util/git"
8 "github.com/MichaelMure/git-bug/util/text"
9)
10
11var _ Operation = &CreateOperation{}
12
13// CreateOperation define the initial creation of a bug
14type CreateOperation struct {
15 *OpBase
16 Title string `json:"title"`
17 Message string `json:"message"`
18 Files []git.Hash `json:"files"`
19}
20
21func (op *CreateOperation) base() *OpBase {
22 return op.OpBase
23}
24
25func (op *CreateOperation) Hash() (git.Hash, error) {
26 return hashOperation(op)
27}
28
29func (op *CreateOperation) Apply(snapshot *Snapshot) {
30 snapshot.Title = op.Title
31
32 comment := Comment{
33 Message: op.Message,
34 Author: op.Author,
35 UnixTime: Timestamp(op.UnixTime),
36 }
37
38 snapshot.Comments = []Comment{comment}
39 snapshot.Author = op.Author
40 snapshot.CreatedAt = op.Time()
41
42 hash, err := op.Hash()
43 if err != nil {
44 // Should never error unless a programming error happened
45 // (covered in OpBase.Validate())
46 panic(err)
47 }
48
49 snapshot.Timeline = []TimelineItem{
50 &CreateTimelineItem{
51 CommentTimelineItem: NewCommentTimelineItem(hash, comment),
52 },
53 }
54}
55
56func (op *CreateOperation) GetFiles() []git.Hash {
57 return op.Files
58}
59
60func (op *CreateOperation) Validate() error {
61 if err := opBaseValidate(op, CreateOp); err != nil {
62 return err
63 }
64
65 if text.Empty(op.Title) {
66 return fmt.Errorf("title is empty")
67 }
68
69 if strings.Contains(op.Title, "\n") {
70 return fmt.Errorf("title should be a single line")
71 }
72
73 if !text.Safe(op.Title) {
74 return fmt.Errorf("title is not fully printable")
75 }
76
77 if !text.Safe(op.Message) {
78 return fmt.Errorf("message is not fully printable")
79 }
80
81 return nil
82}
83
84func NewCreateOp(author Person, unixTime int64, title, message string, files []git.Hash) *CreateOperation {
85 return &CreateOperation{
86 OpBase: newOpBase(CreateOp, author, unixTime),
87 Title: title,
88 Message: message,
89 Files: files,
90 }
91}
92
93// CreateTimelineItem replace a Create operation in the Timeline and hold its edition history
94type CreateTimelineItem struct {
95 CommentTimelineItem
96}
97
98// Convenience function to apply the operation
99func Create(author Person, unixTime int64, title, message string) (*Bug, error) {
100 return CreateWithFiles(author, unixTime, title, message, nil)
101}
102
103func CreateWithFiles(author Person, unixTime int64, title, message string, files []git.Hash) (*Bug, error) {
104 newBug := NewBug()
105 createOp := NewCreateOp(author, unixTime, title, message, files)
106
107 if err := createOp.Validate(); err != nil {
108 return nil, err
109 }
110
111 newBug.Append(createOp)
112
113 return newBug, nil
114}