From 270ab974189e9ae5a7f8e5e9ce6fc6a605af9aec Mon Sep 17 00:00:00 2001 From: James Bardin Date: Wed, 31 Mar 2021 13:24:43 -0400 Subject: [PATCH] don't error when processing autocomplete commands The shell autocomplete command will use the binary name as the first argument which does not show up under the list of subcommands. --- main.go | 7 ++++++- main_test.go | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 12b13d169..68726a0fd 100644 --- a/main.go +++ b/main.go @@ -357,7 +357,12 @@ func wrappedMain() int { // where a command isn't found, because it's likely more helpful to // mention what specifically went wrong, rather than just printing out // a big block of usage information.) - if cmd := cliRunner.Subcommand(); cmd != "" { + + // Check if this is being run via shell auto-complete, which uses the + // binary name as the first argument and won't be listed as a subcommand. + autoComplete := os.Getenv("COMP_LINE") != "" + + if cmd := cliRunner.Subcommand(); cmd != "" && !autoComplete { // Due to the design of cli.CLI, this special error message only works // for typos of top-level commands. For a subcommand typo, like // "terraform state posh", cmd would be "state" here and thus would diff --git a/main_test.go b/main_test.go index 321ce039f..102ea44bb 100644 --- a/main_test.go +++ b/main_test.go @@ -253,6 +253,34 @@ func TestMain_cliArgsFromEnvAdvanced(t *testing.T) { } } +// verify that we output valid autocomplete results +func TestMain_autoComplete(t *testing.T) { + // Restore original CLI args + oldArgs := os.Args + defer func() { os.Args = oldArgs }() + + // Set up test command and restore that + Commands = make(map[string]cli.CommandFactory) + defer func() { + Commands = nil + }() + + // Set up test command and restore that + Commands["foo"] = func() (cli.Command, error) { + return &testCommandCLI{}, nil + } + + os.Setenv("COMP_LINE", "terraform versio") + defer os.Unsetenv("COMP_LINE") + + // Run it! + os.Args = []string{"terraform", "terraform", "versio"} + exit := wrappedMain() + if exit != 0 { + t.Fatalf("unexpected exit status %d; want 0", exit) + } +} + type testCommandCLI struct { Args []string }