op_create.go

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