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}