2018-07-18 17:41:09 +03:00
|
|
|
package operations
|
|
|
|
|
|
|
|
import (
|
2018-07-25 19:01:32 +03:00
|
|
|
"fmt"
|
|
|
|
"io"
|
2018-08-01 22:57:12 +03:00
|
|
|
"io/ioutil"
|
2018-07-18 17:41:09 +03:00
|
|
|
"sort"
|
2018-08-06 21:31:20 +03:00
|
|
|
|
|
|
|
"github.com/MichaelMure/git-bug/bug"
|
2018-07-18 17:41:09 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
var _ bug.Operation = LabelChangeOperation{}
|
|
|
|
|
2018-08-13 16:28:16 +03:00
|
|
|
// LabelChangeOperation define a Bug operation to add or remove labels
|
2018-07-18 17:41:09 +03:00
|
|
|
type LabelChangeOperation struct {
|
|
|
|
bug.OpBase
|
2018-09-12 17:57:04 +03:00
|
|
|
Added []bug.Label `json:"added"`
|
|
|
|
Removed []bug.Label `json:"removed"`
|
2018-07-18 17:41:09 +03:00
|
|
|
}
|
|
|
|
|
2018-08-13 16:28:16 +03:00
|
|
|
// Apply apply the operation
|
2018-07-18 17:41:09 +03:00
|
|
|
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
|
|
|
|
}
|
2018-07-25 19:01:32 +03:00
|
|
|
|
2018-07-25 22:25:26 +03:00
|
|
|
func NewLabelChangeOperation(author bug.Person, added, removed []bug.Label) LabelChangeOperation {
|
|
|
|
return LabelChangeOperation{
|
|
|
|
OpBase: bug.NewOpBase(bug.LabelChangeOp, author),
|
|
|
|
Added: added,
|
|
|
|
Removed: removed,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-13 16:28:16 +03:00
|
|
|
// ChangeLabels is a convenience function to apply the operation
|
2018-08-23 20:11:38 +03:00
|
|
|
func ChangeLabels(out io.Writer, b bug.Interface, author bug.Person, add, remove []string) error {
|
2018-09-07 18:10:40 +03:00
|
|
|
// TODO: return a channel of result (like MergeAll) instead of formatting the result for the upper layers
|
2018-07-25 19:01:32 +03:00
|
|
|
var added, removed []bug.Label
|
|
|
|
|
2018-08-01 22:57:12 +03:00
|
|
|
if out == nil {
|
|
|
|
out = ioutil.Discard
|
|
|
|
}
|
|
|
|
|
2018-07-25 19:01:32 +03:00
|
|
|
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
|
|
|
|
}
|