1package bugcmd
2
3import (
4 "strings"
5
6 "github.com/spf13/cobra"
7
8 "github.com/git-bug/git-bug/cache"
9 "github.com/git-bug/git-bug/commands/completion"
10 "github.com/git-bug/git-bug/commands/execenv"
11 _select "github.com/git-bug/git-bug/commands/select"
12 "github.com/git-bug/git-bug/entities/common"
13)
14
15// BugCompletion complete a bug id
16func BugCompletion(env *execenv.Env) completion.ValidArgsFunction {
17 return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
18 if err := execenv.LoadBackend(env)(cmd, args); err != nil {
19 return completion.HandleError(err)
20 }
21 defer func() {
22 _ = env.Backend.Close()
23 }()
24
25 return BugWithBackend(env.Backend, toComplete)
26 }
27}
28
29func BugWithBackend(backend *cache.RepoCache, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
30 for _, id := range backend.Bugs().AllIds() {
31 if strings.Contains(id.String(), strings.TrimSpace(toComplete)) {
32 excerpt, err := backend.Bugs().ResolveExcerpt(id)
33 if err != nil {
34 return completion.HandleError(err)
35 }
36 completions = append(completions, id.Human()+"\t"+excerpt.Title)
37 }
38 }
39
40 return completions, cobra.ShellCompDirectiveNoFileComp
41}
42
43// BugAndLabelsCompletion complete either a bug ID or a label if we know about the bug
44func BugAndLabelsCompletion(env *execenv.Env, addOrRemove bool) completion.ValidArgsFunction {
45 return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
46 if err := execenv.LoadBackend(env)(cmd, args); err != nil {
47 return completion.HandleError(err)
48 }
49 defer func() {
50 _ = env.Backend.Close()
51 }()
52
53 b, cleanArgs, err := ResolveSelected(env.Backend, args)
54 if _select.IsErrNoValidId(err) {
55 // we need a bug first to complete labels
56 return BugWithBackend(env.Backend, toComplete)
57 }
58 if err != nil {
59 return completion.HandleError(err)
60 }
61
62 snap := b.Snapshot()
63
64 seenLabels := map[common.Label]bool{}
65 for _, label := range cleanArgs {
66 seenLabels[common.Label(label)] = addOrRemove
67 }
68
69 var labels []common.Label
70 if addOrRemove {
71 for _, label := range snap.Labels {
72 seenLabels[label] = true
73 }
74
75 allLabels := env.Backend.Bugs().ValidLabels()
76 labels = make([]common.Label, 0, len(allLabels))
77 for _, label := range allLabels {
78 if !seenLabels[label] {
79 labels = append(labels, label)
80 }
81 }
82 } else {
83 labels = make([]common.Label, 0, len(snap.Labels))
84 for _, label := range snap.Labels {
85 if seenLabels[label] {
86 labels = append(labels, label)
87 }
88 }
89 }
90
91 completions = make([]string, len(labels))
92 for i, label := range labels {
93 completions[i] = string(label) + "\t" + "Label"
94 }
95
96 return completions, cobra.ShellCompDirectiveNoFileComp
97 }
98}