1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
package operations
import (
"fmt"
"github.com/MichaelMure/git-bug/bug"
"github.com/MichaelMure/git-bug/util"
"io"
"io/ioutil"
"sort"
)
// LabelChangeOperation will add or remove a set of labels
var _ bug.Operation = LabelChangeOperation{}
type LabelChangeOperation struct {
bug.OpBase
Added []bug.Label
Removed []bug.Label
}
func (op LabelChangeOperation) Apply(snapshot bug.Snapshot) bug.Snapshot {
// Add in the set
AddLoop:
for _, added := range op.Added {
for _, label := range snapshot.Labels {
if label == added {
// Already exist
continue AddLoop
}
}
snapshot.Labels = append(snapshot.Labels, added)
}
// Remove in the set
for _, removed := range op.Removed {
for i, label := range snapshot.Labels {
if label == removed {
snapshot.Labels[i] = snapshot.Labels[len(snapshot.Labels)-1]
snapshot.Labels = snapshot.Labels[:len(snapshot.Labels)-1]
}
}
}
// Sort
sort.Slice(snapshot.Labels, func(i, j int) bool {
return string(snapshot.Labels[i]) < string(snapshot.Labels[j])
})
return snapshot
}
func (op LabelChangeOperation) Files() []util.Hash {
return nil
}
func NewLabelChangeOperation(author bug.Person, added, removed []bug.Label) LabelChangeOperation {
return LabelChangeOperation{
OpBase: bug.NewOpBase(bug.LabelChangeOp, author),
Added: added,
Removed: removed,
}
}
// Convenience function to apply the operation
func ChangeLabels(out io.Writer, b *bug.Bug, author bug.Person, add, remove []string) error {
var added, removed []bug.Label
if out == nil {
out = ioutil.Discard
}
snap := b.Compile()
for _, str := range add {
label := bug.Label(str)
// check for duplicate
if labelExist(added, label) {
fmt.Fprintf(out, "label \"%s\" is a duplicate\n", str)
continue
}
// check that the label doesn't already exist
if labelExist(snap.Labels, label) {
fmt.Fprintf(out, "label \"%s\" is already set on this bug\n", str)
continue
}
added = append(added, label)
}
for _, str := range remove {
label := bug.Label(str)
// check for duplicate
if labelExist(removed, label) {
fmt.Fprintf(out, "label \"%s\" is a duplicate\n", str)
continue
}
// check that the label actually exist
if !labelExist(snap.Labels, label) {
fmt.Fprintf(out, "label \"%s\" doesn't exist on this bug\n", str)
continue
}
removed = append(removed, label)
}
if len(added) == 0 && len(removed) == 0 {
return fmt.Errorf("no label added or removed")
}
labelOp := NewLabelChangeOperation(author, added, removed)
b.Append(labelOp)
return nil
}
func labelExist(labels []bug.Label, label bug.Label) bool {
for _, l := range labels {
if l == label {
return true
}
}
return false
}
|