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
 77func NewSetTitleOp(author Person, unixTime int64, title string, was string) *SetTitleOperation {
 78	return &SetTitleOperation{
 79		OpBase: newOpBase(SetTitleOp, author, unixTime),
 80		Title:  title,
 81		Was:    was,
 82	}
 83}
 84
 85type SetTitleTimelineItem struct {
 86	hash     git.Hash
 87	Author   Person
 88	UnixTime Timestamp
 89	Title    string
 90	Was      string
 91}
 92
 93func (s SetTitleTimelineItem) Hash() git.Hash {
 94	return s.hash
 95}
 96
 97// Convenience function to apply the operation
 98func SetTitle(b Interface, author Person, unixTime int64, title string) error {
 99	it := NewOperationIterator(b)
100
101	var lastTitleOp Operation
102	for it.Next() {
103		op := it.Value()
104		if op.base().OperationType == SetTitleOp {
105			lastTitleOp = op
106		}
107	}
108
109	var was string
110	if lastTitleOp != nil {
111		was = lastTitleOp.(*SetTitleOperation).Title
112	} else {
113		was = b.FirstOp().(*CreateOperation).Title
114	}
115
116	setTitleOp := NewSetTitleOp(author, unixTime, title, was)
117
118	if err := setTitleOp.Validate(); err != nil {
119		return err
120	}
121
122	b.Append(setTitleOp)
123	return nil
124}