operation_pack.go

 1package bug
 2
 3import (
 4	"bytes"
 5	"encoding/gob"
 6	"github.com/MichaelMure/git-bug/repository"
 7	"github.com/MichaelMure/git-bug/util"
 8)
 9
10// OperationPack represent an ordered set of operation to apply
11// to a Bug. These operations are stored in a single Git commit.
12//
13// These commits will be linked together in a linear chain of commits
14// inside Git to form the complete ordered chain of operation to
15// apply to get the final state of the Bug
16type OperationPack struct {
17	Operations []Operation
18
19	// Private field so not serialized by gob
20	commitHash util.Hash
21}
22
23// ParseOperationPack will deserialize an OperationPack from raw bytes
24func ParseOperationPack(data []byte) (*OperationPack, error) {
25	reader := bytes.NewReader(data)
26	decoder := gob.NewDecoder(reader)
27
28	var opp OperationPack
29
30	err := decoder.Decode(&opp)
31
32	if err != nil {
33		return nil, err
34	}
35
36	return &opp, nil
37}
38
39// Serialize will serialise an OperationPack into raw bytes
40func (opp *OperationPack) Serialize() ([]byte, error) {
41	var data bytes.Buffer
42
43	encoder := gob.NewEncoder(&data)
44	err := encoder.Encode(*opp)
45
46	if err != nil {
47		return nil, err
48	}
49
50	return data.Bytes(), nil
51}
52
53// Append a new operation to the pack
54func (opp *OperationPack) Append(op Operation) {
55	opp.Operations = append(opp.Operations, op)
56}
57
58// IsEmpty tell if the OperationPack is empty
59func (opp *OperationPack) IsEmpty() bool {
60	return len(opp.Operations) == 0
61}
62
63// IsValid tell if the OperationPack is considered valid
64func (opp *OperationPack) IsValid() bool {
65	return !opp.IsEmpty()
66}
67
68// Write will serialize and store the OperationPack as a git blob and return
69// its hash
70func (opp *OperationPack) Write(repo repository.Repo) (util.Hash, error) {
71	data, err := opp.Serialize()
72
73	if err != nil {
74		return "", err
75	}
76
77	hash, err := repo.StoreData(data)
78
79	if err != nil {
80		return "", err
81	}
82
83	return hash, nil
84}
85
86// Make a deep copy
87func (opp *OperationPack) Clone() OperationPack {
88
89	clone := OperationPack{
90		Operations: make([]Operation, len(opp.Operations)),
91		commitHash: opp.commitHash,
92	}
93
94	for i, op := range opp.Operations {
95		clone.Operations[i] = op
96	}
97
98	return clone
99}