helper_completion.go

  1package completion
  2
  3import (
  4	"fmt"
  5	"sort"
  6	"strings"
  7
  8	"github.com/spf13/cobra"
  9
 10	"github.com/git-bug/git-bug/bridge"
 11	"github.com/git-bug/git-bug/bridge/core/auth"
 12	"github.com/git-bug/git-bug/commands/execenv"
 13)
 14
 15type ValidArgsFunction func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective)
 16
 17func HandleError(err error) (completions []string, directives cobra.ShellCompDirective) {
 18	return nil, cobra.ShellCompDirectiveError
 19}
 20
 21func Bridge(env *execenv.Env) ValidArgsFunction {
 22	return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
 23		if err := execenv.LoadBackend(env)(cmd, args); err != nil {
 24			return HandleError(err)
 25		}
 26		defer func() {
 27			_ = env.Backend.Close()
 28		}()
 29
 30		bridges, err := bridge.ConfiguredBridges(env.Backend)
 31		if err != nil {
 32			return HandleError(err)
 33		}
 34
 35		completions = make([]string, len(bridges))
 36		for i, bridge := range bridges {
 37			completions[i] = bridge + "\t" + "Bridge"
 38		}
 39
 40		return completions, cobra.ShellCompDirectiveNoFileComp
 41	}
 42}
 43
 44func BridgeAuth(env *execenv.Env) 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 HandleError(err)
 48		}
 49		defer func() {
 50			_ = env.Backend.Close()
 51		}()
 52
 53		creds, err := auth.List(env.Backend)
 54		if err != nil {
 55			return HandleError(err)
 56		}
 57
 58		completions = make([]string, len(creds))
 59		for i, cred := range creds {
 60			meta := make([]string, 0, len(cred.Metadata()))
 61			for k, v := range cred.Metadata() {
 62				meta = append(meta, k+":"+v)
 63			}
 64			sort.Strings(meta)
 65			metaFmt := strings.Join(meta, ",")
 66
 67			completions[i] = cred.ID().Human() + "\t" + cred.Target() + " " + string(cred.Kind()) + " " + metaFmt
 68		}
 69
 70		return completions, cobra.ShellCompDirectiveNoFileComp
 71	}
 72}
 73
 74func From(choices []string) ValidArgsFunction {
 75	return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
 76		return choices, cobra.ShellCompDirectiveNoFileComp
 77	}
 78}
 79
 80func GitRemote(env *execenv.Env) ValidArgsFunction {
 81	return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
 82		if err := execenv.LoadBackend(env)(cmd, args); err != nil {
 83			return HandleError(err)
 84		}
 85		defer func() {
 86			_ = env.Backend.Close()
 87		}()
 88
 89		remoteMap, err := env.Backend.GetRemotes()
 90		if err != nil {
 91			return HandleError(err)
 92		}
 93		completions = make([]string, 0, len(remoteMap))
 94		for remote, url := range remoteMap {
 95			completions = append(completions, remote+"\t"+"Remote: "+url)
 96		}
 97		sort.Strings(completions)
 98		return completions, cobra.ShellCompDirectiveNoFileComp
 99	}
