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 perform bug completion (id, title) on the environment backend
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
29// BugWithBackend perform bug completion (id, title) on the given backend
30func BugWithBackend(backend *cache.RepoCache, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
31 for _, id := range backend.Bugs().AllIds() {
32 if strings.Contains(id.String(), strings.TrimSpace(toComplete)) {
33 excerpt, err := backend.Bugs().ResolveExcerpt(id)
34 if err != nil {
35 return completion.HandleError(err)
36 }
37 completions = append(completions, id.Human()+"\t"+excerpt.Title)
38 }
39 }
40
41 return completions, cobra.ShellCompDirectiveNoFileComp
42}
43
44// BugAndLabelsCompletion complete either a bug ID or a label if we know about the bug
45func BugAndLabelsCompletion(env *execenv.Env, addOrRemove bool) completion.ValidArgsFunction {
46 return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
47 if err := execenv.LoadBackend(env)(cmd, args); err != nil {
48 return completion.HandleError(err)
49 }
50 defer func() {
51 _ = env.Backend.Close()
52 }()
53
54 b, cleanArgs, err := ResolveSelected(env.Backend, args)
55 if _select.IsErrNoValidId(err) {
56 // we need a bug first to complete labels
57 return BugWithBackend(env.Backend, toComplete)
58 }
59 if err != nil {
60 return completion.HandleError(err)
61 }
62
63 snap := b.Snapshot()
64
65 seenLabels := map[common.Label]bool{}
66 for _, label := range cleanArgs {
67 seenLabels[common.Label(label)] = addOrRemove
68 }
69
70 var labels []common.Label
71 if addOrRemove {
72 for _, label := range snap.Labels {
73 seenLabels[label] = true
74 }
75
76 allLabels := env.Backend.Bugs().ValidLabels()
77 labels = make([]common.Label, 0, len(allLabels))
78 for _, label := range allLabels {
79 if !seenLabels[label] {
80 labels = append(labels, label)
81 }
82 }
83 } else {
84 labels = make([]common.Label, 0, len(snap.Labels))
85 for _, label := range snap.Labels {
86 if seenLabels[label] {
87 labels = append(labels, label)
88 }
89 }
90 }
91
92 completions = make([]string, len(labels))
93 for i, label := range labels {
94 completions[i] = string(label) + "\t" + "Label"
95 }
96
97 return completions, cobra.ShellCompDirectiveNoFileComp
98 }
99}