op_add_comment.go

  1package bug
  2
  3import (
  4	"encoding/json"
  5	"fmt"
  6
  7	"github.com/MichaelMure/git-bug/entity"
  8	"github.com/MichaelMure/git-bug/identity"
  9	"github.com/MichaelMure/git-bug/util/git"
 10	"github.com/MichaelMure/git-bug/util/text"
 11	"github.com/MichaelMure/git-bug/util/timestamp"
 12)
 13
 14var _ Operation = &AddCommentOperation{}
 15
 16// AddCommentOperation will add a new comment in the bug
 17type AddCommentOperation struct {
 18	OpBase
 19	Message string `json:"message"`
 20	// TODO: change for a map[string]util.hash to store the filename ?
 21	Files []git.Hash `json:"files"`
 22}
 23
 24func (op *AddCommentOperation) base() *OpBase {
 25	return &op.OpBase
 26}
 27
 28func (op *AddCommentOperation) Id() entity.Id {
 29	return idOperation(op)
 30}
 31
 32func (op *AddCommentOperation) Apply(snapshot *Snapshot) {
 33	snapshot.addActor(op.Author)
 34	snapshot.addParticipant(op.Author)
 35
 36	comment := Comment{
 37		id:       op.Id(),
 38		Message:  op.Message,
 39		Author:   op.Author,
 40		Files:    op.Files,
 41		UnixTime: timestamp.Timestamp(op.UnixTime),
 42	}
 43
 44	snapshot.Comments = append(snapshot.Comments, comment)
 45
 46	item := &AddCommentTimelineItem{
 47		CommentTimelineItem: NewCommentTimelineItem(op.Id(), comment),
 48	}
 49
 50	snapshot.Timeline = append(snapshot.Timeline, item)
 51}
 52
 53func (op *AddCommentOperation) GetFiles() []git.Hash {
 54	return op.Files
 55}
 56
 57func (op *AddCommentOperation) Validate() error {
 58	if err := opBaseValidate(op, AddCommentOp); err != nil {
 59		return err
 60	}
 61
 62	if !text.Safe(op.Message) {
 63		return fmt.Errorf("message is not fully printable")
 64	}
 65
 66	return nil
 67}
 68
 69// UnmarshalJSON is a two step JSON unmarshaling
 70// This workaround is necessary to avoid the inner OpBase.MarshalJSON
 71// overriding the outer op's MarshalJSON
 72func (op *AddCommentOperation) UnmarshalJSON(data []byte) error {
 73	// Unmarshal OpBase and the op separately
 74
 75	base := OpBase{}
 76	err := json.Unmarshal(data, &base)
 77	if err != nil {
 78		return err
 79	}
 80
 81	aux := struct {
 82		Message string     `json:"message"`
 83		Files   []git.Hash `json:"files"`
 84	}{}
 85
 86	err = json.Unmarshal(data, &aux)
 87	if err != nil {
 88		return err
 89	}
 90
 91	op.OpBase = base
 92	op.Message = aux.Message
 93	op.Files = aux.Files
 94
 95	return nil
 96}
 97
 98// Sign post method for gqlgen
 99func (op *AddCommentOperation) IsAuthored() {}
100
101func NewAddCommentOp(author identity.Interface, unixTime int64, message string, files []git.Hash) *AddCommentOperation {
102	return &AddCommentOperation{
103		OpBase:  newOpBase(AddCommentOp, author, unixTime),
104		Message: message,
105		Files:   files,
106	}
107}
108
109// CreateTimelineItem replace a AddComment operation in the Timeline and hold its edition history
110type AddCommentTimelineItem struct {
111	CommentTimelineItem
112}
113
114// Sign post method for gqlgen
115func (a *AddCommentTimelineItem) IsAuthored() {}
116
117// Convenience function to apply the operation
118func AddComment(b Interface, author identity.Interface, unixTime int64, message string) (*AddCommentOperation, error) {
119	return AddCommentWithFiles(b, author, unixTime, message, nil)
120}
121
122func AddCommentWithFiles(b Interface, author identity.Interface, unixTime int64, message string, files []git.Hash) (*AddCommentOperation, error) {
123	addCommentOp := NewAddCommentOp(author, unixTime, message, files)
124	if err := addCommentOp.Validate(); err != nil {
125		return nil, err
126	}
127	b.Append(addCommentOp)
128	return addCommentOp, nil
129}