op_set_title.go

  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 = &SetTitleOperation{}
 12
 13// SetTitleOperation will change the title of a bug
 14type SetTitleOperation struct {
 15	OpBase
 16	Title string `json:"title"`
 17	Was   string `json:"was"`
 18}
 19
 20func (op *SetTitleOperation) base() *OpBase {
 21	return &op.OpBase
 22}
 23
 24func (op *SetTitleOperation) Hash() (git.Hash, error) {
 25	return hashOperation(op)
 26}
 27
 28func (op *SetTitleOperation) Apply(snapshot *Snapshot) {
 29	snapshot.Title = op.Title
 30
 31	hash, err := op.Hash()
 32	if err != nil {
 33		// Should never error unless a programming error happened
 34		// (covered in OpBase.Validate())
 35		panic(err)
 36	}
 37
 38	item := &SetTitleTimelineItem{
 39		hash:     hash,
 40		Author:   op.Author,
 41		UnixTime: Timestamp(op.UnixTime),
 42		Title:    op.Title,
 43		Was:      op.Was,
 44	}
 45
 46	snapshot.Timeline = append(snapshot.Timeline, item)
 47}
 48
 49func (op *SetTitleOperation) Validate() error {
 50	if err := opBaseValidate(op, SetTitleOp); err != nil {
 51		return err
 52	}
 53
 54	if text.Empty(op.Title) {
 55		return fmt.Errorf("title is empty")
 56	}
 57
 58	if strings.Contains(op.Title, "\n") {
 59		return fmt.Errorf("title should be a single line")
 60	}
 61
 62	if !text.Safe(op.Title) {
 63		return fmt.Errorf("title should be fully printable")
 64	}
 65
 66	if strings.Contains(op.Was, "\n") {
 67		return fmt.Errorf("previous title should be a single line")
 68	}
 69
 70	if !text.Safe(op.Was) {
 71		return fmt.Errorf("previous title should be fully printable")
 72	}
 73
 74	return nil
 75}
 76
 77// Sign post method for gqlgen
 78func (op *SetTitleOperation) IsAuthored() {}
 79
 80func NewSetTitleOp(author Person, unixTime int64, title string, was string) *SetTitleOperation {
 81	return &SetTitleOperation{
 82		OpBase: newOpBase(SetTitleOp, author, unixTime),
 83		Title:  title,
 84		Was:    was,
 85	}
 86}
 87
 88type SetTitleTimelineItem struct {
 89	hash     git.Hash
 90	Author   Person
 91	UnixTime Timestamp
 92	Title    string
 93	Was      string
 94}
 95
 96func (s SetTitleTimelineItem) Hash() git.Hash {
 97	return s.hash
 98}
 99
100// Convenience function to apply the operation
101func SetTitle(b Interface, author Person, unixTime int64, title string) (*SetTitleOperation, error) {
102	it := NewOperationIterator(b)
103
104	var lastTitleOp Operation
105	for it.Next() {
106		op := it.Value()
107		if op.base().OperationType == SetTitleOp {
108			lastTitleOp = op
109		}
110	}
111
112	var was string
113	if lastTitleOp != nil {
114		was = lastTitleOp.(*SetTitleOperation).Title
115	} else {
116		was = b.FirstOp().(*CreateOperation).Title
117	}
118
119	setTitleOp := NewSetTitleOp(author, unixTime, title, was)
120
121	if err := setTitleOp.Validate(); err != nil {
122		return nil, err
123	}
124
125	b.Append(setTitleOp)
126	return setTitleOp, nil
127}