100}
101
102func Label(env *execenv.Env) ValidArgsFunction {
103	return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
104		if err := execenv.LoadBackend(env)(cmd, args); err != nil {
105			return HandleError(err)
106		}
107		defer func() {
108			_ = env.Backend.Close()
109		}()
110
111		labels := env.Backend.Bugs().ValidLabels()
112		completions = make([]string, len(labels))
113		for i, label := range labels {
114			if strings.Contains(label.String(), " ") {
115				completions[i] = fmt.Sprintf("\"%s\"\tLabel", label.String())
116			} else {
117				completions[i] = fmt.Sprintf("%s\tLabel", label.String())
118			}
119		}
120		return completions, cobra.ShellCompDirectiveNoFileComp
121	}
122}
123
124func Ls(env *execenv.Env) ValidArgsFunction {
125	return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
126		if strings.HasPrefix(toComplete, "status:") {
127			completions = append(completions, "status:open\tOpen bugs")
128			completions = append(completions, "status:closed\tClosed bugs")
129			return completions, cobra.ShellCompDirectiveDefault
130		}
131
132		byPerson := []string{"author:", "participant:", "actor:"}
133		byLabel := []string{"label:", "no:"}
134		needBackend := false
135		for _, key := range append(byPerson, byLabel...) {
136			if strings.HasPrefix(toComplete, key) {
137				needBackend = true
138			}
139		}
140
141		if needBackend {
142			if err := execenv.LoadBackend(env)(cmd, args); err != nil {
143				return HandleError(err)
144			}
145			defer func() {
146				_ = env.Backend.Close()
147			}()
148		}
149
150		for _, key := range byPerson {
151			if !strings.HasPrefix(toComplete, key) {
152				continue
153			}
154			ids := env.Backend.Identities().AllIds()
155			completions = make([]string, len(ids))
156			for i, id := range ids {
157				user, err := env.Backend.Identities().ResolveExcerpt(id)
158				if err != nil {
159					return HandleError(err)
160				}
161				var handle string
162				if user.Login != "" {
163					handle = user.Login
164				} else {
165					// "author:John Doe" does not work yet, so use the first name.
166					handle = strings.Split(user.Name, " ")[0]
167				}
168				completions[i] = key + handle + "\t" + user.DisplayName()
169			}
170			return completions, cobra.ShellCompDirectiveNoFileComp
171		}
172
173		for _, key := range byLabel {
174			if !strings.HasPrefix(toComplete, key) {
175				continue
176			}
177			labels := env.Backend.Bugs().ValidLabels()
178			completions = make([]string, len(labels))
179			for i, label := range labels {
180				if strings.Contains(label.String(), " ") {
181					completions[i] = key + "\"" + string(label) + "\""
182				} else {
183					completions[i] = key + string(label)
184				}
185			}
186			return completions, cobra.ShellCompDirectiveNoFileComp
187		}
188
189		completions = []string{
190			"actor:\tFilter by actor",
191			"author:\tFilter by author",
192			"label:\tFilter by label",
193			"no:\tExclude bugs by label",
194			"participant:\tFilter by participant",
195			"status:\tFilter by open/close status",
196			"title:\tFilter by title",
197		}
198		return completions, cobra.ShellCompDirectiveNoSpace
199	}
200}
201
202func User(env *execenv.Env) ValidArgsFunction {
203	return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
204		if err := execenv.LoadBackend(env)(cmd, args); err != nil {
205			return HandleError(err)
206		}
207		defer func() {
208			_ = env.Backend.Close()
209		}()
210
211		ids := env.Backend.Identities().AllIds()
212		completions = make([]string, len(ids))
213		for i, id := range ids {
214			user, err := env.Backend.Identities().ResolveExcerpt(id)
215			if err != nil {
216				return HandleError(err)
217			}
218			completions[i] = user.Id().Human() + "\t" + user.DisplayName()
219		}
220		return completions, cobra.ShellCompDirectiveNoFileComp
221	}
222}
223
224func UserForQuery(env *execenv.Env) ValidArgsFunction {
225	return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
226		if err := execenv.LoadBackend(env)(cmd, args); err != nil {
227			return HandleError(err)
228		}
229		defer func() {
230			_ = env.Backend.Close()
231		}()
232
233		ids := env.Backend.Identities().AllIds()
234		completions = make([]string, len(ids))
235		for i, id := range ids {
236			user, err := env.Backend.Identities().ResolveExcerpt(id)
237			if err != nil {
238				return HandleError(err)
239			}
240			var handle string
241			if user.Login != "" {
242				handle = user.Login
243			} else {
244				// "author:John Doe" does not work yet, so use the first name.
245				handle = strings.Split(user.Name, " ")[0]
246			}
247			completions[i] = handle + "\t" + user.DisplayName()
248		}
249		return completions, cobra.ShellCompDirectiveNoFileComp
250	}
251}