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/repository"
 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 []repository.Hash `json:"files"`
 22}
 23
 24func (op *AddCommentOperation) Id() entity.Id {
 25	return idOperation(op, &op.OpBase)
 26}
 27
 28func (op *AddCommentOperation) Apply(snapshot *Snapshot) {
 29	snapshot.addActor(op.Author_)
 30	snapshot.addParticipant(op.Author_)
 31
 32	commentId := entity.CombineIds(snapshot.Id(), op.Id())
 33	comment := Comment{
 34		id:       commentId,
 35		Message:  op.Message,
 36		Author:   op.Author_,
 37		Files:    op.Files,
 38		UnixTime: timestamp.Timestamp(op.UnixTime),
 39	}
 40
 41	snapshot.Comments = append(snapshot.Comments, comment)
 42
 43	item := &AddCommentTimelineItem{
 44		CommentTimelineItem: NewCommentTimelineItem(commentId, comment),
 45	}
 46
 47	snapshot.Timeline = append(snapshot.Timeline, item)
 48}
 49
 50func (op *AddCommentOperation) GetFiles() []repository.Hash {
 51	return op.Files
 52}
 53
 54func (op *AddCommentOperation) Validate() error {
 55	if err := op.OpBase.Validate(op, AddCommentOp); err != nil {
 56		return err
 57	}
 58
 59	if !text.Safe(op.Message) {
 60		return fmt.Errorf("message is not fully printable")
 61	}
 62
 63	return nil
 64}
 65
 66// UnmarshalJSON is a two step JSON unmarshalling
 67// This workaround is necessary to avoid the inner OpBase.MarshalJSON
 68// overriding the outer op's MarshalJSON
 69func (op *AddCommentOperation) UnmarshalJSON(data []byte) error {
 70	// Unmarshal OpBase and the op separately
 71
 72	base := OpBase{}
 73	err := json.Unmarshal(data, &base)
 74	if err != nil {
 75		return err
 76	}
 77
 78	aux := struct {
 79		Message string            `json:"message"`
 80		Files   []repository.Hash `json:"files"`
 81	}{}
 82
 83	err = json.Unmarshal(data, &aux)
 84	if err != nil {
 85		return err
 86	}
 87
 88	op.OpBase = base
 89	op.Message = aux.Message
 90	op.Files = aux.Files
 91
 92	return nil
 93}
 94
 95// Sign post method for gqlgen
 96func (op *AddCommentOperation) IsAuthored() {}
 97
 98func NewAddCommentOp(author identity.Interface, unixTime int64, message string, files []repository.Hash) *AddCommentOperation {
 99	return &AddCommentOperation{
100		OpBase:  newOpBase(AddCommentOp, author, unixTime),
101		Message: message,
102		Files:   files,
103	}
104}
105
106// CreateTimelineItem replace a AddComment operation in the Timeline and hold its edition history
107type AddCommentTimelineItem struct {
108	CommentTimelineItem
109}
110
111// Sign post method for gqlgen
112func (a *AddCommentTimelineItem) IsAuthored() {}
113
114// Convenience function to apply the operation
115func AddComment(b Interface, author identity.Interface, unixTime int64, message string) (*AddCommentOperation, error) {
116	return AddCommentWithFiles(b, author, unixTime, message, nil)
117}
118
119func AddCommentWithFiles(b Interface, author identity.Interface, unixTime int64, message string, files []repository.Hash) (*AddCommentOperation, error) {
120	addCommentOp := NewAddCommentOp(author, unixTime, message, files)
121	if err := addCommentOp.Validate(); err != nil {
122		return nil, err
123	}
124	b.Append(addCommentOp)
125	return addCommentOp, nil
126}