operation.go

  1package bug
  2
  3import (
  4	"github.com/MichaelMure/git-bug/util/git"
  5	"github.com/pkg/errors"
  6
  7	"fmt"
  8	"time"
  9)
 10
 11// OperationType is an operation type identifier
 12type OperationType int
 13
 14const (
 15	_ OperationType = iota
 16	CreateOp
 17	SetTitleOp
 18	AddCommentOp
 19	SetStatusOp
 20	LabelChangeOp
 21)
 22
 23// Operation define the interface to fulfill for an edit operation of a Bug
 24type Operation interface {
 25	// OpType return the type of operation
 26	OpType() OperationType
 27	// Time return the time when the operation was added
 28	Time() time.Time
 29	// GetUnixTime return the unix timestamp when the operation was added
 30	GetUnixTime() int64
 31	// GetAuthor return the author of the operation
 32	GetAuthor() Person
 33	// GetFiles return the files needed by this operation
 34	GetFiles() []git.Hash
 35	// Apply the operation to a Snapshot to create the final state
 36	Apply(snapshot Snapshot) Snapshot
 37	// Validate check if the operation is valid (ex: a title is a single line)
 38	Validate() error
 39	// SetMetadata store arbitrary metadata about the operation
 40	SetMetadata(key string, value string)
 41	// GetMetadata retrieve arbitrary metadata about the operation
 42	GetMetadata(key string) (string, bool)
 43}
 44
 45// OpBase implement the common code for all operations
 46type OpBase struct {
 47	OperationType OperationType     `json:"type"`
 48	Author        Person            `json:"author"`
 49	UnixTime      int64             `json:"timestamp"`
 50	Metadata      map[string]string `json:"metadata,omitempty"`
 51}
 52
 53// NewOpBase is the constructor for an OpBase
 54func NewOpBase(opType OperationType, author Person, unixTime int64) *OpBase {
 55	return &OpBase{
 56		OperationType: opType,
 57		Author:        author,
 58		UnixTime:      unixTime,
 59	}
 60}
 61
 62// OpType return the type of operation
 63func (op *OpBase) OpType() OperationType {
 64	return op.OperationType
 65}
 66
 67// Time return the time when the operation was added
 68func (op *OpBase) Time() time.Time {
 69	return time.Unix(op.UnixTime, 0)
 70}
 71
 72// GetUnixTime return the unix timestamp when the operation was added
 73func (op *OpBase) GetUnixTime() int64 {
 74	return op.UnixTime
 75}
 76
 77// GetAuthor return the author of the operation
 78func (op *OpBase) GetAuthor() Person {
 79	return op.Author
 80}
 81
 82// GetFiles return the files needed by this operation
 83func (op *OpBase) GetFiles() []git.Hash {
 84	return nil
 85}
 86
 87// Validate check the OpBase for errors
 88func OpBaseValidate(op Operation, opType OperationType) error {
 89	if op.OpType() != opType {
 90		return fmt.Errorf("incorrect operation type (expected: %v, actual: %v)", opType, op.OpType())
 91	}
 92
 93	if op.GetUnixTime() == 0 {
 94		return fmt.Errorf("time not set")
 95	}
 96
 97	if err := op.GetAuthor().Validate(); err != nil {
 98		return errors.Wrap(err, "author")
 99	}
100
101	for _, hash := range op.GetFiles() {
102		if !hash.IsValid() {
103			return fmt.Errorf("file with invalid hash %v", hash)
104		}
105	}
106
107	return nil
108}
109
110// SetMetadata store arbitrary metadata about the operation
111func (op *OpBase) SetMetadata(key string, value string) {
112	if op.Metadata == nil {
113		op.Metadata = make(map[string]string)
114	}
115
116	op.Metadata[key] = value
117}
118
119// GetMetadata retrieve arbitrary metadata about the operation
120func (op *OpBase) GetMetadata(key string) (string, bool) {
121	val, ok := op.Metadata[key]
122	return val, ok
123}