mirror of
https://github.com/docker/compose.git
synced 2025-04-08 17:05:13 +02:00
Merge pull request #741 from gtardif/fix_cli_metrics
Simplify metrics gathering, separate running commands from getting help
This commit is contained in:
commit
cda66b5e90
22
cli/main.go
22
cli/main.go
@ -198,37 +198,37 @@ func main() {
|
||||
if err = root.ExecuteContext(ctx); err != nil {
|
||||
// if user canceled request, simply exit without any error message
|
||||
if errdefs.IsErrCanceled(err) || errors.Is(ctx.Err(), context.Canceled) {
|
||||
metrics.Track(ctype, os.Args[1:], root.PersistentFlags(), metrics.CanceledStatus)
|
||||
metrics.Track(ctype, os.Args[1:], metrics.CanceledStatus)
|
||||
os.Exit(130)
|
||||
}
|
||||
if ctype == store.AwsContextType {
|
||||
exit(root, currentContext, errors.Errorf(`%q context type has been renamed. Recreate the context by running:
|
||||
exit(currentContext, errors.Errorf(`%q context type has been renamed. Recreate the context by running:
|
||||
$ docker context create %s <name>`, cc.Type(), store.EcsContextType), ctype)
|
||||
}
|
||||
|
||||
// Context should always be handled by new CLI
|
||||
requiredCmd, _, _ := root.Find(os.Args[1:])
|
||||
if requiredCmd != nil && isContextAgnosticCommand(requiredCmd) {
|
||||
exit(root, currentContext, err, ctype)
|
||||
exit(currentContext, err, ctype)
|
||||
}
|
||||
mobycli.ExecIfDefaultCtxType(ctx, root)
|
||||
|
||||
checkIfUnknownCommandExistInDefaultContext(err, currentContext, root, ctype)
|
||||
checkIfUnknownCommandExistInDefaultContext(err, currentContext, ctype)
|
||||
|
||||
exit(root, currentContext, err, ctype)
|
||||
exit(currentContext, err, ctype)
|
||||
}
|
||||
metrics.Track(ctype, os.Args[1:], root.PersistentFlags(), metrics.SuccessStatus)
|
||||
metrics.Track(ctype, os.Args[1:], metrics.SuccessStatus)
|
||||
}
|
||||
|
||||
func exit(root *cobra.Command, ctx string, err error, ctype string) {
|
||||
metrics.Track(ctype, os.Args[1:], root.PersistentFlags(), metrics.FailureStatus)
|
||||
func exit(ctx string, err error, ctype string) {
|
||||
metrics.Track(ctype, os.Args[1:], metrics.FailureStatus)
|
||||
|
||||
if errors.Is(err, errdefs.ErrLoginRequired) {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(errdefs.ExitCodeLoginRequired)
|
||||
}
|
||||
if errors.Is(err, errdefs.ErrNotImplemented) {
|
||||
name := metrics.GetCommand(os.Args[1:], root.PersistentFlags())
|
||||
name := metrics.GetCommand(os.Args[1:])
|
||||
fmt.Fprintf(os.Stderr, "Command %q not available in current context (%s)\n", name, ctx)
|
||||
|
||||
os.Exit(1)
|
||||
@ -242,14 +242,14 @@ func fatal(err error) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func checkIfUnknownCommandExistInDefaultContext(err error, currentContext string, root *cobra.Command, contextType string) {
|
||||
func checkIfUnknownCommandExistInDefaultContext(err error, currentContext string, contextType string) {
|
||||
submatch := unknownCommandRegexp.FindSubmatch([]byte(err.Error()))
|
||||
if len(submatch) == 2 {
|
||||
dockerCommand := string(submatch[1])
|
||||
|
||||
if mobycli.IsDefaultContextCommand(dockerCommand) {
|
||||
fmt.Fprintf(os.Stderr, "Command %q not available in current context (%s), you can use the \"default\" context to run this command\n", dockerCommand, currentContext)
|
||||
metrics.Track(contextType, os.Args[1:], root.PersistentFlags(), metrics.FailureStatus)
|
||||
metrics.Track(contextType, os.Args[1:], metrics.FailureStatus)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ func Exec(root *cobra.Command) {
|
||||
err := cmd.Run()
|
||||
childExit <- true
|
||||
if err != nil {
|
||||
metrics.Track(store.DefaultContextType, os.Args[1:], root.PersistentFlags(), metrics.FailureStatus)
|
||||
metrics.Track(store.DefaultContextType, os.Args[1:], metrics.FailureStatus)
|
||||
|
||||
if exiterr, ok := err.(*exec.ExitError); ok {
|
||||
os.Exit(exiterr.ExitCode())
|
||||
@ -94,7 +94,7 @@ func Exec(root *cobra.Command) {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
metrics.Track(store.DefaultContextType, os.Args[1:], root.PersistentFlags(), metrics.SuccessStatus)
|
||||
metrics.Track(store.DefaultContextType, os.Args[1:], metrics.SuccessStatus)
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
|
147
metrics/commands.go
Normal file
147
metrics/commands.go
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
Copyright 2020 Docker Compose CLI 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 metrics
|
||||
|
||||
var commandFlags = []string{
|
||||
//added to catch scan details
|
||||
"--version", "--login",
|
||||
}
|
||||
|
||||
// Generated with generatecommands/main.go
|
||||
var managementCommands = []string{
|
||||
"ecs",
|
||||
"scan",
|
||||
"app",
|
||||
"builder",
|
||||
"imagetools",
|
||||
"buildx",
|
||||
"checkpoint",
|
||||
"config",
|
||||
"container",
|
||||
"context",
|
||||
"create",
|
||||
"image",
|
||||
"manifest",
|
||||
"network",
|
||||
"node",
|
||||
"plugin",
|
||||
"secret",
|
||||
"service",
|
||||
"stack",
|
||||
"swarm",
|
||||
"system",
|
||||
"key",
|
||||
"signer",
|
||||
"trust",
|
||||
"volume",
|
||||
"login",
|
||||
"logout",
|
||||
"compose",
|
||||
}
|
||||
|
||||
var commands = []string{
|
||||
"bundle",
|
||||
"completion",
|
||||
"init",
|
||||
"inspect",
|
||||
"install",
|
||||
"deploy",
|
||||
"list",
|
||||
"ls",
|
||||
"merge",
|
||||
"pull",
|
||||
"push",
|
||||
"render",
|
||||
"split",
|
||||
"status",
|
||||
"uninstall",
|
||||
"upgrade",
|
||||
"validate",
|
||||
"version",
|
||||
"build",
|
||||
"prune",
|
||||
"create",
|
||||
"bake",
|
||||
"f",
|
||||
"b",
|
||||
"du",
|
||||
"rm",
|
||||
"stop",
|
||||
"use",
|
||||
"remove",
|
||||
"attach",
|
||||
"commit",
|
||||
"cp",
|
||||
"diff",
|
||||
"exec",
|
||||
"export",
|
||||
"kill",
|
||||
"logs",
|
||||
"ps",
|
||||
"pause",
|
||||
"port",
|
||||
"rename",
|
||||
"restart",
|
||||
"run",
|
||||
"start",
|
||||
"stats",
|
||||
"top",
|
||||
"unpause",
|
||||
"update",
|
||||
"wait",
|
||||
"aci",
|
||||
"ecs",
|
||||
"show",
|
||||
"history",
|
||||
"import",
|
||||
"load",
|
||||
"images",
|
||||
"rmi",
|
||||
"save",
|
||||
"tag",
|
||||
"annotate",
|
||||
"connect",
|
||||
"disconnect",
|
||||
"demote",
|
||||
"promote",
|
||||
"disable",
|
||||
"enable",
|
||||
"set",
|
||||
"rollback",
|
||||
"scale",
|
||||
"up",
|
||||
"down",
|
||||
"services",
|
||||
"ca",
|
||||
"join",
|
||||
"join-token",
|
||||
"leave",
|
||||
"unlock",
|
||||
"unlock-key",
|
||||
"df",
|
||||
"events",
|
||||
"info",
|
||||
"generate",
|
||||
"add",
|
||||
"revoke",
|
||||
"sign",
|
||||
"login",
|
||||
"azure",
|
||||
"logout",
|
||||
"search",
|
||||
"convert",
|
||||
}
|
106
metrics/generatecommands/main.go
Normal file
106
metrics/generatecommands/main.go
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
Copyright 2020 Docker Compose CLI 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 main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/compose-cli/utils"
|
||||
)
|
||||
|
||||
var managementCommands = []string{"ecs", "scan"}
|
||||
|
||||
var commands = []string{}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Walking through docker help to list commands...")
|
||||
getCommands()
|
||||
getCommands("compose")
|
||||
|
||||
fmt.Printf(`
|
||||
var managementCommands = []string{
|
||||
"%s",
|
||||
}
|
||||
|
||||
var commands = []string{
|
||||
"%s",
|
||||
}
|
||||
`, strings.Join(managementCommands, "\", \n\t\""), strings.Join(commands, "\", \n\t\""))
|
||||
}
|
||||
|
||||
const (
|
||||
mgtCommandsSection = "Management Commands:"
|
||||
commandsSection = "Commands:"
|
||||
aliasesSection = "Aliases:"
|
||||
)
|
||||
|
||||
func getCommands(execCommands ...string) {
|
||||
withHelp := append(execCommands, "--help")
|
||||
cmd := exec.Command("docker", withHelp...)
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
text := string(output)
|
||||
lines := strings.Split(text, "\n")
|
||||
section := ""
|
||||
for _, line := range lines {
|
||||
trimmedLine := strings.TrimSpace(line)
|
||||
if strings.HasPrefix(trimmedLine, mgtCommandsSection) {
|
||||
section = mgtCommandsSection
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(trimmedLine, commandsSection) || strings.HasPrefix(trimmedLine, "Available Commands:") {
|
||||
section = commandsSection
|
||||
if len(execCommands) > 0 {
|
||||
command := execCommands[len(execCommands)-1]
|
||||
managementCommands = append(managementCommands, command)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(trimmedLine, aliasesSection) {
|
||||
section = aliasesSection
|
||||
continue
|
||||
}
|
||||
if trimmedLine == "" {
|
||||
section = ""
|
||||
continue
|
||||
}
|
||||
|
||||
tokens := strings.Split(trimmedLine, " ")
|
||||
command := strings.Replace(tokens[0], "*", "", 1)
|
||||
switch section {
|
||||
case mgtCommandsSection:
|
||||
getCommands(append(execCommands, command)...)
|
||||
case commandsSection:
|
||||
if !utils.StringContains(commands, command) {
|
||||
commands = append(commands, command)
|
||||
}
|
||||
getCommands(append(execCommands, command)...)
|
||||
case aliasesSection:
|
||||
aliases := strings.Split(trimmedLine, ",")
|
||||
for _, alias := range aliases {
|
||||
trimmedAlias := strings.TrimSpace(alias)
|
||||
if !utils.StringContains(commands, trimmedAlias) {
|
||||
commands = append(commands, trimmedAlias)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -17,68 +17,12 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
|
||||
"github.com/docker/compose-cli/utils"
|
||||
)
|
||||
|
||||
var managementCommands = []string{
|
||||
"app",
|
||||
"assemble",
|
||||
"builder",
|
||||
"buildx",
|
||||
"ecs",
|
||||
"ecs compose",
|
||||
"cluster",
|
||||
"compose",
|
||||
"config",
|
||||
"container",
|
||||
"context",
|
||||
// We add "context create" as a management command to be able to catch
|
||||
// calls to "context create aci"
|
||||
"context create",
|
||||
"help",
|
||||
"image",
|
||||
// Adding "login" as a management command so that the system can catch
|
||||
// commands like `docker login azure`
|
||||
"login",
|
||||
"manifest",
|
||||
"network",
|
||||
"node",
|
||||
"plugin",
|
||||
"registry",
|
||||
"secret",
|
||||
"service",
|
||||
"stack",
|
||||
"swarm",
|
||||
"system",
|
||||
"template",
|
||||
"trust",
|
||||
"volume",
|
||||
}
|
||||
|
||||
// managementSubCommands holds a list of allowed subcommands of a management
|
||||
// command. For example we want to send an event for "docker login azure" but
|
||||
// we don't wat to send the name of the registry when the user does a
|
||||
// "docker login my-registry", we only want to send "login"
|
||||
var managementSubCommands = map[string][]string{
|
||||
"login": {
|
||||
"azure",
|
||||
},
|
||||
"context create": {
|
||||
"aci",
|
||||
},
|
||||
}
|
||||
|
||||
const (
|
||||
scanCommand = "scan"
|
||||
)
|
||||
|
||||
// Track sends the tracking analytics to Docker Desktop
|
||||
func Track(context string, args []string, flags *flag.FlagSet, status string) {
|
||||
command := GetCommand(args, flags)
|
||||
func Track(context string, args []string, status string) {
|
||||
command := GetCommand(args)
|
||||
if command != "" {
|
||||
c := NewClient()
|
||||
c.Send(Command{
|
||||
@ -90,115 +34,39 @@ func Track(context string, args []string, flags *flag.FlagSet, status string) {
|
||||
}
|
||||
}
|
||||
|
||||
func isCommand(word string) bool {
|
||||
return utils.StringContains(commands, word) || isManagementCommand(word)
|
||||
}
|
||||
|
||||
func isManagementCommand(word string) bool {
|
||||
return utils.StringContains(managementCommands, word)
|
||||
}
|
||||
|
||||
func isCommandFlag(word string) bool {
|
||||
return utils.StringContains(commandFlags, word)
|
||||
}
|
||||
|
||||
// GetCommand get the invoked command
|
||||
func GetCommand(args []string, flags *flag.FlagSet) string {
|
||||
command := ""
|
||||
strippedArgs := stripFlags(args, flags)
|
||||
|
||||
if len(strippedArgs) != 0 {
|
||||
command = strippedArgs[0]
|
||||
|
||||
if command == scanCommand {
|
||||
return getScanCommand(args)
|
||||
func GetCommand(args []string) string {
|
||||
result := ""
|
||||
onlyFlags := false
|
||||
for _, arg := range args {
|
||||
if arg == "--help" {
|
||||
return ""
|
||||
}
|
||||
|
||||
for {
|
||||
if utils.StringContains(managementCommands, command) {
|
||||
if sub := getSubCommand(command, strippedArgs[1:]); sub != "" {
|
||||
command += " " + sub
|
||||
strippedArgs = strippedArgs[1:]
|
||||
continue
|
||||
}
|
||||
}
|
||||
if arg == "--" {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return command
|
||||
}
|
||||
|
||||
func getScanCommand(args []string) string {
|
||||
command := args[0]
|
||||
|
||||
if utils.StringContains(args, "--auth") {
|
||||
return command + " auth"
|
||||
}
|
||||
|
||||
if utils.StringContains(args, "--version") {
|
||||
return command + " version"
|
||||
}
|
||||
|
||||
return command
|
||||
}
|
||||
|
||||
func getSubCommand(command string, args []string) string {
|
||||
if len(args) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
if val, ok := managementSubCommands[command]; ok {
|
||||
if utils.StringContains(val, args[0]) {
|
||||
return args[0]
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
if isArg(args[0]) {
|
||||
return args[0]
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func stripFlags(args []string, flags *flag.FlagSet) []string {
|
||||
commands := []string{}
|
||||
|
||||
for len(args) > 0 {
|
||||
s := args[0]
|
||||
args = args[1:]
|
||||
|
||||
if s == "--" {
|
||||
return commands
|
||||
}
|
||||
|
||||
if flagArg(s, flags) {
|
||||
if len(args) <= 1 {
|
||||
return commands
|
||||
if isCommandFlag(arg) || (!onlyFlags && isCommand(arg)) {
|
||||
if result == "" {
|
||||
result = arg
|
||||
} else {
|
||||
result = result + " " + arg
|
||||
}
|
||||
if !isManagementCommand(arg) {
|
||||
onlyFlags = true
|
||||
}
|
||||
args = args[1:]
|
||||
}
|
||||
|
||||
if isArg(s) {
|
||||
commands = append(commands, s)
|
||||
}
|
||||
}
|
||||
|
||||
return commands
|
||||
}
|
||||
|
||||
func flagArg(s string, flags *flag.FlagSet) bool {
|
||||
return strings.HasPrefix(s, "--") && !strings.Contains(s, "=") && !hasNoOptDefVal(s[2:], flags) ||
|
||||
strings.HasPrefix(s, "-") && !strings.Contains(s, "=") && len(s) == 2 && !shortHasNoOptDefVal(s[1:], flags)
|
||||
}
|
||||
|
||||
func isArg(s string) bool {
|
||||
return s != "" && !strings.HasPrefix(s, "-")
|
||||
}
|
||||
|
||||
func hasNoOptDefVal(name string, fs *flag.FlagSet) bool {
|
||||
flag := fs.Lookup(name)
|
||||
if flag == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return flag.NoOptDefVal != ""
|
||||
}
|
||||
|
||||
func shortHasNoOptDefVal(name string, fs *flag.FlagSet) bool {
|
||||
flag := fs.ShorthandLookup(name[:1])
|
||||
if flag == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return flag.NoOptDefVal != ""
|
||||
return result
|
||||
}
|
||||
|
@ -19,15 +19,10 @@ package metrics
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
func TestFlag(t *testing.T) {
|
||||
root := &cobra.Command{}
|
||||
root.PersistentFlags().BoolP("debug", "D", false, "debug")
|
||||
root.PersistentFlags().String("str", "str", "str")
|
||||
|
||||
func TestGetCommand(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
@ -58,16 +53,6 @@ func TestFlag(t *testing.T) {
|
||||
args: []string{"--debug", "--str", "str-value"},
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "with unknown short flag",
|
||||
args: []string{"-f", "run"},
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "with unknown long flag",
|
||||
args: []string{"--unknown-flag", "run"},
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "management command",
|
||||
args: []string{"image", "ls"},
|
||||
@ -76,7 +61,7 @@ func TestFlag(t *testing.T) {
|
||||
{
|
||||
name: "management command with flag",
|
||||
args: []string{"image", "--test", "ls"},
|
||||
expected: "image",
|
||||
expected: "image ls",
|
||||
},
|
||||
{
|
||||
name: "management subcommand with flag",
|
||||
@ -88,26 +73,36 @@ func TestFlag(t *testing.T) {
|
||||
args: []string{"login", "azure"},
|
||||
expected: "login azure",
|
||||
},
|
||||
{
|
||||
name: "azure logout",
|
||||
args: []string{"logout", "azure"},
|
||||
expected: "logout azure",
|
||||
},
|
||||
{
|
||||
name: "azure login with flags",
|
||||
args: []string{"login", "-u", "test", "azure"},
|
||||
expected: "login azure",
|
||||
},
|
||||
{
|
||||
name: "azure login with azure user",
|
||||
args: []string{"login", "-u", "azure"},
|
||||
name: "login to a registry",
|
||||
args: []string{"login", "myregistry"},
|
||||
expected: "login",
|
||||
},
|
||||
{
|
||||
name: "login to a registry",
|
||||
args: []string{"login", "registry"},
|
||||
expected: "login",
|
||||
name: "logout from a registry",
|
||||
args: []string{"logout", "myregistry"},
|
||||
expected: "logout",
|
||||
},
|
||||
{
|
||||
name: "context create aci",
|
||||
args: []string{"context", "create", "aci"},
|
||||
expected: "context create aci",
|
||||
},
|
||||
{
|
||||
name: "context create ecs",
|
||||
args: []string{"context", "create", "ecs"},
|
||||
expected: "context create ecs",
|
||||
},
|
||||
{
|
||||
name: "create a context from another context",
|
||||
args: []string{"context", "create", "test-context", "--from=default"},
|
||||
@ -119,9 +114,9 @@ func TestFlag(t *testing.T) {
|
||||
expected: "create",
|
||||
},
|
||||
{
|
||||
name: "create a container named aci",
|
||||
args: []string{"create", "aci"},
|
||||
expected: "create",
|
||||
name: "start a container named aci",
|
||||
args: []string{"start", "aci"},
|
||||
expected: "start",
|
||||
},
|
||||
{
|
||||
name: "create a container named test-container",
|
||||
@ -152,15 +147,44 @@ func TestFlag(t *testing.T) {
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
result := GetCommand(testCase.args, root.PersistentFlags())
|
||||
result := GetCommand(testCase.args)
|
||||
assert.Equal(t, testCase.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIgnoreHelpCommands(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "help",
|
||||
args: []string{"--help"},
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "help on run",
|
||||
args: []string{"run", "--help"},
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "help on compose up",
|
||||
args: []string{"compose", "up", "--help"},
|
||||
expected: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
result := GetCommand(testCase.args)
|
||||
assert.Equal(t, testCase.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEcs(t *testing.T) {
|
||||
root := &cobra.Command{}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
@ -217,23 +241,21 @@ func TestEcs(t *testing.T) {
|
||||
expected: "ecs compose logs",
|
||||
},
|
||||
{
|
||||
name: "setup",
|
||||
args: []string{"ecs", "setup"},
|
||||
expected: "ecs setup",
|
||||
name: "ecs",
|
||||
args: []string{"ecs", "anything"},
|
||||
expected: "ecs",
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
result := GetCommand(testCase.args, root.PersistentFlags())
|
||||
result := GetCommand(testCase.args)
|
||||
assert.Equal(t, testCase.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestScan(t *testing.T) {
|
||||
root := &cobra.Command{}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
args []string
|
||||
@ -246,34 +268,34 @@ func TestScan(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "scan image with long flags",
|
||||
args: []string{"scan", "--file", "file", "image"},
|
||||
args: []string{"scan", "--file", "file", "myimage"},
|
||||
expected: "scan",
|
||||
},
|
||||
{
|
||||
name: "scan image with short flags",
|
||||
args: []string{"scan", "-f", "file", "image"},
|
||||
args: []string{"scan", "-f", "file", "myimage"},
|
||||
expected: "scan",
|
||||
},
|
||||
{
|
||||
name: "scan with long flag",
|
||||
args: []string{"scan", "--dependency-tree", "image"},
|
||||
args: []string{"scan", "--dependency-tree", "myimage"},
|
||||
expected: "scan",
|
||||
},
|
||||
{
|
||||
name: "auth",
|
||||
args: []string{"scan", "--auth"},
|
||||
expected: "scan auth",
|
||||
args: []string{"scan", "--login"},
|
||||
expected: "scan --login",
|
||||
},
|
||||
{
|
||||
name: "version",
|
||||
args: []string{"scan", "--version"},
|
||||
expected: "scan version",
|
||||
expected: "scan --version",
|
||||
},
|
||||
}
|
||||
|
||||
for _, testCase := range testCases {
|
||||
t.Run(testCase.name, func(t *testing.T) {
|
||||
result := GetCommand(testCase.args, root.PersistentFlags())
|
||||
result := GetCommand(testCase.args)
|
||||
assert.Equal(t, testCase.expected, result)
|
||||
})
|
||||
}
|
||||
|
@ -164,6 +164,17 @@ func TestContextMetrics(t *testing.T) {
|
||||
s.Start()
|
||||
defer s.Stop()
|
||||
|
||||
t.Run("do not send metrics on help commands", func(t *testing.T) {
|
||||
s.ResetUsage()
|
||||
|
||||
c.RunDockerCmd("--help")
|
||||
c.RunDockerCmd("ps", "--help")
|
||||
c.RunDockerCmd("run", "--help")
|
||||
|
||||
usage := s.GetUsage()
|
||||
assert.Equal(t, 0, len(usage))
|
||||
})
|
||||
|
||||
t.Run("metrics on default context", func(t *testing.T) {
|
||||
s.ResetUsage()
|
||||
|
||||
@ -185,7 +196,7 @@ func TestContextMetrics(t *testing.T) {
|
||||
c.RunDockerCmd("ps")
|
||||
c.RunDockerCmd("context", "use", "test-example")
|
||||
c.RunDockerCmd("ps")
|
||||
c.RunDockerOrExitError("error")
|
||||
c.RunDockerOrExitError("stop", "unknown")
|
||||
c.RunDockerCmd("context", "use", "default")
|
||||
c.RunDockerCmd("--context", "test-example", "ps")
|
||||
|
||||
@ -195,7 +206,7 @@ func TestContextMetrics(t *testing.T) {
|
||||
assert.Equal(t, `{"command":"ps","context":"moby","source":"cli","status":"success"}`, usage[1])
|
||||
assert.Equal(t, `{"command":"context use","context":"moby","source":"cli","status":"success"}`, usage[2])
|
||||
assert.Equal(t, `{"command":"ps","context":"example","source":"cli","status":"success"}`, usage[3])
|
||||
assert.Equal(t, `{"command":"error","context":"example","source":"cli","status":"failure"}`, usage[4])
|
||||
assert.Equal(t, `{"command":"stop","context":"example","source":"cli","status":"failure"}`, usage[4])
|
||||
assert.Equal(t, `{"command":"context use","context":"example","source":"cli","status":"success"}`, usage[5])
|
||||
assert.Equal(t, `{"command":"ps","context":"example","source":"cli","status":"success"}`, usage[6])
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user