Skip to content
This repository has been archived by the owner on Jul 22, 2024. It is now read-only.

Commit

Permalink
Update to complete v2
Browse files Browse the repository at this point in the history
  • Loading branch information
posener committed Nov 19, 2019
1 parent 3d22a24 commit 5b9cac1
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 53 deletions.
2 changes: 1 addition & 1 deletion autocomplete.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cli

import (
"github.com/posener/complete/cmd/install"
"github.com/posener/complete/v2/install"
)

// autocompleteInstaller is an interface to be implemented to perform the
Expand Down
30 changes: 16 additions & 14 deletions cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (
"text/template"

"github.com/armon/go-radix"
"github.com/posener/complete"
"github.com/posener/complete/v2"
"github.com/posener/complete/v2/predict"
)

// CLI contains the state necessary to run subcommands and parse the
Expand Down Expand Up @@ -106,7 +107,7 @@ type CLI struct {
AutocompleteInstall string
AutocompleteUninstall string
AutocompleteNoDefaultFlags bool
AutocompleteGlobalFlags complete.Flags
AutocompleteGlobalFlags map[string]complete.Predictor
autocompleteInstaller autocompleteInstaller // For tests

// HelpFunc and HelpWriter are used to output help information, if
Expand All @@ -125,7 +126,7 @@ type CLI struct {
// Internal fields set automatically

once sync.Once
autocomplete *complete.Complete
autocomplete complete.Command
commandTree *radix.Tree
commandNested bool
commandHidden map[string]struct{}
Expand Down Expand Up @@ -173,9 +174,10 @@ func (c *CLI) Run() (int, error) {
// If this is a autocompletion request, satisfy it. This must be called
// first before anything else since its possible to be autocompleting
// -help or -version or other flags and we want to show completions
// and not actually write the help or version.
if c.Autocomplete && c.autocomplete.Complete() {
return 0, nil
// and not actually write the help or version. In case of completion
// flow, this function will perform os.Exit.
if c.Autocomplete {
complete.Complete(c.Name, &c.autocomplete)
}

// Just show the version and exit if instructed.
Expand Down Expand Up @@ -402,15 +404,15 @@ func (c *CLI) initAutocomplete() {
// they don't show up on every command.
if !c.AutocompleteNoDefaultFlags {
cmd.Flags = map[string]complete.Predictor{
"-" + c.AutocompleteInstall: complete.PredictNothing,
"-" + c.AutocompleteUninstall: complete.PredictNothing,
"-help": complete.PredictNothing,
"-version": complete.PredictNothing,
"-" + c.AutocompleteInstall: predict.Nothing,
"-" + c.AutocompleteUninstall: predict.Nothing,
"-help": predict.Nothing,
"-version": predict.Nothing,
}
}
cmd.GlobalFlags = c.AutocompleteGlobalFlags
cmd.Flags = c.AutocompleteGlobalFlags

c.autocomplete = complete.New(c.Name, cmd)
c.autocomplete = cmd
}

// initAutocompleteSub creates the complete.Command for a subcommand with
Expand Down Expand Up @@ -451,7 +453,7 @@ func (c *CLI) initAutocompleteSub(prefix string) complete.Command {
}

if cmd.Sub == nil {
cmd.Sub = complete.Commands(make(map[string]complete.Command))
cmd.Sub = make(map[string]*complete.Command)
}
subCmd := c.initAutocompleteSub(fullKey)

Expand All @@ -470,7 +472,7 @@ func (c *CLI) initAutocompleteSub(prefix string) complete.Command {
subCmd.Flags = c.AutocompleteFlags()
}

cmd.Sub[k] = subCmd
cmd.Sub[k] = &subCmd
return false
}

Expand Down
48 changes: 23 additions & 25 deletions cli_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,22 @@ import (
"os"
"reflect"
"sort"
"strconv"
"strings"
"testing"

"github.com/posener/complete"
"github.com/posener/complete/v2"
"github.com/posener/complete/v2/predict"
)

// envComplete is the env var that the complete library sets to specify
// it should be calculating an auto-completion. This isn't exported so we
// reproduce it here. If it changes then we'll have to update this.
const envComplete = "COMP_LINE"
// envComplete and envPoint are the env vars that the complete library sets
// to specify it should be calculating an auto-completion. This isn't
// exported so we reproduce it here. If it changes then we'll have to update
// this.
const (
envComplete = "COMP_LINE"
envPoint = "COMP_POINT"
)

func TestCLIIsHelp(t *testing.T) {
testCases := []struct {
Expand Down Expand Up @@ -1244,7 +1250,7 @@ func TestCLIAutocomplete_rootGlobalFlags(t *testing.T) {

Autocomplete: true,
AutocompleteGlobalFlags: map[string]complete.Predictor{
"-tubes": complete.PredictNothing,
"-tubes": predict.Nothing,
},
}

Expand Down Expand Up @@ -1325,7 +1331,7 @@ func TestCLIAutocomplete_rootDisableDefaultFlags(t *testing.T) {
Autocomplete: true,
AutocompleteNoDefaultFlags: true,
AutocompleteGlobalFlags: map[string]complete.Predictor{
"-tubes": complete.PredictNothing,
"-tubes": predict.Nothing,
},
}
// Setup the autocomplete line
Expand Down Expand Up @@ -1384,20 +1390,19 @@ func TestCLIAutocomplete_rootDisableDefaultFlags(t *testing.T) {

func TestCLIAutocomplete_subcommandArgs(t *testing.T) {
cases := []struct {
Completed []string
Last string
Expected []string
Command string
Expected []string
}{
{[]string{"foo"}, "RE", []string{"README.md"}},
{[]string{"foo", "-go"}, "asdf", []string{"yo"}},
{"foo RE", []string{"README.md"}},
{"foo -go asdf", []string{"yo"}},
}

for _, tc := range cases {
t.Run(tc.Last, func(t *testing.T) {
t.Run(tc.Command, func(t *testing.T) {
command := new(MockCommandAutocomplete)
command.AutocompleteArgsValue = complete.PredictFiles("*")
command.AutocompleteArgsValue = predict.Files("*")
command.AutocompleteFlagsValue = map[string]complete.Predictor{
"-go": complete.PredictFunc(func(complete.Args) []string {
"-go": complete.PredictFunc(func(string) []string {
return []string{"yo"}
}),
}
Expand All @@ -1416,16 +1421,7 @@ func TestCLIAutocomplete_subcommandArgs(t *testing.T) {
cli.init()

// Test the autocompleter
actual := cli.autocomplete.Command.Predict(complete.Args{
Completed: tc.Completed,
Last: tc.Last,
LastCompleted: tc.Completed[len(tc.Completed)-1],
})
sort.Strings(actual)

if !reflect.DeepEqual(actual, tc.Expected) {
t.Fatalf("bad prediction: %#v", actual)
}
complete.Test(t, &cli.autocomplete, tc.Command, tc.Expected)
})
}
}
Expand Down Expand Up @@ -1489,6 +1485,7 @@ func TestCLISubcommand_nested(t *testing.T) {
func testAutocomplete(t *testing.T, input string) func() {
// This env var is used to trigger autocomplete
os.Setenv(envComplete, input)
os.Setenv(envPoint, strconv.Itoa(len(input)))

// Change stdout/stderr since the autocompleter writes directly to them.
oldStdout := os.Stdout
Expand All @@ -1505,6 +1502,7 @@ func testAutocomplete(t *testing.T, input string) func() {
return func() {
// Reset our env
os.Unsetenv(envComplete)
os.Unsetenv(envPoint)

// Reset stdout, stderr
os.Stdout = oldStdout
Expand Down
4 changes: 2 additions & 2 deletions command.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cli

import (
"github.com/posener/complete"
"github.com/posener/complete/v2"
)

const (
Expand Down Expand Up @@ -43,7 +43,7 @@ type CommandAutocomplete interface {
// AutocompleteFlags returns a mapping of supported flags and autocomplete
// options for this command. The map key for the Flags map should be the
// complete flag such as "-foo" or "--foo".
AutocompleteFlags() complete.Flags
AutocompleteFlags() map[string]complete.Predictor
}

// CommandHelpTemplate is an extension of Command that also has a function
Expand Down
6 changes: 3 additions & 3 deletions command_mock.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package cli

import (
"github.com/posener/complete"
"github.com/posener/complete/v2"
)

// MockCommand is an implementation of Command that can be used for tests.
Expand Down Expand Up @@ -39,14 +39,14 @@ type MockCommandAutocomplete struct {

// Settable
AutocompleteArgsValue complete.Predictor
AutocompleteFlagsValue complete.Flags
AutocompleteFlagsValue map[string]complete.Predictor
}

func (c *MockCommandAutocomplete) AutocompleteArgs() complete.Predictor {
return c.AutocompleteArgsValue
}

func (c *MockCommandAutocomplete) AutocompleteFlags() complete.Flags {
func (c *MockCommandAutocomplete) AutocompleteFlags() map[string]complete.Predictor {
return c.AutocompleteFlagsValue
}

Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ require (
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310
github.com/bgentry/speakeasy v0.1.0
github.com/fatih/color v1.7.0
github.com/hashicorp/go-multierror v1.0.0 // indirect
github.com/mattn/go-colorable v0.0.9 // indirect
github.com/mattn/go-isatty v0.0.3
github.com/posener/complete v1.1.1
github.com/posener/complete/v2 v2.0.1-alpha.2
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc // indirect
)

go 1.13
19 changes: 13 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,28 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310 h1:BUAU3CGlLvorLI26
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357 h1:Rem2+U35z1QtPQc6r+WolF7yXiefXqDKyk+lN2pE164=
github.com/hashicorp/errwrap v0.0.0-20180715044906-d6c0cd880357/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0 h1:j30noezaCfvNLcdMYSvHLv81DxYRSt1grlpseG67vhU=
github.com/hashicorp/go-multierror v0.0.0-20180717150148-3d5d8f294aa0/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3 h1:ns/ykhmWi7G9O+8a448SecJU3nSMBXJfqQkl0upE1jI=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete/v2 v2.0.1-alpha.2 h1:y/9Kv6uzksN+fxY+qVBsJpRdyDNG+rEvJ2kiPQ73XVI=
github.com/posener/complete/v2 v2.0.1-alpha.2/go.mod h1:Q5Am7Oqn7AYZ/ZeyLMtB/4R3DYQi4atyOdgD8kP1mQw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc h1:MeuS1UDyZyFH++6vVy44PuufTeFF0d0nfI6XB87YGSk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

0 comments on commit 5b9cac1

Please sign in to comment.