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}