diff options
Diffstat (limited to 'entities/bug/op_create.go')
-rw-r--r-- | entities/bug/op_create.go | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/entities/bug/op_create.go b/entities/bug/op_create.go new file mode 100644 index 00000000..fdfa131b --- /dev/null +++ b/entities/bug/op_create.go @@ -0,0 +1,112 @@ +package bug + +import ( + "fmt" + + "github.com/MichaelMure/git-bug/entities/identity" + "github.com/MichaelMure/git-bug/entity" + "github.com/MichaelMure/git-bug/entity/dag" + "github.com/MichaelMure/git-bug/repository" + "github.com/MichaelMure/git-bug/util/text" + "github.com/MichaelMure/git-bug/util/timestamp" +) + +var _ Operation = &CreateOperation{} +var _ dag.OperationWithFiles = &CreateOperation{} + +// CreateOperation define the initial creation of a bug +type CreateOperation struct { + dag.OpBase + Title string `json:"title"` + Message string `json:"message"` + Files []repository.Hash `json:"files"` +} + +func (op *CreateOperation) Id() entity.Id { + return dag.IdOperation(op, &op.OpBase) +} + +func (op *CreateOperation) Apply(snapshot *Snapshot) { + // sanity check: will fail when adding a second Create + if snapshot.id != "" && snapshot.id != entity.UnsetId && snapshot.id != op.Id() { + return + } + + snapshot.id = op.Id() + + snapshot.addActor(op.Author()) + snapshot.addParticipant(op.Author()) + + snapshot.Title = op.Title + + comment := Comment{ + id: entity.CombineIds(snapshot.Id(), op.Id()), + Message: op.Message, + Author: op.Author(), + UnixTime: timestamp.Timestamp(op.UnixTime), + } + + snapshot.Comments = []Comment{comment} + snapshot.Author = op.Author() + snapshot.CreateTime = op.Time() + + snapshot.Timeline = []TimelineItem{ + &CreateTimelineItem{ + CommentTimelineItem: NewCommentTimelineItem(comment), + }, + } +} + +func (op *CreateOperation) GetFiles() []repository.Hash { + return op.Files +} + +func (op *CreateOperation) Validate() error { + if err := op.OpBase.Validate(op, CreateOp); err != nil { + return err + } + + if text.Empty(op.Title) { + return fmt.Errorf("title is empty") + } + if !text.SafeOneLine(op.Title) { + return fmt.Errorf("title has unsafe characters") + } + + if !text.Safe(op.Message) { + return fmt.Errorf("message is not fully printable") + } + + return nil +} + +func NewCreateOp(author identity.Interface, unixTime int64, title, message string, files []repository.Hash) *CreateOperation { + return &CreateOperation{ + OpBase: dag.NewOpBase(CreateOp, author, unixTime), + Title: title, + Message: message, + Files: files, + } +} + +// CreateTimelineItem replace a Create operation in the Timeline and hold its edition history +type CreateTimelineItem struct { + CommentTimelineItem +} + +// IsAuthored is a sign post method for gqlgen +func (c *CreateTimelineItem) IsAuthored() {} + +// Create is a convenience function to create a bug +func Create(author identity.Interface, unixTime int64, title, message string, files []repository.Hash, metadata map[string]string) (*Bug, *CreateOperation, error) { + b := NewBug() + op := NewCreateOp(author, unixTime, title, message, files) + for key, val := range metadata { + op.SetMetadata(key, val) + } + if err := op.Validate(); err != nil { + return nil, op, err + } + b.Append(op) + return b, op, nil +} |