op_add_comment.go

  1package bug
  2
  3import (
  4	"fmt"
  5
  6	"github.com/MichaelMure/git-bug/entity"
  7	"github.com/MichaelMure/git-bug/entity/dag"
  8	"github.com/MichaelMure/git-bug/repository"
  9	"github.com/MichaelMure/git-bug/util/text"
 10	"github.com/MichaelMure/git-bug/util/timestamp"
 11)
 12
 13var _ Operation = &AddCommentOperation{}
 14var _ entity.OperationWithFiles = &AddCommentOperation{}
 15
 16// AddCommentOperation will add a new comment in the bug
 17type AddCommentOperation struct {
 18	dag.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 dag.IdOperation(op, &op.OpBase)
 26}
 27
 28func (op *AddCommentOperation) Apply(snapshot *Snapshot) {
 29	snapshot.addActor(op.Author())
 30	snapshot.addParticipant(op.Author())
 31
 32	opId := op.Id()
 33
 34	comment := Comment{
 35		combinedId: entity.CombineIds(snapshot.Id(), opId),
 36		targetId:   opId,
 37		Message:    op.Message,
 38		Author:     op.Author(),
 39		Files:      op.Files,
 40		unixTime:   timestamp.Timestamp(op.UnixTime),
 41	}
 42
 43	snapshot.Comments = append(snapshot.Comments, comment)
 44
 45	item := &AddCommentTimelineItem{
 46		CommentTimelineItem: NewCommentTimelineItem(comment),
 47	}
 48
 49	snapshot.Timeline = append(snapshot.Timeline, item)
 50}
 51
 52func (op *AddCommentOperation) GetFiles() []repository.Hash {
 53	return op.Files
 54}
 55
 56func (op *AddCommentOperation) Validate() error {
 57	if err := op.OpBase.Validate(op, AddCommentOp); err != nil {
 58		return err
 59	}
 60
 61	if !text.Safe(op.Message) {
 62		return fmt.Errorf("message is not fully printable")
 63	}
 64
 65	for _, file := range op.Files {
 66		if !file.IsValid() {
 67			return fmt.Errorf("invalid file hash")
 68		}
 69	}
 70
 71	return nil
 72}
 73
 74func NewAddCommentOp(author entity.Identity, unixTime int64, message string, files []repository.Hash) *AddCommentOperation {
 75	return &AddCommentOperation{
 76		OpBase:  dag.NewOpBase(AddCommentOp, author, unixTime),
 77		Message: message,
 78		Files:   files,
 79	}
 80}
 81
 82// AddCommentTimelineItem replace a AddComment operation in the Timeline and hold its edition history
 83type AddCommentTimelineItem struct {
 84	CommentTimelineItem
 85}
 86
 87// IsAuthored is a sign post method for gqlgen
 88func (a *AddCommentTimelineItem) IsAuthored() {}
 89
 90// AddComment is a convenience function to add a comment to a bug
 91func AddComment(b Interface, author entity.Identity, unixTime int64, message string, files []repository.Hash, metadata map[string]string) (entity.CombinedId, *AddCommentOperation, error) {
 92	op := NewAddCommentOp(author, unixTime, message, files)
 93	for key, val := range metadata {
 94		op.SetMetadata(key, val)
 95	}
 96	if err := op.Validate(); err != nil {
 97		return entity.UnsetCombinedId, nil, err
 98	}
 99	b.Append(op)
100	return entity.CombineIds(b.Id(), op.Id()), op, nil
101}