From cfa11372cbcbb5f4553f3dcd8897d5f5207c6507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Mur=C3=A9?= Date: Wed, 18 Jul 2018 16:41:09 +0200 Subject: [PATCH] implement label op+command --- bug/label.go | 4 ++ bug/operation.go | 1 + bug/operations/label_change.go | 56 ++++++++++++++++ bug/operations/operations.go | 1 + commands/command.go | 1 + commands/label.go | 108 +++++++++++++++++++++++++++++++ commands/show.go | 11 +++- tests/operation_iterator_test.go | 5 +- 8 files changed, 184 insertions(+), 3 deletions(-) create mode 100644 bug/operations/label_change.go create mode 100644 commands/label.go diff --git a/bug/label.go b/bug/label.go index c202cd70a13adae12666ac0e467adda12efdea5f..889bf455b1eecccf8f5b2d6a10e45eb4a984a818 100644 --- a/bug/label.go +++ b/bug/label.go @@ -1,3 +1,7 @@ package bug type Label string + +func (l Label) String() string { + return string(l) +} diff --git a/bug/operation.go b/bug/operation.go index 15374f08e2619194a225aec0c78ecf459947b753..9e31637a081800fc1f43c73a561c5e9ecd1e7415 100644 --- a/bug/operation.go +++ b/bug/operation.go @@ -10,6 +10,7 @@ const ( SetTitleOp AddCommentOp SetStatusOp + LabelChangeOp ) type Operation interface { diff --git a/bug/operations/label_change.go b/bug/operations/label_change.go new file mode 100644 index 0000000000000000000000000000000000000000..ca07f6f542eaec2a1baf43860368b5f97c0f06b2 --- /dev/null +++ b/bug/operations/label_change.go @@ -0,0 +1,56 @@ +package operations + +import ( + "github.com/MichaelMure/git-bug/bug" + "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 NewLabelChangeOperation(author bug.Person, added, removed []bug.Label) LabelChangeOperation { + return LabelChangeOperation{ + OpBase: bug.NewOpBase(bug.LabelChangeOp, author), + Added: added, + Removed: removed, + } +} + +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 +} diff --git a/bug/operations/operations.go b/bug/operations/operations.go index 506929528de548a83196d42b0bb3d416529f11f5..0bfd3b8493ddff5372a389d3ba384e5c936a6459 100644 --- a/bug/operations/operations.go +++ b/bug/operations/operations.go @@ -8,4 +8,5 @@ func init() { gob.Register(CreateOperation{}) gob.Register(SetTitleOperation{}) gob.Register(SetStatusOperation{}) + gob.Register(LabelChangeOperation{}) } diff --git a/commands/command.go b/commands/command.go index 30f868489105475659ad2874830f5a8e2aa1a1e3..89420b46da5dd9f2e0d941a4228083a6145e2e94 100644 --- a/commands/command.go +++ b/commands/command.go @@ -47,6 +47,7 @@ func init() { "close": closeCmd, "commands": commandsCmd, "comment": commentCmd, + "label": labelCmd, "ls": lsCmd, "new": newCmd, "open": openCmd, diff --git a/commands/label.go b/commands/label.go new file mode 100644 index 0000000000000000000000000000000000000000..ad3a388b38a4af4fb33f1adbc87bd688d2e41332 --- /dev/null +++ b/commands/label.go @@ -0,0 +1,108 @@ +package commands + +import ( + "errors" + "flag" + "fmt" + "github.com/MichaelMure/git-bug/bug" + "github.com/MichaelMure/git-bug/bug/operations" + "github.com/MichaelMure/git-bug/repository" +) + +var labelFlagSet = flag.NewFlagSet("label", flag.ExitOnError) + +var ( + labelRemove = newFlagSet.Bool("r", false, "Remove a label") +) + +func runLabel(repo repository.Repo, args []string) error { + labelFlagSet.Parse(args) + args = labelFlagSet.Args() + + if len(args) == 0 { + return errors.New("You must provide a bug id") + } + + if len(args) == 1 { + return errors.New("You must provide a label") + } + + prefix := args[0] + + b, err := bug.FindBug(repo, prefix) + if err != nil { + return err + } + + author, err := bug.GetUser(repo) + if err != nil { + return err + } + + var added, removed []bug.Label + + snap := b.Compile() + + for _, arg := range args[1:] { + label := bug.Label(arg) + + if *labelRemove { + // check for duplicate + if labelExist(removed, label) { + fmt.Printf("label \"%s\" is a duplicate\n", arg) + continue + } + + // check that the label actually exist + if !labelExist(snap.Labels, label) { + fmt.Printf("label \"%s\" doesn't exist on this bug\n", arg) + continue + } + + removed = append(removed, label) + } else { + // check for duplicate + if labelExist(added, label) { + fmt.Printf("label \"%s\" is a duplicate\n", arg) + continue + } + + // check that the label doesn't already exist + if labelExist(snap.Labels, label) { + fmt.Printf("label \"%s\" is already set on this bug\n", arg) + continue + } + + added = append(added, label) + } + } + + if len(added) == 0 && len(removed) == 0 { + return errors.New("no label added or removed") + } + + labelOp := operations.NewLabelChangeOperation(author, added, removed) + + b.Append(labelOp) + + err = b.Commit(repo) + + return err +} + +func labelExist(labels []bug.Label, label bug.Label) bool { + for _, l := range labels { + if l == label { + return true + } + } + + return false +} + +var labelCmd = &Command{ + Description: "Manipulate bug's label", + Usage: " [