From 958293bbfa898ca4b72fb56497011bc6db9e10b4 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Sun, 26 Feb 2023 15:46:31 -0500 Subject: [PATCH 1/3] Add a Run func to `vtctldclient`'s Root command to return an error on unknown command Closes #12480. Signed-off-by: Andrew Mason --- go/cmd/vtctldclient/command/root.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/go/cmd/vtctldclient/command/root.go b/go/cmd/vtctldclient/command/root.go index 0e8c850b6d2..ae74ddfb5e6 100644 --- a/go/cmd/vtctldclient/command/root.go +++ b/go/cmd/vtctldclient/command/root.go @@ -19,6 +19,7 @@ package command import ( "context" "errors" + "fmt" "io" "strconv" "time" @@ -78,6 +79,26 @@ var ( // propagated). SilenceErrors: true, Version: servenv.AppVersion.String(), + // If we've reached this function, it means that: + // + // (1) The user specified some positional arguments, which, for the way + // we've structured things can only be a subcommand name, **and** + // + // (2) Cobra was unable to find a subcommand with that name for which to + // call a Run or RunE function. + // + // From this we conclude that the user was trying to either run a + // command that doesn't exist (e.g. "vtctldclient delete-my-data") or + // has misspelled a legitimate command (e.g. "vtctldclient StapReplication"). + // If we think this has happened, return an error, which will get + // displayed to the user in main.go along with the usage. + RunE: func(cmd *cobra.Command, args []string) error { + if cmd.Flags().NArg() > 0 { + return fmt.Errorf("unknown command: %s", cmd.Flags().Arg(0)) + } + + return nil + }, } ) From eb2bf269c9989dad59f5991311081b5ba4b5ae47 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Mon, 27 Feb 2023 06:42:36 -0500 Subject: [PATCH 2/3] Add test Signed-off-by: Andrew Mason --- go/cmd/vtctldclient/command/root_test.go | 54 ++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 go/cmd/vtctldclient/command/root_test.go diff --git a/go/cmd/vtctldclient/command/root_test.go b/go/cmd/vtctldclient/command/root_test.go new file mode 100644 index 00000000000..155fac78705 --- /dev/null +++ b/go/cmd/vtctldclient/command/root_test.go @@ -0,0 +1,54 @@ +/* +Copyright 2023 The Vitess Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package command_test + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "vitess.io/vitess/go/cmd/vtctldclient/command" + "vitess.io/vitess/go/vt/vtctl/localvtctldclient" + + vtctlservicepb "vitess.io/vitess/go/vt/proto/vtctlservice" +) + +type emptyLocalServer struct { + vtctlservicepb.UnimplementedVtctldServer +} + +func TestRoot(t *testing.T) { + t.Run("error on unknown subcommand", func(t *testing.T) { + args := append([]string{}, os.Args...) + protocol := command.VtctldClientProtocol + localvtctldclient.SetServer(&emptyLocalServer{}) + + t.Cleanup(func() { + os.Args = append([]string{}, args...) + command.VtctldClientProtocol = protocol + }) + + os.Args = []string{"vtctldclient", "this-is-bunk"} + command.VtctldClientProtocol = "local" + + err := command.Root.Execute() + require.Error(t, err, "root command should error on unknown command") + assert.Contains(t, err.Error(), "unknown command") + }) +} From 5eb96b803f0b62195ce2044e9622b5a938b90685 Mon Sep 17 00:00:00 2001 From: Andrew Mason Date: Tue, 28 Feb 2023 06:12:06 -0500 Subject: [PATCH 3/3] flags test data Signed-off-by: Andrew Mason --- go/flags/endtoend/vtctldclient.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/go/flags/endtoend/vtctldclient.txt b/go/flags/endtoend/vtctldclient.txt index c6e48e610d6..41c0b64076f 100644 --- a/go/flags/endtoend/vtctldclient.txt +++ b/go/flags/endtoend/vtctldclient.txt @@ -1,6 +1,7 @@ Executes a cluster management command on the remote vtctld server. Usage: + vtctldclient [flags] vtctldclient [command] Available Commands: