mirror of
https://github.com/MichaelMure/git-bug.git
synced 2024-12-14 08:45:30 +03:00
Merge pull request #531 from krobelus/complete-bug-ids
Complete bug IDs where appropriate
This commit is contained in:
commit
547d626c25
@ -41,10 +41,12 @@ func newBridgeAuthAddTokenCommand() *cobra.Command {
|
||||
|
||||
flags.StringVarP(&options.target, "target", "t", "",
|
||||
fmt.Sprintf("The target of the bridge. Valid values are [%s]", strings.Join(bridge.Targets(), ",")))
|
||||
cmd.RegisterFlagCompletionFunc("target", completeFrom(bridge.Targets()))
|
||||
flags.StringVarP(&options.login,
|
||||
"login", "l", "", "The login in the remote bug-tracker")
|
||||
flags.StringVarP(&options.user,
|
||||
"user", "u", "", "The user to add the token to. Default is the current user")
|
||||
cmd.RegisterFlagCompletionFunc("user", completeUser(env))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -16,7 +16,8 @@ func newBridgeAuthRm() *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return runBridgeAuthRm(env, args)
|
||||
},
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: completeBridgeAuth(env),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -21,7 +21,8 @@ func newBridgeAuthShow() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runBridgeAuthShow(env, args)
|
||||
}),
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: completeBridgeAuth(env),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -97,6 +97,7 @@ git bug bridge configure \
|
||||
flags.StringVarP(&options.name, "name", "n", "", "A distinctive name to identify the bridge")
|
||||
flags.StringVarP(&options.target, "target", "t", "",
|
||||
fmt.Sprintf("The target of the bridge. Valid values are [%s]", strings.Join(bridge.Targets(), ",")))
|
||||
cmd.RegisterFlagCompletionFunc("target", completeFrom(bridge.Targets()))
|
||||
flags.StringVarP(&options.params.URL, "url", "u", "", "The URL of the remote repository")
|
||||
flags.StringVarP(&options.params.BaseURL, "base-url", "b", "", "The base URL of your remote issue tracker")
|
||||
flags.StringVarP(&options.params.Login, "login", "l", "", "The login on your remote issue tracker")
|
||||
|
@ -32,7 +32,8 @@ func newBridgePullCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runBridgePull(env, options, args)
|
||||
}),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
ValidArgsFunction: completeBridge(env),
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
@ -23,7 +23,8 @@ func newBridgePushCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runBridgePush(env, args)
|
||||
}),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
ValidArgsFunction: completeBridge(env),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -16,7 +16,8 @@ func newBridgeRm() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runBridgeRm(env, args)
|
||||
}),
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.ExactArgs(1),
|
||||
ValidArgsFunction: completeBridge(env),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -18,6 +18,7 @@ func newCommentCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runComment(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBug(env),
|
||||
}
|
||||
|
||||
cmd.AddCommand(newCommentAddCommand())
|
||||
|
@ -25,6 +25,7 @@ func newCommentAddCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runCommentAdd(env, options, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBug(env),
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
342
commands/helper_completion.go
Normal file
342
commands/helper_completion.go
Normal file
@ -0,0 +1,342 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/MichaelMure/git-bug/bridge"
|
||||
"github.com/MichaelMure/git-bug/bridge/core/auth"
|
||||
"github.com/MichaelMure/git-bug/bug"
|
||||
"github.com/MichaelMure/git-bug/cache"
|
||||
_select "github.com/MichaelMure/git-bug/commands/select"
|
||||
)
|
||||
|
||||
type validArgsFunction func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective)
|
||||
|
||||
func completionHandlerError(err error) (completions []string, directives cobra.ShellCompDirective) {
|
||||
return nil, cobra.ShellCompDirectiveError
|
||||
}
|
||||
|
||||
func completeBridge(env *Env) validArgsFunction {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
|
||||
if err := loadBackend(env)(cmd, args); err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = env.backend.Close()
|
||||
}()
|
||||
|
||||
bridges, err := bridge.ConfiguredBridges(env.backend)
|
||||
if err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
|
||||
completions = make([]string, len(bridges))
|
||||
for i, bridge := range bridges {
|
||||
completions[i] = bridge + "\t" + "Bridge"
|
||||
}
|
||||
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
func completeBridgeAuth(env *Env) validArgsFunction {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
|
||||
if err := loadBackend(env)(cmd, args); err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = env.backend.Close()
|
||||
}()
|
||||
|
||||
creds, err := auth.List(env.backend)
|
||||
if err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
|
||||
completions = make([]string, len(creds))
|
||||
for i, cred := range creds {
|
||||
meta := make([]string, 0, len(cred.Metadata()))
|
||||
for k, v := range cred.Metadata() {
|
||||
meta = append(meta, k+":"+v)
|
||||
}
|
||||
sort.Strings(meta)
|
||||
metaFmt := strings.Join(meta, ",")
|
||||
|
||||
completions[i] = cred.ID().Human() + "\t" + cred.Target() + " " + string(cred.Kind()) + " " + metaFmt
|
||||
}
|
||||
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
func completeBug(env *Env) validArgsFunction {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
|
||||
if err := loadBackend(env)(cmd, args); err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = env.backend.Close()
|
||||
}()
|
||||
|
||||
return completeBugWithBackend(env.backend, toComplete)
|
||||
}
|
||||
}
|
||||
|
||||
func completeBugWithBackend(backend *cache.RepoCache, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
|
||||
allIds := backend.AllBugsIds()
|
||||
bugExcerpt := make([]*cache.BugExcerpt, len(allIds))
|
||||
for i, id := range allIds {
|
||||
var err error
|
||||
bugExcerpt[i], err = backend.ResolveBugExcerpt(id)
|
||||
if err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
}
|
||||
|
||||
for i, id := range allIds {
|
||||
if strings.Contains(id.String(), strings.TrimSpace(toComplete)) {
|
||||
completions = append(completions, id.Human()+"\t"+bugExcerpt[i].Title)
|
||||
}
|
||||
}
|
||||
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
func completeBugAndLabels(env *Env, addOrRemove bool) validArgsFunction {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
|
||||
if err := loadBackend(env)(cmd, args); err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = env.backend.Close()
|
||||
}()
|
||||
|
||||
b, args, err := _select.ResolveBug(env.backend, args)
|
||||
if err == _select.ErrNoValidId {
|
||||
// we need a bug first to complete labels
|
||||
return completeBugWithBackend(env.backend, toComplete)
|
||||
}
|
||||
if err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
|
||||
snap := b.Snapshot()
|
||||
|
||||
seenLabels := map[bug.Label]bool{}
|
||||
for _, label := range args {
|
||||
seenLabels[bug.Label(label)] = addOrRemove
|
||||
}
|
||||
|
||||
var labels []bug.Label
|
||||
if addOrRemove {
|
||||
for _, label := range snap.Labels {
|
||||
seenLabels[label] = true
|
||||
}
|
||||
|
||||
allLabels := env.backend.ValidLabels()
|
||||
labels = make([]bug.Label, 0, len(allLabels))
|
||||
for _, label := range allLabels {
|
||||
if !seenLabels[label] {
|
||||
labels = append(labels, label)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
labels = make([]bug.Label, 0, len(snap.Labels))
|
||||
for _, label := range snap.Labels {
|
||||
if seenLabels[label] {
|
||||
labels = append(labels, label)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
completions = make([]string, len(labels))
|
||||
for i, label := range labels {
|
||||
completions[i] = string(label) + "\t" + "Label"
|
||||
}
|
||||
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
func completeFrom(choices []string) validArgsFunction {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return choices, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
func completeGitRemote(env *Env) validArgsFunction {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
|
||||
if err := loadBackend(env)(cmd, args); err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = env.backend.Close()
|
||||
}()
|
||||
|
||||
remoteMap, err := env.backend.GetRemotes()
|
||||
if err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
completions = make([]string, 0, len(remoteMap))
|
||||
for remote, url := range remoteMap {
|
||||
completions = append(completions, remote+"\t"+"Remote: "+url)
|
||||
}
|
||||
sort.Strings(completions)
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
func completeLabel(env *Env) validArgsFunction {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
|
||||
if err := loadBackend(env)(cmd, args); err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = env.backend.Close()
|
||||
}()
|
||||
|
||||
labels := env.backend.ValidLabels()
|
||||
completions = make([]string, len(labels))
|
||||
for i, label := range labels {
|
||||
if strings.Contains(label.String(), " ") {
|
||||
completions[i] = fmt.Sprintf("\"%s\"\tLabel", label.String())
|
||||
} else {
|
||||
completions[i] = fmt.Sprintf("%s\tLabel", label.String())
|
||||
}
|
||||
}
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
func completeLs(env *Env) validArgsFunction {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
|
||||
if strings.HasPrefix(toComplete, "status:") {
|
||||
completions = append(completions, "status:open\tOpen bugs")
|
||||
completions = append(completions, "status:closed\tClosed bugs")
|
||||
return completions, cobra.ShellCompDirectiveDefault
|
||||
}
|
||||
|
||||
byPerson := []string{"author:", "participant:", "actor:"}
|
||||
byLabel := []string{"label:", "no:"}
|
||||
needBackend := false
|
||||
for _, key := range append(byPerson, byLabel...) {
|
||||
if strings.HasPrefix(toComplete, key) {
|
||||
needBackend = true
|
||||
}
|
||||
}
|
||||
|
||||
if needBackend {
|
||||
if err := loadBackend(env)(cmd, args); err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = env.backend.Close()
|
||||
}()
|
||||
}
|
||||
|
||||
for _, key := range byPerson {
|
||||
if !strings.HasPrefix(toComplete, key) {
|
||||
continue
|
||||
}
|
||||
ids := env.backend.AllIdentityIds()
|
||||
completions = make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
user, err := env.backend.ResolveIdentityExcerpt(id)
|
||||
if err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
var handle string
|
||||
if user.Login != "" {
|
||||
handle = user.Login
|
||||
} else {
|
||||
// "author:John Doe" does not work yet, so use the first name.
|
||||
handle = strings.Split(user.Name, " ")[0]
|
||||
}
|
||||
completions[i] = key + handle + "\t" + user.DisplayName()
|
||||
}
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
for _, key := range byLabel {
|
||||
if !strings.HasPrefix(toComplete, key) {
|
||||
continue
|
||||
}
|
||||
labels := env.backend.ValidLabels()
|
||||
completions = make([]string, len(labels))
|
||||
for i, label := range labels {
|
||||
if strings.Contains(label.String(), " ") {
|
||||
completions[i] = key + "\"" + string(label) + "\""
|
||||
} else {
|
||||
completions[i] = key + string(label)
|
||||
}
|
||||
}
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
|
||||
completions = []string{
|
||||
"actor:\tFilter by actor",
|
||||
"author:\tFilter by author",
|
||||
"label:\tFilter by label",
|
||||
"no:\tExclude bugs by label",
|
||||
"participant:\tFilter by participant",
|
||||
"status:\tFilter by open/close status",
|
||||
"title:\tFilter by title",
|
||||
}
|
||||
return completions, cobra.ShellCompDirectiveNoSpace
|
||||
}
|
||||
}
|
||||
|
||||
func completeUser(env *Env) validArgsFunction {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
|
||||
if err := loadBackend(env)(cmd, args); err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = env.backend.Close()
|
||||
}()
|
||||
|
||||
ids := env.backend.AllIdentityIds()
|
||||
completions = make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
user, err := env.backend.ResolveIdentityExcerpt(id)
|
||||
if err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
completions[i] = user.Id.Human() + "\t" + user.DisplayName()
|
||||
}
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
||||
|
||||
func completeUserForQuery(env *Env) validArgsFunction {
|
||||
return func(cmd *cobra.Command, args []string, toComplete string) (completions []string, directives cobra.ShellCompDirective) {
|
||||
if err := loadBackend(env)(cmd, args); err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
defer func() {
|
||||
_ = env.backend.Close()
|
||||
}()
|
||||
|
||||
ids := env.backend.AllIdentityIds()
|
||||
completions = make([]string, len(ids))
|
||||
for i, id := range ids {
|
||||
user, err := env.backend.ResolveIdentityExcerpt(id)
|
||||
if err != nil {
|
||||
return completionHandlerError(err)
|
||||
}
|
||||
var handle string
|
||||
if user.Login != "" {
|
||||
handle = user.Login
|
||||
} else {
|
||||
// "author:John Doe" does not work yet, so use the first name.
|
||||
handle = strings.Split(user.Name, " ")[0]
|
||||
}
|
||||
completions[i] = handle + "\t" + user.DisplayName()
|
||||
}
|
||||
return completions, cobra.ShellCompDirectiveNoFileComp
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ func newLabelCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runLabel(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBug(env),
|
||||
}
|
||||
|
||||
cmd.AddCommand(newLabelAddCommand())
|
||||
|
@ -17,6 +17,7 @@ func newLabelAddCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runLabelAdd(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBugAndLabels(env, true),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -17,6 +17,7 @@ func newLabelRmCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runLabelRm(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBugAndLabels(env, false),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -56,6 +56,7 @@ git bug ls status:open --by creation "foo bar" baz
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runLs(env, options, args)
|
||||
}),
|
||||
ValidArgsFunction: completeLs(env),
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
@ -63,26 +64,36 @@ git bug ls status:open --by creation "foo bar" baz
|
||||
|
||||
flags.StringSliceVarP(&options.statusQuery, "status", "s", nil,
|
||||
"Filter by status. Valid values are [open,closed]")
|
||||
cmd.RegisterFlagCompletionFunc("status", completeFrom([]string{"open", "closed"}))
|
||||
flags.StringSliceVarP(&options.authorQuery, "author", "a", nil,
|
||||
"Filter by author")
|
||||
flags.StringSliceVarP(&options.metadataQuery, "metadata", "m", nil,
|
||||
"Filter by metadata. Example: github-url=URL")
|
||||
cmd.RegisterFlagCompletionFunc("author", completeUserForQuery(env))
|
||||
flags.StringSliceVarP(&options.participantQuery, "participant", "p", nil,
|
||||
"Filter by participant")
|
||||
cmd.RegisterFlagCompletionFunc("participant", completeUserForQuery(env))
|
||||
flags.StringSliceVarP(&options.actorQuery, "actor", "A", nil,
|
||||
"Filter by actor")
|
||||
cmd.RegisterFlagCompletionFunc("actor", completeUserForQuery(env))
|
||||
flags.StringSliceVarP(&options.labelQuery, "label", "l", nil,
|
||||
"Filter by label")
|
||||
cmd.RegisterFlagCompletionFunc("label", completeLabel(env))
|
||||
flags.StringSliceVarP(&options.titleQuery, "title", "t", nil,
|
||||
"Filter by title")
|
||||
flags.StringSliceVarP(&options.noQuery, "no", "n", nil,
|
||||
"Filter by absence of something. Valid values are [label]")
|
||||
cmd.RegisterFlagCompletionFunc("no", completeLabel(env))
|
||||
flags.StringVarP(&options.sortBy, "by", "b", "creation",
|
||||
"Sort the results by a characteristic. Valid values are [id,creation,edit]")
|
||||
cmd.RegisterFlagCompletionFunc("by", completeFrom([]string{"id", "creation", "edit"}))
|
||||
flags.StringVarP(&options.sortDirection, "direction", "d", "asc",
|
||||
"Select the sorting direction. Valid values are [asc,desc]")
|
||||
cmd.RegisterFlagCompletionFunc("direction", completeFrom([]string{"asc", "desc"}))
|
||||
flags.StringVarP(&options.outputFormat, "format", "f", "default",
|
||||
"Select the output formatting style. Valid values are [default,plain,json,org-mode]")
|
||||
cmd.RegisterFlagCompletionFunc("format",
|
||||
completeFrom([]string{"default", "plain", "json", "org-mode"}))
|
||||
|
||||
return cmd
|
||||
}
|
||||
@ -92,13 +103,9 @@ func runLs(env *Env, opts lsOptions, args []string) error {
|
||||
var err error
|
||||
|
||||
if len(args) >= 1 {
|
||||
// either the shell or cobra remove the quotes, we need them back for the parsing
|
||||
for i, arg := range args {
|
||||
if strings.Contains(arg, " ") {
|
||||
args[i] = fmt.Sprintf("\"%s\"", arg)
|
||||
}
|
||||
}
|
||||
assembled := strings.Join(args, " ")
|
||||
// either the shell or cobra remove the quotes, we need them back for the query parsing
|
||||
assembled := repairQuery(args)
|
||||
|
||||
q, err = query.Parse(assembled)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -142,6 +149,19 @@ func runLs(env *Env, opts lsOptions, args []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
func repairQuery(args []string) string {
|
||||
for i, arg := range args {
|
||||
split := strings.Split(arg, ":")
|
||||
for j, s := range split {
|
||||
if strings.Contains(s, " ") {
|
||||
split[j] = fmt.Sprintf("\"%s\"", s)
|
||||
}
|
||||
}
|
||||
args[i] = strings.Join(split, ":")
|
||||
}
|
||||
return strings.Join(args, " ")
|
||||
}
|
||||
|
||||
type JSONBugExcerpt struct {
|
||||
Id string `json:"id"`
|
||||
HumanId string `json:"human_id"`
|
||||
|
43
commands/ls_test.go
Normal file
43
commands/ls_test.go
Normal file
@ -0,0 +1,43 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_repairQuery(t *testing.T) {
|
||||
cases := []struct {
|
||||
args []string
|
||||
output string
|
||||
}{
|
||||
{
|
||||
[]string{""},
|
||||
"",
|
||||
},
|
||||
{
|
||||
[]string{"foo"},
|
||||
"foo",
|
||||
},
|
||||
{
|
||||
[]string{"foo", "bar"},
|
||||
"foo bar",
|
||||
},
|
||||
{
|
||||
[]string{"foo bar", "baz"},
|
||||
"\"foo bar\" baz",
|
||||
},
|
||||
{
|
||||
[]string{"foo:bar", "baz"},
|
||||
"foo:bar baz",
|
||||
},
|
||||
{
|
||||
[]string{"foo:bar boo", "baz"},
|
||||
"foo:\"bar boo\" baz",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
require.Equal(t, tc.output, repairQuery(tc.args))
|
||||
}
|
||||
}
|
@ -18,6 +18,7 @@ func newPullCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runPull(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeGitRemote(env),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -16,6 +16,7 @@ func newPushCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runPush(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeGitRemote(env),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -17,6 +17,7 @@ func newRmCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runRm(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBug(env),
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
@ -50,14 +50,6 @@ the same git remote you are already using to collaborate with other people.
|
||||
|
||||
SilenceUsage: true,
|
||||
DisableAutoGenTag: true,
|
||||
|
||||
// Custom bash code to connect the git completion for "git bug" to the
|
||||
// git-bug completion for "git-bug"
|
||||
BashCompletionFunction: `
|
||||
_git_bug() {
|
||||
__start_git-bug "$@"
|
||||
}
|
||||
`,
|
||||
}
|
||||
|
||||
cmd.AddCommand(newAddCommand())
|
||||
|
@ -31,6 +31,7 @@ The complementary command is "git bug deselect" performing the opposite operatio
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runSelect(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBug(env),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -29,13 +29,17 @@ func newShowCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runShow(env, options, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBug(env),
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
flags.SortFlags = false
|
||||
|
||||
fields := []string{"author", "authorEmail", "createTime", "lastEdit", "humanId",
|
||||
"id", "labels", "shortId", "status", "title", "actors", "participants"}
|
||||
flags.StringVarP(&options.fields, "field", "", "",
|
||||
"Select field to display. Valid values are [author,authorEmail,createTime,lastEdit,humanId,id,labels,shortId,status,title,actors,participants]")
|
||||
"Select field to display. Valid values are ["+strings.Join(fields, ",")+"]")
|
||||
cmd.RegisterFlagCompletionFunc("by", completeFrom(fields))
|
||||
flags.StringVarP(&options.format, "format", "f", "default",
|
||||
"Select the output formatting style. Valid values are [default,json,org-mode]")
|
||||
|
||||
|
@ -15,6 +15,7 @@ func newStatusCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runStatus(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBug(env),
|
||||
}
|
||||
|
||||
cmd.AddCommand(newStatusCloseCommand())
|
||||
|
@ -15,6 +15,7 @@ func newTitleCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runTitle(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBug(env),
|
||||
}
|
||||
|
||||
cmd.AddCommand(newTitleEditCommand())
|
||||
|
@ -24,6 +24,7 @@ func newTitleEditCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runTitleEdit(env, options, args)
|
||||
}),
|
||||
ValidArgsFunction: completeBug(env),
|
||||
}
|
||||
|
||||
flags := cmd.Flags()
|
||||
|
@ -3,6 +3,7 @@ package commands
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@ -24,6 +25,7 @@ func newUserCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runUser(env, options, args)
|
||||
}),
|
||||
ValidArgsFunction: completeUser(env),
|
||||
}
|
||||
|
||||
cmd.AddCommand(newUserAdoptCommand())
|
||||
@ -33,8 +35,10 @@ func newUserCommand() *cobra.Command {
|
||||
flags := cmd.Flags()
|
||||
flags.SortFlags = false
|
||||
|
||||
fields := []string{"email", "humanId", "id", "lastModification", "lastModificationLamports", "login", "metadata", "name"}
|
||||
flags.StringVarP(&options.fields, "field", "f", "",
|
||||
"Select field to display. Valid values are [email,humanId,id,lastModification,lastModificationLamports,login,metadata,name]")
|
||||
"Select field to display. Valid values are ["+strings.Join(fields, ",")+"]")
|
||||
cmd.RegisterFlagCompletionFunc("field", completeFrom(fields))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ func newUserAdoptCommand() *cobra.Command {
|
||||
RunE: closeBackend(env, func(cmd *cobra.Command, args []string) error {
|
||||
return runUserAdopt(env, args)
|
||||
}),
|
||||
ValidArgsFunction: completeUser(env),
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
@ -32,6 +32,7 @@ func newUserLsCommand() *cobra.Command {
|
||||
|
||||
flags.StringVarP(&options.format, "format", "f", "default",
|
||||
"Select the output formatting style. Valid values are [default,json]")
|
||||
cmd.RegisterFlagCompletionFunc("format", completeFrom([]string{"default", "json"}))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -40,25 +40,86 @@ func main() {
|
||||
}
|
||||
|
||||
func genBash(root *cobra.Command) error {
|
||||
cwd, _ := os.Getwd()
|
||||
dir := filepath.Join(cwd, "misc", "bash_completion", "git-bug")
|
||||
return root.GenBashCompletionFile(dir)
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f, err := os.Create(filepath.Join(cwd, "misc", "bash_completion", "git-bug"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
const patch = `
|
||||
_git_bug() {
|
||||
local cur prev words cword split
|
||||
|
||||
COMPREPLY=()
|
||||
|
||||
# Call _init_completion from the bash-completion package
|
||||
# to prepare the arguments properly
|
||||
if declare -F _init_completion >/dev/null 2>&1; then
|
||||
_init_completion -n "=:" || return
|
||||
else
|
||||
__git-bug_init_completion -n "=:" || return
|
||||
fi
|
||||
|
||||
# START PATCH
|
||||
# replace in the array ("git","bug", ...) to ("git-bug", ...) and adjust the index in cword
|
||||
words=("git-bug" "${words[@]:2}")
|
||||
cword=$(($cword-1))
|
||||
# END PATCH
|
||||
|
||||
__git-bug_debug
|
||||
__git-bug_debug "========= starting completion logic =========="
|
||||
__git-bug_debug "cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}, cword is $cword"
|
||||
|
||||
# The user could have moved the cursor backwards on the command-line.
|
||||
# We need to trigger completion from the $cword location, so we need
|
||||
# to truncate the command-line ($words) up to the $cword location.
|
||||
words=("${words[@]:0:$cword+1}")
|
||||
__git-bug_debug "Truncated words[*]: ${words[*]},"
|
||||
|
||||
local out directive
|
||||
__git-bug_get_completion_results
|
||||
__git-bug_process_completion_results
|
||||
}
|
||||
`
|
||||
err = root.GenBashCompletionV2(f, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Custom bash code to connect the git completion for "git bug" to the
|
||||
// git-bug completion for "git-bug"
|
||||
_, err = f.WriteString(patch)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func genFish(root *cobra.Command) error {
|
||||
cwd, _ := os.Getwd()
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dir := filepath.Join(cwd, "misc", "fish_completion", "git-bug")
|
||||
return root.GenFishCompletionFile(dir, true)
|
||||
}
|
||||
|
||||
func genPowerShell(root *cobra.Command) error {
|
||||
cwd, _ := os.Getwd()
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
path := filepath.Join(cwd, "misc", "powershell_completion", "git-bug")
|
||||
return root.GenPowerShellCompletionFile(path)
|
||||
}
|
||||
|
||||
func genZsh(root *cobra.Command) error {
|
||||
cwd, _ := os.Getwd()
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
path := filepath.Join(cwd, "misc", "zsh_completion", "git-bug")
|
||||
return root.GenZshCompletionFile(path)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user