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