From ae5c58505087508311eb6907ea7619f1a1956788 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sat, 29 Aug 2020 12:46:55 -0700 Subject: [PATCH 1/5] Revert "Add config file support" This reverts commit e1dc3451bcecac8c67e4342aea44955a82bfa932. Signed-off-by: Darren Shepherd --- cmd/agent/main.go | 4 +- cmd/k3s/main.go | 7 +- cmd/server/main.go | 4 +- go.mod | 1 - go.sum | 13 +- main.go | 4 +- pkg/cli/agent/agent.go | 7 +- pkg/cli/cmds/agent.go | 125 ++-- pkg/cli/cmds/check-config.go | 7 +- pkg/cli/cmds/config.go | 16 - pkg/cli/cmds/crictl.go | 7 +- pkg/cli/cmds/ctr.go | 7 +- pkg/cli/cmds/debug.go | 31 - pkg/cli/cmds/kubectl.go | 7 +- pkg/cli/cmds/log.go | 39 +- pkg/cli/cmds/root.go | 24 +- pkg/cli/cmds/server.go | 228 +++--- pkg/cli/crictl/crictl.go | 2 +- pkg/cli/ctr/ctr.go | 2 +- pkg/cli/kubectl/kubectl.go | 2 +- pkg/cli/server/server.go | 7 +- vendor/github.com/rancher/spur/LICENSE | 201 ------ vendor/github.com/rancher/spur/cli/.flake8 | 2 - vendor/github.com/rancher/spur/cli/.gitignore | 7 - vendor/github.com/rancher/spur/cli/LICENSE | 21 - .../rancher/spur/cli/_flag.template.go | 40 -- .../spur/cli/altsrc/conf_file_loader.go | 23 - .../spur/cli/altsrc/map_input_source.go | 49 -- .../spur/cli/altsrc/yaml_file_loader.go | 56 -- vendor/github.com/rancher/spur/cli/app.go | 540 -------------- vendor/github.com/rancher/spur/cli/args.go | 54 -- .../github.com/rancher/spur/cli/category.go | 79 --- vendor/github.com/rancher/spur/cli/command.go | 301 -------- vendor/github.com/rancher/spur/cli/context.go | 275 -------- vendor/github.com/rancher/spur/cli/docs.go | 160 ----- vendor/github.com/rancher/spur/cli/errors.go | 141 ---- vendor/github.com/rancher/spur/cli/fish.go | 178 ----- vendor/github.com/rancher/spur/cli/flag.go | 318 --------- .../spur/cli/flag.zz_generated_bool.go | 40 -- .../spur/cli/flag.zz_generated_boolSlice.go | 40 -- .../spur/cli/flag.zz_generated_duration.go | 40 -- .../cli/flag.zz_generated_durationSlice.go | 40 -- .../spur/cli/flag.zz_generated_float64.go | 40 -- .../cli/flag.zz_generated_float64Slice.go | 40 -- .../rancher/spur/cli/flag.zz_generated_int.go | 40 -- .../spur/cli/flag.zz_generated_int64.go | 40 -- .../spur/cli/flag.zz_generated_int64Slice.go | 40 -- .../spur/cli/flag.zz_generated_intSlice.go | 40 -- .../spur/cli/flag.zz_generated_string.go | 40 -- .../spur/cli/flag.zz_generated_stringSlice.go | 40 -- .../spur/cli/flag.zz_generated_time.go | 40 -- .../spur/cli/flag.zz_generated_timeSlice.go | 40 -- .../spur/cli/flag.zz_generated_uint.go | 40 -- .../spur/cli/flag.zz_generated_uint64.go | 40 -- .../spur/cli/flag.zz_generated_uint64Slice.go | 40 -- .../spur/cli/flag.zz_generated_uintSlice.go | 40 -- .../github.com/rancher/spur/cli/flag_apply.go | 105 --- .../rancher/spur/cli/flag_fields.go | 92 --- .../rancher/spur/cli/flag_generic.go | 36 - vendor/github.com/rancher/spur/cli/funcs.go | 44 -- vendor/github.com/rancher/spur/cli/help.go | 378 ---------- .../rancher/spur/cli/input_source.go | 79 --- vendor/github.com/rancher/spur/cli/parse.go | 95 --- vendor/github.com/rancher/spur/cli/sort.go | 29 - .../github.com/rancher/spur/cli/template.go | 120 ---- vendor/github.com/rancher/spur/flag/LICENSE | 27 - .../rancher/spur/flag/_flag.template.go | 35 - vendor/github.com/rancher/spur/flag/flag.go | 661 ------------------ .../spur/flag/flag.zz_generated_bool.go | 35 - .../spur/flag/flag.zz_generated_boolSlice.go | 35 - .../spur/flag/flag.zz_generated_duration.go | 35 - .../flag/flag.zz_generated_durationSlice.go | 35 - .../spur/flag/flag.zz_generated_float64.go | 35 - .../flag/flag.zz_generated_float64Slice.go | 35 - .../spur/flag/flag.zz_generated_int.go | 35 - .../spur/flag/flag.zz_generated_int64.go | 35 - .../spur/flag/flag.zz_generated_int64Slice.go | 35 - .../spur/flag/flag.zz_generated_intSlice.go | 35 - .../spur/flag/flag.zz_generated_string.go | 35 - .../flag/flag.zz_generated_stringSlice.go | 35 - .../spur/flag/flag.zz_generated_time.go | 35 - .../spur/flag/flag.zz_generated_timeSlice.go | 35 - .../spur/flag/flag.zz_generated_uint.go | 35 - .../spur/flag/flag.zz_generated_uint64.go | 35 - .../flag/flag.zz_generated_uint64Slice.go | 35 - .../spur/flag/flag.zz_generated_uintSlice.go | 35 - .../rancher/spur/flag/flag_generic.go | 83 --- .../github.com/rancher/spur/generic/error.go | 32 - .../rancher/spur/generic/generic.go | 241 ------- .../rancher/spur/generic/string_from.go | 57 -- .../rancher/spur/generic/string_to.go | 43 -- vendor/gopkg.in/yaml.v2/apic.go | 1 - vendor/modules.txt | 9 +- 93 files changed, 255 insertions(+), 6251 deletions(-) delete mode 100644 pkg/cli/cmds/config.go delete mode 100644 pkg/cli/cmds/debug.go delete mode 100644 vendor/github.com/rancher/spur/LICENSE delete mode 100644 vendor/github.com/rancher/spur/cli/.flake8 delete mode 100644 vendor/github.com/rancher/spur/cli/.gitignore delete mode 100644 vendor/github.com/rancher/spur/cli/LICENSE delete mode 100644 vendor/github.com/rancher/spur/cli/_flag.template.go delete mode 100644 vendor/github.com/rancher/spur/cli/altsrc/conf_file_loader.go delete mode 100644 vendor/github.com/rancher/spur/cli/altsrc/map_input_source.go delete mode 100644 vendor/github.com/rancher/spur/cli/altsrc/yaml_file_loader.go delete mode 100644 vendor/github.com/rancher/spur/cli/app.go delete mode 100644 vendor/github.com/rancher/spur/cli/args.go delete mode 100644 vendor/github.com/rancher/spur/cli/category.go delete mode 100644 vendor/github.com/rancher/spur/cli/command.go delete mode 100644 vendor/github.com/rancher/spur/cli/context.go delete mode 100644 vendor/github.com/rancher/spur/cli/docs.go delete mode 100644 vendor/github.com/rancher/spur/cli/errors.go delete mode 100644 vendor/github.com/rancher/spur/cli/fish.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_bool.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_boolSlice.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_duration.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_durationSlice.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_float64.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_float64Slice.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_int.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_int64.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_int64Slice.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_intSlice.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_string.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_stringSlice.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_time.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_timeSlice.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_uint.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64Slice.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag.zz_generated_uintSlice.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag_apply.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag_fields.go delete mode 100644 vendor/github.com/rancher/spur/cli/flag_generic.go delete mode 100644 vendor/github.com/rancher/spur/cli/funcs.go delete mode 100644 vendor/github.com/rancher/spur/cli/help.go delete mode 100644 vendor/github.com/rancher/spur/cli/input_source.go delete mode 100644 vendor/github.com/rancher/spur/cli/parse.go delete mode 100644 vendor/github.com/rancher/spur/cli/sort.go delete mode 100644 vendor/github.com/rancher/spur/cli/template.go delete mode 100644 vendor/github.com/rancher/spur/flag/LICENSE delete mode 100644 vendor/github.com/rancher/spur/flag/_flag.template.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_bool.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_boolSlice.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_duration.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_durationSlice.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_float64.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_float64Slice.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_int.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_int64.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_int64Slice.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_intSlice.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_string.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_stringSlice.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_time.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_timeSlice.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_uint.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64Slice.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag.zz_generated_uintSlice.go delete mode 100644 vendor/github.com/rancher/spur/flag/flag_generic.go delete mode 100644 vendor/github.com/rancher/spur/generic/error.go delete mode 100644 vendor/github.com/rancher/spur/generic/generic.go delete mode 100644 vendor/github.com/rancher/spur/generic/string_from.go delete mode 100644 vendor/github.com/rancher/spur/generic/string_to.go diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 41c8f0aa65..9d9049bcb1 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -5,13 +5,13 @@ import ( "github.com/rancher/k3s/pkg/cli/agent" "github.com/rancher/k3s/pkg/cli/cmds" - "github.com/rancher/spur/cli" "github.com/sirupsen/logrus" + "github.com/urfave/cli" ) func main() { app := cmds.NewApp() - app.Commands = []*cli.Command{ + app.Commands = []cli.Command{ cmds.NewAgentCommand(agent.Run), } diff --git a/cmd/k3s/main.go b/cmd/k3s/main.go index bc528cbdaf..0234bf8648 100644 --- a/cmd/k3s/main.go +++ b/cmd/k3s/main.go @@ -14,8 +14,8 @@ import ( "github.com/rancher/k3s/pkg/datadir" "github.com/rancher/k3s/pkg/untar" "github.com/rancher/k3s/pkg/version" - "github.com/rancher/spur/cli" "github.com/sirupsen/logrus" + "github.com/urfave/cli" ) func main() { @@ -24,7 +24,7 @@ func main() { } app := cmds.NewApp() - app.Commands = []*cli.Command{ + app.Commands = []cli.Command{ cmds.NewServerCommand(wrap(version.Program+"-server", os.Args)), cmds.NewAgentCommand(wrap(version.Program+"-agent", os.Args)), cmds.NewKubectlCommand(externalCLIAction("kubectl")), @@ -56,7 +56,7 @@ func runCLIs() bool { func externalCLIAction(cmd string) func(cli *cli.Context) error { return func(cli *cli.Context) error { - return externalCLI(cmd, cli.String("data-dir"), cli.Args().Slice()) + return externalCLI(cmd, cli.String("data-dir"), cli.Args()) } } @@ -100,6 +100,7 @@ func stageAndRun(dataDir string, cmd string, args []string) error { if err != nil { return err } + logrus.Debugf("Running %s %v", cmd, args) return syscall.Exec(cmd, args, os.Environ()) } diff --git a/cmd/server/main.go b/cmd/server/main.go index 386231610b..7fcd6e047b 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -15,8 +15,8 @@ import ( "github.com/rancher/k3s/pkg/containerd" ctr2 "github.com/rancher/k3s/pkg/ctr" kubectl2 "github.com/rancher/k3s/pkg/kubectl" - "github.com/rancher/spur/cli" "github.com/sirupsen/logrus" + "github.com/urfave/cli" ) func init() { @@ -35,7 +35,7 @@ func main() { os.Args[0] = cmd app := cmds.NewApp() - app.Commands = []*cli.Command{ + app.Commands = []cli.Command{ cmds.NewServerCommand(server.Run), cmds.NewAgentCommand(agent.Run), cmds.NewKubectlCommand(kubectl.Run), diff --git a/go.mod b/go.mod index 7171bdd4b0..3a21ee4bde 100644 --- a/go.mod +++ b/go.mod @@ -86,7 +86,6 @@ require ( github.com/rancher/helm-controller v0.7.2 github.com/rancher/kine v0.4.0 github.com/rancher/remotedialer v0.2.0 - github.com/rancher/spur v0.0.0-20200617165101-8702c8e4ce7a github.com/rancher/wrangler v0.6.1 github.com/rancher/wrangler-api v0.6.0 github.com/robfig/cron/v3 v3.0.1 diff --git a/go.sum b/go.sum index 0ce7e40fa4..36f849ab29 100644 --- a/go.sum +++ b/go.sum @@ -186,6 +186,7 @@ github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+ github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbpBpLoyyu8B6e44T7hJy6potg= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -382,6 +383,7 @@ github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-containerregistry v0.0.0-20190617215043-876b8855d23c/go.mod h1:yZAFP63pRshzrEYLXLGPmUt0Ay+2zdjmMN1loCnRLUk= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -557,6 +559,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976 h1:aZQToFSLH8ejFeSkTc3r3L4dPImcj7Ib/KgmkQqbGGg= github.com/mrunalp/fileutils v0.0.0-20200520151820-abd8a0e76976/go.mod h1:x8F1gnqOkIEiO4rqoeEEEqQbo7HjGMTvyoq3gej4iT0= @@ -581,6 +584,7 @@ github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3 h1:OoxbjfXVZyod1fmWYhI7SEyaD8B00ynP3T+D5GiyHOY= github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -618,6 +622,7 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -719,9 +724,8 @@ github.com/rancher/moq v0.0.0-20190404221404-ee5226d43009/go.mod h1:wpITyDPTi/Na github.com/rancher/nocode v0.0.0-20200630202308-cb097102c09f/go.mod h1:iAAt6Amgbysi6srDJs9SxGSbG2j/JSRb/xCrnEtA69g= github.com/rancher/remotedialer v0.2.0 h1:xD7t3K6JYwTdAsxmGtTHQMkEkFgKouQ1foLxVW424Dc= github.com/rancher/remotedialer v0.2.0/go.mod h1:tkU8ZvrR5lRgaKWaX71nAy6daeqvPFx/lJEnbW7tXSI= -github.com/rancher/spur v0.0.0-20200617165101-8702c8e4ce7a h1:MIWeFYPZ/XXnskvcUqV8W89PFs+n/mr4YWMHeZuMpYs= -github.com/rancher/spur v0.0.0-20200617165101-8702c8e4ce7a/go.mod h1:Q6L6c+4FRxY5CF1xG3oEAfH3tSQDf0NAZes7q7wRyPE= github.com/rancher/wrangler v0.1.4/go.mod h1:EYP7cqpg42YqElaCm+U9ieSrGQKAXxUH5xsr+XGpWyE= +github.com/rancher/wrangler v0.4.0 h1:iLvuJcZkd38E3RGG74dFMMNEju0PeTzfT1PQiv5okVU= github.com/rancher/wrangler v0.4.0/go.mod h1:1cR91WLhZgkZ+U4fV9nVuXqKurWbgXcIReU4wnQvTN8= github.com/rancher/wrangler v0.6.0/go.mod h1:L4HtjPeX8iqLgsxfJgz+JjKMcX2q3qbRXSeTlC/CSd4= github.com/rancher/wrangler v0.6.1 h1:7tyLk/FV2zCQkYg5SEtT4lSlsHNwa5yMOa797/VJhiQ= @@ -1044,6 +1048,7 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485 h1:OB/uP/Puiu5vS5QMRPrXCDWUPb+kt8f1KW8oQzFejQw= gonum.org/v1/gonum v0.0.0-20190331200053-3d26580ed485/go.mod h1:2ltnJ7xHfj0zHS40VVPYEAAMTa3ZGguvHGBSJeRWqE0= gonum.org/v1/gonum v0.6.2 h1:4r+yNT0+8SWcOkXP+63H2zQbN+USnC73cjGUxnDF94Q= gonum.org/v1/gonum v0.6.2/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= @@ -1068,7 +1073,6 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63 h1:YzfoEYWbODU5Fbt google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -1102,6 +1106,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1119,6 +1124,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20190327210449-e17681d19d3a/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20191120174120-e74f70b9b27e h1:HqlU9dKk5YVs7R84jmq6U3Wo/XslpkxHpBv2iWHLtLc= k8s.io/gengo v0.0.0-20191120174120-e74f70b9b27e/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= @@ -1157,6 +1163,7 @@ sigs.k8s.io/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65 h1:xJNnO2qz sigs.k8s.io/structured-merge-diff v0.0.0-20190426204423-ea680f03cc65/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI= sigs.k8s.io/structured-merge-diff/v4 v4.0.1 h1:YXTMot5Qz/X1iBRJhAt+vI+HVttY0WkSqqhKxQ0xVbA= sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= diff --git a/main.go b/main.go index a582f8a1ed..62908bb7bb 100644 --- a/main.go +++ b/main.go @@ -14,13 +14,13 @@ import ( "github.com/rancher/k3s/pkg/cli/crictl" "github.com/rancher/k3s/pkg/cli/kubectl" "github.com/rancher/k3s/pkg/cli/server" - "github.com/rancher/spur/cli" "github.com/sirupsen/logrus" + "github.com/urfave/cli" ) func main() { app := cmds.NewApp() - app.Commands = []*cli.Command{ + app.Commands = []cli.Command{ cmds.NewServerCommand(server.Run), cmds.NewAgentCommand(agent.Run), cmds.NewKubectlCommand(kubectl.Run), diff --git a/pkg/cli/agent/agent.go b/pkg/cli/agent/agent.go index 2630cfcacf..3bed674b78 100644 --- a/pkg/cli/agent/agent.go +++ b/pkg/cli/agent/agent.go @@ -13,9 +13,9 @@ import ( "github.com/rancher/k3s/pkg/netutil" "github.com/rancher/k3s/pkg/token" "github.com/rancher/k3s/pkg/version" - "github.com/rancher/spur/cli" "github.com/rancher/wrangler/pkg/signals" "github.com/sirupsen/logrus" + "github.com/urfave/cli" ) func Run(ctx *cli.Context) error { @@ -23,6 +23,9 @@ func Run(ctx *cli.Context) error { // database credentials or other secrets. gspt.SetProcTitle(os.Args[0] + " agent") + if err := cmds.InitLogging(); err != nil { + return err + } if os.Getuid() != 0 && runtime.GOOS != "windows" { return fmt.Errorf("agent must be ran as root") } @@ -59,7 +62,7 @@ func Run(ctx *cli.Context) error { } cfg := cmds.AgentConfig - cfg.Debug = ctx.Bool("debug") + cfg.Debug = ctx.GlobalBool("debug") cfg.DataDir = dataDir contextCtx := signals.SetupSignalHandler(context.Background()) diff --git a/pkg/cli/cmds/agent.go b/pkg/cli/cmds/agent.go index 300062dbf4..01d9ce75fa 100644 --- a/pkg/cli/cmds/agent.go +++ b/pkg/cli/cmds/agent.go @@ -6,8 +6,7 @@ import ( "github.com/pkg/errors" "github.com/rancher/k3s/pkg/version" - "github.com/rancher/spur/cli" - "github.com/rancher/spur/cli/altsrc" + "github.com/urfave/cli" ) type Agent struct { @@ -33,13 +32,13 @@ type Agent struct { RootlessAlreadyUnshared bool WithNodeID bool EnableSELinux bool - ExtraKubeletArgs []string - ExtraKubeProxyArgs []string - Labels []string - Taints []string - PrivateRegistry string ProtectKernelDefaults bool AgentShared + ExtraKubeletArgs cli.StringSlice + ExtraKubeProxyArgs cli.StringSlice + Labels cli.StringSlice + Taints cli.StringSlice + PrivateRegistry string } type AgentShared struct { @@ -62,7 +61,7 @@ var ( NodeNameFlag = cli.StringFlag{ Name: "node-name", Usage: "(agent/node) Node name", - EnvVars: []string{version.ProgramUpper + "_NODE_NAME"}, + EnvVar: version.ProgramUpper + "_NODE_NAME", Destination: &AgentConfig.NodeName, } WithNodeIDFlag = cli.BoolFlag{ @@ -116,34 +115,33 @@ var ( ResolvConfFlag = cli.StringFlag{ Name: "resolv-conf", Usage: "(agent/networking) Kubelet resolv.conf file", - EnvVars: []string{version.ProgramUpper + "_RESOLV_CONF"}, + EnvVar: version.ProgramUpper + "_RESOLV_CONF", Destination: &AgentConfig.ResolvConf, } ExtraKubeletArgs = cli.StringSliceFlag{ - Name: "kubelet-arg", - Usage: "(agent/flags) Customized flag for kubelet process", - Destination: &AgentConfig.ExtraKubeletArgs, + Name: "kubelet-arg", + Usage: "(agent/flags) Customized flag for kubelet process", + Value: &AgentConfig.ExtraKubeletArgs, } ExtraKubeProxyArgs = cli.StringSliceFlag{ - Name: "kube-proxy-arg", - Usage: "(agent/flags) Customized flag for kube-proxy process", - Destination: &AgentConfig.ExtraKubeProxyArgs, + Name: "kube-proxy-arg", + Usage: "(agent/flags) Customized flag for kube-proxy process", + Value: &AgentConfig.ExtraKubeProxyArgs, } NodeTaints = cli.StringSliceFlag{ - Name: "node-taint", - Usage: "(agent/node) Registering kubelet with set of taints", - Destination: &AgentConfig.Taints, + Name: "node-taint", + Usage: "(agent/node) Registering kubelet with set of taints", + Value: &AgentConfig.Taints, } NodeLabels = cli.StringSliceFlag{ - Name: "node-label", - Usage: "(agent/node) Registering and starting kubelet with set of labels", - Destination: &AgentConfig.Labels, + Name: "node-label", + Usage: "(agent/node) Registering and starting kubelet with set of labels", + Value: &AgentConfig.Labels, } - DisableSELinuxFlag = cli.BoolFlag{ + DisableSELinuxFlag = cli.BoolTFlag{ Name: "disable-selinux", Usage: "(deprecated) Use --selinux to explicitly enable SELinux", Hidden: true, - Value: true, // disabled by default } ProtectKernelDefaultsFlag = cli.BoolFlag{ Name: "protect-kernel-defaults", @@ -155,7 +153,7 @@ var ( Usage: "(agent/node) Enable SELinux in containerd", Hidden: false, Destination: &AgentConfig.EnableSELinux, - EnvVars: []string{version.ProgramUpper + "_SELINUX"}, + EnvVar: version.ProgramUpper + "_SELINUX", } ) @@ -169,67 +167,60 @@ func CheckSELinuxFlags(ctx *cli.Context) error { } return nil } -func NewAgentCommand(action func(ctx *cli.Context) error) *cli.Command { - return &cli.Command{ +func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command { + return cli.Command{ Name: "agent", Usage: "Run node agent", UsageText: appName + " agent [OPTIONS]", - Before: func(ctx *cli.Context) error { - if err := CheckSELinuxFlags(ctx); err != nil { - return err - } - return DebugContext(cli.InitAllInputSource(altsrc.NewConfigFromFlag(ConfigFlag.Name)))(ctx) - }, - Action: InitLogging(action), + Before: CheckSELinuxFlags, + Action: action, Flags: []cli.Flag{ - &ConfigFlag, - &DebugFlag, - &VLevel, - &VModule, - &LogFile, - &AlsoLogToStderr, - &cli.StringFlag{ + VLevel, + VModule, + LogFile, + AlsoLogToStderr, + cli.StringFlag{ Name: "token,t", Usage: "(cluster) Token to use for authentication", - EnvVars: []string{version.ProgramUpper + "_TOKEN"}, + EnvVar: version.ProgramUpper + "_TOKEN", Destination: &AgentConfig.Token, }, - &cli.StringFlag{ + cli.StringFlag{ Name: "token-file", Usage: "(cluster) Token file to use for authentication", - EnvVars: []string{version.ProgramUpper + "_TOKEN_FILE"}, + EnvVar: version.ProgramUpper + "_TOKEN_FILE", Destination: &AgentConfig.TokenFile, }, - &cli.StringFlag{ + cli.StringFlag{ Name: "server,s", Usage: "(cluster) Server to connect to", - EnvVars: []string{version.ProgramUpper + "_URL"}, + EnvVar: version.ProgramUpper + "_URL", Destination: &AgentConfig.ServerURL, }, - &cli.StringFlag{ + cli.StringFlag{ Name: "data-dir,d", Usage: "(agent/data) Folder to hold state", Destination: &AgentConfig.DataDir, Value: "/var/lib/rancher/" + version.Program + "", }, - &NodeNameFlag, - &WithNodeIDFlag, - &NodeLabels, - &NodeTaints, - &DockerFlag, - &CRIEndpointFlag, - &PauseImageFlag, - &SnapshotterFlag, - &PrivateRegistryFlag, - &NodeIPFlag, - &NodeExternalIPFlag, - &ResolvConfFlag, - &FlannelIfaceFlag, - &FlannelConfFlag, - &ExtraKubeletArgs, - &ExtraKubeProxyArgs, - &ProtectKernelDefaultsFlag, - &cli.BoolFlag{ + NodeNameFlag, + WithNodeIDFlag, + NodeLabels, + NodeTaints, + DockerFlag, + CRIEndpointFlag, + PauseImageFlag, + SnapshotterFlag, + PrivateRegistryFlag, + NodeIPFlag, + NodeExternalIPFlag, + ResolvConfFlag, + FlannelIfaceFlag, + FlannelConfFlag, + ExtraKubeletArgs, + ExtraKubeProxyArgs, + ProtectKernelDefaultsFlag, + cli.BoolFlag{ Name: "rootless", Usage: "(experimental) Run rootless", Destination: &AgentConfig.Rootless, @@ -239,12 +230,12 @@ func NewAgentCommand(action func(ctx *cli.Context) error) *cli.Command { // Deprecated/hidden below &DisableSELinuxFlag, - &FlannelFlag, - &cli.StringFlag{ + FlannelFlag, + cli.StringFlag{ Name: "cluster-secret", Usage: "(deprecated) use --token", Destination: &AgentConfig.ClusterSecret, - EnvVars: []string{version.ProgramUpper + "_CLUSTER_SECRET"}, + EnvVar: version.ProgramUpper + "_CLUSTER_SECRET", }, }, } diff --git a/pkg/cli/cmds/check-config.go b/pkg/cli/cmds/check-config.go index 71f0f009f2..ead97e47a9 100644 --- a/pkg/cli/cmds/check-config.go +++ b/pkg/cli/cmds/check-config.go @@ -1,14 +1,15 @@ package cmds import ( - "github.com/rancher/spur/cli" + "github.com/urfave/cli" ) -func NewCheckConfigCommand(action func(*cli.Context) error) *cli.Command { - return &cli.Command{ +func NewCheckConfigCommand(action func(*cli.Context) error) cli.Command { + return cli.Command{ Name: "check-config", Usage: "Run config check", SkipFlagParsing: true, + SkipArgReorder: true, Action: action, } } diff --git a/pkg/cli/cmds/config.go b/pkg/cli/cmds/config.go deleted file mode 100644 index 998533a07d..0000000000 --- a/pkg/cli/cmds/config.go +++ /dev/null @@ -1,16 +0,0 @@ -package cmds - -import ( - "github.com/rancher/spur/cli" -) - -var ( - DefaultConfig = "/etc/rancher/k3s/config.yaml" - ConfigFlag = cli.StringFlag{ - Name: "config", - Aliases: []string{"c"}, - Usage: "(config) Load configuration from `FILE`", - EnvVars: []string{"K3S_CONFIG_FILE"}, - Value: DefaultConfig, - } -) diff --git a/pkg/cli/cmds/crictl.go b/pkg/cli/cmds/crictl.go index 79c8a4e700..ff1bbbbfd0 100644 --- a/pkg/cli/cmds/crictl.go +++ b/pkg/cli/cmds/crictl.go @@ -1,14 +1,15 @@ package cmds import ( - "github.com/rancher/spur/cli" + "github.com/urfave/cli" ) -func NewCRICTL(action func(*cli.Context) error) *cli.Command { - return &cli.Command{ +func NewCRICTL(action func(*cli.Context) error) cli.Command { + return cli.Command{ Name: "crictl", Usage: "Run crictl", SkipFlagParsing: true, + SkipArgReorder: true, Action: action, } } diff --git a/pkg/cli/cmds/ctr.go b/pkg/cli/cmds/ctr.go index 3d701eaf14..c6a5e30ef7 100644 --- a/pkg/cli/cmds/ctr.go +++ b/pkg/cli/cmds/ctr.go @@ -1,14 +1,15 @@ package cmds import ( - "github.com/rancher/spur/cli" + "github.com/urfave/cli" ) -func NewCtrCommand(action func(*cli.Context) error) *cli.Command { - return &cli.Command{ +func NewCtrCommand(action func(*cli.Context) error) cli.Command { + return cli.Command{ Name: "ctr", Usage: "Run ctr", SkipFlagParsing: true, + SkipArgReorder: true, Action: action, } } diff --git a/pkg/cli/cmds/debug.go b/pkg/cli/cmds/debug.go deleted file mode 100644 index 1290658dca..0000000000 --- a/pkg/cli/cmds/debug.go +++ /dev/null @@ -1,31 +0,0 @@ -package cmds - -import ( - "github.com/rancher/k3s/pkg/version" - "github.com/rancher/spur/cli" - "github.com/sirupsen/logrus" -) - -var ( - Debug = false - DebugFlag = cli.BoolFlag{ - Name: "debug", - Usage: "(logging) Turn on debug logs", - Destination: &Debug, - EnvVars: []string{version.ProgramUpper + "_DEBUG"}, - } -) - -func DebugContext(f func(*cli.Context) error) func(ctx *cli.Context) error { - return func(ctx *cli.Context) error { - if f != nil { - if err := f(ctx); err != nil { - return err - } - } - if Debug { - logrus.SetLevel(logrus.DebugLevel) - } - return nil - } -} diff --git a/pkg/cli/cmds/kubectl.go b/pkg/cli/cmds/kubectl.go index a7338a74f9..72bdd92371 100644 --- a/pkg/cli/cmds/kubectl.go +++ b/pkg/cli/cmds/kubectl.go @@ -1,14 +1,15 @@ package cmds import ( - "github.com/rancher/spur/cli" + "github.com/urfave/cli" ) -func NewKubectlCommand(action func(*cli.Context) error) *cli.Command { - return &cli.Command{ +func NewKubectlCommand(action func(*cli.Context) error) cli.Command { + return cli.Command{ Name: "kubectl", Usage: "Run kubectl", SkipFlagParsing: true, + SkipArgReorder: true, Action: action, } } diff --git a/pkg/cli/cmds/log.go b/pkg/cli/cmds/log.go index 094fb488fa..44f6bd8d01 100644 --- a/pkg/cli/cmds/log.go +++ b/pkg/cli/cmds/log.go @@ -12,7 +12,7 @@ import ( "github.com/docker/docker/pkg/reexec" "github.com/natefinch/lumberjack" "github.com/rancher/k3s/pkg/version" - "github.com/rancher/spur/cli" + "github.com/urfave/cli" ) type Log struct { @@ -49,31 +49,22 @@ var ( logSetupOnce sync.Once ) -func InitLogging(action func(*cli.Context) error) func(*cli.Context) error { - return func(ctx *cli.Context) error { - var ( - err error - reExec bool - ) - logSetupOnce.Do(func() { - if LogConfig.LogFile != "" && os.Getenv("_K3S_LOG_REEXEC_") == "" { - reExec = true - err = runWithLogging() - return - } - if err = checkUnixTimestamp(); err != nil { - return - } - setupLogging() - }) - if reExec || err != nil { - return err +func InitLogging() error { + var rErr error + logSetupOnce.Do(func() { + if LogConfig.LogFile != "" && os.Getenv("_K3S_LOG_REEXEC_") == "" { + rErr = runWithLogging() + return } - if action != nil { - return action(ctx) + + if err := checkUnixTimestamp(); err != nil { + rErr = err + return } - return nil - } + + setupLogging() + }) + return rErr } func checkUnixTimestamp() error { diff --git a/pkg/cli/cmds/root.go b/pkg/cli/cmds/root.go index 6c3da34e13..212ec13075 100644 --- a/pkg/cli/cmds/root.go +++ b/pkg/cli/cmds/root.go @@ -5,7 +5,12 @@ import ( "os" "github.com/rancher/k3s/pkg/version" - "github.com/rancher/spur/cli" + "github.com/sirupsen/logrus" + "github.com/urfave/cli" +) + +var ( + Debug bool ) func init() { @@ -23,8 +28,21 @@ func NewApp() *cli.App { cli.VersionPrinter = func(c *cli.Context) { fmt.Printf("%s version %s\n", app.Name, app.Version) } - app.Flags = []cli.Flag{&DebugFlag} - app.Before = DebugContext(nil) + app.Flags = []cli.Flag{ + cli.BoolFlag{ + Name: "debug", + Usage: "Turn on debug logs", + Destination: &Debug, + EnvVar: version.ProgramUpper + "_DEBUG", + }, + } + + app.Before = func(ctx *cli.Context) error { + if Debug { + logrus.SetLevel(logrus.DebugLevel) + } + return nil + } return app } diff --git a/pkg/cli/cmds/server.go b/pkg/cli/cmds/server.go index fafd4b6aa6..b01ded9ce2 100644 --- a/pkg/cli/cmds/server.go +++ b/pkg/cli/cmds/server.go @@ -5,8 +5,7 @@ import ( "github.com/rancher/k3s/pkg/daemons/config" "github.com/rancher/k3s/pkg/version" - "github.com/rancher/spur/cli" - "github.com/rancher/spur/cli/altsrc" + "github.com/urfave/cli" ) const ( @@ -37,12 +36,12 @@ type Server struct { DisableAgent bool KubeConfigOutput string KubeConfigMode string - TLSSan []string + TLSSan cli.StringSlice BindAddress string - ExtraAPIArgs []string - ExtraSchedulerArgs []string - ExtraControllerArgs []string - ExtraCloudControllerArgs []string + ExtraAPIArgs cli.StringSlice + ExtraSchedulerArgs cli.StringSlice + ExtraControllerArgs cli.StringSlice + ExtraCloudControllerArgs cli.StringSlice Rootless bool DatastoreEndpoint string DatastoreCAFile string @@ -70,153 +69,146 @@ type Server struct { var ServerConfig Server -func NewServerCommand(action func(*cli.Context) error) *cli.Command { - return &cli.Command{ +func NewServerCommand(action func(*cli.Context) error) cli.Command { + return cli.Command{ Name: "server", Usage: "Run management server", UsageText: appName + " server [OPTIONS]", - Before: func(ctx *cli.Context) error { - if err := CheckSELinuxFlags(ctx); err != nil { - return err - } - return DebugContext(cli.InitAllInputSource(altsrc.NewConfigFromFlag(ConfigFlag.Name)))(ctx) - }, - Action: InitLogging(action), + Before: CheckSELinuxFlags, + Action: action, Flags: []cli.Flag{ - &ConfigFlag, - &DebugFlag, - &VLevel, - &VModule, - &LogFile, - &AlsoLogToStderr, - &cli.StringFlag{ + VLevel, + VModule, + LogFile, + AlsoLogToStderr, + cli.StringFlag{ Name: "bind-address", Usage: "(listener) " + version.Program + " bind address (default: 0.0.0.0)", Destination: &ServerConfig.BindAddress, }, - &cli.IntFlag{ + cli.IntFlag{ Name: "https-listen-port", Usage: "(listener) HTTPS listen port", Value: 6443, Destination: &ServerConfig.HTTPSPort, }, - &cli.StringFlag{ + cli.StringFlag{ Name: "advertise-address", Usage: "(listener) IP address that apiserver uses to advertise to members of the cluster (default: node-external-ip/node-ip)", Destination: &ServerConfig.AdvertiseIP, }, - &cli.IntFlag{ + cli.IntFlag{ Name: "advertise-port", Usage: "(listener) Port that apiserver uses to advertise to members of the cluster (default: listen-port)", Destination: &ServerConfig.AdvertisePort, }, - &cli.StringSliceFlag{ - Name: "tls-san", - Usage: "(listener) Add additional hostname or IP as a Subject Alternative Name in the TLS cert", - Destination: &ServerConfig.TLSSan, + cli.StringSliceFlag{ + Name: "tls-san", + Usage: "(listener) Add additional hostname or IP as a Subject Alternative Name in the TLS cert", + Value: &ServerConfig.TLSSan, }, - &cli.StringFlag{ + cli.StringFlag{ Name: "data-dir,d", Usage: "(data) Folder to hold state default /var/lib/rancher/" + version.Program + " or ${HOME}/.rancher/" + version.Program + " if not root", Destination: &ServerConfig.DataDir, }, - &cli.StringFlag{ + cli.StringFlag{ Name: "cluster-cidr", Usage: "(networking) Network CIDR to use for pod IPs", Destination: &ServerConfig.ClusterCIDR, Value: "10.42.0.0/16", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "service-cidr", Usage: "(networking) Network CIDR to use for services IPs", Destination: &ServerConfig.ServiceCIDR, Value: "10.43.0.0/16", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "cluster-dns", Usage: "(networking) Cluster IP for coredns service. Should be in your service-cidr range (default: 10.43.0.10)", Destination: &ServerConfig.ClusterDNS, Value: "", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "cluster-domain", Usage: "(networking) Cluster Domain", Destination: &ServerConfig.ClusterDomain, Value: "cluster.local", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "flannel-backend", Usage: "(networking) One of 'none', 'vxlan', 'ipsec', 'host-gw', or 'wireguard'", Destination: &ServerConfig.FlannelBackend, Value: "vxlan", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "token,t", Usage: "(cluster) Shared secret used to join a server or agent to a cluster", Destination: &ServerConfig.Token, - EnvVars: []string{version.ProgramUpper + "_TOKEN"}, + EnvVar: version.ProgramUpper + "_TOKEN", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "token-file", Usage: "(cluster) File containing the cluster-secret/token", Destination: &ServerConfig.TokenFile, - EnvVars: []string{version.ProgramUpper + "_TOKEN_FILE"}, + EnvVar: version.ProgramUpper + "_TOKEN_FILE", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "write-kubeconfig,o", Usage: "(client) Write kubeconfig for admin client to this file", Destination: &ServerConfig.KubeConfigOutput, - EnvVars: []string{version.ProgramUpper + "_KUBECONFIG_OUTPUT"}, + EnvVar: version.ProgramUpper + "_KUBECONFIG_OUTPUT", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "write-kubeconfig-mode", Usage: "(client) Write kubeconfig with this mode", Destination: &ServerConfig.KubeConfigMode, - EnvVars: []string{version.ProgramUpper + "_KUBECONFIG_MODE"}, + EnvVar: version.ProgramUpper + "_KUBECONFIG_MODE", }, - &cli.StringSliceFlag{ - Name: "kube-apiserver-arg", - Usage: "(flags) Customized flag for kube-apiserver process", - Destination: &ServerConfig.ExtraAPIArgs, + cli.StringSliceFlag{ + Name: "kube-apiserver-arg", + Usage: "(flags) Customized flag for kube-apiserver process", + Value: &ServerConfig.ExtraAPIArgs, }, - &cli.StringSliceFlag{ - Name: "kube-scheduler-arg", - Usage: "(flags) Customized flag for kube-scheduler process", - Destination: &ServerConfig.ExtraSchedulerArgs, + cli.StringSliceFlag{ + Name: "kube-scheduler-arg", + Usage: "(flags) Customized flag for kube-scheduler process", + Value: &ServerConfig.ExtraSchedulerArgs, }, - &cli.StringSliceFlag{ - Name: "kube-controller-manager-arg", - Usage: "(flags) Customized flag for kube-controller-manager process", - Destination: &ServerConfig.ExtraControllerArgs, + cli.StringSliceFlag{ + Name: "kube-controller-manager-arg", + Usage: "(flags) Customized flag for kube-controller-manager process", + Value: &ServerConfig.ExtraControllerArgs, }, - &cli.StringSliceFlag{ - Name: "kube-cloud-controller-manager-arg", - Usage: "(flags) Customized flag for kube-cloud-controller-manager process", - Destination: &ServerConfig.ExtraCloudControllerArgs, + cli.StringSliceFlag{ + Name: "kube-cloud-controller-manager-arg", + Usage: "(flags) Customized flag for kube-cloud-controller-manager process", + Value: &ServerConfig.ExtraCloudControllerArgs, }, - &cli.StringFlag{ + cli.StringFlag{ Name: "datastore-endpoint", Usage: "(db) Specify etcd, Mysql, Postgres, or Sqlite (default) data source name", Destination: &ServerConfig.DatastoreEndpoint, - EnvVars: []string{version.ProgramUpper + "_DATASTORE_ENDPOINT"}, + EnvVar: version.ProgramUpper + "_DATASTORE_ENDPOINT", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "datastore-cafile", Usage: "(db) TLS Certificate Authority file used to secure datastore backend communication", Destination: &ServerConfig.DatastoreCAFile, - EnvVars: []string{version.ProgramUpper + "_DATASTORE_CAFILE"}, + EnvVar: version.ProgramUpper + "_DATASTORE_CAFILE", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "datastore-certfile", Usage: "(db) TLS certification file used to secure datastore backend communication", Destination: &ServerConfig.DatastoreCertFile, - EnvVars: []string{version.ProgramUpper + "_DATASTORE_CERTFILE"}, + EnvVar: version.ProgramUpper + "_DATASTORE_CERTFILE", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "datastore-keyfile", Usage: "(db) TLS key file used to secure datastore backend communication", Destination: &ServerConfig.DatastoreKeyFile, - EnvVars: []string{version.ProgramUpper + "_DATASTORE_KEYFILE"}, + EnvVar: version.ProgramUpper + "_DATASTORE_KEYFILE", }, &cli.BoolFlag{ Name: "etcd-disable-snapshots", @@ -240,88 +232,88 @@ func NewServerCommand(action func(*cli.Context) error) *cli.Command { Usage: "(db) Directory to save db snapshots. (Default location: ${data-dir}/db/snapshots)", Destination: &ServerConfig.EtcdSnapshotDir, }, - &cli.StringFlag{ + cli.StringFlag{ Name: "default-local-storage-path", Usage: "(storage) Default local storage path for local provisioner storage class", Destination: &ServerConfig.DefaultLocalStoragePath, }, - &cli.StringSliceFlag{ + cli.StringSliceFlag{ Name: "disable", Usage: "(components) Do not deploy packaged components and delete any deployed components (valid items: " + DisableItems + ")", }, - &cli.BoolFlag{ + cli.BoolFlag{ Name: "disable-scheduler", Usage: "(components) Disable Kubernetes default scheduler", Destination: &ServerConfig.DisableScheduler, }, - &cli.BoolFlag{ + cli.BoolFlag{ Name: "disable-cloud-controller", Usage: "(components) Disable " + version.Program + " default cloud controller manager", Destination: &ServerConfig.DisableCCM, }, - &cli.BoolFlag{ + cli.BoolFlag{ Name: "disable-kube-proxy", Usage: "(components) Disable running kube-proxy", Destination: &ServerConfig.DisableKubeProxy, }, - &cli.BoolFlag{ + cli.BoolFlag{ Name: "disable-network-policy", Usage: "(components) Disable " + version.Program + " default network policy controller", Destination: &ServerConfig.DisableNPC, }, - &NodeNameFlag, - &WithNodeIDFlag, - &NodeLabels, - &NodeTaints, - &DockerFlag, - &CRIEndpointFlag, - &PauseImageFlag, - &SnapshotterFlag, - &PrivateRegistryFlag, - &NodeIPFlag, - &NodeExternalIPFlag, - &ResolvConfFlag, - &FlannelIfaceFlag, - &FlannelConfFlag, - &ExtraKubeletArgs, - &ExtraKubeProxyArgs, - &ProtectKernelDefaultsFlag, - &cli.BoolFlag{ + NodeNameFlag, + WithNodeIDFlag, + NodeLabels, + NodeTaints, + DockerFlag, + CRIEndpointFlag, + PauseImageFlag, + SnapshotterFlag, + PrivateRegistryFlag, + NodeIPFlag, + NodeExternalIPFlag, + ResolvConfFlag, + FlannelIfaceFlag, + FlannelConfFlag, + ExtraKubeletArgs, + ExtraKubeProxyArgs, + ProtectKernelDefaultsFlag, + cli.BoolFlag{ Name: "rootless", Usage: "(experimental) Run rootless", Destination: &ServerConfig.Rootless, }, - &cli.StringFlag{ + cli.StringFlag{ Name: "agent-token", Usage: "(experimental/cluster) Shared secret used to join agents to the cluster, but not servers", Destination: &ServerConfig.AgentToken, - EnvVars: []string{version.ProgramUpper + "_AGENT_TOKEN"}, + EnvVar: version.ProgramUpper + "_AGENT_TOKEN", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "agent-token-file", Usage: "(experimental/cluster) File containing the agent secret", Destination: &ServerConfig.AgentTokenFile, - EnvVars: []string{version.ProgramUpper + "_AGENT_TOKEN_FILE"}, + EnvVar: version.ProgramUpper + "_AGENT_TOKEN_FILE", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "server,s", Hidden: hideClusterFlags, Usage: "(experimental/cluster) Server to connect to, used to join a cluster", - EnvVars: []string{version.ProgramUpper + "_URL"}, + EnvVar: version.ProgramUpper + "_URL", Destination: &ServerConfig.ServerURL, }, - &cli.BoolFlag{ + cli.BoolFlag{ Name: "cluster-init", Hidden: hideClusterFlags, Usage: "(experimental/cluster) Initialize a new cluster", - EnvVars: []string{version.ProgramUpper + "_CLUSTER_INIT"}, + EnvVar: version.ProgramUpper + "_CLUSTER_INIT", Destination: &ServerConfig.ClusterInit, }, - &cli.BoolFlag{ + cli.BoolFlag{ Name: "cluster-reset", Hidden: hideClusterFlags, Usage: "(experimental/cluster) Forget all peers and become sole member of a new cluster", - EnvVars: []string{version.ProgramUpper + "_CLUSTER_RESET"}, + EnvVar: version.ProgramUpper + "_CLUSTER_RESET", Destination: &ServerConfig.ClusterReset, }, &cli.StringFlag{ @@ -329,7 +321,7 @@ func NewServerCommand(action func(*cli.Context) error) *cli.Command { Usage: "(db) Path to snapshot file to be restored", Destination: &ServerConfig.ClusterResetRestorePath, }, - &cli.BoolFlag{ + cli.BoolFlag{ Name: "secrets-encryption", Usage: "(experimental) Enable Secret encryption at rest", Destination: &ServerConfig.EncryptSecrets, @@ -339,34 +331,34 @@ func NewServerCommand(action func(*cli.Context) error) *cli.Command { // Hidden/Deprecated flags below &DisableSELinuxFlag, - &FlannelFlag, - &cli.StringSliceFlag{ + FlannelFlag, + cli.StringSliceFlag{ Name: "no-deploy", Usage: "(deprecated) Do not deploy packaged components (valid items: " + DisableItems + ")", }, - &cli.StringFlag{ + cli.StringFlag{ Name: "cluster-secret", Usage: "(deprecated) use --token", Destination: &ServerConfig.ClusterSecret, - EnvVars: []string{version.ProgramUpper + "_CLUSTER_SECRET"}, + EnvVar: version.ProgramUpper + "_CLUSTER_SECRET", }, - &cli.BoolFlag{ + cli.BoolFlag{ Name: "disable-agent", Usage: "Do not run a local agent and register a local kubelet", Hidden: true, Destination: &ServerConfig.DisableAgent, }, - &cli.StringSliceFlag{ - Hidden: true, - Name: "kube-controller-arg", - Usage: "(flags) Customized flag for kube-controller-manager process", - Destination: &ServerConfig.ExtraControllerArgs, + cli.StringSliceFlag{ + Hidden: true, + Name: "kube-controller-arg", + Usage: "(flags) Customized flag for kube-controller-manager process", + Value: &ServerConfig.ExtraControllerArgs, }, - &cli.StringSliceFlag{ - Hidden: true, - Name: "kube-cloud-controller-arg", - Usage: "(flags) Customized flag for kube-cloud-controller-manager process", - Destination: &ServerConfig.ExtraCloudControllerArgs, + cli.StringSliceFlag{ + Hidden: true, + Name: "kube-cloud-controller-arg", + Usage: "(flags) Customized flag for kube-cloud-controller-manager process", + Value: &ServerConfig.ExtraCloudControllerArgs, }, }, } diff --git a/pkg/cli/crictl/crictl.go b/pkg/cli/crictl/crictl.go index 951aee2521..03b3b5b661 100644 --- a/pkg/cli/crictl/crictl.go +++ b/pkg/cli/crictl/crictl.go @@ -2,7 +2,7 @@ package crictl import ( "github.com/kubernetes-sigs/cri-tools/cmd/crictl" - "github.com/rancher/spur/cli" + "github.com/urfave/cli" ) func Run(ctx *cli.Context) error { diff --git a/pkg/cli/ctr/ctr.go b/pkg/cli/ctr/ctr.go index fefe68df27..a8aab2d60c 100644 --- a/pkg/cli/ctr/ctr.go +++ b/pkg/cli/ctr/ctr.go @@ -2,7 +2,7 @@ package ctr import ( "github.com/rancher/k3s/pkg/ctr" - "github.com/rancher/spur/cli" + "github.com/urfave/cli" ) func Run(ctx *cli.Context) error { diff --git a/pkg/cli/kubectl/kubectl.go b/pkg/cli/kubectl/kubectl.go index d9b24e97b6..4c047a4c53 100644 --- a/pkg/cli/kubectl/kubectl.go +++ b/pkg/cli/kubectl/kubectl.go @@ -2,7 +2,7 @@ package kubectl import ( "github.com/rancher/k3s/pkg/kubectl" - "github.com/rancher/spur/cli" + "github.com/urfave/cli" ) func Run(ctx *cli.Context) error { diff --git a/pkg/cli/server/server.go b/pkg/cli/server/server.go index 9a09c7e16d..56c2ac7166 100644 --- a/pkg/cli/server/server.go +++ b/pkg/cli/server/server.go @@ -19,9 +19,9 @@ import ( "github.com/rancher/k3s/pkg/server" "github.com/rancher/k3s/pkg/token" "github.com/rancher/k3s/pkg/version" - "github.com/rancher/spur/cli" "github.com/rancher/wrangler/pkg/signals" "github.com/sirupsen/logrus" + "github.com/urfave/cli" "k8s.io/apimachinery/pkg/util/net" kubeapiserverflag "k8s.io/component-base/cli/flag" "k8s.io/kubernetes/pkg/master" @@ -32,6 +32,9 @@ import ( ) func Run(app *cli.Context) error { + if err := cmds.InitLogging(); err != nil { + return err + } return run(app, &cmds.ServerConfig) } @@ -263,7 +266,7 @@ func run(app *cli.Context, cfg *cmds.Server) error { } agentConfig := cmds.AgentConfig - agentConfig.Debug = app.Bool("debug") + agentConfig.Debug = app.GlobalBool("bool") agentConfig.DataDir = filepath.Dir(serverConfig.ControlConfig.DataDir) agentConfig.ServerURL = url agentConfig.Token = token diff --git a/vendor/github.com/rancher/spur/LICENSE b/vendor/github.com/rancher/spur/LICENSE deleted file mode 100644 index 261eeb9e9f..0000000000 --- a/vendor/github.com/rancher/spur/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/vendor/github.com/rancher/spur/cli/.flake8 b/vendor/github.com/rancher/spur/cli/.flake8 deleted file mode 100644 index 6deafc2617..0000000000 --- a/vendor/github.com/rancher/spur/cli/.flake8 +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length = 120 diff --git a/vendor/github.com/rancher/spur/cli/.gitignore b/vendor/github.com/rancher/spur/cli/.gitignore deleted file mode 100644 index 2d5e149b43..0000000000 --- a/vendor/github.com/rancher/spur/cli/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -*.coverprofile -*.orig -node_modules/ -vendor -.idea -internal/*/built-example -coverage.txt diff --git a/vendor/github.com/rancher/spur/cli/LICENSE b/vendor/github.com/rancher/spur/cli/LICENSE deleted file mode 100644 index 42a597e29b..0000000000 --- a/vendor/github.com/rancher/spur/cli/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Jeremy Saenz & Contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/rancher/spur/cli/_flag.template.go b/vendor/github.com/rancher/spur/cli/_flag.template.go deleted file mode 100644 index eff484c1fb..0000000000 --- a/vendor/github.com/rancher/spur/cli/_flag.template.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Title__ is a type alias for Type__ -type Title__ = Type__ - -// Title__Flag is a flag with type Type__ -type Title__Flag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Title__ - Destination *Title__ -} - -// Apply populates the flag given the flag set and environment -func (f *Title__Flag) Apply(set *flag.FlagSet) error { - return Apply(f, "LongName__", set) -} - -// Title__ looks up the value of a local Title__Flag, returns -// an empty value if not found -func (c *Context) Title__(name string) Type__ { - return c.Lookup(name, *new(Title__)).(Type__) -} diff --git a/vendor/github.com/rancher/spur/cli/altsrc/conf_file_loader.go b/vendor/github.com/rancher/spur/cli/altsrc/conf_file_loader.go deleted file mode 100644 index f8cc022e24..0000000000 --- a/vendor/github.com/rancher/spur/cli/altsrc/conf_file_loader.go +++ /dev/null @@ -1,23 +0,0 @@ -package altsrc - -import ( - "fmt" - "os" - - "github.com/rancher/spur/cli" -) - -// NewConfigFromFlag creates a new Yaml cli.InputSourceContext from a provided flag name and source context. -// If the flag is not set and the default config does not exist then returns an empty input and no error. -func NewConfigFromFlag(flagFileName string) func(*cli.Context) (cli.InputSourceContext, error) { - return func(ctx *cli.Context) (cli.InputSourceContext, error) { - filePath := ctx.String(flagFileName) - if isc, err := NewYamlSourceFromFile(filePath); ctx.IsSet(flagFileName) || !os.IsNotExist(err) { - if err != nil { - err = fmt.Errorf("unable to load config file '%s': %s", filePath, err) - } - return isc, err - } - return &MapInputSource{}, nil - } -} diff --git a/vendor/github.com/rancher/spur/cli/altsrc/map_input_source.go b/vendor/github.com/rancher/spur/cli/altsrc/map_input_source.go deleted file mode 100644 index dca2977263..0000000000 --- a/vendor/github.com/rancher/spur/cli/altsrc/map_input_source.go +++ /dev/null @@ -1,49 +0,0 @@ -package altsrc - -import ( - "strings" -) - -// MapInputSource implements InputSourceContext to return -// data from the map that is loaded. -type MapInputSource struct { - file string - valueMap map[interface{}]interface{} -} - -// nestedVal checks if the name has '.' delimiters. -// If so, it tries to traverse the tree by the '.' delimited sections to find -// a nested value for the key. -func nestedVal(name string, tree map[interface{}]interface{}) (interface{}, bool) { - if sections := strings.Split(name, "."); len(sections) > 1 { - node := tree - for _, section := range sections[:len(sections)-1] { - child, ok := node[section] - if !ok { - return nil, false - } - ctype, ok := child.(map[interface{}]interface{}) - if !ok { - return nil, false - } - node = ctype - } - if val, ok := node[sections[len(sections)-1]]; ok { - return val, true - } - } - return nil, false -} - -// Get returns the named value -func (fsm *MapInputSource) Get(name string) (interface{}, bool) { - if value, exists := fsm.valueMap[name]; exists { - return value, true - } - return nestedVal(name, fsm.valueMap) -} - -// Source returns the path of the source file -func (fsm *MapInputSource) Source() string { - return fsm.file -} diff --git a/vendor/github.com/rancher/spur/cli/altsrc/yaml_file_loader.go b/vendor/github.com/rancher/spur/cli/altsrc/yaml_file_loader.go deleted file mode 100644 index 6df659f541..0000000000 --- a/vendor/github.com/rancher/spur/cli/altsrc/yaml_file_loader.go +++ /dev/null @@ -1,56 +0,0 @@ -package altsrc - -import ( - "fmt" - "io/ioutil" - "net/http" - "net/url" - "os" - - "github.com/rancher/spur/cli" - "gopkg.in/yaml.v2" -) - -type yamlSourceContext struct { - FilePath string -} - -// NewYamlSourceFromFile creates a new Yaml cli.InputSourceContext from a filepath. -func NewYamlSourceFromFile(file string) (cli.InputSourceContext, error) { - ysc := &yamlSourceContext{FilePath: file} - var results map[interface{}]interface{} - err := readCommandYaml(ysc.FilePath, &results) - return &MapInputSource{file: file, valueMap: results}, err -} - -func readCommandYaml(filePath string, container interface{}) error { - b, err := loadDataFrom(filePath) - if err != nil { - return err - } - return yaml.Unmarshal(b, container) -} - -func loadDataFrom(filePath string) ([]byte, error) { - u, err := url.Parse(filePath) - if err != nil { - return nil, err - } - - if u.Host != "" { // i have a host, now do i support the scheme? - switch u.Scheme { - case "http", "https": - res, err := http.Get(filePath) - if err != nil { - return nil, err - } - return ioutil.ReadAll(res.Body) - default: - return nil, fmt.Errorf("scheme of %s is unsupported", filePath) - } - } - if _, err := os.Stat(filePath); err != nil { - return nil, os.ErrNotExist - } - return ioutil.ReadFile(filePath) -} diff --git a/vendor/github.com/rancher/spur/cli/app.go b/vendor/github.com/rancher/spur/cli/app.go deleted file mode 100644 index 4966214ba7..0000000000 --- a/vendor/github.com/rancher/spur/cli/app.go +++ /dev/null @@ -1,540 +0,0 @@ -package cli - -import ( - "context" - "fmt" - "io" - "os" - "path/filepath" - "sort" - "time" - - "github.com/rancher/spur/flag" -) - -// App is the main structure of a cli application. It is recommended that -// an app be created with the cli.NewApp() function -type App struct { - // The name of the program. Defaults to path.Base(os.Args[0]) - Name string - // Full name of command for help, defaults to Name - HelpName string - // Description of the program. - Usage string - // Text to override the USAGE section of help - UsageText string - // Description of the program argument format. - ArgsUsage string - // Version of the program - Version string - // Description of the program - Description string - // List of commands to execute - Commands []*Command - // List of flags to parse - Flags []Flag - // Boolean to enable bash completion commands - EnableBashCompletion bool - // Boolean to hide built-in help command and help flag - HideHelp bool - // Boolean to hide built-in help command but keep help flag. - // Ignored if HideHelp is true. - HideHelpCommand bool - // Boolean to hide built-in version flag and the VERSION section of help - HideVersion bool - // categories contains the categorized commands and is populated on app startup - categories CommandCategories - // An action to execute when the shell completion flag is set - BashComplete BashCompleteFunc - // An action to execute before any subcommands are run, but after the context is ready - // If a non-nil error is returned, no subcommands are run - Before BeforeFunc - // An action to execute after any subcommands are run, but after the subcommand has finished - // It is run even if Action() panics - After AfterFunc - // The action to execute when no subcommands are specified - Action ActionFunc - // Execute this function if the proper command cannot be found - CommandNotFound CommandNotFoundFunc - // Execute this function if an usage error occurs - OnUsageError OnUsageErrorFunc - // Compilation date - Compiled time.Time - // List of all authors who contributed - Authors []*Author - // Copyright of the binary if any - Copyright string - // Writer writer to write output to - Writer io.Writer - // ErrWriter writes error output - ErrWriter io.Writer - // ExitErrHandler processes any error encountered while running an App before - // it is returned to the caller. If no function is provided, HandleExitCoder - // is used as the default behavior. - ExitErrHandler ExitErrHandlerFunc - // Other custom info - Metadata map[string]interface{} - // Carries a function which returns app specific info. - ExtraInfo func() map[string]string - // CustomAppHelpTemplate the text template for app help topic. - // cli.go uses text/template to render templates. You can - // render custom help text by setting this variable. - CustomAppHelpTemplate string - // Boolean to enable short-option handling so user can combine several - // single-character bool arguments into one - // i.e. foobar -o -v -> foobar -ov - UseShortOptionHandling bool - - didSetup bool -} - -type showHelpFunc = func(context *Context) error - -type showHelpError struct { - error -} - -// ShowHelpOnError will take a BeforeFunc and show command usage on error -func ShowHelpOnError(someFunc BeforeFunc) BeforeFunc { - return func(context *Context) error { - if err := someFunc(context); err != nil { - return showHelpError{err} - } - return nil - } -} - -// Tries to find out when this binary was compiled. -// Returns the current time if it fails to find it. -func compileTime() time.Time { - info, err := os.Stat(os.Args[0]) - if err != nil { - return time.Now() - } - return info.ModTime() -} - -// NewApp creates a new cli Application with some reasonable defaults for Name, -// Usage, Version and Action. -func NewApp() *App { - return &App{ - Name: filepath.Base(os.Args[0]), - HelpName: filepath.Base(os.Args[0]), - Usage: "A new cli application", - UsageText: "", - BashComplete: DefaultAppComplete, - Action: helpCommand.Action, - Compiled: compileTime(), - Writer: os.Stdout, - ErrWriter: os.Stderr, - } -} - -// Setup runs initialization code to ensure all data structures are ready for -// `Run` or inspection prior to `Run`. It is internally called by `Run`, but -// will return early if setup has already happened. -func (a *App) Setup() { - if a.didSetup { - return - } - - a.didSetup = true - - if a.Name == "" { - a.Name = filepath.Base(os.Args[0]) - } - - if a.HelpName == "" { - a.HelpName = filepath.Base(os.Args[0]) - } - - if a.Usage == "" { - a.Usage = "A new cli application" - } - - if a.Version == "" { - a.HideVersion = true - } - - if a.BashComplete == nil { - a.BashComplete = DefaultAppComplete - } - - if a.Action == nil { - a.Action = helpCommand.Action - } - - if a.Compiled == (time.Time{}) { - a.Compiled = compileTime() - } - - if a.Writer == nil { - a.Writer = os.Stdout - } - - if a.ErrWriter == nil { - a.ErrWriter = os.Stderr - } - - var newCommands []*Command - - for _, c := range a.Commands { - if c.HelpName == "" { - c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) - } - newCommands = append(newCommands, c) - } - a.Commands = newCommands - - if a.Command(helpCommand.Name) == nil && !a.HideHelp { - if !a.HideHelpCommand { - a.appendCommand(helpCommand) - } - - if HelpFlag != nil { - a.appendFlag(HelpFlag) - } - } - - if !a.HideVersion { - a.appendFlag(VersionFlag) - } - - a.categories = newCommandCategories() - for _, command := range a.Commands { - a.categories.AddCommand(command.Category, command) - } - sort.Sort(a.categories.(*commandCategories)) - - if a.Metadata == nil { - a.Metadata = make(map[string]interface{}) - } -} - -func (a *App) newFlagSet() (*flag.FlagSet, error) { - return flagSet(a.Name, a.Flags) -} - -func (a *App) useShortOptionHandling() bool { - return a.UseShortOptionHandling -} - -// Run is the entry point to the cli app. Parses the arguments slice and routes -// to the proper flag/args combination -func (a *App) Run(arguments []string) (err error) { - return a.RunContext(context.Background(), arguments) -} - -// RunContext is like Run except it takes a Context that will be -// passed to its commands and sub-commands. Through this, you can -// propagate timeouts and cancellation requests -func (a *App) RunContext(ctx context.Context, arguments []string) (err error) { - if len(arguments) == 0 { - return fmt.Errorf("arguments not provided") - } - a.Setup() - - // handle the completion flag separately from the flagset since - // completion could be attempted after a flag, but before its value was put - // on the command line. this causes the flagset to interpret the completion - // flag name as the value of the flag before it which is undesirable - // note that we can only do this because the shell autocomplete function - // always appends the completion flag at the end of the command - shellComplete, arguments := checkShellCompleteFlag(a, arguments) - - set, err := a.newFlagSet() - if err != nil { - return err - } - - err = parseIter(set, a, arguments[1:], shellComplete) - nerr := normalizeFlags(a.Flags, set) - context := NewContext(a, set, &Context{Context: ctx}) - if nerr != nil { - fmt.Fprintln(a.Writer, nerr) - ShowAppHelp(context) - return nerr - } - context.shellComplete = shellComplete - - if checkCompletions(context) { - return nil - } - - if err != nil { - return a.helpOnError(ShowAppHelp, context, showHelpError{err}) - } - - if !a.HideHelp && checkHelp(context) { - ShowAppHelp(context) - return nil - } - - if !a.HideVersion && checkVersion(context) { - ShowVersion(context) - return nil - } - - cerr := checkRequiredFlags(a.Flags, context) - if cerr != nil { - ShowAppHelp(context) - return cerr - } - - if a.After != nil { - defer func() { - if afterErr := a.After(context); afterErr != nil { - a.handleExitCoder(context, err) - if err != nil { - err = newMultiError(err, afterErr) - } else { - err = afterErr - } - } - }() - } - - if a.Before != nil { - if err := a.Before(context); err != nil { - return a.helpOnError(ShowAppHelp, context, err) - } - } - - args := context.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(context) - } - } - - if a.Action == nil { - a.Action = helpCommand.Action - } - - // Run default Action - err = a.Action(context) - - a.handleExitCoder(context, err) - return err -} - -func (a *App) helpOnError(showHelp showHelpFunc, context *Context, err error) error { - if err == nil { - return nil - } - if e, ok := err.(showHelpError); ok { - err = e.error - if a.OnUsageError != nil { - err = a.OnUsageError(context, err, false) - } else { - fmt.Fprintf(a.Writer, "%s:\n %s\n\n", "Incorrect Usage", err.Error()) - showHelp(context) - } - } - a.handleExitCoder(context, err) - return err -} - -// RunAndExitOnError calls .Run() and exits non-zero if an error was returned -// -// Deprecated: instead you should return an error that fulfills cli.ExitCoder -// to cli.App.Run. This will cause the application to exit with the given error -// code in the cli.ExitCoder -func (a *App) RunAndExitOnError() { - if err := a.Run(os.Args); err != nil { - fmt.Fprintf(a.ErrWriter, "\nFatal: %s\n", err) - OsExiter(1) - } -} - -// RunAsSubcommand invokes the subcommand given the context, parses ctx.Args() to -// generate command-specific flags -func (a *App) RunAsSubcommand(ctx *Context) (err error) { - // Setup also handles HideHelp and HideHelpCommand - a.Setup() - - var newCmds []*Command - for _, c := range a.Commands { - if c.HelpName == "" { - c.HelpName = fmt.Sprintf("%s %s", a.HelpName, c.Name) - } - newCmds = append(newCmds, c) - } - a.Commands = newCmds - - set, err := a.newFlagSet() - if err != nil { - return err - } - - err = parseIter(set, a, ctx.Args().Tail(), ctx.shellComplete) - nerr := normalizeFlags(a.Flags, set) - context := NewContext(a, set, ctx) - - if nerr != nil { - fmt.Fprintln(a.Writer, nerr) - fmt.Fprintln(a.Writer) - if len(a.Commands) > 0 { - ShowSubcommandHelp(context) - } else { - ShowCommandHelp(ctx, context.Args().First()) - } - return nerr - } - - if checkCompletions(context) { - return nil - } - - if err != nil { - return a.helpOnError(ShowSubcommandHelp, context, showHelpError{err}) - } - - if len(a.Commands) > 0 { - if checkSubcommandHelp(context) { - return nil - } - } else { - if checkCommandHelp(ctx, context.Args().First()) { - return nil - } - } - - cerr := checkRequiredFlags(a.Flags, context) - if cerr != nil { - ShowSubcommandHelp(context) - return cerr - } - - if a.After != nil { - defer func() { - if afterErr := a.After(context); afterErr != nil { - a.handleExitCoder(context, err) - if err != nil { - err = newMultiError(err, afterErr) - } else { - err = afterErr - } - } - }() - } - - if a.Before != nil { - if err := a.Before(context); err != nil { - return a.helpOnError(ShowSubcommandHelp, context, err) - } - } - - args := context.Args() - if args.Present() { - name := args.First() - c := a.Command(name) - if c != nil { - return c.Run(context) - } - } - - // Run default Action - err = a.Action(context) - - a.handleExitCoder(context, err) - return err -} - -// Command returns the named command on App. Returns nil if the command does not exist -func (a *App) Command(name string) *Command { - for _, c := range a.Commands { - if c.HasName(name) { - return c - } - } - - return nil -} - -// VisibleCategories returns a slice of categories and commands that are -// Hidden=false -func (a *App) VisibleCategories() []CommandCategory { - ret := []CommandCategory{} - for _, category := range a.categories.Categories() { - if visible := func() CommandCategory { - if len(category.VisibleCommands()) > 0 { - return category - } - return nil - }(); visible != nil { - ret = append(ret, visible) - } - } - return ret -} - -// VisibleCommands returns a slice of the Commands with Hidden=false -func (a *App) VisibleCommands() []*Command { - var ret []*Command - for _, command := range a.Commands { - if !command.Hidden { - ret = append(ret, command) - } - } - return ret -} - -// VisibleFlags returns a slice of the Flags with Hidden=false -func (a *App) VisibleFlags() []Flag { - return visibleFlags(a.Flags) -} - -func (a *App) appendFlag(fl Flag) { - if !hasFlag(a.Flags, fl) { - a.Flags = append(a.Flags, fl) - } -} - -func (a *App) appendCommand(c *Command) { - if !hasCommand(a.Commands, c) { - a.Commands = append(a.Commands, c) - } -} - -func (a *App) handleExitCoder(context *Context, err error) { - if a.ExitErrHandler != nil { - a.ExitErrHandler(context, err) - } else { - HandleExitCoder(err) - } -} - -// Author represents someone who has contributed to a cli project. -type Author struct { - Name string // The Authors name - Email string // The Authors email -} - -// String makes Author comply to the Stringer interface, to allow an easy print in the templating process -func (a *Author) String() string { - e := "" - if a.Email != "" { - e = " <" + a.Email + ">" - } - - return fmt.Sprintf("%v%v", a.Name, e) -} - -// HandleAction attempts to figure out which Action signature was used. If -// it's an ActionFunc or a func with the legacy signature for Action, the func -// is run! Panics on invalid function signature. -func HandleAction(action interface{}, context *Context) (err error) { - switch a := action.(type) { - case ActionFunc: - return a(context) - case func(*Context) error: - return a(context) - case func(*Context): // deprecated function signature - a(context) - return nil - } - panic(fmt.Sprintf("invalid Action type '%T', should be 'func(*Context) error'", action)) -} diff --git a/vendor/github.com/rancher/spur/cli/args.go b/vendor/github.com/rancher/spur/cli/args.go deleted file mode 100644 index bd65c17bde..0000000000 --- a/vendor/github.com/rancher/spur/cli/args.go +++ /dev/null @@ -1,54 +0,0 @@ -package cli - -type Args interface { - // Get returns the nth argument, or else a blank string - Get(n int) string - // First returns the first argument, or else a blank string - First() string - // Tail returns the rest of the arguments (not the first one) - // or else an empty string slice - Tail() []string - // Len returns the length of the wrapped slice - Len() int - // Present checks if there are any arguments present - Present() bool - // Slice returns a copy of the internal slice - Slice() []string -} - -type args []string - -func (a *args) Get(n int) string { - if len(*a) > n { - return (*a)[n] - } - return "" -} - -func (a *args) First() string { - return a.Get(0) -} - -func (a *args) Tail() []string { - if a.Len() >= 2 { - tail := []string((*a)[1:]) - ret := make([]string, len(tail)) - copy(ret, tail) - return ret - } - return []string{} -} - -func (a *args) Len() int { - return len(*a) -} - -func (a *args) Present() bool { - return a.Len() != 0 -} - -func (a *args) Slice() []string { - ret := make([]string, len(*a)) - copy(ret, *a) - return ret -} diff --git a/vendor/github.com/rancher/spur/cli/category.go b/vendor/github.com/rancher/spur/cli/category.go deleted file mode 100644 index 867e3908ca..0000000000 --- a/vendor/github.com/rancher/spur/cli/category.go +++ /dev/null @@ -1,79 +0,0 @@ -package cli - -// CommandCategories interface allows for category manipulation -type CommandCategories interface { - // AddCommand adds a command to a category, creating a new category if necessary. - AddCommand(category string, command *Command) - // categories returns a copy of the category slice - Categories() []CommandCategory -} - -type commandCategories []*commandCategory - -func newCommandCategories() CommandCategories { - ret := commandCategories([]*commandCategory{}) - return &ret -} - -func (c *commandCategories) Less(i, j int) bool { - return lexicographicLess((*c)[i].Name(), (*c)[j].Name()) -} - -func (c *commandCategories) Len() int { - return len(*c) -} - -func (c *commandCategories) Swap(i, j int) { - (*c)[i], (*c)[j] = (*c)[j], (*c)[i] -} - -func (c *commandCategories) AddCommand(category string, command *Command) { - for _, commandCategory := range []*commandCategory(*c) { - if commandCategory.name == category { - commandCategory.commands = append(commandCategory.commands, command) - return - } - } - newVal := append(*c, - &commandCategory{name: category, commands: []*Command{command}}) - *c = newVal -} - -func (c *commandCategories) Categories() []CommandCategory { - ret := make([]CommandCategory, len(*c)) - for i, cat := range *c { - ret[i] = cat - } - return ret -} - -// CommandCategory is a category containing commands. -type CommandCategory interface { - // Name returns the category name string - Name() string - // VisibleCommands returns a slice of the Commands with Hidden=false - VisibleCommands() []*Command -} - -type commandCategory struct { - name string - commands []*Command -} - -func (c *commandCategory) Name() string { - return c.name -} - -func (c *commandCategory) VisibleCommands() []*Command { - if c.commands == nil { - c.commands = []*Command{} - } - - var ret []*Command - for _, command := range c.commands { - if !command.Hidden { - ret = append(ret, command) - } - } - return ret -} diff --git a/vendor/github.com/rancher/spur/cli/command.go b/vendor/github.com/rancher/spur/cli/command.go deleted file mode 100644 index 3f0779eb96..0000000000 --- a/vendor/github.com/rancher/spur/cli/command.go +++ /dev/null @@ -1,301 +0,0 @@ -package cli - -import ( - "fmt" - "sort" - "strings" - - "github.com/rancher/spur/flag" -) - -// Command is a subcommand for a cli.App. -type Command struct { - // The name of the command - Name string - // A list of aliases for the command - Aliases []string - // A short description of the usage of this command - Usage string - // Custom text to show on USAGE section of help - UsageText string - // A longer explanation of how the command works - Description string - // A short description of the arguments of this command - ArgsUsage string - // The category the command is part of - Category string - // The function to call when checking for bash command completions - BashComplete BashCompleteFunc - // An action to execute before any sub-subcommands are run, but after the context is ready - // If a non-nil error is returned, no sub-subcommands are run - Before BeforeFunc - // An action to execute after any subcommands are run, but after the subcommand has finished - // It is run even if Action() panics - After AfterFunc - // The function to call when this command is invoked - Action ActionFunc - // Execute this function if a usage error occurs. - OnUsageError OnUsageErrorFunc - // List of child commands - Subcommands []*Command - // List of flags to parse - Flags []Flag - // Treat all flags as normal arguments if true - SkipFlagParsing bool - // Boolean to hide built-in help command and help flag - HideHelp bool - // Boolean to hide built-in help command but keep help flag - // Ignored if HideHelp is true. - HideHelpCommand bool - // Boolean to hide this command from help or completion - Hidden bool - // Boolean to enable short-option handling so user can combine several - // single-character bool arguments into one - // i.e. foobar -o -v -> foobar -ov - UseShortOptionHandling bool - - // Full name of command for help, defaults to full command name, including parent commands. - HelpName string - commandNamePath []string - - // CustomHelpTemplate the text template for the command help topic. - // cli.go uses text/template to render templates. You can - // render custom help text by setting this variable. - CustomHelpTemplate string -} - -type Commands []*Command - -type CommandsByName []*Command - -func (c CommandsByName) Len() int { - return len(c) -} - -func (c CommandsByName) Less(i, j int) bool { - return lexicographicLess(c[i].Name, c[j].Name) -} - -func (c CommandsByName) Swap(i, j int) { - c[i], c[j] = c[j], c[i] -} - -// FullName returns the full name of the command. -// For subcommands this ensures that parent commands are part of the command path -func (c *Command) FullName() string { - if c.commandNamePath == nil { - return c.Name - } - return strings.Join(c.commandNamePath, " ") -} - -// Run invokes the command given the context, parses ctx.Args() to generate command-specific flags -func (c *Command) Run(ctx *Context) (err error) { - if len(c.Subcommands) > 0 { - return c.startApp(ctx) - } - - if !c.HideHelp && HelpFlag != nil { - // append help to flags - c.appendFlag(HelpFlag) - } - - if ctx.App.UseShortOptionHandling { - c.UseShortOptionHandling = true - } - - set, err := c.parseFlags(ctx.Args(), ctx.shellComplete) - - context := NewContext(ctx.App, set, ctx) - context.Command = c - if checkCommandCompletions(context, c.Name) { - return nil - } - - if err != nil { - if c.OnUsageError != nil { - err = c.OnUsageError(context, err, false) - context.App.handleExitCoder(context, err) - return err - } - fmt.Fprintln(context.App.Writer, "Incorrect Usage:", err.Error()) - fmt.Fprintln(context.App.Writer) - ShowCommandHelp(context, c.Name) - return err - } - - if checkCommandHelp(context, c.Name) { - return nil - } - - cerr := checkRequiredFlags(c.Flags, context) - if cerr != nil { - ShowCommandHelp(context, c.Name) - return cerr - } - - if c.After != nil { - defer func() { - afterErr := c.After(context) - if afterErr != nil { - context.App.handleExitCoder(context, err) - if err != nil { - err = newMultiError(err, afterErr) - } else { - err = afterErr - } - } - }() - } - - if c.Before != nil { - err = c.Before(context) - if err != nil { - context.App.handleExitCoder(context, err) - return err - } - } - - if c.Action == nil { - c.Action = helpSubcommand.Action - } - - context.Command = c - err = c.Action(context) - - if err != nil { - context.App.handleExitCoder(context, err) - } - return err -} - -func (c *Command) newFlagSet() (*flag.FlagSet, error) { - return flagSet(c.Name, c.Flags) -} - -func (c *Command) useShortOptionHandling() bool { - return c.UseShortOptionHandling -} - -func (c *Command) parseFlags(args Args, shellComplete bool) (*flag.FlagSet, error) { - set, err := c.newFlagSet() - if err != nil { - return nil, err - } - - if c.SkipFlagParsing { - return set, set.Parse(append([]string{"--"}, args.Tail()...)) - } - - err = parseIter(set, c, args.Tail(), shellComplete) - if err != nil { - return nil, err - } - - err = normalizeFlags(c.Flags, set) - if err != nil { - return nil, err - } - - return set, nil -} - -// Names returns the names including short names and aliases. -func (c *Command) Names() []string { - return append([]string{c.Name}, c.Aliases...) -} - -// HasName returns true if Command.Name matches given name -func (c *Command) HasName(name string) bool { - for _, n := range c.Names() { - if n == name { - return true - } - } - return false -} - -func (c *Command) startApp(ctx *Context) error { - app := &App{ - Metadata: ctx.App.Metadata, - Name: fmt.Sprintf("%s %s", ctx.App.Name, c.Name), - } - - if c.HelpName == "" { - app.HelpName = c.HelpName - } else { - app.HelpName = app.Name - } - - app.Usage = c.Usage - app.Description = c.Description - app.ArgsUsage = c.ArgsUsage - - // set CommandNotFound - app.CommandNotFound = ctx.App.CommandNotFound - app.CustomAppHelpTemplate = c.CustomHelpTemplate - - // set the flags and commands - app.Commands = c.Subcommands - app.Flags = c.Flags - app.HideHelp = c.HideHelp - app.HideHelpCommand = c.HideHelpCommand - - app.Version = ctx.App.Version - app.HideVersion = ctx.App.HideVersion - app.Compiled = ctx.App.Compiled - app.Writer = ctx.App.Writer - app.ErrWriter = ctx.App.ErrWriter - app.ExitErrHandler = ctx.App.ExitErrHandler - app.UseShortOptionHandling = ctx.App.UseShortOptionHandling - - app.categories = newCommandCategories() - for _, command := range c.Subcommands { - app.categories.AddCommand(command.Category, command) - } - - sort.Sort(app.categories.(*commandCategories)) - - // bash completion - app.EnableBashCompletion = ctx.App.EnableBashCompletion - if c.BashComplete != nil { - app.BashComplete = c.BashComplete - } - - // set the actions - app.Before = c.Before - app.After = c.After - if c.Action != nil { - app.Action = c.Action - } else { - app.Action = helpSubcommand.Action - } - app.OnUsageError = c.OnUsageError - - for index, cc := range app.Commands { - app.Commands[index].commandNamePath = []string{c.Name, cc.Name} - } - - return app.RunAsSubcommand(ctx) -} - -// VisibleFlags returns a slice of the Flags with Hidden=false -func (c *Command) VisibleFlags() []Flag { - return visibleFlags(c.Flags) -} - -func (c *Command) appendFlag(fl Flag) { - if !hasFlag(c.Flags, fl) { - c.Flags = append(c.Flags, fl) - } -} - -func hasCommand(commands []*Command, command *Command) bool { - for _, existing := range commands { - if command == existing { - return true - } - } - - return false -} diff --git a/vendor/github.com/rancher/spur/cli/context.go b/vendor/github.com/rancher/spur/cli/context.go deleted file mode 100644 index 8e41ce675d..0000000000 --- a/vendor/github.com/rancher/spur/cli/context.go +++ /dev/null @@ -1,275 +0,0 @@ -package cli - -import ( - "context" - "fmt" - "reflect" - "strings" - - "github.com/rancher/spur/flag" -) - -// Context is a type that is passed through to -// each Handler action in a cli application. Context -// can be used to retrieve context-specific args and -// parsed command-line options. -type Context struct { - context.Context - App *App - Command *Command - shellComplete bool - flagSet *flag.FlagSet - parentContext *Context -} - -// NewContext creates a new context. For use in when invoking an App or Command action. -func NewContext(app *App, set *flag.FlagSet, parentCtx *Context) *Context { - c := &Context{App: app, flagSet: set, parentContext: parentCtx} - if parentCtx != nil { - c.Context = parentCtx.Context - c.shellComplete = parentCtx.shellComplete - if parentCtx.flagSet == nil { - parentCtx.flagSet = &flag.FlagSet{} - } - } - - c.Command = &Command{} - - if c.Context == nil { - c.Context = context.Background() - } - - return c -} - -// NumFlags returns the number of flags set -func (c *Context) NumFlags() int { - return c.flagSet.NFlag() -} - -// Set sets a context flag to a value. -func (c *Context) Set(name string, value interface{}) error { - return c.flagSet.Set(name, value) -} - -// IsSet determines if the flag was actually set -func (c *Context) IsSet(name string) bool { - if fs := lookupFlagSet(name, c); fs != nil { - isSet := false - fs.Visit(func(f *flag.Flag) { - if f.Name == name { - isSet = true - } - }) - if isSet { - return true - } - } - return false -} - -// LocalFlagNames returns a slice of flag names used in this context. -func (c *Context) LocalFlagNames() []string { - var names []string - c.flagSet.Visit(makeFlagNameVisitor(&names)) - return names -} - -// FlagNames returns a slice of flag names used by the this context and all of -// its parent contexts. -func (c *Context) FlagNames() []string { - var names []string - for _, ctx := range c.Lineage() { - ctx.flagSet.Visit(makeFlagNameVisitor(&names)) - } - return names -} - -// Lineage returns *this* context and all of its ancestor contexts in order from -// child to parent -func (c *Context) Lineage() []*Context { - var lineage []*Context - - for cur := c; cur != nil; cur = cur.parentContext { - lineage = append(lineage, cur) - } - - return lineage -} - -// Value returns the value of the flag corresponding to `name` -func (c *Context) Value(name string) interface{} { - return c.flagSet.Lookup(name).Value.(flag.Getter).Get() -} - -// Args returns the command line arguments associated with the context. -func (c *Context) Args() Args { - ret := args(c.flagSet.Args()) - return &ret -} - -// NArg returns the number of the command line arguments. -func (c *Context) NArg() int { - return c.Args().Len() -} - -// Lookup will return the value for a flag, or the default value if -// the flag value does not exist or is not of the same type -func (c *Context) Lookup(name string, defaultVal interface{}) interface{} { - var result interface{} - if fs := lookupFlagSet(name, c); fs != nil { - if f := fs.Lookup(name); f != nil { - result = f.Value - } - } - if result == nil { - return defaultVal - } - // if we don't have a default value assume they want they flag.Value - if defaultVal != nil { - result = result.(flag.Getter).Get() - } - if defaultVal == nil || reflect.TypeOf(result) == reflect.TypeOf(defaultVal) { - return result - } - return defaultVal -} - -// GetFlags will return all of the flags found for this context -func (c *Context) GetFlags() []Flag { - flags := []Flag{} - for _, ctx := range c.Lineage() { - if ctx.Command != nil { - flags = append(flags, ctx.Command.Flags...) - } - } - if c.App != nil { - flags = append(flags, c.App.Flags...) - } - return flags -} - -func lookupFlag(name string, ctx *Context) Flag { - for _, f := range ctx.GetFlags() { - for _, n := range FlagNames(f) { - if n == name { - return f - } - } - } - return nil -} - -func lookupFlagSet(name string, ctx *Context) *flag.FlagSet { - for _, c := range ctx.Lineage() { - if f := c.flagSet.Lookup(name); f != nil { - return c.flagSet - } - } - - return nil -} - -func copyFlag(name string, ff *flag.Flag, set *flag.FlagSet) { - set.Set(name, ff.Value.String()) -} - -func normalizeFlags(flags []Flag, set *flag.FlagSet) error { - visited := make(map[string]bool) - set.Visit(func(f *flag.Flag) { - visited[f.Name] = true - }) - for _, f := range flags { - parts := FlagNames(f) - if len(parts) == 1 { - continue - } - var ff *flag.Flag - for _, name := range parts { - name = strings.Trim(name, " ") - if visited[name] { - ff = set.Lookup(name) - } - } - if ff == nil { - continue - } - for _, name := range parts { - name = strings.Trim(name, " ") - if !visited[name] { - copyFlag(name, ff, set) - } - } - } - return nil -} - -func makeFlagNameVisitor(names *[]string) func(*flag.Flag) { - return func(f *flag.Flag) { - nameParts := strings.Split(f.Name, ",") - name := strings.TrimSpace(nameParts[0]) - - for _, part := range nameParts { - part = strings.TrimSpace(part) - if len(part) > len(name) { - name = part - } - } - - if name != "" { - *names = append(*names, name) - } - } -} - -type requiredFlagsErr interface { - error - getMissingFlags() []string -} - -type errRequiredFlags struct { - missingFlags []string -} - -func (e *errRequiredFlags) Error() string { - numberOfMissingFlags := len(e.missingFlags) - if numberOfMissingFlags == 1 { - return fmt.Sprintf("Required flag %q not set", e.missingFlags[0]) - } - joinedMissingFlags := strings.Join(e.missingFlags, ", ") - return fmt.Sprintf("Required flags %q not set", joinedMissingFlags) -} - -func (e *errRequiredFlags) getMissingFlags() []string { - return e.missingFlags -} - -func checkRequiredFlags(flags []Flag, context *Context) requiredFlagsErr { - var missingFlags []string - for _, f := range flags { - if required, ok := getFlagRequired(f); ok && required { - var flagPresent bool - var flagName string - - for _, key := range FlagNames(f) { - if len(key) > 1 { - flagName = key - } - - if context.IsSet(strings.TrimSpace(key)) { - flagPresent = true - } - } - - if !flagPresent && flagName != "" { - missingFlags = append(missingFlags, flagName) - } - } - } - - if len(missingFlags) != 0 { - return &errRequiredFlags{missingFlags: missingFlags} - } - - return nil -} diff --git a/vendor/github.com/rancher/spur/cli/docs.go b/vendor/github.com/rancher/spur/cli/docs.go deleted file mode 100644 index 0046a3d70c..0000000000 --- a/vendor/github.com/rancher/spur/cli/docs.go +++ /dev/null @@ -1,160 +0,0 @@ -// +build docgen - -package cli - -import ( - "bytes" - "fmt" - "io" - "sort" - "strings" - "text/template" - - "github.com/cpuguy83/go-md2man/v2/md2man" - "github.com/rancher/spur/flag" - "github.com/rancher/spur/generic" -) - -// ToMarkdown creates a markdown string for the `*App` -// The function errors if either parsing or writing of the string fails. -func (a *App) ToMarkdown() (string, error) { - var w bytes.Buffer - if err := a.writeDocTemplate(&w); err != nil { - return "", err - } - return w.String(), nil -} - -// ToMan creates a man page string for the `*App` -// The function errors if either parsing or writing of the string fails. -func (a *App) ToMan() (string, error) { - var w bytes.Buffer - if err := a.writeDocTemplate(&w); err != nil { - return "", err - } - man := md2man.Render(w.Bytes()) - return string(man), nil -} - -type cliTemplate struct { - App *App - Commands []string - GlobalArgs []string - SynopsisArgs []string -} - -func (a *App) writeDocTemplate(w io.Writer) error { - const name = "cli" - t, err := template.New(name).Parse(MarkdownDocTemplate) - if err != nil { - return err - } - return t.ExecuteTemplate(w, name, &cliTemplate{ - App: a, - Commands: prepareCommands(a.Commands, 0), - GlobalArgs: prepareArgsWithValues(a.VisibleFlags()), - SynopsisArgs: prepareArgsSynopsis(a.VisibleFlags()), - }) -} - -func prepareCommands(commands []*Command, level int) []string { - var coms []string - for _, command := range commands { - if command.Hidden { - continue - } - usage := "" - if command.Usage != "" { - usage = command.Usage - } - - prepared := fmt.Sprintf("%s %s\n\n%s\n", - strings.Repeat("#", level+2), - strings.Join(command.Names(), ", "), - usage, - ) - - flags := prepareArgsWithValues(command.Flags) - if len(flags) > 0 { - prepared += fmt.Sprintf("\n%s", strings.Join(flags, "\n")) - } - - coms = append(coms, prepared) - - // recursevly iterate subcommands - if len(command.Subcommands) > 0 { - coms = append( - coms, - prepareCommands(command.Subcommands, level+1)..., - ) - } - } - - return coms -} - -func prepareArgsWithValues(flags []Flag) []string { - return prepareFlags(flags, ", ", "**", "**", `""`, true) -} - -func prepareArgsSynopsis(flags []Flag) []string { - return prepareFlags(flags, "|", "[", "]", "[value]", false) -} - -func prepareFlags( - flags []Flag, - sep, opener, closer, value string, - addDetails bool, -) []string { - args := []string{} - for _, f := range flags { - modifiedArg := opener - - for _, s := range FlagNames(f) { - trimmed := strings.TrimSpace(s) - if len(modifiedArg) > len(opener) { - modifiedArg += sep - } - if len(trimmed) > 1 { - modifiedArg += fmt.Sprintf("--%s", trimmed) - } else { - modifiedArg += fmt.Sprintf("-%s", trimmed) - } - } - modifiedArg += closer - if v, ok := getFlagValue(f); ok && !flag.IsBoolValue(v) { - modifiedArg += fmt.Sprintf("=%s", value) - } - - if addDetails { - modifiedArg += flagDetails(f) - } - - args = append(args, modifiedArg+"\n") - - } - sort.Strings(args) - return args -} - -// flagDetails returns a string containing the flags metadata -func flagDetails(f Flag) string { - description, _ := getFlagUsage(f) - value, _ := getFlagValue(f) - valStr := "" - - if !flag.IsBoolValue(value) { - if v, ok := value.(Generic); ok { - valStr = v.String() - } else if s, ok := generic.ToString(value); ok { - valStr = s - } else { - valStr = fmt.Sprintf("%v", value) - } - } - - if valStr != "" { - description += " (default: " + valStr + ")" - } - return ": " + description -} diff --git a/vendor/github.com/rancher/spur/cli/errors.go b/vendor/github.com/rancher/spur/cli/errors.go deleted file mode 100644 index f8a5c35b38..0000000000 --- a/vendor/github.com/rancher/spur/cli/errors.go +++ /dev/null @@ -1,141 +0,0 @@ -package cli - -import ( - "fmt" - "io" - "os" - "strings" -) - -// OsExiter is the function used when the app exits. If not set defaults to os.Exit. -var OsExiter = os.Exit - -// ErrWriter is used to write errors to the user. This can be anything -// implementing the io.Writer interface and defaults to os.Stderr. -var ErrWriter io.Writer = os.Stderr - -// MultiError is an error that wraps multiple errors. -type MultiError interface { - error - Errors() []error -} - -// newMultiError creates a new MultiError. Pass in one or more errors. -func newMultiError(err ...error) MultiError { - ret := multiError(err) - return &ret -} - -type multiError []error - -// Error implements the error interface. -func (m *multiError) Error() string { - errs := make([]string, len(*m)) - for i, err := range *m { - errs[i] = err.Error() - } - - return strings.Join(errs, "\n") -} - -// Errors returns a copy of the errors slice -func (m *multiError) Errors() []error { - errs := make([]error, len(*m)) - for _, err := range *m { - errs = append(errs, err) - } - return errs -} - -// ErrorFormatter is the interface that will suitably format the error output -type ErrorFormatter interface { - Format(s fmt.State, verb rune) -} - -// ExitCoder is the interface checked by `App` and `Command` for a custom exit -// code -type ExitCoder interface { - error - ExitCode() int -} - -type exitError struct { - exitCode int - message interface{} -} - -// NewExitError calls Exit to create a new ExitCoder. -// -// Deprecated: This function is a duplicate of Exit and will eventually be removed. -func NewExitError(message interface{}, exitCode int) ExitCoder { - return Exit(message, exitCode) -} - -// Exit wraps a message and exit code into an error, which by default is -// handled with a call to os.Exit during default error handling. -// -// This is the simplest way to trigger a non-zero exit code for an App without -// having to call os.Exit manually. During testing, this behavior can be avoided -// by overiding the ExitErrHandler function on an App or the package-global -// OsExiter function. -func Exit(message interface{}, exitCode int) ExitCoder { - return &exitError{ - message: message, - exitCode: exitCode, - } -} - -func (ee *exitError) Error() string { - return fmt.Sprintf("%v", ee.message) -} - -func (ee *exitError) ExitCode() int { - return ee.exitCode -} - -// HandleExitCoder handles errors implementing ExitCoder by printing their -// message and calling OsExiter with the given exit code. -// -// If the given error instead implements MultiError, each error will be checked -// for the ExitCoder interface, and OsExiter will be called with the last exit -// code found, or exit code 1 if no ExitCoder is found. -// -// This function is the default error-handling behavior for an App. -func HandleExitCoder(err error) { - if err == nil { - return - } - - if exitErr, ok := err.(ExitCoder); ok { - if err.Error() != "" { - if _, ok := exitErr.(ErrorFormatter); ok { - fmt.Fprintf(ErrWriter, "%+v\n", err) - } else { - fmt.Fprintln(ErrWriter, err) - } - } - OsExiter(exitErr.ExitCode()) - return - } - - if multiErr, ok := err.(MultiError); ok { - code := handleMultiError(multiErr) - OsExiter(code) - return - } -} - -func handleMultiError(multiErr MultiError) int { - code := 1 - for _, merr := range multiErr.Errors() { - if multiErr2, ok := merr.(MultiError); ok { - code = handleMultiError(multiErr2) - } else if merr != nil { - fmt.Fprintln(ErrWriter, merr) - if exitErr, ok := merr.(ExitCoder); ok { - code = exitErr.ExitCode() - } - } - } - return code -} diff --git a/vendor/github.com/rancher/spur/cli/fish.go b/vendor/github.com/rancher/spur/cli/fish.go deleted file mode 100644 index 016e484e94..0000000000 --- a/vendor/github.com/rancher/spur/cli/fish.go +++ /dev/null @@ -1,178 +0,0 @@ -package cli - -import ( - "bytes" - "fmt" - "io" - "strings" - "text/template" - - "github.com/rancher/spur/flag" -) - -// ToFishCompletion creates a fish completion string for the `*App` -// The function errors if either parsing or writing of the string fails. -func (a *App) ToFishCompletion() (string, error) { - var w bytes.Buffer - if err := a.writeFishCompletionTemplate(&w); err != nil { - return "", err - } - return w.String(), nil -} - -type fishCompletionTemplate struct { - App *App - Completions []string - AllCommands []string -} - -func (a *App) writeFishCompletionTemplate(w io.Writer) error { - const name = "cli" - t, err := template.New(name).Parse(FishCompletionTemplate) - if err != nil { - return err - } - allCommands := []string{} - - // Add global flags - completions := a.prepareFishFlags(a.VisibleFlags(), allCommands) - - // Add help flag - if !a.HideHelp { - completions = append( - completions, - a.prepareFishFlags([]Flag{HelpFlag}, allCommands)..., - ) - } - - // Add version flag - if !a.HideVersion { - completions = append( - completions, - a.prepareFishFlags([]Flag{VersionFlag}, allCommands)..., - ) - } - - // Add commands and their flags - completions = append( - completions, - a.prepareFishCommands(a.VisibleCommands(), &allCommands, []string{})..., - ) - - return t.ExecuteTemplate(w, name, &fishCompletionTemplate{ - App: a, - Completions: completions, - AllCommands: allCommands, - }) -} - -func (a *App) prepareFishCommands(commands []*Command, allCommands *[]string, previousCommands []string) []string { - completions := []string{} - for _, command := range commands { - if command.Hidden { - continue - } - - var completion strings.Builder - completion.WriteString(fmt.Sprintf( - "complete -r -c %s -n '%s' -a '%s'", - a.Name, - a.fishSubcommandHelper(previousCommands), - strings.Join(command.Names(), " "), - )) - - if command.Usage != "" { - completion.WriteString(fmt.Sprintf(" -d '%s'", - escapeSingleQuotes(command.Usage))) - } - - if !command.HideHelp { - completions = append( - completions, - a.prepareFishFlags([]Flag{HelpFlag}, command.Names())..., - ) - } - - *allCommands = append(*allCommands, command.Names()...) - completions = append(completions, completion.String()) - completions = append( - completions, - a.prepareFishFlags(command.Flags, command.Names())..., - ) - - // recursevly iterate subcommands - if len(command.Subcommands) > 0 { - completions = append( - completions, - a.prepareFishCommands( - command.Subcommands, allCommands, command.Names(), - )..., - ) - } - } - - return completions -} - -func (a *App) prepareFishFlags(flags []Flag, previousCommands []string) []string { - completions := []string{} - for _, f := range flags { - completion := &strings.Builder{} - completion.WriteString(fmt.Sprintf( - "complete -c %s -n '%s'", - a.Name, - a.fishSubcommandHelper(previousCommands), - )) - - fishAddFileFlag(f, completion) - - for idx, opt := range FlagNames(f) { - if idx == 0 { - completion.WriteString(fmt.Sprintf( - " -l %s", strings.TrimSpace(opt), - )) - } else { - completion.WriteString(fmt.Sprintf( - " -s %s", strings.TrimSpace(opt), - )) - - } - } - - if v, ok := getFlagValue(f); ok && !flag.IsBoolValue(v) { - completion.WriteString(" -r") - } - - if usage, ok := getFlagUsage(f); ok && usage != "" { - completion.WriteString(fmt.Sprintf(" -d '%s'", - escapeSingleQuotes(usage))) - } - - completions = append(completions, completion.String()) - } - - return completions -} - -func fishAddFileFlag(flag Flag, completion *strings.Builder) { - if takesFile, ok := getFlagTakesFile(flag); ok && takesFile { - return - } - completion.WriteString(" -f") -} - -func (a *App) fishSubcommandHelper(allCommands []string) string { - fishHelper := fmt.Sprintf("__fish_%s_no_subcommand", a.Name) - if len(allCommands) > 0 { - fishHelper = fmt.Sprintf( - "__fish_seen_subcommand_from %s", - strings.Join(allCommands, " "), - ) - } - return fishHelper - -} - -func escapeSingleQuotes(input string) string { - return strings.Replace(input, `'`, `\'`, -1) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.go b/vendor/github.com/rancher/spur/cli/flag.go deleted file mode 100644 index ff263a103b..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.go +++ /dev/null @@ -1,318 +0,0 @@ -package cli - -import ( - "fmt" - "io/ioutil" - "reflect" - "regexp" - "runtime" - "strings" - - "github.com/rancher/spur/flag" - "github.com/rancher/spur/generic" -) - -// Flag is a common interface related to parsing flags in cli. -type Flag interface { - // Apply Flag settings to the given flag set - Apply(*flag.FlagSet) error -} - -// BashCompletionFlag enables bash-completion for all commands and subcommands -var BashCompletionFlag Flag = &BoolFlag{ - Name: "generate-bash-completion", - Hidden: true, -} - -// VersionFlag prints the version for the application -var VersionFlag Flag = &BoolFlag{ - Name: "version", - Aliases: []string{"v"}, - Usage: "print the version", -} - -// HelpFlag prints the help for all commands and subcommands. -// Set to nil to disable the flag. The subcommand -// will still be added unless HideHelp or HideHelpCommand is set to true. -var HelpFlag Flag = &BoolFlag{ - Name: "help", - Aliases: []string{"h"}, - Usage: "show help", -} - -// FlagStringer converts a flag definition to a string. This is used by help -// to display a flag. -var FlagStringer FlagStringFunc = stringifyFlag - -// FlagNamePrefixer converts a full flag name and its placeholder into the help -// message flag prefix. This is used by the default FlagStringer. -var FlagNamePrefixer FlagNamePrefixFunc = prefixedNames - -// FlagEnvHinter annotates flag help message with the environment variable -// details. This is used by the default FlagStringer. -var FlagEnvHinter FlagEnvHintFunc = withEnvHint - -// FlagFileHinter annotates flag help message with the environment variable -// details. This is used by the default FlagStringer. -var FlagFileHinter FlagFileHintFunc = withFileHint - -// FlagsByName is a slice of Flag. -type FlagsByName []Flag - -const defaultPlaceholder = "value" - -func (f FlagsByName) Len() int { - return len(f) -} - -func (f FlagsByName) Less(i, j int) bool { - namesI := FlagNames(f[i]) - namesJ := FlagNames(f[j]) - if len(namesJ) == 0 { - return false - } else if len(namesI) == 0 { - return true - } - return lexicographicLess(namesI[0], namesJ[0]) -} - -func (f FlagsByName) Swap(i, j int) { - f[i], f[j] = f[j], f[i] -} - -func flagSet(name string, flags []Flag) (*flag.FlagSet, error) { - set := flag.NewFlagSet(name, flag.ContinueOnError) - - for _, f := range flags { - if err := f.Apply(set); err != nil { - return nil, err - } - } - set.SetOutput(ioutil.Discard) - return set, nil -} - -func visibleFlags(fl []Flag) []Flag { - var visible []Flag - for _, f := range fl { - if hidden, ok := getFlagHidden(f); !hidden || !ok { - visible = append(visible, f) - } - } - return visible -} - -func prefixFor(name string) (prefix string) { - if len(name) == 1 { - prefix = "-" - } else { - prefix = "--" - } - - return -} - -// Returns the placeholder, if any, and the unquoted usage string. -func unquoteUsage(usage string) (string, string) { - for i := 0; i < len(usage); i++ { - if usage[i] == '`' { - for j := i + 1; j < len(usage); j++ { - if usage[j] == '`' { - name := usage[i+1 : j] - usage = usage[:i] + name + usage[j+1:] - return name, usage - } - } - break - } - } - return "", usage -} - -func prefixedNames(names []string, placeholder string) string { - var prefixed string - for i, name := range names { - if name == "" { - continue - } - - prefixed += prefixFor(name) + name - if placeholder != "" { - prefixed += " " + placeholder - } - if i < len(names)-1 { - prefixed += ", " - } - } - return prefixed -} - -func withEnvHint(envVars []string, str string) string { - envText := "" - if envVars != nil && len(envVars) > 0 { - prefix := "$" - suffix := "" - sep := ", $" - if runtime.GOOS == "windows" { - prefix = "%" - suffix = "%" - sep = "%, %" - } - - envText = fmt.Sprintf(" [%s%s%s]", prefix, strings.Join(envVars, sep), suffix) - } - return str + envText -} - -// FlagNames returns the name and aliases for a given flag, and panics -// if any of the values are invalid -func FlagNames(f Flag) []string { - name, ok := getFlagName(f) - if !ok { - panic("flag is missing name field") - } - aliases, _ := getFlagAliases(f) - - var ret []string - - for _, part := range strings.Split(name, ",") { - // urfave/cli v1 -> v2 migration warning zone: - // split name as per v1 standard - ret = append(ret, strings.TrimSpace(part)) - } - - // add the aliases to our names - ret = append(ret, aliases...) - - // validate the names and panic on failure - for _, part := range ret { - if strings.Contains(part, ",") { - panic(fmt.Errorf("flag name contains a comma: %q", part)) - } - if regexp.MustCompile(`\s`).Match([]byte(part)) { - panic(fmt.Errorf("flag name contains whitespace: %q", part)) - } - if part == "" { - panic("flag has an empty name") - } - } - - return ret -} - -func flagStringSliceField(f Flag, name string) []string { - fv := flagValue(f) - field := fv.FieldByName(name) - - if field.IsValid() { - return field.Interface().([]string) - } - - return []string{} -} - -func withFileHint(filePath, str string) string { - fileText := "" - if filePath != "" { - fileText = fmt.Sprintf(" [%s]", filePath) - } - return str + fileText -} - -func flagValue(f Flag) reflect.Value { - fv := reflect.ValueOf(f) - for fv.Kind() == reflect.Ptr { - fv = reflect.Indirect(fv) - } - return fv -} - -func formatDefault(format string) string { - return " (default: " + format + ")" -} - -func stringifyFlag(f Flag) string { - value, _ := getFlagValue(f) - usage, _ := getFlagUsage(f) - - if generic.IsSlice(value) { - return withEnvHint(flagStringSliceField(f, "EnvVars"), - stringifySlice(usage, FlagNames(f), value)) - } - - placeholder, usage := unquoteUsage(usage) - - needsPlaceholder := false - defaultValueString := "" - - var valKind reflect.Kind - - if valType := generic.TypeOf(value); valType != nil { - valKind = valType.Kind() - needsPlaceholder = valKind != reflect.Bool - } - - defaultValueString = fmt.Sprintf(formatDefault("%v"), value) - if valKind == reflect.String && value.(string) != "" { - defaultValueString = fmt.Sprintf(formatDefault("%q"), value) - } - - if helpText, ok := getFlagDefaultText(f); ok && helpText != "" { - defaultValueString = fmt.Sprintf(formatDefault("%s"), helpText) - } - - if defaultValueString == formatDefault("") { - defaultValueString = "" - } - - if needsPlaceholder && placeholder == "" { - placeholder = defaultPlaceholder - } - - usageWithDefault := strings.TrimSpace(usage + defaultValueString) - - return withEnvHint(flagStringSliceField(f, "EnvVars"), - fmt.Sprintf("%s\t%s", prefixedNames(FlagNames(f), placeholder), usageWithDefault)) -} - -func stringifySlice(usage string, names []string, value interface{}) string { - var defaults []string - for i := 0; i < generic.Len(value); i++ { - v := generic.Index(value, i) - s, ok := v.(string) - if ok && s == "" { - continue - } - if ok { - s = fmt.Sprintf("%q", s) - } else { - s, _ = generic.ToString(v) - } - defaults = append(defaults, s) - } - return stringifySliceFlag(usage, names, defaults) -} - -func stringifySliceFlag(usage string, names, defaultVals []string) string { - placeholder, usage := unquoteUsage(usage) - if placeholder == "" { - placeholder = defaultPlaceholder - } - - defaultVal := "" - if len(defaultVals) > 0 { - defaultVal = fmt.Sprintf(formatDefault("%s"), strings.Join(defaultVals, ", ")) - } - - usageWithDefault := strings.TrimSpace(fmt.Sprintf("%s%s", usage, defaultVal)) - return fmt.Sprintf("%s\t%s", prefixedNames(names, placeholder), usageWithDefault) -} - -func hasFlag(flags []Flag, fl Flag) bool { - for _, existing := range flags { - if fl == existing { - return true - } - } - return false -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_bool.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_bool.go deleted file mode 100644 index 40cf8b7b21..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_bool.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Bool is a type alias for bool -type Bool = bool - -// BoolFlag is a flag with type bool -type BoolFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Bool - Destination *Bool -} - -// Apply populates the flag given the flag set and environment -func (f *BoolFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "bool", set) -} - -// Bool looks up the value of a local BoolFlag, returns -// an empty value if not found -func (c *Context) Bool(name string) bool { - return c.Lookup(name, *new(Bool)).(bool) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_boolSlice.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_boolSlice.go deleted file mode 100644 index cb01262f13..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_boolSlice.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// BoolSlice is a type alias for []bool -type BoolSlice = []bool - -// BoolSliceFlag is a flag with type []bool -type BoolSliceFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value BoolSlice - Destination *BoolSlice -} - -// Apply populates the flag given the flag set and environment -func (f *BoolSliceFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "bool slice", set) -} - -// BoolSlice looks up the value of a local BoolSliceFlag, returns -// an empty value if not found -func (c *Context) BoolSlice(name string) []bool { - return c.Lookup(name, *new(BoolSlice)).([]bool) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_duration.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_duration.go deleted file mode 100644 index 6c4609a728..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_duration.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Duration is a type alias for time.Duration -type Duration = time.Duration - -// DurationFlag is a flag with type time.Duration -type DurationFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Duration - Destination *Duration -} - -// Apply populates the flag given the flag set and environment -func (f *DurationFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "duration", set) -} - -// Duration looks up the value of a local DurationFlag, returns -// an empty value if not found -func (c *Context) Duration(name string) time.Duration { - return c.Lookup(name, *new(Duration)).(time.Duration) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_durationSlice.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_durationSlice.go deleted file mode 100644 index b309500cb1..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_durationSlice.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// DurationSlice is a type alias for []time.Duration -type DurationSlice = []time.Duration - -// DurationSliceFlag is a flag with type []time.Duration -type DurationSliceFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value DurationSlice - Destination *DurationSlice -} - -// Apply populates the flag given the flag set and environment -func (f *DurationSliceFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "duration slice", set) -} - -// DurationSlice looks up the value of a local DurationSliceFlag, returns -// an empty value if not found -func (c *Context) DurationSlice(name string) []time.Duration { - return c.Lookup(name, *new(DurationSlice)).([]time.Duration) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_float64.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_float64.go deleted file mode 100644 index 4d08689c84..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_float64.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Float64 is a type alias for float64 -type Float64 = float64 - -// Float64Flag is a flag with type float64 -type Float64Flag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Float64 - Destination *Float64 -} - -// Apply populates the flag given the flag set and environment -func (f *Float64Flag) Apply(set *flag.FlagSet) error { - return Apply(f, "float64", set) -} - -// Float64 looks up the value of a local Float64Flag, returns -// an empty value if not found -func (c *Context) Float64(name string) float64 { - return c.Lookup(name, *new(Float64)).(float64) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_float64Slice.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_float64Slice.go deleted file mode 100644 index 6f97ce5549..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_float64Slice.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Float64Slice is a type alias for []float64 -type Float64Slice = []float64 - -// Float64SliceFlag is a flag with type []float64 -type Float64SliceFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Float64Slice - Destination *Float64Slice -} - -// Apply populates the flag given the flag set and environment -func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "float64 slice", set) -} - -// Float64Slice looks up the value of a local Float64SliceFlag, returns -// an empty value if not found -func (c *Context) Float64Slice(name string) []float64 { - return c.Lookup(name, *new(Float64Slice)).([]float64) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_int.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_int.go deleted file mode 100644 index 864361c7b7..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_int.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Int is a type alias for int -type Int = int - -// IntFlag is a flag with type int -type IntFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Int - Destination *Int -} - -// Apply populates the flag given the flag set and environment -func (f *IntFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "int", set) -} - -// Int looks up the value of a local IntFlag, returns -// an empty value if not found -func (c *Context) Int(name string) int { - return c.Lookup(name, *new(Int)).(int) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_int64.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_int64.go deleted file mode 100644 index a7ad8bbd4a..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_int64.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Int64 is a type alias for int64 -type Int64 = int64 - -// Int64Flag is a flag with type int64 -type Int64Flag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Int64 - Destination *Int64 -} - -// Apply populates the flag given the flag set and environment -func (f *Int64Flag) Apply(set *flag.FlagSet) error { - return Apply(f, "int64", set) -} - -// Int64 looks up the value of a local Int64Flag, returns -// an empty value if not found -func (c *Context) Int64(name string) int64 { - return c.Lookup(name, *new(Int64)).(int64) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_int64Slice.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_int64Slice.go deleted file mode 100644 index 537e5cfb4a..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_int64Slice.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Int64Slice is a type alias for []int64 -type Int64Slice = []int64 - -// Int64SliceFlag is a flag with type []int64 -type Int64SliceFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Int64Slice - Destination *Int64Slice -} - -// Apply populates the flag given the flag set and environment -func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "int64 slice", set) -} - -// Int64Slice looks up the value of a local Int64SliceFlag, returns -// an empty value if not found -func (c *Context) Int64Slice(name string) []int64 { - return c.Lookup(name, *new(Int64Slice)).([]int64) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_intSlice.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_intSlice.go deleted file mode 100644 index 9d5c63dd4d..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_intSlice.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// IntSlice is a type alias for []int -type IntSlice = []int - -// IntSliceFlag is a flag with type []int -type IntSliceFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value IntSlice - Destination *IntSlice -} - -// Apply populates the flag given the flag set and environment -func (f *IntSliceFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "int slice", set) -} - -// IntSlice looks up the value of a local IntSliceFlag, returns -// an empty value if not found -func (c *Context) IntSlice(name string) []int { - return c.Lookup(name, *new(IntSlice)).([]int) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_string.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_string.go deleted file mode 100644 index d09830677d..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_string.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// String is a type alias for string -type String = string - -// StringFlag is a flag with type string -type StringFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value String - Destination *String -} - -// Apply populates the flag given the flag set and environment -func (f *StringFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "string", set) -} - -// String looks up the value of a local StringFlag, returns -// an empty value if not found -func (c *Context) String(name string) string { - return c.Lookup(name, *new(String)).(string) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_stringSlice.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_stringSlice.go deleted file mode 100644 index 5e52110c33..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_stringSlice.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// StringSlice is a type alias for []string -type StringSlice = []string - -// StringSliceFlag is a flag with type []string -type StringSliceFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value StringSlice - Destination *StringSlice -} - -// Apply populates the flag given the flag set and environment -func (f *StringSliceFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "string slice", set) -} - -// StringSlice looks up the value of a local StringSliceFlag, returns -// an empty value if not found -func (c *Context) StringSlice(name string) []string { - return c.Lookup(name, *new(StringSlice)).([]string) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_time.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_time.go deleted file mode 100644 index 60b2d861c2..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_time.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Time is a type alias for time.Time -type Time = time.Time - -// TimeFlag is a flag with type time.Time -type TimeFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Time - Destination *Time -} - -// Apply populates the flag given the flag set and environment -func (f *TimeFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "time", set) -} - -// Time looks up the value of a local TimeFlag, returns -// an empty value if not found -func (c *Context) Time(name string) time.Time { - return c.Lookup(name, *new(Time)).(time.Time) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_timeSlice.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_timeSlice.go deleted file mode 100644 index abe19b154f..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_timeSlice.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// TimeSlice is a type alias for []time.Time -type TimeSlice = []time.Time - -// TimeSliceFlag is a flag with type []time.Time -type TimeSliceFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value TimeSlice - Destination *TimeSlice -} - -// Apply populates the flag given the flag set and environment -func (f *TimeSliceFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "time slice", set) -} - -// TimeSlice looks up the value of a local TimeSliceFlag, returns -// an empty value if not found -func (c *Context) TimeSlice(name string) []time.Time { - return c.Lookup(name, *new(TimeSlice)).([]time.Time) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_uint.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_uint.go deleted file mode 100644 index e9a901f96e..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_uint.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Uint is a type alias for uint -type Uint = uint - -// UintFlag is a flag with type uint -type UintFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Uint - Destination *Uint -} - -// Apply populates the flag given the flag set and environment -func (f *UintFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "uint", set) -} - -// Uint looks up the value of a local UintFlag, returns -// an empty value if not found -func (c *Context) Uint(name string) uint { - return c.Lookup(name, *new(Uint)).(uint) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64.go deleted file mode 100644 index f2d290b779..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Uint64 is a type alias for uint64 -type Uint64 = uint64 - -// Uint64Flag is a flag with type uint64 -type Uint64Flag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Uint64 - Destination *Uint64 -} - -// Apply populates the flag given the flag set and environment -func (f *Uint64Flag) Apply(set *flag.FlagSet) error { - return Apply(f, "uint64", set) -} - -// Uint64 looks up the value of a local Uint64Flag, returns -// an empty value if not found -func (c *Context) Uint64(name string) uint64 { - return c.Lookup(name, *new(Uint64)).(uint64) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64Slice.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64Slice.go deleted file mode 100644 index 07eadae801..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64Slice.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// Uint64Slice is a type alias for []uint64 -type Uint64Slice = []uint64 - -// Uint64SliceFlag is a flag with type []uint64 -type Uint64SliceFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Uint64Slice - Destination *Uint64Slice -} - -// Apply populates the flag given the flag set and environment -func (f *Uint64SliceFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "uint64 slice", set) -} - -// Uint64Slice looks up the value of a local Uint64SliceFlag, returns -// an empty value if not found -func (c *Context) Uint64Slice(name string) []uint64 { - return c.Lookup(name, *new(Uint64Slice)).([]uint64) -} diff --git a/vendor/github.com/rancher/spur/cli/flag.zz_generated_uintSlice.go b/vendor/github.com/rancher/spur/cli/flag.zz_generated_uintSlice.go deleted file mode 100644 index 90938a0eaa..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag.zz_generated_uintSlice.go +++ /dev/null @@ -1,40 +0,0 @@ -package cli - -import ( - "time" - - "github.com/rancher/spur/flag" -) - -var _ = time.Time{} - -// UintSlice is a type alias for []uint -type UintSlice = []uint - -// UintSliceFlag is a flag with type []uint -type UintSliceFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value UintSlice - Destination *UintSlice -} - -// Apply populates the flag given the flag set and environment -func (f *UintSliceFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "uint slice", set) -} - -// UintSlice looks up the value of a local UintSliceFlag, returns -// an empty value if not found -func (c *Context) UintSlice(name string) []uint { - return c.Lookup(name, *new(UintSlice)).([]uint) -} diff --git a/vendor/github.com/rancher/spur/cli/flag_apply.go b/vendor/github.com/rancher/spur/cli/flag_apply.go deleted file mode 100644 index b33e91514f..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag_apply.go +++ /dev/null @@ -1,105 +0,0 @@ -package cli - -import ( - "fmt" - "io/ioutil" - "strings" - "syscall" - - "github.com/rancher/spur/flag" - "github.com/rancher/spur/generic" -) - -// Apply will attempt to apply generic flag values to a flagset -func Apply(f Flag, typ string, set *flag.FlagSet) error { - name := FlagNames(f)[0] - value, _ := getFlagValue(f) - usage, _ := getFlagUsage(f) - envVars, _ := getFlagEnvVars(f) - filePath, _ := getFlagFilePath(f) - // make sure we have a pointer to value (for non-generic values) - if !generic.IsPtr(value) { - value, _ = getFlagValuePtr(f) - } - destination, _ := getFlagDestination(f) - // create new destination if not defined - if destination == nil || generic.ValueOfPtr(destination) == nil { - destination = generic.New(value) - } - // create new value if not defined (for generic flag.Value) - if value == nil || generic.ValueOfPtr(value) == nil { - value = generic.New(destination) - } - wasSet := false - // load flags from environment or file - if val, ok := flagFromEnvOrFile(envVars, filePath); ok { - newValue := generic.New(value) - if err := applyValue(newValue, val); err != nil { - return fmt.Errorf("could not parse %q as %s value for flag %s: %s", val, typ, name, err) - } - value = newValue - wasSet = true - } - // copy value to destination - generic.Set(destination, generic.ValueOfPtr(value)) - dest, ok := destination.(flag.Value) - if !ok { - dest = flag.NewGenericValue(destination) - } - // for all of the names set the flag variable - for _, name := range FlagNames(f) { - set.Var(dest, name, usage) - } - // if value is not default mark as needs visit - if wasSet { - set.NeedsVisit(name) - } - return nil -} - -func applyValue(ptr interface{}, val string) error { - if !generic.IsSlice(ptr) { - // if we are a slice just return the applied elem - return applyElem(ptr, val) - } - // otherwise create a new slice and apply the split values - values := generic.Zero(ptr) - for _, val := range strings.Split(val, ",") { - value := generic.NewElem(ptr) - if err := generic.FromString(val, value); err != nil { - return err - } - values = generic.Append(values, generic.ValueOfPtr(value)) - } - generic.Set(ptr, values) - return nil -} - -func applyElem(ptr interface{}, val string) error { - if gen, ok := ptr.(flag.Value); ok { - // if we are a generic flag.Value then apply Set - return gen.Set(val) - } - // otherwise create a new value and convert it - value := generic.NewElem(ptr) - if err := generic.FromString(val, value); err != nil { - return err - } - generic.Set(ptr, generic.ValueOfPtr(value)) - return nil -} - -func flagFromEnvOrFile(envVars []string, filePath string) (val string, ok bool) { - for _, envVar := range envVars { - envVar = strings.TrimSpace(envVar) - if val, ok := syscall.Getenv(envVar); ok { - return val, true - } - } - for _, fileVar := range strings.Split(filePath, ",") { - if data, err := ioutil.ReadFile(fileVar); err == nil { - return string(data), true - } - } - return "", false -} diff --git a/vendor/github.com/rancher/spur/cli/flag_fields.go b/vendor/github.com/rancher/spur/cli/flag_fields.go deleted file mode 100644 index 8d1358b336..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag_fields.go +++ /dev/null @@ -1,92 +0,0 @@ -package cli - -func getFlagName(f Flag) (result string, ok bool) { - if v := flagValue(f).FieldByName("Name"); v.IsValid() { - return v.Interface().(string), true - } - return -} - -func getFlagAliases(f Flag) (result []string, ok bool) { - if v := flagValue(f).FieldByName("Aliases"); v.IsValid() { - return v.Interface().([]string), true - } - return -} - -func getFlagEnvVars(f Flag) (result []string, ok bool) { - if v := flagValue(f).FieldByName("EnvVars"); v.IsValid() { - return v.Interface().([]string), true - } - return -} - -func getFlagUsage(f Flag) (result string, ok bool) { - if v := flagValue(f).FieldByName("Usage"); v.IsValid() { - return v.Interface().(string), true - } - return -} - -func getFlagDefaultText(f Flag) (result string, ok bool) { - if v := flagValue(f).FieldByName("DefaultText"); v.IsValid() { - return v.Interface().(string), true - } - return -} - -func getFlagFilePath(f Flag) (result string, ok bool) { - if v := flagValue(f).FieldByName("FilePath"); v.IsValid() { - return v.Interface().(string), true - } - return -} - -func getFlagRequired(f Flag) (result bool, ok bool) { - if v := flagValue(f).FieldByName("Required"); v.IsValid() { - return v.Interface().(bool), true - } - return -} - -func getFlagHidden(f Flag) (result bool, ok bool) { - if v := flagValue(f).FieldByName("Hidden"); v.IsValid() { - return v.Interface().(bool), true - } - return -} - -func getFlagTakesFile(f Flag) (result bool, ok bool) { - if v := flagValue(f).FieldByName("TakesFile"); v.IsValid() { - return v.Interface().(bool), true - } - return -} - -func getFlagSkipAltSrc(f Flag) (result bool, ok bool) { - if v := flagValue(f).FieldByName("SkipAltSrc"); v.IsValid() { - return v.Interface().(bool), true - } - return -} - -func getFlagValue(f Flag) (result interface{}, ok bool) { - if v := flagValue(f).FieldByName("Value"); v.IsValid() { - return v.Interface(), true - } - return -} - -func getFlagValuePtr(f Flag) (result interface{}, ok bool) { - if v := flagValue(f).FieldByName("Value"); v.IsValid() { - return v.Addr().Interface(), true - } - return -} - -func getFlagDestination(f Flag) (result interface{}, ok bool) { - if v := flagValue(f).FieldByName("Destination"); v.IsValid() { - return v.Interface(), true - } - return -} diff --git a/vendor/github.com/rancher/spur/cli/flag_generic.go b/vendor/github.com/rancher/spur/cli/flag_generic.go deleted file mode 100644 index cd8d66097a..0000000000 --- a/vendor/github.com/rancher/spur/cli/flag_generic.go +++ /dev/null @@ -1,36 +0,0 @@ -package cli - -import ( - "github.com/rancher/spur/flag" -) - -// Generic is a type alias for flag.Value -type Generic = flag.Value - -// GenericFlag is a flag with type flag.Value -type GenericFlag struct { - Name string - Aliases []string - EnvVars []string - Usage string - DefaultText string - FilePath string - Required bool - Hidden bool - TakesFile bool - SkipAltSrc bool - - Value Generic - Destination Generic -} - -// Apply populates the flag given the flag set and environment -func (f *GenericFlag) Apply(set *flag.FlagSet) error { - return Apply(f, "generic", set) -} - -// Generic looks up the value of a local GenericFlag, returns -// an empty value if not found -func (c *Context) Generic(name string) interface{} { - return c.Lookup(name, nil) -} diff --git a/vendor/github.com/rancher/spur/cli/funcs.go b/vendor/github.com/rancher/spur/cli/funcs.go deleted file mode 100644 index 474c48faf9..0000000000 --- a/vendor/github.com/rancher/spur/cli/funcs.go +++ /dev/null @@ -1,44 +0,0 @@ -package cli - -// BashCompleteFunc is an action to execute when the shell completion flag is set -type BashCompleteFunc func(*Context) - -// BeforeFunc is an action to execute before any subcommands are run, but after -// the context is ready if a non-nil error is returned, no subcommands are run -type BeforeFunc func(*Context) error - -// AfterFunc is an action to execute after any subcommands are run, but after the -// subcommand has finished it is run even if Action() panics -type AfterFunc func(*Context) error - -// ActionFunc is the action to execute when no subcommands are specified -type ActionFunc func(*Context) error - -// CommandNotFoundFunc is executed if the proper command cannot be found -type CommandNotFoundFunc func(*Context, string) - -// OnUsageErrorFunc is executed if an usage error occurs. This is useful for displaying -// customized usage error messages. This function is able to replace the -// original error messages. If this function is not set, the "Incorrect usage" -// is displayed and the execution is interrupted. -type OnUsageErrorFunc func(context *Context, err error, isSubcommand bool) error - -// ExitErrHandlerFunc is executed if provided in order to handle exitError values -// returned by Actions and Before/After functions. -type ExitErrHandlerFunc func(context *Context, err error) - -// FlagStringFunc is used by the help generation to display a flag, which is -// expected to be a single line. -type FlagStringFunc func(Flag) string - -// FlagNamePrefixFunc is used by the default FlagStringFunc to create prefix -// text for a flag's full name. -type FlagNamePrefixFunc func(fullName []string, placeholder string) string - -// FlagEnvHintFunc is used by the default FlagStringFunc to annotate flag help -// with the environment variable details. -type FlagEnvHintFunc func(envVars []string, str string) string - -// FlagFileHintFunc is used by the default FlagStringFunc to annotate flag help -// with the file path details. -type FlagFileHintFunc func(filePath, str string) string diff --git a/vendor/github.com/rancher/spur/cli/help.go b/vendor/github.com/rancher/spur/cli/help.go deleted file mode 100644 index 286fcce85c..0000000000 --- a/vendor/github.com/rancher/spur/cli/help.go +++ /dev/null @@ -1,378 +0,0 @@ -package cli - -import ( - "fmt" - "io" - "os" - "strings" - "text/tabwriter" - "text/template" - "unicode/utf8" -) - -var helpCommand = &Command{ - Name: "help", - Aliases: []string{"h"}, - Usage: "Shows a list of commands or help for one command", - ArgsUsage: "[command]", - Action: func(c *Context) error { - args := c.Args() - if args.Present() { - return ShowCommandHelp(c, args.First()) - } - - ShowAppHelp(c) - return nil - }, -} - -var helpSubcommand = &Command{ - Name: "help", - Aliases: []string{"h"}, - Usage: "Shows a list of commands or help for one command", - ArgsUsage: "[command]", - Action: func(c *Context) error { - args := c.Args() - if args.Present() { - return ShowCommandHelp(c, args.First()) - } - - return ShowSubcommandHelp(c) - }, -} - -// Prints help for the App or Command -type helpPrinter func(w io.Writer, templ string, data interface{}) - -// Prints help for the App or Command with custom template function. -type helpPrinterCustom func(w io.Writer, templ string, data interface{}, customFunc map[string]interface{}) - -// HelpPrinter is a function that writes the help output. If not set explicitly, -// this calls HelpPrinterCustom using only the default template functions. -// -// If custom logic for printing help is required, this function can be -// overridden. If the ExtraInfo field is defined on an App, this function -// should not be modified, as HelpPrinterCustom will be used directly in order -// to capture the extra information. -var HelpPrinter helpPrinter = printHelp - -// HelpPrinterCustom is a function that writes the help output. It is used as -// the default implementation of HelpPrinter, and may be called directly if -// the ExtraInfo field is set on an App. -var HelpPrinterCustom helpPrinterCustom = printHelpCustom - -// VersionPrinter prints the version for the App -var VersionPrinter = printVersion - -// ShowAppHelpAndExit - Prints the list of subcommands for the app and exits with exit code. -func ShowAppHelpAndExit(c *Context, exitCode int) { - ShowAppHelp(c) - os.Exit(exitCode) -} - -// ShowAppHelp is an action that displays the help. -func ShowAppHelp(c *Context) error { - template := c.App.CustomAppHelpTemplate - if template == "" { - template = AppHelpTemplate - } - - if c.App.ExtraInfo == nil { - HelpPrinter(c.App.Writer, template, c.App) - return nil - } - - customAppData := func() map[string]interface{} { - return map[string]interface{}{ - "ExtraInfo": c.App.ExtraInfo, - } - } - HelpPrinterCustom(c.App.Writer, template, c.App, customAppData()) - - return nil -} - -// DefaultAppComplete prints the list of subcommands as the default app completion method -func DefaultAppComplete(c *Context) { - DefaultCompleteWithFlags(nil)(c) -} - -func printCommandSuggestions(commands []*Command, writer io.Writer) { - for _, command := range commands { - if command.Hidden { - continue - } - if os.Getenv("_CLI_ZSH_AUTOCOMPLETE_HACK") == "1" { - for _, name := range command.Names() { - fmt.Fprintf(writer, "%s:%s\n", name, command.Usage) - } - } else { - for _, name := range command.Names() { - fmt.Fprintf(writer, "%s\n", name) - } - } - } -} - -func cliArgContains(flagName string) bool { - for _, name := range strings.Split(flagName, ",") { - name = strings.TrimSpace(name) - count := utf8.RuneCountInString(name) - if count > 2 { - count = 2 - } - flag := fmt.Sprintf("%s%s", strings.Repeat("-", count), name) - for _, a := range os.Args { - if a == flag { - return true - } - } - } - return false -} - -func printFlagSuggestions(lastArg string, flags []Flag, writer io.Writer) { - cur := strings.TrimPrefix(lastArg, "-") - cur = strings.TrimPrefix(cur, "-") - for _, flag := range flags { - if bflag, ok := flag.(*BoolFlag); ok && bflag.Hidden { - continue - } - for _, name := range FlagNames(flag) { - name = strings.TrimSpace(name) - // this will get total count utf8 letters in flag name - count := utf8.RuneCountInString(name) - if count > 2 { - count = 2 // resuse this count to generate single - or -- in flag completion - } - // if flag name has more than one utf8 letter and last argument in cli has -- prefix then - // skip flag completion for short flags example -v or -x - if strings.HasPrefix(lastArg, "--") && count == 1 { - continue - } - // match if last argument matches this flag and it is not repeated - if strings.HasPrefix(name, cur) && cur != name && !cliArgContains(name) { - flagCompletion := fmt.Sprintf("%s%s", strings.Repeat("-", count), name) - fmt.Fprintln(writer, flagCompletion) - } - } - } -} - -func DefaultCompleteWithFlags(cmd *Command) func(c *Context) { - return func(c *Context) { - if len(os.Args) > 2 { - lastArg := os.Args[len(os.Args)-2] - if strings.HasPrefix(lastArg, "-") { - printFlagSuggestions(lastArg, c.App.Flags, c.App.Writer) - if cmd != nil { - printFlagSuggestions(lastArg, cmd.Flags, c.App.Writer) - } - return - } - } - if cmd != nil { - printCommandSuggestions(cmd.Subcommands, c.App.Writer) - } else { - printCommandSuggestions(c.App.Commands, c.App.Writer) - } - } -} - -// ShowCommandHelpAndExit - exits with code after showing help -func ShowCommandHelpAndExit(c *Context, command string, code int) { - ShowCommandHelp(c, command) - os.Exit(code) -} - -// ShowCommandHelp prints help for the given command -func ShowCommandHelp(ctx *Context, command string) error { - // show the subcommand help for a command with subcommands - if command == "" { - HelpPrinter(ctx.App.Writer, SubcommandHelpTemplate, ctx.App) - return nil - } - - for _, c := range ctx.App.Commands { - if c.HasName(command) { - templ := c.CustomHelpTemplate - if templ == "" { - templ = CommandHelpTemplate - } - - HelpPrinter(ctx.App.Writer, templ, c) - - return nil - } - } - - if ctx.App.CommandNotFound == nil { - return Exit(fmt.Sprintf("No help topic for '%v'", command), 3) - } - - ctx.App.CommandNotFound(ctx, command) - return nil -} - -// ShowSubcommandHelp prints help for the given subcommand -func ShowSubcommandHelp(c *Context) error { - if c == nil { - return nil - } - - if c.Command != nil { - return ShowCommandHelp(c, c.Command.Name) - } - - return ShowCommandHelp(c, "") -} - -// ShowVersion prints the version number of the App -func ShowVersion(c *Context) { - VersionPrinter(c) -} - -func printVersion(c *Context) { - fmt.Fprintf(c.App.Writer, "%v version %v\n", c.App.Name, c.App.Version) -} - -// ShowCompletions prints the lists of commands within a given context -func ShowCompletions(c *Context) { - a := c.App - if a != nil && a.BashComplete != nil { - a.BashComplete(c) - } -} - -// ShowCommandCompletions prints the custom completions for a given command -func ShowCommandCompletions(ctx *Context, command string) { - c := ctx.App.Command(command) - if c != nil { - if c.BashComplete != nil { - c.BashComplete(ctx) - } else { - DefaultCompleteWithFlags(c)(ctx) - } - } - -} - -// FlagToString will convert a flag to a string, using either it's String() -// function, or FlagStringer if String() is not defined -func FlagToString(f Flag) string { - if stringer, ok := f.(fmt.Stringer); ok { - return stringer.String() - } - return FlagStringer(f) -} - -// printHelpCustom is the default implementation of HelpPrinterCustom. -// -// The customFuncs map will be combined with a default template.FuncMap to -// allow using arbitrary functions in template rendering. -func printHelpCustom(out io.Writer, templ string, data interface{}, customFuncs map[string]interface{}) { - funcMap := template.FuncMap{ - "join": strings.Join, - "FlagToString": FlagToString, - } - for key, value := range customFuncs { - funcMap[key] = value - } - - w := tabwriter.NewWriter(out, 1, 8, 2, ' ', 0) - t := template.Must(template.New("help").Funcs(funcMap).Parse(templ)) - - err := t.Execute(w, data) - if err != nil { - // If the writer is closed, t.Execute will fail, and there's nothing - // we can do to recover. - if os.Getenv("CLI_TEMPLATE_ERROR_DEBUG") != "" { - fmt.Fprintf(ErrWriter, "CLI TEMPLATE ERROR: %#v\n", err) - } - return - } - w.Flush() -} - -func printHelp(out io.Writer, templ string, data interface{}) { - HelpPrinterCustom(out, templ, data, nil) -} - -func checkVersion(c *Context) bool { - found := false - for _, name := range FlagNames(VersionFlag) { - if c.Bool(name) { - found = true - } - } - return found -} - -func checkHelp(c *Context) bool { - found := false - for _, name := range FlagNames(HelpFlag) { - if c.Bool(name) { - found = true - } - } - return found -} - -func checkCommandHelp(c *Context, name string) bool { - if c.Bool("h") || c.Bool("help") { - ShowCommandHelp(c, name) - return true - } - - return false -} - -func checkSubcommandHelp(c *Context) bool { - if c.Bool("h") || c.Bool("help") { - ShowSubcommandHelp(c) - return true - } - - return false -} - -func checkShellCompleteFlag(a *App, arguments []string) (bool, []string) { - if !a.EnableBashCompletion { - return false, arguments - } - - pos := len(arguments) - 1 - lastArg := arguments[pos] - - if lastArg != "--generate-bash-completion" { - return false, arguments - } - - return true, arguments[:pos] -} - -func checkCompletions(c *Context) bool { - if !c.shellComplete { - return false - } - - if args := c.Args(); args.Present() { - name := args.First() - if cmd := c.App.Command(name); cmd != nil { - // let the command handle the completion - return false - } - } - - ShowCompletions(c) - return true -} - -func checkCommandCompletions(c *Context, name string) bool { - if !c.shellComplete { - return false - } - - ShowCommandCompletions(c, name) - return true -} diff --git a/vendor/github.com/rancher/spur/cli/input_source.go b/vendor/github.com/rancher/spur/cli/input_source.go deleted file mode 100644 index cb179d4b93..0000000000 --- a/vendor/github.com/rancher/spur/cli/input_source.go +++ /dev/null @@ -1,79 +0,0 @@ -package cli - -import ( - "fmt" - - "github.com/rancher/spur/flag" -) - -// InputSourceContext is an interface used to allow -// other input sources to be implemented as needed. -// -// Source returns an identifier for the input source. In case of file source -// it should return path to the file. -type InputSourceContext interface { - Source() string - Get(name string) (interface{}, bool) -} - -// ApplyInputSourceValue will attempt to apply an input source to a generic flag -func ApplyInputSourceValue(f Flag, context *Context, isc InputSourceContext) error { - name := FlagNames(f)[0] - skipAltSrc, _ := getFlagSkipAltSrc(f) - - if !skipAltSrc && context.flagSet != nil { - if !context.IsSet(name) { - // only checks the first name of this flag - value, ok := isc.Get(name) - if !ok || value == nil { - return nil - } - // if a generic flag.Value get the string representation - if v, ok := value.(flag.Value); ok { - value = v.String() - } - // sets the new value from some source - if err := context.Set(name, value); err != nil { - return fmt.Errorf("unable to apply input source '%s': %s", isc.Source(), err) - } - } - } - return nil -} - -// ApplyInputSourceValues iterates over all provided flags and executes ApplyInputSourceValue -// on each flag to apply an alternate input source. -func ApplyInputSourceValues(context *Context, inputSourceContext InputSourceContext, flags []Flag) (err error) { - for _, f := range flags { - if err = ApplyInputSourceValue(f, context, inputSourceContext); err != nil { - return err - } - } - return -} - -// InitInputSource is used to to setup an InputSourceContext on a Command Before method. It will create a new -// input source based on the func provided with potentially using existing Context values to initialize itself. If there is -// no error it will then apply the new input source to any flags that are supported by the input source -func InitInputSource(flags []Flag, createInputSource func(context *Context) (InputSourceContext, error)) BeforeFunc { - return func(context *Context) error { - inputSource, err := createInputSource(context) - if err != nil { - return err - } - return ApplyInputSourceValues(context, inputSource, flags) - } -} - -// InitAllInputSource is used to to setup an InputSourceContext on a Command Before method. It will create a new -// input source based on the func provided with potentially using existing Context values to initialize itself. If there is -// no error it will then apply the new input source to all flags that are supported by the input source -func InitAllInputSource(createInputSource func(context *Context) (InputSourceContext, error)) BeforeFunc { - return func(context *Context) error { - inputSource, err := createInputSource(context) - if err != nil { - return err - } - return ApplyInputSourceValues(context, inputSource, context.GetFlags()) - } -} diff --git a/vendor/github.com/rancher/spur/cli/parse.go b/vendor/github.com/rancher/spur/cli/parse.go deleted file mode 100644 index 3106686bde..0000000000 --- a/vendor/github.com/rancher/spur/cli/parse.go +++ /dev/null @@ -1,95 +0,0 @@ -package cli - -import ( - "strings" - - "github.com/rancher/spur/flag" -) - -type iterativeParser interface { - newFlagSet() (*flag.FlagSet, error) - useShortOptionHandling() bool -} - -// To enable short-option handling (e.g., "-it" vs "-i -t") we have to -// iteratively catch parsing errors. This way we achieve LR parsing without -// transforming any arguments. Otherwise, there is no way we can discriminate -// combined short options from common arguments that should be left untouched. -// Pass `shellComplete` to continue parsing options on failure during shell -// completion when, the user-supplied options may be incomplete. -func parseIter(set *flag.FlagSet, ip iterativeParser, args []string, shellComplete bool) error { - for { - err := set.Parse(args) - if !ip.useShortOptionHandling() || err == nil { - if shellComplete { - return nil - } - return err - } - - errStr := err.Error() - trimmed := strings.TrimPrefix(errStr, "flag provided but not defined: -") - if errStr == trimmed { - return err - } - - // regenerate the initial args with the split short opts - argsWereSplit := false - for i, arg := range args { - // skip args that are not part of the error message - if name := strings.TrimLeft(arg, "-"); name != trimmed { - continue - } - - // if we can't split, the error was accurate - shortOpts := splitShortOptions(set, arg) - if len(shortOpts) == 1 { - return err - } - - // swap current argument with the split version - args = append(args[:i], append(shortOpts, args[i+1:]...)...) - argsWereSplit = true - break - } - - // This should be an impossible to reach code path, but in case the arg - // splitting failed to happen, this will prevent infinite loops - if !argsWereSplit { - return err - } - - // Since custom parsing failed, replace the flag set before retrying - newSet, err := ip.newFlagSet() - if err != nil { - return err - } - *set = *newSet - } -} - -func splitShortOptions(set *flag.FlagSet, arg string) []string { - shortFlagsExist := func(s string) bool { - for _, c := range s[1:] { - if f := set.Lookup(string(c)); f == nil { - return false - } - } - return true - } - - if !isSplittable(arg) || !shortFlagsExist(arg) { - return []string{arg} - } - - separated := make([]string, 0, len(arg)-1) - for _, flagChar := range arg[1:] { - separated = append(separated, "-"+string(flagChar)) - } - - return separated -} - -func isSplittable(flagArg string) bool { - return strings.HasPrefix(flagArg, "-") && !strings.HasPrefix(flagArg, "--") && len(flagArg) > 2 -} diff --git a/vendor/github.com/rancher/spur/cli/sort.go b/vendor/github.com/rancher/spur/cli/sort.go deleted file mode 100644 index 23d1c2f772..0000000000 --- a/vendor/github.com/rancher/spur/cli/sort.go +++ /dev/null @@ -1,29 +0,0 @@ -package cli - -import "unicode" - -// lexicographicLess compares strings alphabetically considering case. -func lexicographicLess(i, j string) bool { - iRunes := []rune(i) - jRunes := []rune(j) - - lenShared := len(iRunes) - if lenShared > len(jRunes) { - lenShared = len(jRunes) - } - - for index := 0; index < lenShared; index++ { - ir := iRunes[index] - jr := jRunes[index] - - if lir, ljr := unicode.ToLower(ir), unicode.ToLower(jr); lir != ljr { - return lir < ljr - } - - if ir != jr { - return ir < jr - } - } - - return i < j -} diff --git a/vendor/github.com/rancher/spur/cli/template.go b/vendor/github.com/rancher/spur/cli/template.go deleted file mode 100644 index 2d2ac300e5..0000000000 --- a/vendor/github.com/rancher/spur/cli/template.go +++ /dev/null @@ -1,120 +0,0 @@ -package cli - -// AppHelpTemplate is the text template for the Default help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var AppHelpTemplate = `NAME: - {{.Name}}{{if .Usage}} - {{.Usage}}{{end}} - -USAGE: - {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} {{if .VisibleFlags}}[global options]{{end}}{{if .Commands}} command [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Version}}{{if not .HideVersion}} - -VERSION: - {{.Version}}{{end}}{{end}}{{if .Description}} - -DESCRIPTION: - {{.Description}}{{end}}{{if len .Authors}} - -AUTHOR{{with $length := len .Authors}}{{if ne 1 $length}}S{{end}}{{end}}: - {{range $index, $author := .Authors}}{{if $index}} - {{end}}{{$author}}{{end}}{{end}}{{if .VisibleCommands}} - -COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} - -GLOBAL OPTIONS: - {{range $index, $option := .VisibleFlags}}{{if $index}} - {{end}}{{FlagToString $option}}{{end}}{{end}}{{if .Copyright}} - -COPYRIGHT: - {{.Copyright}}{{end}} -` - -// CommandHelpTemplate is the text template for the command help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var CommandHelpTemplate = `NAME: - {{.HelpName}} - {{.Usage}} - -USAGE: - {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}}{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Category}} - -CATEGORY: - {{.Category}}{{end}}{{if .Description}} - -DESCRIPTION: - {{.Description}}{{end}}{{if .VisibleFlags}} - -OPTIONS: - {{range .VisibleFlags}}{{FlagToString .}} - {{end}}{{end}} -` - -// SubcommandHelpTemplate is the text template for the subcommand help topic. -// cli.go uses text/template to render templates. You can -// render custom help text by setting this variable. -var SubcommandHelpTemplate = `NAME: - {{.HelpName}} - {{.Usage}} - -USAGE: - {{if .UsageText}}{{.UsageText}}{{else}}{{.HelpName}} command{{if .VisibleFlags}} [command options]{{end}} {{if .ArgsUsage}}{{.ArgsUsage}}{{else}}[arguments...]{{end}}{{end}}{{if .Description}} - -DESCRIPTION: - {{.Description}}{{end}} - -COMMANDS:{{range .VisibleCategories}}{{if .Name}} - {{.Name}}:{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{else}}{{range .VisibleCommands}} - {{join .Names ", "}}{{"\t"}}{{.Usage}}{{end}}{{end}}{{end}}{{if .VisibleFlags}} - -OPTIONS: - {{range .VisibleFlags}}{{FlagToString .}} - {{end}}{{end}} -` - -var MarkdownDocTemplate = `% {{ .App.Name }} 8 - -# NAME - -{{ .App.Name }}{{ if .App.Usage }} - {{ .App.Usage }}{{ end }} - -# SYNOPSIS - -{{ .App.Name }} -{{ if .SynopsisArgs }} -` + "```" + ` -{{ range $v := .SynopsisArgs }}{{ $v }}{{ end }}` + "```" + ` -{{ end }}{{ if .App.UsageText }} -# DESCRIPTION - -{{ .App.UsageText }} -{{ end }} -**Usage**: - -` + "```" + ` -{{ .App.Name }} [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...] -` + "```" + ` -{{ if .GlobalArgs }} -# GLOBAL OPTIONS -{{ range $v := .GlobalArgs }} -{{ $v }}{{ end }} -{{ end }}{{ if .Commands }} -# COMMANDS -{{ range $v := .Commands }} -{{ $v }}{{ end }}{{ end }}` - -var FishCompletionTemplate = `# {{ .App.Name }} fish shell completion - -function __fish_{{ .App.Name }}_no_subcommand --description 'Test if there has been any subcommand yet' - for i in (commandline -opc) - if contains -- $i{{ range $v := .AllCommands }} {{ $v }}{{ end }} - return 1 - end - end - return 0 -end - -{{ range $v := .Completions }}{{ $v }} -{{ end }}` diff --git a/vendor/github.com/rancher/spur/flag/LICENSE b/vendor/github.com/rancher/spur/flag/LICENSE deleted file mode 100644 index 6a66aea5ea..0000000000 --- a/vendor/github.com/rancher/spur/flag/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/rancher/spur/flag/_flag.template.go b/vendor/github.com/rancher/spur/flag/_flag.template.go deleted file mode 100644 index 88b42247e0..0000000000 --- a/vendor/github.com/rancher/spur/flag/_flag.template.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// Title__Var defines a Type__ flag with specified name, default value, and usage string. -// The argument p points to a Type__ variable in which to store the value of the flag. -func (f *FlagSet) Title__Var(ptr *Type__, name string, value Type__, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Title__ defines a Type__ flag with specified name, default value, and usage string. -// The return value is the address of a Type__ variable that stores the value of the flag. -func (f *FlagSet) Title__(name string, value Type__, usage string) *Type__ { - return f.Generic(name, value, usage).(*Type__) -} - -// Title__Var defines a Type__ flag with specified name, default value, and usage string. -// The argument p points to a Type__ variable in which to store the value of the flag. -func Title__Var(ptr *Type__, name string, value Type__, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Title__ defines a Type__ flag with specified name, default value, and usage string. -// The return value is the address of a Type__ variable that stores the value of the flag. -func Title__(name string, value Type__, usage string) *Type__ { - return CommandLine.Generic(name, value, usage).(*Type__) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.go b/vendor/github.com/rancher/spur/flag/flag.go deleted file mode 100644 index c466190ab9..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.go +++ /dev/null @@ -1,661 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -/* - Package flag implements command-line flag parsing. - - Usage - - Define flags using flag.String(), Bool(), Int(), etc. - - This declares an integer flag, -n, stored in the pointer nFlag, with type *int: - import "flag" - var nFlag = flag.Int("n", 1234, "help message for flag n") - If you like, you can bind the flag to a variable using the Var() functions. - var flagvar int - func init() { - flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname") - } - Or you can create custom flags that satisfy the Value interface (with - pointer receivers) and couple them to flag parsing by - flag.Var(&flagVal, "name", "help message for flagname") - For such flags, the default value is just the initial value of the variable. - - After all flags are defined, call - flag.Parse() - to parse the command line into the defined flags. - - Flags may then be used directly. If you're using the flags themselves, - they are all pointers; if you bind to variables, they're values. - fmt.Println("ip has value ", *ip) - fmt.Println("flagvar has value ", flagvar) - - After parsing, the arguments following the flags are available as the - slice flag.Args() or individually as flag.Arg(i). - The arguments are indexed from 0 through flag.NArg()-1. - - Command line flag syntax - - The following forms are permitted: - - -flag - -flag=x - -flag x // non-boolean flags only - One or two minus signs may be used; they are equivalent. - The last form is not permitted for boolean flags because the - meaning of the command - cmd -x * - where * is a Unix shell wildcard, will change if there is a file - called 0, false, etc. You must use the -flag=false form to turn - off a boolean flag. - - Flag parsing stops just before the first non-flag argument - ("-" is a non-flag argument) or after the terminator "--". - - Integer flags accept 1234, 0664, 0x1234 and may be negative. - Boolean flags may be: - 1, 0, t, f, T, F, true, false, TRUE, FALSE, True, False - Duration flags accept any input valid for time.ParseDuration. - - The default set of command-line flags is controlled by - top-level functions. The FlagSet type allows one to define - independent sets of flags, such as to implement subcommands - in a command-line interface. The methods of FlagSet are - analogous to the top-level functions for the command-line - flag set. -*/ -package flag - -import ( - "errors" - "fmt" - "io" - "os" - "reflect" - "sort" - "strings" - - "github.com/rancher/spur/generic" -) - -// ErrHelp is the error returned if the -help or -h flag is invoked -// but no such flag is defined. -var ErrHelp = errors.New("flag: help requested") - -// Value is the interface to the dynamic value stored in a flag. -// (The default value is represented as a string.) -// -// If a Value has an IsBoolFlag() bool method returning true, -// the command-line parser makes -name equivalent to -name=true -// rather than using the next command-line argument. -// -// Set is called once, in command line order, for each flag present. -// The flag package may call the String method with a zero-valued receiver, -// such as a nil pointer. -type Value interface { - String() string - Set(interface{}) error -} - -// Getter is an interface that allows the contents of a Value to be retrieved. -// It wraps the Value interface, rather than being part of it, because it -// appeared after Go 1 and its compatibility rules. All Value types provided -// by this package satisfy the Getter interface. -type Getter interface { - Value - Get() interface{} -} - -// BoolFlag is an interface for determining if the value of a flag is needed. -type BoolFlag interface { - IsBoolFlag() bool -} - -// IsBoolValue returns true for data types which don't require a flag value -func IsBoolValue(value interface{}) bool { - if v, ok := value.(BoolFlag); ok { - return v.IsBoolFlag() - } - var t reflect.Type - if v, ok := value.(Getter); ok { - t = generic.ElemTypeOf(v.Get()) - } else { - t = generic.ElemTypeOf(value) - } - return t != nil && t.String() == "bool" -} - -// ErrorHandling defines how FlagSet.Parse behaves if the parse fails. -type ErrorHandling int - -// These constants cause FlagSet.Parse to behave as described if the parse fails. -const ( - ContinueOnError ErrorHandling = iota // Return a descriptive error. - ExitOnError // Call os.Exit(2) or for -h/-help Exit(0). - PanicOnError // Call panic with a descriptive error. -) - -// A FlagSet represents a set of defined flags. The zero value of a FlagSet -// has no name and has ContinueOnError error handling. -// -// Flag names must be unique within a FlagSet. An attempt to define a flag whose -// name is already in use will cause a panic. -type FlagSet struct { - // Usage is the function called when an error occurs while parsing flags. - // The field is a function (not a method) that may be changed to point to - // a custom error handler. What happens after Usage is called depends - // on the ErrorHandling setting; for the command line, this defaults - // to ExitOnError, which exits the program after calling Usage. - Usage func() - - name string - parsed bool - actual map[string]*Flag - formal map[string]*Flag - args []string // arguments after flags - errorHandling ErrorHandling - output io.Writer // nil means stderr; use Output() accessor -} - -// A Flag represents the state of a flag. -type Flag struct { - Name string // name as it appears on command line - Usage string // help message - Value Value // value as set - DefValue string // default value (as text); for usage message -} - -// sortFlags returns the flags as a slice in lexicographical sorted order. -func sortFlags(flags map[string]*Flag) []*Flag { - result := make([]*Flag, len(flags)) - i := 0 - for _, f := range flags { - result[i] = f - i++ - } - sort.Slice(result, func(i, j int) bool { - return result[i].Name < result[j].Name - }) - return result -} - -const invalidValueTemplate = "invalid value %q for flag -%s: %v" - -func (f *FlagSet) addActual(name string, flag *Flag) { - if f.actual == nil { - f.actual = make(map[string]*Flag) - } - f.actual[name] = flag -} - -// Output returns the destination for usage and error messages. os.Stderr is returned if -// output was not set or was set to nil. -func (f *FlagSet) Output() io.Writer { - if f.output == nil { - return os.Stderr - } - return f.output -} - -// Name returns the name of the flag set. -func (f *FlagSet) Name() string { - return f.name -} - -// ErrorHandling returns the error handling behavior of the flag set. -func (f *FlagSet) ErrorHandling() ErrorHandling { - return f.errorHandling -} - -// SetOutput sets the destination for usage and error messages. -// If output is nil, os.Stderr is used. -func (f *FlagSet) SetOutput(output io.Writer) { - f.output = output -} - -// VisitAll visits the flags in lexicographical order, calling fn for each. -// It visits all flags, even those not set. -func (f *FlagSet) VisitAll(fn func(*Flag)) { - for _, flag := range sortFlags(f.formal) { - fn(flag) - } -} - -// VisitAll visits the command-line flags in lexicographical order, calling -// fn for each. It visits all flags, even those not set. -func VisitAll(fn func(*Flag)) { - CommandLine.VisitAll(fn) -} - -// Visit visits the flags in lexicographical order, calling fn for each. -// It visits only those flags that have been set. -func (f *FlagSet) Visit(fn func(*Flag)) { - for _, flag := range sortFlags(f.actual) { - fn(flag) - } -} - -// NeedsVisit marks the named flags for visit. -func (f *FlagSet) NeedsVisit(names ...string) { - for _, name := range names { - if flag := f.Lookup(name); flag != nil { - f.addActual(name, flag) - } - } -} - -// Visit visits the command-line flags in lexicographical order, calling fn -// for each. It visits only those flags that have been set. -func Visit(fn func(*Flag)) { - CommandLine.Visit(fn) -} - -// Lookup returns the Flag structure of the named flag, returning nil if none exists. -func (f *FlagSet) Lookup(name string) *Flag { - return f.formal[name] -} - -// Lookup returns the Flag structure of the named command-line flag, -// returning nil if none exists. -func Lookup(name string) *Flag { - return CommandLine.formal[name] -} - -// Set sets the value of the named flag. -func (f *FlagSet) Set(name string, value interface{}) error { - flag, ok := f.formal[name] - if !ok { - return fmt.Errorf("no such flag -%v", name) - } - err := flag.Value.Set(value) - if err != nil { - return fmt.Errorf(invalidValueTemplate, value, name, err) - } - f.addActual(name, flag) - return nil -} - -// Set sets the value of the named command-line flag. -func Set(name string, value interface{}) error { - return CommandLine.Set(name, value) -} - -// isZeroValue determines whether the string represents the zero -// value for a flag. -func isZeroValue(flag *Flag, value string) bool { - // Build a zero value of the flag's Value type, and see if the - // result of calling its String method equals the value passed in. - if val, ok := flag.Value.(Getter); ok { - if s, ok := generic.ToString(generic.Zero(val.Get())); ok { - return value == s - } - } - return false -} - -// UnquoteUsage extracts a back-quoted name from the usage -// string for a flag and returns it and the un-quoted usage. -// Given "a `name` to show" it returns ("name", "a name to show"). -// If there are no back quotes, the name is an educated guess of the -// type of the flag's value, or the empty string if the flag is boolean. -func UnquoteUsage(flag *Flag) (name string, usage string) { - // Look for a back-quoted name, but avoid the strings package. - usage = flag.Usage - for i := 0; i < len(usage); i++ { - if usage[i] == '`' { - for j := i + 1; j < len(usage); j++ { - if usage[j] == '`' { - name = usage[i+1 : j] - usage = usage[:i] + name + usage[j+1:] - return name, usage - } - } - break // Only one back quote; use type name. - } - } - // No explicit name, so use type if we can find one. - name = "value" - if v, ok := flag.Value.(Getter); ok { - name = generic.TypeOf(v.Get()).String() - } - if IsBoolValue(flag.Value) { - name = "" - } - return -} - -// PrintDefaults prints, to standard error unless configured otherwise, the -// default values of all defined command-line flags in the set. See the -// documentation for the global function PrintDefaults for more information. -func (f *FlagSet) PrintDefaults() { - f.VisitAll(func(flag *Flag) { - s := fmt.Sprintf(" -%s", flag.Name) // Two spaces before -; see next two comments. - name, usage := UnquoteUsage(flag) - if len(name) > 0 { - s += " " + name - } - // Boolean flags of one ASCII letter are so common we - // treat them specially, putting their usage on the same line. - if len(s) <= 4 { // space, space, '-', 'x'. - s += "\t" - } else { - // Four spaces before the tab triggers good alignment - // for both 4- and 8-space tab stops. - s += "\n \t" - } - s += strings.ReplaceAll(usage, "\n", "\n \t") - - if !isZeroValue(flag, flag.DefValue) { - if v, ok := flag.Value.(Getter); ok && generic.TypeOf(v.Get()).String() == "string" { - // put quotes on the value - s += fmt.Sprintf(" (default %q)", flag.DefValue) - } else { - s += fmt.Sprintf(" (default %v)", flag.DefValue) - } - } - fmt.Fprint(f.Output(), s, "\n") - }) -} - -// PrintDefaults prints, to standard error unless configured otherwise, -// a usage message showing the default settings of all defined -// command-line flags. -// For an integer valued flag x, the default output has the form -// -x int -// usage-message-for-x (default 7) -// The usage message will appear on a separate line for anything but -// a bool flag with a one-byte name. For bool flags, the type is -// omitted and if the flag name is one byte the usage message appears -// on the same line. The parenthetical default is omitted if the -// default is the zero value for the type. The listed type, here int, -// can be changed by placing a back-quoted name in the flag's usage -// string; the first such item in the message is taken to be a parameter -// name to show in the message and the back quotes are stripped from -// the message when displayed. For instance, given -// flag.String("I", "", "search `directory` for include files") -// the output will be -// -I directory -// search directory for include files. -// -// To change the destination for flag messages, call CommandLine.SetOutput. -func PrintDefaults() { - CommandLine.PrintDefaults() -} - -// defaultUsage is the default function to print a usage message. -func (f *FlagSet) defaultUsage() { - if f.name == "" { - fmt.Fprintf(f.Output(), "Usage:\n") - } else { - fmt.Fprintf(f.Output(), "Usage of %s:\n", f.name) - } - f.PrintDefaults() -} - -// NOTE: Usage is not just defaultUsage(CommandLine) -// because it serves (via godoc flag Usage) as the example -// for how to write your own usage function. - -// Usage prints a usage message documenting all defined command-line flags -// to CommandLine's output, which by default is os.Stderr. -// It is called when an error occurs while parsing flags. -// The function is a variable that may be changed to point to a custom function. -// By default it prints a simple header and calls PrintDefaults; for details about the -// format of the output and how to control it, see the documentation for PrintDefaults. -// Custom usage functions may choose to exit the program; by default exiting -// happens anyway as the command line's error handling strategy is set to -// ExitOnError. -var Usage = func() { - fmt.Fprintf(CommandLine.Output(), "Usage of %s:\n", os.Args[0]) - PrintDefaults() -} - -// NFlag returns the number of flags that have been set. -func (f *FlagSet) NFlag() int { return len(f.actual) } - -// NFlag returns the number of command-line flags that have been set. -func NFlag() int { return len(CommandLine.actual) } - -// Arg returns the i'th argument. Arg(0) is the first remaining argument -// after flags have been processed. Arg returns an empty string if the -// requested element does not exist. -func (f *FlagSet) Arg(i int) string { - if i < 0 || i >= len(f.args) { - return "" - } - return f.args[i] -} - -// Arg returns the i'th command-line argument. Arg(0) is the first remaining argument -// after flags have been processed. Arg returns an empty string if the -// requested element does not exist. -func Arg(i int) string { - return CommandLine.Arg(i) -} - -// NArg is the number of arguments remaining after flags have been processed. -func (f *FlagSet) NArg() int { return len(f.args) } - -// NArg is the number of arguments remaining after flags have been processed. -func NArg() int { return len(CommandLine.args) } - -// Args returns the non-flag arguments. -func (f *FlagSet) Args() []string { return f.args } - -// Args returns the non-flag command-line arguments. -func Args() []string { return CommandLine.args } - -// Var defines a flag with the specified name and usage string. The type and -// value of the flag are represented by the first argument, of type Value, which -// typically holds a user-defined implementation of Value. For instance, the -// caller could create a flag that turns a comma-separated string into a slice -// of strings by giving the slice the methods of Value; in particular, Set would -// decompose the comma-separated string into the slice. -func (f *FlagSet) Var(value Value, name string, usage string) { - // Remember the default value as a string; it won't change. - flag := &Flag{name, usage, value, value.String()} - _, alreadythere := f.formal[name] - if alreadythere { - var msg string - if f.name == "" { - msg = fmt.Sprintf("flag redefined: %s", name) - } else { - msg = fmt.Sprintf("%s flag redefined: %s", f.name, name) - } - fmt.Fprintln(f.Output(), msg) - panic(msg) // Happens only if flags are declared with identical names - } - if f.formal == nil { - f.formal = make(map[string]*Flag) - } - f.formal[name] = flag -} - -// Var defines a flag with the specified name and usage string. The type and -// value of the flag are represented by the first argument, of type Value, which -// typically holds a user-defined implementation of Value. For instance, the -// caller could create a flag that turns a comma-separated string into a slice -// of strings by giving the slice the methods of Value; in particular, Set would -// decompose the comma-separated string into the slice. -func Var(value Value, name string, usage string) { - CommandLine.Var(value, name, usage) -} - -// failf prints to standard error a formatted error and usage message and -// returns the error. -func (f *FlagSet) failf(format string, a ...interface{}) error { - err := fmt.Errorf(format, a...) - fmt.Fprintln(f.Output(), err) - f.usage() - return err -} - -// usage calls the Usage method for the flag set if one is specified, -// or the appropriate default usage function otherwise. -func (f *FlagSet) usage() { - if f.Usage == nil { - f.defaultUsage() - } else { - f.Usage() - } -} - -// parseOne parses one flag. It reports whether a flag was seen. -func (f *FlagSet) parseOne() (bool, error) { - if len(f.args) == 0 { - return false, nil - } - s := f.args[0] - if len(s) < 2 || s[0] != '-' { - return false, nil - } - numMinuses := 1 - if s[1] == '-' { - numMinuses++ - if len(s) == 2 { // "--" terminates the flags - f.args = f.args[1:] - return false, nil - } - } - name := s[numMinuses:] - if len(name) == 0 || name[0] == '-' || name[0] == '=' { - return false, f.failf("bad flag syntax: %s", s) - } - - // it's a flag. does it have an argument? - f.args = f.args[1:] - hasValue := false - value := "" - for i := 1; i < len(name); i++ { // equals cannot be first - if name[i] == '=' { - value = name[i+1:] - hasValue = true - name = name[0:i] - break - } - } - m := f.formal - flag, alreadythere := m[name] // BUG - if !alreadythere { - if name == "help" || name == "h" { // special case for nice help message. - f.usage() - return false, ErrHelp - } - return false, f.failf("flag provided but not defined: -%s", name) - } - - if IsBoolValue(flag.Value) { // special case: doesn't need an arg - if hasValue { - if err := flag.Value.Set(value); err != nil { - return false, f.failf(invalidValueTemplate, value, name, err) - } - } else { - if err := flag.Value.Set("true"); err != nil { - return false, f.failf("invalid boolean flag %s: %v", name, err) - } - } - } else { - // It must have a value, which might be the next argument. - if !hasValue && len(f.args) > 0 { - // value is the next arg - hasValue = true - value, f.args = f.args[0], f.args[1:] - } - if !hasValue { - return false, f.failf("flag needs an argument: -%s", name) - } - if err := flag.Value.Set(value); err != nil { - return false, f.failf(invalidValueTemplate, value, name, err) - } - } - if f.actual == nil { - f.actual = make(map[string]*Flag) - } - f.actual[name] = flag - return true, nil -} - -// Parse parses flag definitions from the argument list, which should not -// include the command name. Must be called after all flags in the FlagSet -// are defined and before flags are accessed by the program. -// The return value will be ErrHelp if -help or -h were set but not defined. -func (f *FlagSet) Parse(arguments []string) error { - f.parsed = true - f.args = arguments - for { - seen, err := f.parseOne() - if seen { - continue - } - if err == nil { - break - } - switch f.errorHandling { - case ContinueOnError: - return err - case ExitOnError: - if err == ErrHelp { - os.Exit(0) - } - os.Exit(2) - case PanicOnError: - panic(err) - } - } - return nil -} - -// Parsed reports whether f.Parse has been called. -func (f *FlagSet) Parsed() bool { - return f.parsed -} - -// Parse parses the command-line flags from os.Args[1:]. Must be called -// after all flags are defined and before flags are accessed by the program. -func Parse() { - // Ignore errors; CommandLine is set for ExitOnError. - CommandLine.Parse(os.Args[1:]) -} - -// Parsed reports whether the command-line flags have been parsed. -func Parsed() bool { - return CommandLine.Parsed() -} - -// CommandLine is the default set of command-line flags, parsed from os.Args. -// The top-level functions such as BoolVar, Arg, and so on are wrappers for the -// methods of CommandLine. -var CommandLine = NewFlagSet(os.Args[0], ExitOnError) - -func init() { - // Override generic FlagSet default Usage with call to global Usage. - // Note: This is not CommandLine.Usage = Usage, - // because we want any eventual call to use any updated value of Usage, - // not the value it has when this line is run. - CommandLine.Usage = commandLineUsage -} - -func commandLineUsage() { - Usage() -} - -// NewFlagSet returns a new, empty flag set with the specified name and -// error handling property. If the name is not empty, it will be printed -// in the default usage message and in error messages. -func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet { - f := &FlagSet{ - name: name, - errorHandling: errorHandling, - } - f.Usage = f.defaultUsage - return f -} - -// Init sets the name and error handling property for a flag set. -// By default, the zero FlagSet uses an empty name and the -// ContinueOnError error handling policy. -func (f *FlagSet) Init(name string, errorHandling ErrorHandling) { - f.name = name - f.errorHandling = errorHandling -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_bool.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_bool.go deleted file mode 100644 index 692753e026..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_bool.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// BoolVar defines a bool flag with specified name, default value, and usage string. -// The argument p points to a bool variable in which to store the value of the flag. -func (f *FlagSet) BoolVar(ptr *bool, name string, value bool, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Bool defines a bool flag with specified name, default value, and usage string. -// The return value is the address of a bool variable that stores the value of the flag. -func (f *FlagSet) Bool(name string, value bool, usage string) *bool { - return f.Generic(name, value, usage).(*bool) -} - -// BoolVar defines a bool flag with specified name, default value, and usage string. -// The argument p points to a bool variable in which to store the value of the flag. -func BoolVar(ptr *bool, name string, value bool, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Bool defines a bool flag with specified name, default value, and usage string. -// The return value is the address of a bool variable that stores the value of the flag. -func Bool(name string, value bool, usage string) *bool { - return CommandLine.Generic(name, value, usage).(*bool) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_boolSlice.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_boolSlice.go deleted file mode 100644 index 7a7ea43a36..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_boolSlice.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// BoolSliceVar defines a []bool flag with specified name, default value, and usage string. -// The argument p points to a []bool variable in which to store the value of the flag. -func (f *FlagSet) BoolSliceVar(ptr *[]bool, name string, value []bool, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// BoolSlice defines a []bool flag with specified name, default value, and usage string. -// The return value is the address of a []bool variable that stores the value of the flag. -func (f *FlagSet) BoolSlice(name string, value []bool, usage string) *[]bool { - return f.Generic(name, value, usage).(*[]bool) -} - -// BoolSliceVar defines a []bool flag with specified name, default value, and usage string. -// The argument p points to a []bool variable in which to store the value of the flag. -func BoolSliceVar(ptr *[]bool, name string, value []bool, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// BoolSlice defines a []bool flag with specified name, default value, and usage string. -// The return value is the address of a []bool variable that stores the value of the flag. -func BoolSlice(name string, value []bool, usage string) *[]bool { - return CommandLine.Generic(name, value, usage).(*[]bool) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_duration.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_duration.go deleted file mode 100644 index 6b7a00a7d8..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_duration.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// DurationVar defines a time.Duration flag with specified name, default value, and usage string. -// The argument p points to a time.Duration variable in which to store the value of the flag. -func (f *FlagSet) DurationVar(ptr *time.Duration, name string, value time.Duration, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Duration defines a time.Duration flag with specified name, default value, and usage string. -// The return value is the address of a time.Duration variable that stores the value of the flag. -func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration { - return f.Generic(name, value, usage).(*time.Duration) -} - -// DurationVar defines a time.Duration flag with specified name, default value, and usage string. -// The argument p points to a time.Duration variable in which to store the value of the flag. -func DurationVar(ptr *time.Duration, name string, value time.Duration, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Duration defines a time.Duration flag with specified name, default value, and usage string. -// The return value is the address of a time.Duration variable that stores the value of the flag. -func Duration(name string, value time.Duration, usage string) *time.Duration { - return CommandLine.Generic(name, value, usage).(*time.Duration) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_durationSlice.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_durationSlice.go deleted file mode 100644 index 00ed6103ae..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_durationSlice.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// DurationSliceVar defines a []time.Duration flag with specified name, default value, and usage string. -// The argument p points to a []time.Duration variable in which to store the value of the flag. -func (f *FlagSet) DurationSliceVar(ptr *[]time.Duration, name string, value []time.Duration, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string. -// The return value is the address of a []time.Duration variable that stores the value of the flag. -func (f *FlagSet) DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration { - return f.Generic(name, value, usage).(*[]time.Duration) -} - -// DurationSliceVar defines a []time.Duration flag with specified name, default value, and usage string. -// The argument p points to a []time.Duration variable in which to store the value of the flag. -func DurationSliceVar(ptr *[]time.Duration, name string, value []time.Duration, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// DurationSlice defines a []time.Duration flag with specified name, default value, and usage string. -// The return value is the address of a []time.Duration variable that stores the value of the flag. -func DurationSlice(name string, value []time.Duration, usage string) *[]time.Duration { - return CommandLine.Generic(name, value, usage).(*[]time.Duration) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_float64.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_float64.go deleted file mode 100644 index bd267a647b..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_float64.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// Float64Var defines a float64 flag with specified name, default value, and usage string. -// The argument p points to a float64 variable in which to store the value of the flag. -func (f *FlagSet) Float64Var(ptr *float64, name string, value float64, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Float64 defines a float64 flag with specified name, default value, and usage string. -// The return value is the address of a float64 variable that stores the value of the flag. -func (f *FlagSet) Float64(name string, value float64, usage string) *float64 { - return f.Generic(name, value, usage).(*float64) -} - -// Float64Var defines a float64 flag with specified name, default value, and usage string. -// The argument p points to a float64 variable in which to store the value of the flag. -func Float64Var(ptr *float64, name string, value float64, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Float64 defines a float64 flag with specified name, default value, and usage string. -// The return value is the address of a float64 variable that stores the value of the flag. -func Float64(name string, value float64, usage string) *float64 { - return CommandLine.Generic(name, value, usage).(*float64) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_float64Slice.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_float64Slice.go deleted file mode 100644 index 81fa1ceb7e..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_float64Slice.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// Float64SliceVar defines a []float64 flag with specified name, default value, and usage string. -// The argument p points to a []float64 variable in which to store the value of the flag. -func (f *FlagSet) Float64SliceVar(ptr *[]float64, name string, value []float64, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Float64Slice defines a []float64 flag with specified name, default value, and usage string. -// The return value is the address of a []float64 variable that stores the value of the flag. -func (f *FlagSet) Float64Slice(name string, value []float64, usage string) *[]float64 { - return f.Generic(name, value, usage).(*[]float64) -} - -// Float64SliceVar defines a []float64 flag with specified name, default value, and usage string. -// The argument p points to a []float64 variable in which to store the value of the flag. -func Float64SliceVar(ptr *[]float64, name string, value []float64, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Float64Slice defines a []float64 flag with specified name, default value, and usage string. -// The return value is the address of a []float64 variable that stores the value of the flag. -func Float64Slice(name string, value []float64, usage string) *[]float64 { - return CommandLine.Generic(name, value, usage).(*[]float64) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_int.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_int.go deleted file mode 100644 index f5a5d4f75a..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_int.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// IntVar defines a int flag with specified name, default value, and usage string. -// The argument p points to a int variable in which to store the value of the flag. -func (f *FlagSet) IntVar(ptr *int, name string, value int, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Int defines a int flag with specified name, default value, and usage string. -// The return value is the address of a int variable that stores the value of the flag. -func (f *FlagSet) Int(name string, value int, usage string) *int { - return f.Generic(name, value, usage).(*int) -} - -// IntVar defines a int flag with specified name, default value, and usage string. -// The argument p points to a int variable in which to store the value of the flag. -func IntVar(ptr *int, name string, value int, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Int defines a int flag with specified name, default value, and usage string. -// The return value is the address of a int variable that stores the value of the flag. -func Int(name string, value int, usage string) *int { - return CommandLine.Generic(name, value, usage).(*int) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_int64.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_int64.go deleted file mode 100644 index 235ae50312..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_int64.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// Int64Var defines a int64 flag with specified name, default value, and usage string. -// The argument p points to a int64 variable in which to store the value of the flag. -func (f *FlagSet) Int64Var(ptr *int64, name string, value int64, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Int64 defines a int64 flag with specified name, default value, and usage string. -// The return value is the address of a int64 variable that stores the value of the flag. -func (f *FlagSet) Int64(name string, value int64, usage string) *int64 { - return f.Generic(name, value, usage).(*int64) -} - -// Int64Var defines a int64 flag with specified name, default value, and usage string. -// The argument p points to a int64 variable in which to store the value of the flag. -func Int64Var(ptr *int64, name string, value int64, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Int64 defines a int64 flag with specified name, default value, and usage string. -// The return value is the address of a int64 variable that stores the value of the flag. -func Int64(name string, value int64, usage string) *int64 { - return CommandLine.Generic(name, value, usage).(*int64) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_int64Slice.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_int64Slice.go deleted file mode 100644 index be7d543f70..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_int64Slice.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// Int64SliceVar defines a []int64 flag with specified name, default value, and usage string. -// The argument p points to a []int64 variable in which to store the value of the flag. -func (f *FlagSet) Int64SliceVar(ptr *[]int64, name string, value []int64, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Int64Slice defines a []int64 flag with specified name, default value, and usage string. -// The return value is the address of a []int64 variable that stores the value of the flag. -func (f *FlagSet) Int64Slice(name string, value []int64, usage string) *[]int64 { - return f.Generic(name, value, usage).(*[]int64) -} - -// Int64SliceVar defines a []int64 flag with specified name, default value, and usage string. -// The argument p points to a []int64 variable in which to store the value of the flag. -func Int64SliceVar(ptr *[]int64, name string, value []int64, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Int64Slice defines a []int64 flag with specified name, default value, and usage string. -// The return value is the address of a []int64 variable that stores the value of the flag. -func Int64Slice(name string, value []int64, usage string) *[]int64 { - return CommandLine.Generic(name, value, usage).(*[]int64) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_intSlice.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_intSlice.go deleted file mode 100644 index f34ba31f23..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_intSlice.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// IntSliceVar defines a []int flag with specified name, default value, and usage string. -// The argument p points to a []int variable in which to store the value of the flag. -func (f *FlagSet) IntSliceVar(ptr *[]int, name string, value []int, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// IntSlice defines a []int flag with specified name, default value, and usage string. -// The return value is the address of a []int variable that stores the value of the flag. -func (f *FlagSet) IntSlice(name string, value []int, usage string) *[]int { - return f.Generic(name, value, usage).(*[]int) -} - -// IntSliceVar defines a []int flag with specified name, default value, and usage string. -// The argument p points to a []int variable in which to store the value of the flag. -func IntSliceVar(ptr *[]int, name string, value []int, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// IntSlice defines a []int flag with specified name, default value, and usage string. -// The return value is the address of a []int variable that stores the value of the flag. -func IntSlice(name string, value []int, usage string) *[]int { - return CommandLine.Generic(name, value, usage).(*[]int) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_string.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_string.go deleted file mode 100644 index 1abdeca846..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_string.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// StringVar defines a string flag with specified name, default value, and usage string. -// The argument p points to a string variable in which to store the value of the flag. -func (f *FlagSet) StringVar(ptr *string, name string, value string, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// String defines a string flag with specified name, default value, and usage string. -// The return value is the address of a string variable that stores the value of the flag. -func (f *FlagSet) String(name string, value string, usage string) *string { - return f.Generic(name, value, usage).(*string) -} - -// StringVar defines a string flag with specified name, default value, and usage string. -// The argument p points to a string variable in which to store the value of the flag. -func StringVar(ptr *string, name string, value string, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// String defines a string flag with specified name, default value, and usage string. -// The return value is the address of a string variable that stores the value of the flag. -func String(name string, value string, usage string) *string { - return CommandLine.Generic(name, value, usage).(*string) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_stringSlice.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_stringSlice.go deleted file mode 100644 index 0e336230ea..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_stringSlice.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// StringSliceVar defines a []string flag with specified name, default value, and usage string. -// The argument p points to a []string variable in which to store the value of the flag. -func (f *FlagSet) StringSliceVar(ptr *[]string, name string, value []string, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// StringSlice defines a []string flag with specified name, default value, and usage string. -// The return value is the address of a []string variable that stores the value of the flag. -func (f *FlagSet) StringSlice(name string, value []string, usage string) *[]string { - return f.Generic(name, value, usage).(*[]string) -} - -// StringSliceVar defines a []string flag with specified name, default value, and usage string. -// The argument p points to a []string variable in which to store the value of the flag. -func StringSliceVar(ptr *[]string, name string, value []string, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// StringSlice defines a []string flag with specified name, default value, and usage string. -// The return value is the address of a []string variable that stores the value of the flag. -func StringSlice(name string, value []string, usage string) *[]string { - return CommandLine.Generic(name, value, usage).(*[]string) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_time.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_time.go deleted file mode 100644 index 5a4fd1acb2..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_time.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// TimeVar defines a time.Time flag with specified name, default value, and usage string. -// The argument p points to a time.Time variable in which to store the value of the flag. -func (f *FlagSet) TimeVar(ptr *time.Time, name string, value time.Time, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Time defines a time.Time flag with specified name, default value, and usage string. -// The return value is the address of a time.Time variable that stores the value of the flag. -func (f *FlagSet) Time(name string, value time.Time, usage string) *time.Time { - return f.Generic(name, value, usage).(*time.Time) -} - -// TimeVar defines a time.Time flag with specified name, default value, and usage string. -// The argument p points to a time.Time variable in which to store the value of the flag. -func TimeVar(ptr *time.Time, name string, value time.Time, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Time defines a time.Time flag with specified name, default value, and usage string. -// The return value is the address of a time.Time variable that stores the value of the flag. -func Time(name string, value time.Time, usage string) *time.Time { - return CommandLine.Generic(name, value, usage).(*time.Time) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_timeSlice.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_timeSlice.go deleted file mode 100644 index 9ae104c7ca..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_timeSlice.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// TimeSliceVar defines a []time.Time flag with specified name, default value, and usage string. -// The argument p points to a []time.Time variable in which to store the value of the flag. -func (f *FlagSet) TimeSliceVar(ptr *[]time.Time, name string, value []time.Time, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// TimeSlice defines a []time.Time flag with specified name, default value, and usage string. -// The return value is the address of a []time.Time variable that stores the value of the flag. -func (f *FlagSet) TimeSlice(name string, value []time.Time, usage string) *[]time.Time { - return f.Generic(name, value, usage).(*[]time.Time) -} - -// TimeSliceVar defines a []time.Time flag with specified name, default value, and usage string. -// The argument p points to a []time.Time variable in which to store the value of the flag. -func TimeSliceVar(ptr *[]time.Time, name string, value []time.Time, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// TimeSlice defines a []time.Time flag with specified name, default value, and usage string. -// The return value is the address of a []time.Time variable that stores the value of the flag. -func TimeSlice(name string, value []time.Time, usage string) *[]time.Time { - return CommandLine.Generic(name, value, usage).(*[]time.Time) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_uint.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_uint.go deleted file mode 100644 index ec2563117d..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_uint.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// UintVar defines a uint flag with specified name, default value, and usage string. -// The argument p points to a uint variable in which to store the value of the flag. -func (f *FlagSet) UintVar(ptr *uint, name string, value uint, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Uint defines a uint flag with specified name, default value, and usage string. -// The return value is the address of a uint variable that stores the value of the flag. -func (f *FlagSet) Uint(name string, value uint, usage string) *uint { - return f.Generic(name, value, usage).(*uint) -} - -// UintVar defines a uint flag with specified name, default value, and usage string. -// The argument p points to a uint variable in which to store the value of the flag. -func UintVar(ptr *uint, name string, value uint, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Uint defines a uint flag with specified name, default value, and usage string. -// The return value is the address of a uint variable that stores the value of the flag. -func Uint(name string, value uint, usage string) *uint { - return CommandLine.Generic(name, value, usage).(*uint) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64.go deleted file mode 100644 index 7aefd26981..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// Uint64Var defines a uint64 flag with specified name, default value, and usage string. -// The argument p points to a uint64 variable in which to store the value of the flag. -func (f *FlagSet) Uint64Var(ptr *uint64, name string, value uint64, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Uint64 defines a uint64 flag with specified name, default value, and usage string. -// The return value is the address of a uint64 variable that stores the value of the flag. -func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64 { - return f.Generic(name, value, usage).(*uint64) -} - -// Uint64Var defines a uint64 flag with specified name, default value, and usage string. -// The argument p points to a uint64 variable in which to store the value of the flag. -func Uint64Var(ptr *uint64, name string, value uint64, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Uint64 defines a uint64 flag with specified name, default value, and usage string. -// The return value is the address of a uint64 variable that stores the value of the flag. -func Uint64(name string, value uint64, usage string) *uint64 { - return CommandLine.Generic(name, value, usage).(*uint64) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64Slice.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64Slice.go deleted file mode 100644 index f2cd099adc..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64Slice.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// Uint64SliceVar defines a []uint64 flag with specified name, default value, and usage string. -// The argument p points to a []uint64 variable in which to store the value of the flag. -func (f *FlagSet) Uint64SliceVar(ptr *[]uint64, name string, value []uint64, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// Uint64Slice defines a []uint64 flag with specified name, default value, and usage string. -// The return value is the address of a []uint64 variable that stores the value of the flag. -func (f *FlagSet) Uint64Slice(name string, value []uint64, usage string) *[]uint64 { - return f.Generic(name, value, usage).(*[]uint64) -} - -// Uint64SliceVar defines a []uint64 flag with specified name, default value, and usage string. -// The argument p points to a []uint64 variable in which to store the value of the flag. -func Uint64SliceVar(ptr *[]uint64, name string, value []uint64, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Uint64Slice defines a []uint64 flag with specified name, default value, and usage string. -// The return value is the address of a []uint64 variable that stores the value of the flag. -func Uint64Slice(name string, value []uint64, usage string) *[]uint64 { - return CommandLine.Generic(name, value, usage).(*[]uint64) -} diff --git a/vendor/github.com/rancher/spur/flag/flag.zz_generated_uintSlice.go b/vendor/github.com/rancher/spur/flag/flag.zz_generated_uintSlice.go deleted file mode 100644 index 5fd690766a..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag.zz_generated_uintSlice.go +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "time" -) - -var _ = time.Time{} - -// UintSliceVar defines a []uint flag with specified name, default value, and usage string. -// The argument p points to a []uint variable in which to store the value of the flag. -func (f *FlagSet) UintSliceVar(ptr *[]uint, name string, value []uint, usage string) { - f.GenericVar(ptr, name, value, usage) -} - -// UintSlice defines a []uint flag with specified name, default value, and usage string. -// The return value is the address of a []uint variable that stores the value of the flag. -func (f *FlagSet) UintSlice(name string, value []uint, usage string) *[]uint { - return f.Generic(name, value, usage).(*[]uint) -} - -// UintSliceVar defines a []uint flag with specified name, default value, and usage string. -// The argument p points to a []uint variable in which to store the value of the flag. -func UintSliceVar(ptr *[]uint, name string, value []uint, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// UintSlice defines a []uint flag with specified name, default value, and usage string. -// The return value is the address of a []uint variable that stores the value of the flag. -func UintSlice(name string, value []uint, usage string) *[]uint { - return CommandLine.Generic(name, value, usage).(*[]uint) -} diff --git a/vendor/github.com/rancher/spur/flag/flag_generic.go b/vendor/github.com/rancher/spur/flag/flag_generic.go deleted file mode 100644 index 0f70f83d9b..0000000000 --- a/vendor/github.com/rancher/spur/flag/flag_generic.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package flag - -import ( - "fmt" - "time" - - "github.com/rancher/spur/generic" -) - -var _ = time.Time{} - -// GenericValue takes a pointer to a generic type -type GenericValue struct { - ptr interface{} - set bool -} - -// NewGenericValue returns a flag.Value given a pointer -func NewGenericValue(ptr interface{}) Value { - generic.PtrPanic(ptr) - return &GenericValue{ptr: ptr} -} - -// Get returns the contents of the stored pointer -func (v *GenericValue) Get() interface{} { - return generic.ValueOfPtr(v.ptr) -} - -// Set will convert a given value to the type of our pointer -// and store the new value -func (v *GenericValue) Set(value interface{}) error { - if generic.IsSlice(v.Get()) && !v.set { - // If this is a slice and has not already been set then - // clear any existing value - generic.Set(v.ptr, generic.Zero(v.Get())) - v.set = true - } - val, err := generic.Convert(v.Get(), value) - if err != nil { - return err - } - generic.Set(v.ptr, val) - return nil -} - -// String returns a string representation of our generic value -func (v *GenericValue) String() string { - return generic.Stringify(v.Get()) -} - -// GenericVar defines a generic flag with specified name, default value, and usage string. -// The argument p points to a generic variable in which to store the value of the flag. -func (f *FlagSet) GenericVar(ptr interface{}, name string, value interface{}, usage string) { - generic.Set(ptr, value) - f.Var(NewGenericValue(ptr), name, usage) -} - -// Generic defines a generic flag with specified name, default value, and usage string. -// The return value is the address of a generic variable that stores the value of the flag. -func (f *FlagSet) Generic(name string, value interface{}, usage string) interface{} { - if value == nil { - panic(fmt.Errorf("creating generic from nil interface %s", name)) - } - ptr := generic.New(value) - f.GenericVar(ptr, name, value, usage) - return ptr -} - -// GenericVar defines a generic flag with specified name, default value, and usage string. -// The argument p points to a generic variable in which to store the value of the flag. -func GenericVar(ptr interface{}, name string, value interface{}, usage string) { - CommandLine.GenericVar(ptr, name, value, usage) -} - -// Generic defines a generic flag with specified name, default value, and usage string. -// The return value is the address of a generic variable that stores the value of the flag. -func Generic(name string, value interface{}, usage string) interface{} { - return CommandLine.Generic(name, value, usage) -} diff --git a/vendor/github.com/rancher/spur/generic/error.go b/vendor/github.com/rancher/spur/generic/error.go deleted file mode 100644 index 7c80fe810c..0000000000 --- a/vendor/github.com/rancher/spur/generic/error.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package generic - -import ( - "errors" - "strconv" -) - -// errParse is returned by Set if a flag's value fails to parse, such as with an invalid integer for Int. -// It then gets wrapped through failf to provide more information. -var errParse = errors.New("parse error") - -// errRange is returned by Set if a flag's value is out of range. -// It then gets wrapped through failf to provide more information. -var errRange = errors.New("value out of range") - -func numError(err error) error { - ne, ok := err.(*strconv.NumError) - if !ok { - return err - } - if ne.Err == strconv.ErrSyntax { - return errParse - } - if ne.Err == strconv.ErrRange { - return errRange - } - return err -} diff --git a/vendor/github.com/rancher/spur/generic/generic.go b/vendor/github.com/rancher/spur/generic/generic.go deleted file mode 100644 index 02a9dbb45b..0000000000 --- a/vendor/github.com/rancher/spur/generic/generic.go +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package generic - -import ( - "encoding/json" - "fmt" - "reflect" - "time" - - "gopkg.in/yaml.v2" -) - -// Marshal is the function used for marshaling slices -var Marshal = json.Marshal - -// Unmarshal is the function used for un-marshaling slices -var Unmarshal = yaml.Unmarshal - -// ToStringFunc is the function definition for converting types to strings -type ToStringFunc = func(interface{}) (string, bool) - -// FromStringFunc is the function definition for converting strings to types -type FromStringFunc = func(string) (interface{}, error) - -// ToStringMap provides a mapping of type to string conversion function -var ToStringMap = map[string]ToStringFunc{} - -// FromStringMap provides a mapping of string to type conversion function -var FromStringMap = map[string]FromStringFunc{} - -// TimeLayouts provides a list of layouts to attempt when converting time strings -var TimeLayouts = []string{ - time.RFC3339Nano, - time.RFC3339, - time.UnixDate, - time.RubyDate, - time.ANSIC, - time.RFC822, - time.RFC822Z, - time.RFC850, - time.RFC1123, - time.RFC1123Z, - time.StampNano, - time.StampMicro, - time.StampMilli, - time.Stamp, - time.Kitchen, -} - -// ToString is a convenience function for converting types to strings as defined in ToStringMap -func ToString(value interface{}) (string, bool) { - if value == nil { - return "", false - } - if toString := ToStringMap[TypeOf(value).String()]; toString != nil { - return toString(value) - } - return "", false -} - -// FromString is a convenience function for converting strings to types as defined in FromStringMap -func FromString(value string, ptr interface{}) error { - PtrPanic(ptr) - typ := reflect.TypeOf(ptr).Elem().String() - fromString := FromStringMap[typ] - if fromString == nil { - return errParse - } - val, err := fromString(value) - if err != nil { - return numError(err) - } - Set(ptr, val) - return nil -} - -// TypeOf returns the dereferenced value's type -func TypeOf(value interface{}) reflect.Type { - typ := reflect.TypeOf(value) - if typ != nil && typ.Kind() == reflect.Ptr { - typ = typ.Elem() - } - return typ -} - -// ElemTypeOf returns the dereferenced value's type or TypeOf is not an Elem -func ElemTypeOf(value interface{}) reflect.Type { - typ := TypeOf(value) - if typ.Kind() == reflect.Slice { - return typ.Elem() - } - return typ -} - -// New returns a new reflection with TypeOf value -func New(value interface{}) interface{} { - return reflect.New(TypeOf(value)).Interface() -} - -// NewElem returns a new reflection with ElemTypeOf value -func NewElem(value interface{}) interface{} { - return reflect.New(ElemTypeOf(value)).Interface() -} - -// Zero returns a zero reflection with TypeOf value -func Zero(value interface{}) interface{} { - return reflect.Zero(TypeOf(value)).Interface() -} - -// IsSlice return true if the TypeOf value is a slice -func IsSlice(value interface{}) bool { - if value == nil { - return false - } - return TypeOf(value).Kind() == reflect.Slice -} - -// PtrPanic halts execution if the passed ptr is not a pointer -func PtrPanic(ptr interface{}) { - if !IsPtr(ptr) { - panic(fmt.Errorf("expected pointer type, got %s", reflect.TypeOf(ptr).String())) - } -} - -// Set will assign the contents of ptr to value -func Set(ptr interface{}, value interface{}) { - PtrPanic(ptr) - if value == nil { - return - } - reflect.ValueOf(ptr).Elem().Set(reflect.ValueOf(value)) -} - -// Len returns the length of a slice, or -1 if not a slice -func Len(value interface{}) int { - if !IsSlice(value) { - return -1 - } - return reflect.ValueOf(value).Len() -} - -// Index will return the value of a slice at a given index -func Index(value interface{}, i int) interface{} { - if !IsSlice(value) { - return nil - } - return reflect.ValueOf(value).Index(i).Interface() -} - -// Append will append an element onto a generic slice -func Append(slice interface{}, elem interface{}) interface{} { - return reflect.Append(reflect.ValueOf(slice), reflect.ValueOf(elem)).Interface() -} - -// IsPtr returns true if the given value is of kind reflect.Ptr -func IsPtr(value interface{}) bool { - if value == nil { - return false - } - return reflect.TypeOf(value).Kind() == reflect.Ptr -} - -// ValueOfPtr returns the contents of a pointer, or the given value if not a pointer -func ValueOfPtr(value interface{}) interface{} { - if !IsPtr(value) { - return value - } - elem := reflect.ValueOf(value).Elem() - if !elem.IsValid() { - return nil - } - return elem.Interface() -} - -// Convert will return a new result of type src, where value is converted to the type -// of src or appended if src is a slice and value is an element -func Convert(src interface{}, value interface{}) (interface{}, error) { - // Convert an element - elem, err := ConvertElem(src, value) - if !IsSlice(src) { - // Return value and error if not a slice - return elem, err - } - // Try deserializing as string - if s, ok := value.(string); ok { - val := New(src) - if err := Unmarshal([]byte(s), val); err == nil { - return ValueOfPtr(val), nil - } - } - // If no error from converting element return appended value - if err == nil { - return Append(src, elem), nil - } - // Try evaluating value as a slice of interfaces - otherValue, ok := value.([]interface{}) - if !ok { - return nil, errParse - } - // Create a new slice and append each converted element - slice := Zero(src) - for _, other := range otherValue { - elem, err := ConvertElem(src, other) - if err != nil { - return nil, err - } - slice = Append(slice, elem) - } - return slice, nil -} - -// ConvertElem will return a new result, where value is converted to the type -// of src or returned as an element if src is a slice -func ConvertElem(src interface{}, value interface{}) (interface{}, error) { - // Get our value as a string - s, ok := value.(string) - if !ok { - if s, ok = ToString(value); !ok { - return nil, errParse - } - } - // Return a new value from the string - ptr := NewElem(src) - err := FromString(s, ptr) - return ValueOfPtr(ptr), err -} - -// Stringify returns the ToString version of the value, or the Marshaled version -// in the case of slices, otherwise panic if cannot be converted to string -func Stringify(value interface{}) string { - if s, ok := ToString(value); ok { - return s - } - if b, err := Marshal(value); err == nil { - return string(b) - } - panic(errParse) -} diff --git a/vendor/github.com/rancher/spur/generic/string_from.go b/vendor/github.com/rancher/spur/generic/string_from.go deleted file mode 100644 index ec698c06cc..0000000000 --- a/vendor/github.com/rancher/spur/generic/string_from.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package generic - -import ( - "strconv" - "time" -) - -func init() { - FromStringMap["string"] = func(s string) (interface{}, error) { - return s, nil - } - FromStringMap["bool"] = func(s string) (interface{}, error) { - if s == "" { - s = "false" - } - v, err := strconv.ParseBool(s) - return bool(v), err - } - FromStringMap["int"] = func(s string) (interface{}, error) { - v, err := strconv.ParseInt(s, 0, strconv.IntSize) - return int(v), err - } - FromStringMap["int64"] = func(s string) (interface{}, error) { - v, err := strconv.ParseInt(s, 0, 64) - return int64(v), err - } - FromStringMap["uint"] = func(s string) (interface{}, error) { - v, err := strconv.ParseUint(s, 0, strconv.IntSize) - return uint(v), err - } - FromStringMap["uint64"] = func(s string) (interface{}, error) { - v, err := strconv.ParseUint(s, 0, 64) - return uint64(v), err - } - FromStringMap["float64"] = func(s string) (interface{}, error) { - v, err := strconv.ParseFloat(s, 64) - return float64(v), err - } - FromStringMap["time.Duration"] = func(s string) (interface{}, error) { - if v, err := time.ParseDuration(s); err == nil { - return time.Duration(v), nil - } - return nil, errParse - } - FromStringMap["time.Time"] = func(s string) (interface{}, error) { - for _, layout := range TimeLayouts { - if v, err := time.Parse(layout, s); err == nil { - return time.Time(v), nil - } - } - return nil, errParse - } -} diff --git a/vendor/github.com/rancher/spur/generic/string_to.go b/vendor/github.com/rancher/spur/generic/string_to.go deleted file mode 100644 index 6d2ea98ad9..0000000000 --- a/vendor/github.com/rancher/spur/generic/string_to.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2020 Rancher Labs, Inc. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package generic - -import ( - "strconv" - "time" -) - -func init() { - ToStringMap["string"] = func(value interface{}) (string, bool) { - return value.(string), true - } - ToStringMap["bool"] = func(value interface{}) (string, bool) { - return strconv.FormatBool(value.(bool)), true - } - ToStringMap["int"] = func(value interface{}) (string, bool) { - return strconv.Itoa(value.(int)), true - } - ToStringMap["int64"] = func(value interface{}) (string, bool) { - return strconv.FormatInt(value.(int64), 10), true - } - ToStringMap["uint"] = func(value interface{}) (string, bool) { - return strconv.FormatUint(uint64(value.(uint)), 10), true - } - ToStringMap["uint64"] = func(value interface{}) (string, bool) { - return strconv.FormatUint(value.(uint64), 10), true - } - ToStringMap["float64"] = func(value interface{}) (string, bool) { - return strconv.FormatFloat(value.(float64), 'g', -1, 64), true - } - ToStringMap["time.Duration"] = func(value interface{}) (string, bool) { - return value.(time.Duration).String(), true - } - ToStringMap["time.Time"] = func(value interface{}) (string, bool) { - if len(TimeLayouts) > 0 { - return value.(time.Time).Format(TimeLayouts[0]), true - } - return "", false - } -} diff --git a/vendor/gopkg.in/yaml.v2/apic.go b/vendor/gopkg.in/yaml.v2/apic.go index d2c2308f1f..1f7e87e672 100644 --- a/vendor/gopkg.in/yaml.v2/apic.go +++ b/vendor/gopkg.in/yaml.v2/apic.go @@ -86,7 +86,6 @@ func yaml_emitter_initialize(emitter *yaml_emitter_t) { raw_buffer: make([]byte, 0, output_raw_buffer_size), states: make([]yaml_emitter_state_t, 0, initial_stack_size), events: make([]yaml_event_t, 0, initial_queue_size), - best_width: -1, } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 122002dde5..4f24461df8 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -400,7 +400,7 @@ github.com/coreos/go-systemd/v22/daemon github.com/coreos/go-systemd/v22/dbus # github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f github.com/coreos/pkg/capnslog -# github.com/cpuguy83/go-md2man/v2 v2.0.0 +# github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d github.com/cpuguy83/go-md2man/v2/md2man # github.com/cyphar/filepath-securejoin v0.2.2 github.com/cyphar/filepath-securejoin @@ -820,11 +820,6 @@ github.com/rancher/kine/pkg/server github.com/rancher/kine/pkg/tls # github.com/rancher/remotedialer v0.2.0 github.com/rancher/remotedialer -# github.com/rancher/spur v0.0.0-20200617165101-8702c8e4ce7a -github.com/rancher/spur/cli -github.com/rancher/spur/cli/altsrc -github.com/rancher/spur/flag -github.com/rancher/spur/generic # github.com/rancher/wrangler v0.6.1 github.com/rancher/wrangler/pkg/apply github.com/rancher/wrangler/pkg/apply/injectors @@ -1292,7 +1287,7 @@ gopkg.in/square/go-jose.v2/json gopkg.in/square/go-jose.v2/jwt # gopkg.in/warnings.v0 v0.1.1 gopkg.in/warnings.v0 -# gopkg.in/yaml.v2 v2.3.0 +# gopkg.in/yaml.v2 v2.2.8 gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 gopkg.in/yaml.v3 From 21d21ddd4d1de3c1a96ad1c502a98b61b7711d08 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sat, 29 Aug 2020 20:30:07 -0700 Subject: [PATCH 2/5] Add config file support independent of CLI framework Signed-off-by: Darren Shepherd --- cmd/agent/main.go | 3 +- cmd/server/main.go | 3 +- main.go | 3 +- pkg/cli/cmds/agent.go | 4 +- pkg/cli/cmds/config.go | 17 ++ pkg/cli/cmds/root.go | 35 ++-- pkg/cli/cmds/server.go | 2 +- pkg/configfilearg/defaultparser.go | 20 +++ pkg/configfilearg/parser.go | 139 ++++++++++++++++ pkg/configfilearg/parser_test.go | 233 +++++++++++++++++++++++++++ pkg/configfilearg/testdata/data.yaml | 9 ++ 11 files changed, 449 insertions(+), 19 deletions(-) create mode 100644 pkg/cli/cmds/config.go create mode 100644 pkg/configfilearg/defaultparser.go create mode 100644 pkg/configfilearg/parser.go create mode 100644 pkg/configfilearg/parser_test.go create mode 100644 pkg/configfilearg/testdata/data.yaml diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 9d9049bcb1..dfb75dfe30 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -5,6 +5,7 @@ import ( "github.com/rancher/k3s/pkg/cli/agent" "github.com/rancher/k3s/pkg/cli/cmds" + "github.com/rancher/k3s/pkg/configfilearg" "github.com/sirupsen/logrus" "github.com/urfave/cli" ) @@ -15,7 +16,7 @@ func main() { cmds.NewAgentCommand(agent.Run), } - err := app.Run(os.Args) + err := app.Run(configfilearg.MustParse(os.Args)) if err != nil { logrus.Fatal(err) } diff --git a/cmd/server/main.go b/cmd/server/main.go index 7fcd6e047b..fffafb7248 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -12,6 +12,7 @@ import ( "github.com/rancher/k3s/pkg/cli/ctr" "github.com/rancher/k3s/pkg/cli/kubectl" "github.com/rancher/k3s/pkg/cli/server" + "github.com/rancher/k3s/pkg/configfilearg" "github.com/rancher/k3s/pkg/containerd" ctr2 "github.com/rancher/k3s/pkg/ctr" kubectl2 "github.com/rancher/k3s/pkg/kubectl" @@ -43,7 +44,7 @@ func main() { cmds.NewCtrCommand(ctr.Run), } - err := app.Run(os.Args) + err := app.Run(configfilearg.MustParse(os.Args)) if err != nil { logrus.Fatal(err) } diff --git a/main.go b/main.go index 62908bb7bb..10624f69bf 100644 --- a/main.go +++ b/main.go @@ -14,6 +14,7 @@ import ( "github.com/rancher/k3s/pkg/cli/crictl" "github.com/rancher/k3s/pkg/cli/kubectl" "github.com/rancher/k3s/pkg/cli/server" + "github.com/rancher/k3s/pkg/configfilearg" "github.com/sirupsen/logrus" "github.com/urfave/cli" ) @@ -27,7 +28,7 @@ func main() { cmds.NewCRICTL(crictl.Run), } - if err := app.Run(os.Args); err != nil { + if err := app.Run(configfilearg.MustParse(os.Args)); err != nil { logrus.Fatal(err) } } diff --git a/pkg/cli/cmds/agent.go b/pkg/cli/cmds/agent.go index 01d9ce75fa..c9470ce8ee 100644 --- a/pkg/cli/cmds/agent.go +++ b/pkg/cli/cmds/agent.go @@ -172,9 +172,11 @@ func NewAgentCommand(action func(ctx *cli.Context) error) cli.Command { Name: "agent", Usage: "Run node agent", UsageText: appName + " agent [OPTIONS]", - Before: CheckSELinuxFlags, + Before: SetupDebug(CheckSELinuxFlags), Action: action, Flags: []cli.Flag{ + ConfigFlag, + DebugFlag, VLevel, VModule, LogFile, diff --git a/pkg/cli/cmds/config.go b/pkg/cli/cmds/config.go new file mode 100644 index 0000000000..1b05078efe --- /dev/null +++ b/pkg/cli/cmds/config.go @@ -0,0 +1,17 @@ +package cmds + +import ( + "github.com/rancher/k3s/pkg/version" + "github.com/urfave/cli" +) + +var ( + // ConfigFlag is here to show to the user, but the actually processing is done by configfileargs before + // call urfave + ConfigFlag = cli.StringFlag{ + Name: "config,c", + Usage: "(config) Load configuration from `FILE`", + EnvVar: "K3S_CONFIG_FILE", + Value: "/etc/rancher/" + version.Program + "/config.yaml", + } +) diff --git a/pkg/cli/cmds/root.go b/pkg/cli/cmds/root.go index 212ec13075..8233fcb90e 100644 --- a/pkg/cli/cmds/root.go +++ b/pkg/cli/cmds/root.go @@ -10,7 +10,13 @@ import ( ) var ( - Debug bool + Debug bool + DebugFlag = cli.BoolFlag{ + Name: "debug", + Usage: "Turn on debug logs", + Destination: &Debug, + EnvVar: version.ProgramUpper + "_DEBUG", + } ) func init() { @@ -29,20 +35,21 @@ func NewApp() *cli.App { fmt.Printf("%s version %s\n", app.Name, app.Version) } app.Flags = []cli.Flag{ - cli.BoolFlag{ - Name: "debug", - Usage: "Turn on debug logs", - Destination: &Debug, - EnvVar: version.ProgramUpper + "_DEBUG", - }, - } - - app.Before = func(ctx *cli.Context) error { - if Debug { - logrus.SetLevel(logrus.DebugLevel) - } - return nil + DebugFlag, } + app.Before = SetupDebug(nil) return app } + +func SetupDebug(next func(ctx *cli.Context) error) func(ctx *cli.Context) error { + return func(ctx *cli.Context) error { + if Debug { + logrus.SetLevel(logrus.DebugLevel) + } + if next != nil { + return next(ctx) + } + return nil + } +} diff --git a/pkg/cli/cmds/server.go b/pkg/cli/cmds/server.go index b01ded9ce2..5b4e61ae76 100644 --- a/pkg/cli/cmds/server.go +++ b/pkg/cli/cmds/server.go @@ -74,7 +74,7 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command { Name: "server", Usage: "Run management server", UsageText: appName + " server [OPTIONS]", - Before: CheckSELinuxFlags, + Before: SetupDebug(CheckSELinuxFlags), Action: action, Flags: []cli.Flag{ VLevel, diff --git a/pkg/configfilearg/defaultparser.go b/pkg/configfilearg/defaultparser.go new file mode 100644 index 0000000000..7a7f10c0fc --- /dev/null +++ b/pkg/configfilearg/defaultparser.go @@ -0,0 +1,20 @@ +package configfilearg + +import ( + "github.com/rancher/k3s/pkg/version" + "github.com/sirupsen/logrus" +) + +func MustParse(args []string) []string { + parser := &Parser{ + After: []string{"server", "agent"}, + FlagNames: []string{"--config", "-c"}, + EnvName: version.ProgramUpper + "_CONFIG_FILE", + DefaultConfig: "/etc/rancher/" + version.Program + "/config.yaml", + } + result, err := parser.Parse(args) + if err != nil { + logrus.Fatal(err) + } + return result +} diff --git a/pkg/configfilearg/parser.go b/pkg/configfilearg/parser.go new file mode 100644 index 0000000000..600e56f413 --- /dev/null +++ b/pkg/configfilearg/parser.go @@ -0,0 +1,139 @@ +package configfilearg + +import ( + "fmt" + "io/ioutil" + "net/http" + "net/url" + "os" + "strings" + + "github.com/rancher/wrangler/pkg/data/convert" + "gopkg.in/yaml.v2" +) + +type Parser struct { + After []string + FlagNames []string + EnvName string + DefaultConfig string +} + +// Parser will parse an os.Args style slice looking for Parser.FlagNames after Parse.After. +// It will read the parameter value of Parse.FlagNames and read the file, appending all flags directly after +// the Parser.After value. This means a the non-config file flags will override, or if a slice append to, the config +// file values. +// If Parser.DefaultConfig is set, the existence of the config file is optional if not set in the os.Args. This means +// if Parser.DefaultConfig is set we will always try to read the config file but only fail if it's not found if the +// args contains Parser.FlagNames +func (p *Parser) Parse(args []string) ([]string, error) { + prefix, suffix, found := p.findStart(args) + if !found { + return args, nil + } + + configFile, isSet := p.findConfigFileFlag(args) + if configFile != "" { + values, err := readConfigFile(configFile) + if !isSet && os.IsNotExist(err) { + return args, nil + } else if err != nil { + return nil, err + } + return append(prefix, append(values, suffix...)...), nil + } + + return args, nil +} + +func (p *Parser) findConfigFileFlag(args []string) (string, bool) { + if envVal := os.Getenv(p.EnvName); p.EnvName != "" && envVal != "" { + return envVal, true + } + + for i, arg := range args { + for _, flagName := range p.FlagNames { + if flagName == arg { + if len(args) > i+1 { + return args[i+1], true + } + // This is actually invalid, so we rely on the CLI parser after the fact flagging it as bad + return "", false + } else if strings.HasPrefix(arg, flagName+"=") { + return arg[len(flagName)+1:], true + } + } + } + + return p.DefaultConfig, false +} + +func (p *Parser) findStart(args []string) ([]string, []string, bool) { + if len(p.After) == 0 { + return []string{}, args, true + } + + for i, val := range args { + for _, test := range p.After { + if val == test { + return args[0 : i+1], args[i+1:], true + } + } + } + + return args, nil, false +} + +func readConfigFile(file string) (result []string, _ error) { + bytes, err := readConfigFileData(file) + if err != nil { + return nil, err + } + + data := yaml.MapSlice{} + if err := yaml.Unmarshal(bytes, &data); err != nil { + return nil, err + } + + for _, i := range data { + k, v := convert.ToString(i.Key), i.Value + prefix := "--" + if len(k) == 1 { + prefix = "-" + } + + if slice, ok := v.([]interface{}); ok { + for _, v := range slice { + result = append(result, prefix+k, convert.ToString(v)) + result = append(result) + } + } else { + str := convert.ToString(v) + result = append(result, prefix+k) + if str != "" { + result = append(result, str) + } + } + } + + return +} + +func readConfigFileData(file string) ([]byte, error) { + u, err := url.Parse(file) + if err != nil { + return nil, fmt.Errorf("failed to parse config location %s: %w", file, err) + } + + switch u.Scheme { + case "http", "https": + resp, err := http.Get(file) + if err != nil { + return nil, fmt.Errorf("failed to read http config %s: %w", file, err) + } + defer resp.Body.Close() + return ioutil.ReadAll(resp.Body) + default: + return ioutil.ReadFile(file) + } +} diff --git a/pkg/configfilearg/parser_test.go b/pkg/configfilearg/parser_test.go new file mode 100644 index 0000000000..47145e1daa --- /dev/null +++ b/pkg/configfilearg/parser_test.go @@ -0,0 +1,233 @@ +package configfilearg + +import ( + "os" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFindStart(t *testing.T) { + testCases := []struct { + input []string + prefix []string + suffix []string + found bool + what string + }{ + { + input: nil, + prefix: nil, + suffix: nil, + found: false, + what: "default case", + }, + { + input: []string{"server"}, + prefix: []string{"server"}, + suffix: []string{}, + found: true, + what: "simple case", + }, + { + input: []string{"server", "foo"}, + prefix: []string{"server"}, + suffix: []string{"foo"}, + found: true, + what: "also simple case", + }, + { + input: []string{"server", "foo", "bar"}, + prefix: []string{"server"}, + suffix: []string{"foo", "bar"}, + found: true, + what: "longer simple case", + }, + { + input: []string{"not-server", "foo", "bar"}, + prefix: []string{"not-server", "foo", "bar"}, + found: false, + what: "not found", + }, + } + + p := Parser{ + After: []string{"server", "agent"}, + } + + for _, testCase := range testCases { + prefix, suffix, found := p.findStart(testCase.input) + assert.Equal(t, testCase.prefix, prefix) + assert.Equal(t, testCase.suffix, suffix) + assert.Equal(t, testCase.found, found) + } +} + +func TestConfigFile(t *testing.T) { + testCases := []struct { + input []string + env string + def string + configFile string + found bool + what string + }{ + { + input: nil, + found: false, + what: "default case", + }, + { + input: []string{"asdf", "-c", "value"}, + configFile: "value", + found: true, + what: "simple case", + }, + { + input: []string{"-c"}, + found: false, + what: "invalid args string", + }, + { + input: []string{"-c="}, + found: true, + what: "empty arg value", + }, + { + def: "def", + input: []string{"-c="}, + found: true, + what: "empty arg value override default", + }, + { + def: "def", + input: []string{"-c"}, + found: false, + what: "invalid args always return no value", + }, + { + def: "def", + input: []string{"-c", "value"}, + configFile: "value", + found: true, + what: "value override default", + }, + { + def: "def", + configFile: "def", + found: false, + what: "default gets used when nothing is passed", + }, + { + def: "def", + input: []string{"-c", "value"}, + env: "env", + configFile: "env", + found: true, + what: "env override args", + }, + { + def: "def", + input: []string{"before", "-c", "value", "after"}, + configFile: "value", + found: true, + what: "garbage in start and end", + }, + } + + for _, testCase := range testCases { + p := Parser{ + FlagNames: []string{"--config", "-c"}, + EnvName: "_TEST_FLAG_ENV", + DefaultConfig: testCase.def, + } + os.Setenv(p.EnvName, testCase.env) + configFile, found := p.findConfigFileFlag(testCase.input) + assert.Equal(t, testCase.configFile, configFile, testCase.what) + assert.Equal(t, testCase.found, found, testCase.what) + } +} + +func TestParse(t *testing.T) { + testDataOutput := []string{ + "--foo-bar", "baz", + "--a-slice", "1", + "--a-slice", "2", + "--a-slice", "", + "--a-slice", "three", + "--isempty", + "-c", "b", + "--islast", "true", + } + + defParser := Parser{ + After: []string{"server", "agent"}, + FlagNames: []string{"-c", "--config"}, + EnvName: "_TEST_ENV", + DefaultConfig: "./testdata/data.yaml", + } + + testCases := []struct { + parser Parser + env string + input []string + output []string + err string + what string + }{ + { + parser: defParser, + what: "default case", + }, + { + parser: defParser, + input: []string{"server"}, + output: append([]string{"server"}, testDataOutput...), + what: "read config file when not specified", + }, + { + parser: Parser{ + After: []string{"server", "agent"}, + FlagNames: []string{"-c", "--config"}, + DefaultConfig: "missing", + }, + input: []string{"server"}, + output: []string{"server"}, + what: "ignore missing config when not set", + }, + { + parser: Parser{ + After: []string{"server", "agent"}, + FlagNames: []string{"-c", "--config"}, + DefaultConfig: "missing", + }, + input: []string{"server", "-c=missing"}, + output: []string{"server", "-c=missing"}, + what: "fail when missing config", + err: "open missing: no such file or directory", + }, + { + parser: Parser{ + After: []string{"server", "agent"}, + FlagNames: []string{"-c", "--config"}, + DefaultConfig: "missing", + }, + input: []string{"before", "server", "before", "-c", "./testdata/data.yaml", "after"}, + output: append(append([]string{"before", "server"}, testDataOutput...), "before", "-c", "./testdata/data.yaml", "after"), + what: "read config file", + }, + } + + for _, testCase := range testCases { + os.Setenv(testCase.parser.EnvName, testCase.env) + output, err := testCase.parser.Parse(testCase.input) + if err == nil { + assert.Equal(t, testCase.err, "", testCase.what) + } else { + assert.Equal(t, testCase.err, err.Error(), testCase.what) + } + if testCase.err == "" { + assert.Equal(t, testCase.output, output, testCase.what) + } + } +} diff --git a/pkg/configfilearg/testdata/data.yaml b/pkg/configfilearg/testdata/data.yaml new file mode 100644 index 0000000000..61910e4d1a --- /dev/null +++ b/pkg/configfilearg/testdata/data.yaml @@ -0,0 +1,9 @@ +foo-bar: baz +a-slice: +- 1 +- "2" +- "" +- three +isempty: +c: b +islast: true \ No newline at end of file From 0c29005bb39dfaad5193d65b9ba6b47bbd5c68f3 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Sat, 29 Aug 2020 20:30:12 -0700 Subject: [PATCH 3/5] Update vendor Signed-off-by: Darren Shepherd --- go.mod | 1 + vendor/github.com/pmezard/go-difflib/LICENSE | 27 + .../pmezard/go-difflib/difflib/difflib.go | 772 ++++++++ vendor/github.com/stretchr/testify/LICENSE | 21 + .../testify/assert/assertion_compare.go | 274 +++ .../testify/assert/assertion_format.go | 644 +++++++ .../testify/assert/assertion_format.go.tmpl | 5 + .../testify/assert/assertion_forward.go | 1276 +++++++++++++ .../testify/assert/assertion_forward.go.tmpl | 5 + .../stretchr/testify/assert/assertions.go | 1695 +++++++++++++++++ .../github.com/stretchr/testify/assert/doc.go | 45 + .../stretchr/testify/assert/errors.go | 10 + .../testify/assert/forward_assertions.go | 16 + .../testify/assert/http_assertions.go | 162 ++ vendor/gopkg.in/yaml.v2/apic.go | 1 + vendor/modules.txt | 8 +- 16 files changed, 4960 insertions(+), 2 deletions(-) create mode 100644 vendor/github.com/pmezard/go-difflib/LICENSE create mode 100644 vendor/github.com/pmezard/go-difflib/difflib/difflib.go create mode 100644 vendor/github.com/stretchr/testify/LICENSE create mode 100644 vendor/github.com/stretchr/testify/assert/assertion_compare.go create mode 100644 vendor/github.com/stretchr/testify/assert/assertion_format.go create mode 100644 vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl create mode 100644 vendor/github.com/stretchr/testify/assert/assertion_forward.go create mode 100644 vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl create mode 100644 vendor/github.com/stretchr/testify/assert/assertions.go create mode 100644 vendor/github.com/stretchr/testify/assert/doc.go create mode 100644 vendor/github.com/stretchr/testify/assert/errors.go create mode 100644 vendor/github.com/stretchr/testify/assert/forward_assertions.go create mode 100644 vendor/github.com/stretchr/testify/assert/http_assertions.go diff --git a/go.mod b/go.mod index 3a21ee4bde..15788efa1d 100644 --- a/go.mod +++ b/go.mod @@ -92,6 +92,7 @@ require ( github.com/rootless-containers/rootlesskit v0.10.0 github.com/sirupsen/logrus v1.6.0 github.com/spf13/pflag v1.0.5 + github.com/stretchr/testify v1.6.1 github.com/tchap/go-patricia v2.3.0+incompatible // indirect github.com/urfave/cli v1.22.2 go.etcd.io/etcd v0.5.0-alpha.5.0.20200819165624-17cef6e3e9d5 diff --git a/vendor/github.com/pmezard/go-difflib/LICENSE b/vendor/github.com/pmezard/go-difflib/LICENSE new file mode 100644 index 0000000000..c67dad612a --- /dev/null +++ b/vendor/github.com/pmezard/go-difflib/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2013, Patrick Mezard +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + The names of its contributors may not be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/pmezard/go-difflib/difflib/difflib.go b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go new file mode 100644 index 0000000000..003e99fadb --- /dev/null +++ b/vendor/github.com/pmezard/go-difflib/difflib/difflib.go @@ -0,0 +1,772 @@ +// Package difflib is a partial port of Python difflib module. +// +// It provides tools to compare sequences of strings and generate textual diffs. +// +// The following class and functions have been ported: +// +// - SequenceMatcher +// +// - unified_diff +// +// - context_diff +// +// Getting unified diffs was the main goal of the port. Keep in mind this code +// is mostly suitable to output text differences in a human friendly way, there +// are no guarantees generated diffs are consumable by patch(1). +package difflib + +import ( + "bufio" + "bytes" + "fmt" + "io" + "strings" +) + +func min(a, b int) int { + if a < b { + return a + } + return b +} + +func max(a, b int) int { + if a > b { + return a + } + return b +} + +func calculateRatio(matches, length int) float64 { + if length > 0 { + return 2.0 * float64(matches) / float64(length) + } + return 1.0 +} + +type Match struct { + A int + B int + Size int +} + +type OpCode struct { + Tag byte + I1 int + I2 int + J1 int + J2 int +} + +// SequenceMatcher compares sequence of strings. The basic +// algorithm predates, and is a little fancier than, an algorithm +// published in the late 1980's by Ratcliff and Obershelp under the +// hyperbolic name "gestalt pattern matching". The basic idea is to find +// the longest contiguous matching subsequence that contains no "junk" +// elements (R-O doesn't address junk). The same idea is then applied +// recursively to the pieces of the sequences to the left and to the right +// of the matching subsequence. This does not yield minimal edit +// sequences, but does tend to yield matches that "look right" to people. +// +// SequenceMatcher tries to compute a "human-friendly diff" between two +// sequences. Unlike e.g. UNIX(tm) diff, the fundamental notion is the +// longest *contiguous* & junk-free matching subsequence. That's what +// catches peoples' eyes. The Windows(tm) windiff has another interesting +// notion, pairing up elements that appear uniquely in each sequence. +// That, and the method here, appear to yield more intuitive difference +// reports than does diff. This method appears to be the least vulnerable +// to synching up on blocks of "junk lines", though (like blank lines in +// ordinary text files, or maybe "

" lines in HTML files). That may be +// because this is the only method of the 3 that has a *concept* of +// "junk" . +// +// Timing: Basic R-O is cubic time worst case and quadratic time expected +// case. SequenceMatcher is quadratic time for the worst case and has +// expected-case behavior dependent in a complicated way on how many +// elements the sequences have in common; best case time is linear. +type SequenceMatcher struct { + a []string + b []string + b2j map[string][]int + IsJunk func(string) bool + autoJunk bool + bJunk map[string]struct{} + matchingBlocks []Match + fullBCount map[string]int + bPopular map[string]struct{} + opCodes []OpCode +} + +func NewMatcher(a, b []string) *SequenceMatcher { + m := SequenceMatcher{autoJunk: true} + m.SetSeqs(a, b) + return &m +} + +func NewMatcherWithJunk(a, b []string, autoJunk bool, + isJunk func(string) bool) *SequenceMatcher { + + m := SequenceMatcher{IsJunk: isJunk, autoJunk: autoJunk} + m.SetSeqs(a, b) + return &m +} + +// Set two sequences to be compared. +func (m *SequenceMatcher) SetSeqs(a, b []string) { + m.SetSeq1(a) + m.SetSeq2(b) +} + +// Set the first sequence to be compared. The second sequence to be compared is +// not changed. +// +// SequenceMatcher computes and caches detailed information about the second +// sequence, so if you want to compare one sequence S against many sequences, +// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other +// sequences. +// +// See also SetSeqs() and SetSeq2(). +func (m *SequenceMatcher) SetSeq1(a []string) { + if &a == &m.a { + return + } + m.a = a + m.matchingBlocks = nil + m.opCodes = nil +} + +// Set the second sequence to be compared. The first sequence to be compared is +// not changed. +func (m *SequenceMatcher) SetSeq2(b []string) { + if &b == &m.b { + return + } + m.b = b + m.matchingBlocks = nil + m.opCodes = nil + m.fullBCount = nil + m.chainB() +} + +func (m *SequenceMatcher) chainB() { + // Populate line -> index mapping + b2j := map[string][]int{} + for i, s := range m.b { + indices := b2j[s] + indices = append(indices, i) + b2j[s] = indices + } + + // Purge junk elements + m.bJunk = map[string]struct{}{} + if m.IsJunk != nil { + junk := m.bJunk + for s, _ := range b2j { + if m.IsJunk(s) { + junk[s] = struct{}{} + } + } + for s, _ := range junk { + delete(b2j, s) + } + } + + // Purge remaining popular elements + popular := map[string]struct{}{} + n := len(m.b) + if m.autoJunk && n >= 200 { + ntest := n/100 + 1 + for s, indices := range b2j { + if len(indices) > ntest { + popular[s] = struct{}{} + } + } + for s, _ := range popular { + delete(b2j, s) + } + } + m.bPopular = popular + m.b2j = b2j +} + +func (m *SequenceMatcher) isBJunk(s string) bool { + _, ok := m.bJunk[s] + return ok +} + +// Find longest matching block in a[alo:ahi] and b[blo:bhi]. +// +// If IsJunk is not defined: +// +// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where +// alo <= i <= i+k <= ahi +// blo <= j <= j+k <= bhi +// and for all (i',j',k') meeting those conditions, +// k >= k' +// i <= i' +// and if i == i', j <= j' +// +// In other words, of all maximal matching blocks, return one that +// starts earliest in a, and of all those maximal matching blocks that +// start earliest in a, return the one that starts earliest in b. +// +// If IsJunk is defined, first the longest matching block is +// determined as above, but with the additional restriction that no +// junk element appears in the block. Then that block is extended as +// far as possible by matching (only) junk elements on both sides. So +// the resulting block never matches on junk except as identical junk +// happens to be adjacent to an "interesting" match. +// +// If no blocks match, return (alo, blo, 0). +func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match { + // CAUTION: stripping common prefix or suffix would be incorrect. + // E.g., + // ab + // acab + // Longest matching block is "ab", but if common prefix is + // stripped, it's "a" (tied with "b"). UNIX(tm) diff does so + // strip, so ends up claiming that ab is changed to acab by + // inserting "ca" in the middle. That's minimal but unintuitive: + // "it's obvious" that someone inserted "ac" at the front. + // Windiff ends up at the same place as diff, but by pairing up + // the unique 'b's and then matching the first two 'a's. + besti, bestj, bestsize := alo, blo, 0 + + // find longest junk-free match + // during an iteration of the loop, j2len[j] = length of longest + // junk-free match ending with a[i-1] and b[j] + j2len := map[int]int{} + for i := alo; i != ahi; i++ { + // look at all instances of a[i] in b; note that because + // b2j has no junk keys, the loop is skipped if a[i] is junk + newj2len := map[int]int{} + for _, j := range m.b2j[m.a[i]] { + // a[i] matches b[j] + if j < blo { + continue + } + if j >= bhi { + break + } + k := j2len[j-1] + 1 + newj2len[j] = k + if k > bestsize { + besti, bestj, bestsize = i-k+1, j-k+1, k + } + } + j2len = newj2len + } + + // Extend the best by non-junk elements on each end. In particular, + // "popular" non-junk elements aren't in b2j, which greatly speeds + // the inner loop above, but also means "the best" match so far + // doesn't contain any junk *or* popular non-junk elements. + for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + !m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + // Now that we have a wholly interesting match (albeit possibly + // empty!), we may as well suck up the matching junk on each + // side of it too. Can't think of a good reason not to, and it + // saves post-processing the (possibly considerable) expense of + // figuring out what to do with it. In the case of an empty + // interesting match, this is clearly the right thing to do, + // because no other kind of match is possible in the regions. + for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) && + m.a[besti-1] == m.b[bestj-1] { + besti, bestj, bestsize = besti-1, bestj-1, bestsize+1 + } + for besti+bestsize < ahi && bestj+bestsize < bhi && + m.isBJunk(m.b[bestj+bestsize]) && + m.a[besti+bestsize] == m.b[bestj+bestsize] { + bestsize += 1 + } + + return Match{A: besti, B: bestj, Size: bestsize} +} + +// Return list of triples describing matching subsequences. +// +// Each triple is of the form (i, j, n), and means that +// a[i:i+n] == b[j:j+n]. The triples are monotonically increasing in +// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are +// adjacent triples in the list, and the second is not the last triple in the +// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe +// adjacent equal blocks. +// +// The last triple is a dummy, (len(a), len(b), 0), and is the only +// triple with n==0. +func (m *SequenceMatcher) GetMatchingBlocks() []Match { + if m.matchingBlocks != nil { + return m.matchingBlocks + } + + var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match + matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match { + match := m.findLongestMatch(alo, ahi, blo, bhi) + i, j, k := match.A, match.B, match.Size + if match.Size > 0 { + if alo < i && blo < j { + matched = matchBlocks(alo, i, blo, j, matched) + } + matched = append(matched, match) + if i+k < ahi && j+k < bhi { + matched = matchBlocks(i+k, ahi, j+k, bhi, matched) + } + } + return matched + } + matched := matchBlocks(0, len(m.a), 0, len(m.b), nil) + + // It's possible that we have adjacent equal blocks in the + // matching_blocks list now. + nonAdjacent := []Match{} + i1, j1, k1 := 0, 0, 0 + for _, b := range matched { + // Is this block adjacent to i1, j1, k1? + i2, j2, k2 := b.A, b.B, b.Size + if i1+k1 == i2 && j1+k1 == j2 { + // Yes, so collapse them -- this just increases the length of + // the first block by the length of the second, and the first + // block so lengthened remains the block to compare against. + k1 += k2 + } else { + // Not adjacent. Remember the first block (k1==0 means it's + // the dummy we started with), and make the second block the + // new block to compare against. + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + i1, j1, k1 = i2, j2, k2 + } + } + if k1 > 0 { + nonAdjacent = append(nonAdjacent, Match{i1, j1, k1}) + } + + nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0}) + m.matchingBlocks = nonAdjacent + return m.matchingBlocks +} + +// Return list of 5-tuples describing how to turn a into b. +// +// Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple +// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the +// tuple preceding it, and likewise for j1 == the previous j2. +// +// The tags are characters, with these meanings: +// +// 'r' (replace): a[i1:i2] should be replaced by b[j1:j2] +// +// 'd' (delete): a[i1:i2] should be deleted, j1==j2 in this case. +// +// 'i' (insert): b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case. +// +// 'e' (equal): a[i1:i2] == b[j1:j2] +func (m *SequenceMatcher) GetOpCodes() []OpCode { + if m.opCodes != nil { + return m.opCodes + } + i, j := 0, 0 + matching := m.GetMatchingBlocks() + opCodes := make([]OpCode, 0, len(matching)) + for _, m := range matching { + // invariant: we've pumped out correct diffs to change + // a[:i] into b[:j], and the next matching block is + // a[ai:ai+size] == b[bj:bj+size]. So we need to pump + // out a diff to change a[i:ai] into b[j:bj], pump out + // the matching block, and move (i,j) beyond the match + ai, bj, size := m.A, m.B, m.Size + tag := byte(0) + if i < ai && j < bj { + tag = 'r' + } else if i < ai { + tag = 'd' + } else if j < bj { + tag = 'i' + } + if tag > 0 { + opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) + } + i, j = ai+size, bj+size + // the list of matching blocks is terminated by a + // sentinel with size 0 + if size > 0 { + opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) + } + } + m.opCodes = opCodes + return m.opCodes +} + +// Isolate change clusters by eliminating ranges with no changes. +// +// Return a generator of groups with up to n lines of context. +// Each group is in the same format as returned by GetOpCodes(). +func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode { + if n < 0 { + n = 3 + } + codes := m.GetOpCodes() + if len(codes) == 0 { + codes = []OpCode{OpCode{'e', 0, 1, 0, 1}} + } + // Fixup leading and trailing groups if they show no changes. + if codes[0].Tag == 'e' { + c := codes[0] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2} + } + if codes[len(codes)-1].Tag == 'e' { + c := codes[len(codes)-1] + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)} + } + nn := n + n + groups := [][]OpCode{} + group := []OpCode{} + for _, c := range codes { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + // End the current group and start a new one whenever + // there is a large range with no changes. + if c.Tag == 'e' && i2-i1 > nn { + group = append(group, OpCode{c.Tag, i1, min(i2, i1+n), + j1, min(j2, j1+n)}) + groups = append(groups, group) + group = []OpCode{} + i1, j1 = max(i1, i2-n), max(j1, j2-n) + } + group = append(group, OpCode{c.Tag, i1, i2, j1, j2}) + } + if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') { + groups = append(groups, group) + } + return groups +} + +// Return a measure of the sequences' similarity (float in [0,1]). +// +// Where T is the total number of elements in both sequences, and +// M is the number of matches, this is 2.0*M / T. +// Note that this is 1 if the sequences are identical, and 0 if +// they have nothing in common. +// +// .Ratio() is expensive to compute if you haven't already computed +// .GetMatchingBlocks() or .GetOpCodes(), in which case you may +// want to try .QuickRatio() or .RealQuickRation() first to get an +// upper bound. +func (m *SequenceMatcher) Ratio() float64 { + matches := 0 + for _, m := range m.GetMatchingBlocks() { + matches += m.Size + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() relatively quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute. +func (m *SequenceMatcher) QuickRatio() float64 { + // viewing a and b as multisets, set matches to the cardinality + // of their intersection; this counts the number of matches + // without regard to order, so is clearly an upper bound + if m.fullBCount == nil { + m.fullBCount = map[string]int{} + for _, s := range m.b { + m.fullBCount[s] = m.fullBCount[s] + 1 + } + } + + // avail[x] is the number of times x appears in 'b' less the + // number of times we've seen it in 'a' so far ... kinda + avail := map[string]int{} + matches := 0 + for _, s := range m.a { + n, ok := avail[s] + if !ok { + n = m.fullBCount[s] + } + avail[s] = n - 1 + if n > 0 { + matches += 1 + } + } + return calculateRatio(matches, len(m.a)+len(m.b)) +} + +// Return an upper bound on ratio() very quickly. +// +// This isn't defined beyond that it is an upper bound on .Ratio(), and +// is faster to compute than either .Ratio() or .QuickRatio(). +func (m *SequenceMatcher) RealQuickRatio() float64 { + la, lb := len(m.a), len(m.b) + return calculateRatio(min(la, lb), la+lb) +} + +// Convert range to the "ed" format +func formatRangeUnified(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 1 { + return fmt.Sprintf("%d", beginning) + } + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + return fmt.Sprintf("%d,%d", beginning, length) +} + +// Unified diff parameters +type UnifiedDiff struct { + A []string // First sequence lines + FromFile string // First file name + FromDate string // First file time + B []string // Second sequence lines + ToFile string // Second file name + ToDate string // Second file time + Eol string // Headers end of line, defaults to LF + Context int // Number of context lines +} + +// Compare two sequences of lines; generate the delta as a unified diff. +// +// Unified diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by 'n' which +// defaults to three. +// +// By default, the diff control lines (those with ---, +++, or @@) are +// created with a trailing newline. This is helpful so that inputs +// created from file.readlines() result in diffs that are suitable for +// file.writelines() since both the inputs and outputs have trailing +// newlines. +// +// For inputs that do not have trailing newlines, set the lineterm +// argument to "" so that the output will be uniformly newline free. +// +// The unidiff format normally has a header for filenames and modification +// times. Any or all of these may be specified using strings for +// 'fromfile', 'tofile', 'fromfiledate', and 'tofiledate'. +// The modification times are normally expressed in the ISO 8601 format. +func WriteUnifiedDiff(writer io.Writer, diff UnifiedDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + wf := func(format string, args ...interface{}) error { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + return err + } + ws := func(s string) error { + _, err := buf.WriteString(s) + return err + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + err := wf("--- %s%s%s", diff.FromFile, fromDate, diff.Eol) + if err != nil { + return err + } + err = wf("+++ %s%s%s", diff.ToFile, toDate, diff.Eol) + if err != nil { + return err + } + } + } + first, last := g[0], g[len(g)-1] + range1 := formatRangeUnified(first.I1, last.I2) + range2 := formatRangeUnified(first.J1, last.J2) + if err := wf("@@ -%s +%s @@%s", range1, range2, diff.Eol); err != nil { + return err + } + for _, c := range g { + i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2 + if c.Tag == 'e' { + for _, line := range diff.A[i1:i2] { + if err := ws(" " + line); err != nil { + return err + } + } + continue + } + if c.Tag == 'r' || c.Tag == 'd' { + for _, line := range diff.A[i1:i2] { + if err := ws("-" + line); err != nil { + return err + } + } + } + if c.Tag == 'r' || c.Tag == 'i' { + for _, line := range diff.B[j1:j2] { + if err := ws("+" + line); err != nil { + return err + } + } + } + } + } + return nil +} + +// Like WriteUnifiedDiff but returns the diff a string. +func GetUnifiedDiffString(diff UnifiedDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteUnifiedDiff(w, diff) + return string(w.Bytes()), err +} + +// Convert range to the "ed" format. +func formatRangeContext(start, stop int) string { + // Per the diff spec at http://www.unix.org/single_unix_specification/ + beginning := start + 1 // lines start numbering with one + length := stop - start + if length == 0 { + beginning -= 1 // empty ranges begin at line just before the range + } + if length <= 1 { + return fmt.Sprintf("%d", beginning) + } + return fmt.Sprintf("%d,%d", beginning, beginning+length-1) +} + +type ContextDiff UnifiedDiff + +// Compare two sequences of lines; generate the delta as a context diff. +// +// Context diffs are a compact way of showing line changes and a few +// lines of context. The number of context lines is set by diff.Context +// which defaults to three. +// +// By default, the diff control lines (those with *** or ---) are +// created with a trailing newline. +// +// For inputs that do not have trailing newlines, set the diff.Eol +// argument to "" so that the output will be uniformly newline free. +// +// The context diff format normally has a header for filenames and +// modification times. Any or all of these may be specified using +// strings for diff.FromFile, diff.ToFile, diff.FromDate, diff.ToDate. +// The modification times are normally expressed in the ISO 8601 format. +// If not specified, the strings default to blanks. +func WriteContextDiff(writer io.Writer, diff ContextDiff) error { + buf := bufio.NewWriter(writer) + defer buf.Flush() + var diffErr error + wf := func(format string, args ...interface{}) { + _, err := buf.WriteString(fmt.Sprintf(format, args...)) + if diffErr == nil && err != nil { + diffErr = err + } + } + ws := func(s string) { + _, err := buf.WriteString(s) + if diffErr == nil && err != nil { + diffErr = err + } + } + + if len(diff.Eol) == 0 { + diff.Eol = "\n" + } + + prefix := map[byte]string{ + 'i': "+ ", + 'd': "- ", + 'r': "! ", + 'e': " ", + } + + started := false + m := NewMatcher(diff.A, diff.B) + for _, g := range m.GetGroupedOpCodes(diff.Context) { + if !started { + started = true + fromDate := "" + if len(diff.FromDate) > 0 { + fromDate = "\t" + diff.FromDate + } + toDate := "" + if len(diff.ToDate) > 0 { + toDate = "\t" + diff.ToDate + } + if diff.FromFile != "" || diff.ToFile != "" { + wf("*** %s%s%s", diff.FromFile, fromDate, diff.Eol) + wf("--- %s%s%s", diff.ToFile, toDate, diff.Eol) + } + } + + first, last := g[0], g[len(g)-1] + ws("***************" + diff.Eol) + + range1 := formatRangeContext(first.I1, last.I2) + wf("*** %s ****%s", range1, diff.Eol) + for _, c := range g { + if c.Tag == 'r' || c.Tag == 'd' { + for _, cc := range g { + if cc.Tag == 'i' { + continue + } + for _, line := range diff.A[cc.I1:cc.I2] { + ws(prefix[cc.Tag] + line) + } + } + break + } + } + + range2 := formatRangeContext(first.J1, last.J2) + wf("--- %s ----%s", range2, diff.Eol) + for _, c := range g { + if c.Tag == 'r' || c.Tag == 'i' { + for _, cc := range g { + if cc.Tag == 'd' { + continue + } + for _, line := range diff.B[cc.J1:cc.J2] { + ws(prefix[cc.Tag] + line) + } + } + break + } + } + } + return diffErr +} + +// Like WriteContextDiff but returns the diff a string. +func GetContextDiffString(diff ContextDiff) (string, error) { + w := &bytes.Buffer{} + err := WriteContextDiff(w, diff) + return string(w.Bytes()), err +} + +// Split a string on "\n" while preserving them. The output can be used +// as input for UnifiedDiff and ContextDiff structures. +func SplitLines(s string) []string { + lines := strings.SplitAfter(s, "\n") + lines[len(lines)-1] += "\n" + return lines +} diff --git a/vendor/github.com/stretchr/testify/LICENSE b/vendor/github.com/stretchr/testify/LICENSE new file mode 100644 index 0000000000..4b0421cf9e --- /dev/null +++ b/vendor/github.com/stretchr/testify/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/stretchr/testify/assert/assertion_compare.go b/vendor/github.com/stretchr/testify/assert/assertion_compare.go new file mode 100644 index 0000000000..dc200395ce --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_compare.go @@ -0,0 +1,274 @@ +package assert + +import ( + "fmt" + "reflect" +) + +type CompareType int + +const ( + compareLess CompareType = iota - 1 + compareEqual + compareGreater +) + +func compare(obj1, obj2 interface{}, kind reflect.Kind) (CompareType, bool) { + switch kind { + case reflect.Int: + { + intobj1 := obj1.(int) + intobj2 := obj2.(int) + if intobj1 > intobj2 { + return compareGreater, true + } + if intobj1 == intobj2 { + return compareEqual, true + } + if intobj1 < intobj2 { + return compareLess, true + } + } + case reflect.Int8: + { + int8obj1 := obj1.(int8) + int8obj2 := obj2.(int8) + if int8obj1 > int8obj2 { + return compareGreater, true + } + if int8obj1 == int8obj2 { + return compareEqual, true + } + if int8obj1 < int8obj2 { + return compareLess, true + } + } + case reflect.Int16: + { + int16obj1 := obj1.(int16) + int16obj2 := obj2.(int16) + if int16obj1 > int16obj2 { + return compareGreater, true + } + if int16obj1 == int16obj2 { + return compareEqual, true + } + if int16obj1 < int16obj2 { + return compareLess, true + } + } + case reflect.Int32: + { + int32obj1 := obj1.(int32) + int32obj2 := obj2.(int32) + if int32obj1 > int32obj2 { + return compareGreater, true + } + if int32obj1 == int32obj2 { + return compareEqual, true + } + if int32obj1 < int32obj2 { + return compareLess, true + } + } + case reflect.Int64: + { + int64obj1 := obj1.(int64) + int64obj2 := obj2.(int64) + if int64obj1 > int64obj2 { + return compareGreater, true + } + if int64obj1 == int64obj2 { + return compareEqual, true + } + if int64obj1 < int64obj2 { + return compareLess, true + } + } + case reflect.Uint: + { + uintobj1 := obj1.(uint) + uintobj2 := obj2.(uint) + if uintobj1 > uintobj2 { + return compareGreater, true + } + if uintobj1 == uintobj2 { + return compareEqual, true + } + if uintobj1 < uintobj2 { + return compareLess, true + } + } + case reflect.Uint8: + { + uint8obj1 := obj1.(uint8) + uint8obj2 := obj2.(uint8) + if uint8obj1 > uint8obj2 { + return compareGreater, true + } + if uint8obj1 == uint8obj2 { + return compareEqual, true + } + if uint8obj1 < uint8obj2 { + return compareLess, true + } + } + case reflect.Uint16: + { + uint16obj1 := obj1.(uint16) + uint16obj2 := obj2.(uint16) + if uint16obj1 > uint16obj2 { + return compareGreater, true + } + if uint16obj1 == uint16obj2 { + return compareEqual, true + } + if uint16obj1 < uint16obj2 { + return compareLess, true + } + } + case reflect.Uint32: + { + uint32obj1 := obj1.(uint32) + uint32obj2 := obj2.(uint32) + if uint32obj1 > uint32obj2 { + return compareGreater, true + } + if uint32obj1 == uint32obj2 { + return compareEqual, true + } + if uint32obj1 < uint32obj2 { + return compareLess, true + } + } + case reflect.Uint64: + { + uint64obj1 := obj1.(uint64) + uint64obj2 := obj2.(uint64) + if uint64obj1 > uint64obj2 { + return compareGreater, true + } + if uint64obj1 == uint64obj2 { + return compareEqual, true + } + if uint64obj1 < uint64obj2 { + return compareLess, true + } + } + case reflect.Float32: + { + float32obj1 := obj1.(float32) + float32obj2 := obj2.(float32) + if float32obj1 > float32obj2 { + return compareGreater, true + } + if float32obj1 == float32obj2 { + return compareEqual, true + } + if float32obj1 < float32obj2 { + return compareLess, true + } + } + case reflect.Float64: + { + float64obj1 := obj1.(float64) + float64obj2 := obj2.(float64) + if float64obj1 > float64obj2 { + return compareGreater, true + } + if float64obj1 == float64obj2 { + return compareEqual, true + } + if float64obj1 < float64obj2 { + return compareLess, true + } + } + case reflect.String: + { + stringobj1 := obj1.(string) + stringobj2 := obj2.(string) + if stringobj1 > stringobj2 { + return compareGreater, true + } + if stringobj1 == stringobj2 { + return compareEqual, true + } + if stringobj1 < stringobj2 { + return compareLess, true + } + } + } + + return compareEqual, false +} + +// Greater asserts that the first element is greater than the second +// +// assert.Greater(t, 2, 1) +// assert.Greater(t, float64(2), float64(1)) +// assert.Greater(t, "b", "a") +func Greater(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { + return compareTwoValues(t, e1, e2, []CompareType{compareGreater}, "\"%v\" is not greater than \"%v\"", msgAndArgs) +} + +// GreaterOrEqual asserts that the first element is greater than or equal to the second +// +// assert.GreaterOrEqual(t, 2, 1) +// assert.GreaterOrEqual(t, 2, 2) +// assert.GreaterOrEqual(t, "b", "a") +// assert.GreaterOrEqual(t, "b", "b") +func GreaterOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { + return compareTwoValues(t, e1, e2, []CompareType{compareGreater, compareEqual}, "\"%v\" is not greater than or equal to \"%v\"", msgAndArgs) +} + +// Less asserts that the first element is less than the second +// +// assert.Less(t, 1, 2) +// assert.Less(t, float64(1), float64(2)) +// assert.Less(t, "a", "b") +func Less(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { + return compareTwoValues(t, e1, e2, []CompareType{compareLess}, "\"%v\" is not less than \"%v\"", msgAndArgs) +} + +// LessOrEqual asserts that the first element is less than or equal to the second +// +// assert.LessOrEqual(t, 1, 2) +// assert.LessOrEqual(t, 2, 2) +// assert.LessOrEqual(t, "a", "b") +// assert.LessOrEqual(t, "b", "b") +func LessOrEqual(t TestingT, e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { + return compareTwoValues(t, e1, e2, []CompareType{compareLess, compareEqual}, "\"%v\" is not less than or equal to \"%v\"", msgAndArgs) +} + +func compareTwoValues(t TestingT, e1 interface{}, e2 interface{}, allowedComparesResults []CompareType, failMessage string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + e1Kind := reflect.ValueOf(e1).Kind() + e2Kind := reflect.ValueOf(e2).Kind() + if e1Kind != e2Kind { + return Fail(t, "Elements should be the same type", msgAndArgs...) + } + + compareResult, isComparable := compare(e1, e2, e1Kind) + if !isComparable { + return Fail(t, fmt.Sprintf("Can not compare type \"%s\"", reflect.TypeOf(e1)), msgAndArgs...) + } + + if !containsValue(allowedComparesResults, compareResult) { + return Fail(t, fmt.Sprintf(failMessage, e1, e2), msgAndArgs...) + } + + return true +} + +func containsValue(values []CompareType, value CompareType) bool { + for _, v := range values { + if v == value { + return true + } + } + + return false +} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go b/vendor/github.com/stretchr/testify/assert/assertion_format.go new file mode 100644 index 0000000000..49370eb167 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go @@ -0,0 +1,644 @@ +/* +* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen +* THIS FILE MUST NOT BE EDITED BY HAND + */ + +package assert + +import ( + http "net/http" + url "net/url" + time "time" +) + +// Conditionf uses a Comparison to assert a complex condition. +func Conditionf(t TestingT, comp Comparison, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Condition(t, comp, append([]interface{}{msg}, args...)...) +} + +// Containsf asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// assert.Containsf(t, "Hello World", "World", "error message %s", "formatted") +// assert.Containsf(t, ["Hello", "World"], "World", "error message %s", "formatted") +// assert.Containsf(t, {"Hello": "World"}, "Hello", "error message %s", "formatted") +func Containsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Contains(t, s, contains, append([]interface{}{msg}, args...)...) +} + +// DirExistsf checks whether a directory exists in the given path. It also fails +// if the path is a file rather a directory or there is an error checking whether it exists. +func DirExistsf(t TestingT, path string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return DirExists(t, path, append([]interface{}{msg}, args...)...) +} + +// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// assert.ElementsMatchf(t, [1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") +func ElementsMatchf(t TestingT, listA interface{}, listB interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return ElementsMatch(t, listA, listB, append([]interface{}{msg}, args...)...) +} + +// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// assert.Emptyf(t, obj, "error message %s", "formatted") +func Emptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Empty(t, object, append([]interface{}{msg}, args...)...) +} + +// Equalf asserts that two objects are equal. +// +// assert.Equalf(t, 123, 123, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. +func Equalf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Equal(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// assert.EqualErrorf(t, err, expectedErrorString, "error message %s", "formatted") +func EqualErrorf(t TestingT, theError error, errString string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return EqualError(t, theError, errString, append([]interface{}{msg}, args...)...) +} + +// EqualValuesf asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValuesf(t, uint32(123), int32(123), "error message %s", "formatted") +func EqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return EqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Errorf asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if assert.Errorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } +func Errorf(t TestingT, err error, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Error(t, err, append([]interface{}{msg}, args...)...) +} + +// Eventuallyf asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. +// +// assert.Eventuallyf(t, func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +func Eventuallyf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Eventually(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...) +} + +// Exactlyf asserts that two objects are equal in value and type. +// +// assert.Exactlyf(t, int32(123), int64(123), "error message %s", "formatted") +func Exactlyf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Exactly(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Failf reports a failure through +func Failf(t TestingT, failureMessage string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Fail(t, failureMessage, append([]interface{}{msg}, args...)...) +} + +// FailNowf fails test +func FailNowf(t TestingT, failureMessage string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return FailNow(t, failureMessage, append([]interface{}{msg}, args...)...) +} + +// Falsef asserts that the specified value is false. +// +// assert.Falsef(t, myBool, "error message %s", "formatted") +func Falsef(t TestingT, value bool, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return False(t, value, append([]interface{}{msg}, args...)...) +} + +// FileExistsf checks whether a file exists in the given path. It also fails if +// the path points to a directory or there is an error when trying to check the file. +func FileExistsf(t TestingT, path string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return FileExists(t, path, append([]interface{}{msg}, args...)...) +} + +// Greaterf asserts that the first element is greater than the second +// +// assert.Greaterf(t, 2, 1, "error message %s", "formatted") +// assert.Greaterf(t, float64(2), float64(1), "error message %s", "formatted") +// assert.Greaterf(t, "b", "a", "error message %s", "formatted") +func Greaterf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Greater(t, e1, e2, append([]interface{}{msg}, args...)...) +} + +// GreaterOrEqualf asserts that the first element is greater than or equal to the second +// +// assert.GreaterOrEqualf(t, 2, 1, "error message %s", "formatted") +// assert.GreaterOrEqualf(t, 2, 2, "error message %s", "formatted") +// assert.GreaterOrEqualf(t, "b", "a", "error message %s", "formatted") +// assert.GreaterOrEqualf(t, "b", "b", "error message %s", "formatted") +func GreaterOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return GreaterOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...) +} + +// HTTPBodyContainsf asserts that a specified handler returns a +// body that contains a string. +// +// assert.HTTPBodyContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPBodyContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...) +} + +// HTTPBodyNotContainsf asserts that a specified handler returns a +// body that does not contain a string. +// +// assert.HTTPBodyNotContainsf(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyNotContainsf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPBodyNotContains(t, handler, method, url, values, str, append([]interface{}{msg}, args...)...) +} + +// HTTPErrorf asserts that a specified handler returns an error status code. +// +// assert.HTTPErrorf(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPErrorf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPError(t, handler, method, url, values, append([]interface{}{msg}, args...)...) +} + +// HTTPRedirectf asserts that a specified handler returns a redirect status code. +// +// assert.HTTPRedirectf(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPRedirectf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPRedirect(t, handler, method, url, values, append([]interface{}{msg}, args...)...) +} + +// HTTPStatusCodef asserts that a specified handler returns a specified status code. +// +// assert.HTTPStatusCodef(t, myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPStatusCodef(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPStatusCode(t, handler, method, url, values, statuscode, append([]interface{}{msg}, args...)...) +} + +// HTTPSuccessf asserts that a specified handler returns a success status code. +// +// assert.HTTPSuccessf(t, myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPSuccessf(t TestingT, handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return HTTPSuccess(t, handler, method, url, values, append([]interface{}{msg}, args...)...) +} + +// Implementsf asserts that an object is implemented by the specified interface. +// +// assert.Implementsf(t, (*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +func Implementsf(t TestingT, interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Implements(t, interfaceObject, object, append([]interface{}{msg}, args...)...) +} + +// InDeltaf asserts that the two numerals are within delta of each other. +// +// assert.InDeltaf(t, math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +func InDeltaf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return InDelta(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func InDeltaMapValuesf(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return InDeltaMapValues(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// InDeltaSlicef is the same as InDelta, except it compares two slices. +func InDeltaSlicef(t TestingT, expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return InDeltaSlice(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// InEpsilonf asserts that expected and actual have a relative error less than epsilon +func InEpsilonf(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return InEpsilon(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...) +} + +// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. +func InEpsilonSlicef(t TestingT, expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return InEpsilonSlice(t, expected, actual, epsilon, append([]interface{}{msg}, args...)...) +} + +// IsTypef asserts that the specified objects are of the same type. +func IsTypef(t TestingT, expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return IsType(t, expectedType, object, append([]interface{}{msg}, args...)...) +} + +// JSONEqf asserts that two JSON strings are equivalent. +// +// assert.JSONEqf(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +func JSONEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return JSONEq(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Lenf asserts that the specified object has specific length. +// Lenf also fails if the object has a type that len() not accept. +// +// assert.Lenf(t, mySlice, 3, "error message %s", "formatted") +func Lenf(t TestingT, object interface{}, length int, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Len(t, object, length, append([]interface{}{msg}, args...)...) +} + +// Lessf asserts that the first element is less than the second +// +// assert.Lessf(t, 1, 2, "error message %s", "formatted") +// assert.Lessf(t, float64(1), float64(2), "error message %s", "formatted") +// assert.Lessf(t, "a", "b", "error message %s", "formatted") +func Lessf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Less(t, e1, e2, append([]interface{}{msg}, args...)...) +} + +// LessOrEqualf asserts that the first element is less than or equal to the second +// +// assert.LessOrEqualf(t, 1, 2, "error message %s", "formatted") +// assert.LessOrEqualf(t, 2, 2, "error message %s", "formatted") +// assert.LessOrEqualf(t, "a", "b", "error message %s", "formatted") +// assert.LessOrEqualf(t, "b", "b", "error message %s", "formatted") +func LessOrEqualf(t TestingT, e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return LessOrEqual(t, e1, e2, append([]interface{}{msg}, args...)...) +} + +// Neverf asserts that the given condition doesn't satisfy in waitFor time, +// periodically checking the target function each tick. +// +// assert.Neverf(t, func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +func Neverf(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Never(t, condition, waitFor, tick, append([]interface{}{msg}, args...)...) +} + +// Nilf asserts that the specified object is nil. +// +// assert.Nilf(t, err, "error message %s", "formatted") +func Nilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Nil(t, object, append([]interface{}{msg}, args...)...) +} + +// NoDirExistsf checks whether a directory does not exist in the given path. +// It fails if the path points to an existing _directory_ only. +func NoDirExistsf(t TestingT, path string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NoDirExists(t, path, append([]interface{}{msg}, args...)...) +} + +// NoErrorf asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if assert.NoErrorf(t, err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } +func NoErrorf(t TestingT, err error, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NoError(t, err, append([]interface{}{msg}, args...)...) +} + +// NoFileExistsf checks whether a file does not exist in a given path. It fails +// if the path points to an existing _file_ only. +func NoFileExistsf(t TestingT, path string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NoFileExists(t, path, append([]interface{}{msg}, args...)...) +} + +// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// assert.NotContainsf(t, "Hello World", "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, ["Hello", "World"], "Earth", "error message %s", "formatted") +// assert.NotContainsf(t, {"Hello": "World"}, "Earth", "error message %s", "formatted") +func NotContainsf(t TestingT, s interface{}, contains interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotContains(t, s, contains, append([]interface{}{msg}, args...)...) +} + +// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if assert.NotEmptyf(t, obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } +func NotEmptyf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotEmpty(t, object, append([]interface{}{msg}, args...)...) +} + +// NotEqualf asserts that the specified values are NOT equal. +// +// assert.NotEqualf(t, obj1, obj2, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). +func NotEqualf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotEqual(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// NotEqualValuesf asserts that two objects are not equal even when converted to the same type +// +// assert.NotEqualValuesf(t, obj1, obj2, "error message %s", "formatted") +func NotEqualValuesf(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotEqualValues(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// NotNilf asserts that the specified object is not nil. +// +// assert.NotNilf(t, err, "error message %s", "formatted") +func NotNilf(t TestingT, object interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotNil(t, object, append([]interface{}{msg}, args...)...) +} + +// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// assert.NotPanicsf(t, func(){ RemainCalm() }, "error message %s", "formatted") +func NotPanicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotPanics(t, f, append([]interface{}{msg}, args...)...) +} + +// NotRegexpf asserts that a specified regexp does not match a string. +// +// assert.NotRegexpf(t, regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// assert.NotRegexpf(t, "^start", "it's not starting", "error message %s", "formatted") +func NotRegexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotRegexp(t, rx, str, append([]interface{}{msg}, args...)...) +} + +// NotSamef asserts that two pointers do not reference the same object. +// +// assert.NotSamef(t, ptr1, ptr2, "error message %s", "formatted") +// +// Both arguments must be pointer variables. Pointer variable sameness is +// determined based on the equality of both type and value. +func NotSamef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotSame(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// NotSubsetf asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// assert.NotSubsetf(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +func NotSubsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotSubset(t, list, subset, append([]interface{}{msg}, args...)...) +} + +// NotZerof asserts that i is not the zero value for its type. +func NotZerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return NotZero(t, i, append([]interface{}{msg}, args...)...) +} + +// Panicsf asserts that the code inside the specified PanicTestFunc panics. +// +// assert.Panicsf(t, func(){ GoCrazy() }, "error message %s", "formatted") +func Panicsf(t TestingT, f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Panics(t, f, append([]interface{}{msg}, args...)...) +} + +// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc +// panics, and that the recovered panic value is an error that satisfies the +// EqualError comparison. +// +// assert.PanicsWithErrorf(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +func PanicsWithErrorf(t TestingT, errString string, f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return PanicsWithError(t, errString, f, append([]interface{}{msg}, args...)...) +} + +// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// assert.PanicsWithValuef(t, "crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +func PanicsWithValuef(t TestingT, expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return PanicsWithValue(t, expected, f, append([]interface{}{msg}, args...)...) +} + +// Regexpf asserts that a specified regexp matches a string. +// +// assert.Regexpf(t, regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// assert.Regexpf(t, "start...$", "it's not starting", "error message %s", "formatted") +func Regexpf(t TestingT, rx interface{}, str interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Regexp(t, rx, str, append([]interface{}{msg}, args...)...) +} + +// Samef asserts that two pointers reference the same object. +// +// assert.Samef(t, ptr1, ptr2, "error message %s", "formatted") +// +// Both arguments must be pointer variables. Pointer variable sameness is +// determined based on the equality of both type and value. +func Samef(t TestingT, expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Same(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Subsetf asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// assert.Subsetf(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +func Subsetf(t TestingT, list interface{}, subset interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Subset(t, list, subset, append([]interface{}{msg}, args...)...) +} + +// Truef asserts that the specified value is true. +// +// assert.Truef(t, myBool, "error message %s", "formatted") +func Truef(t TestingT, value bool, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return True(t, value, append([]interface{}{msg}, args...)...) +} + +// WithinDurationf asserts that the two times are within duration delta of each other. +// +// assert.WithinDurationf(t, time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +func WithinDurationf(t TestingT, expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return WithinDuration(t, expected, actual, delta, append([]interface{}{msg}, args...)...) +} + +// YAMLEqf asserts that two YAML strings are equivalent. +func YAMLEqf(t TestingT, expected string, actual string, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return YAMLEq(t, expected, actual, append([]interface{}{msg}, args...)...) +} + +// Zerof asserts that i is the zero value for its type. +func Zerof(t TestingT, i interface{}, msg string, args ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Zero(t, i, append([]interface{}{msg}, args...)...) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl b/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl new file mode 100644 index 0000000000..d2bb0b8177 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl @@ -0,0 +1,5 @@ +{{.CommentFormat}} +func {{.DocInfo.Name}}f(t TestingT, {{.ParamsFormat}}) bool { + if h, ok := t.(tHelper); ok { h.Helper() } + return {{.DocInfo.Name}}(t, {{.ForwardedParamsFormat}}) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go b/vendor/github.com/stretchr/testify/assert/assertion_forward.go new file mode 100644 index 0000000000..9db889427a --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go @@ -0,0 +1,1276 @@ +/* +* CODE GENERATED AUTOMATICALLY WITH github.com/stretchr/testify/_codegen +* THIS FILE MUST NOT BE EDITED BY HAND + */ + +package assert + +import ( + http "net/http" + url "net/url" + time "time" +) + +// Condition uses a Comparison to assert a complex condition. +func (a *Assertions) Condition(comp Comparison, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Condition(a.t, comp, msgAndArgs...) +} + +// Conditionf uses a Comparison to assert a complex condition. +func (a *Assertions) Conditionf(comp Comparison, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Conditionf(a.t, comp, msg, args...) +} + +// Contains asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// a.Contains("Hello World", "World") +// a.Contains(["Hello", "World"], "World") +// a.Contains({"Hello": "World"}, "Hello") +func (a *Assertions) Contains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Contains(a.t, s, contains, msgAndArgs...) +} + +// Containsf asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// a.Containsf("Hello World", "World", "error message %s", "formatted") +// a.Containsf(["Hello", "World"], "World", "error message %s", "formatted") +// a.Containsf({"Hello": "World"}, "Hello", "error message %s", "formatted") +func (a *Assertions) Containsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Containsf(a.t, s, contains, msg, args...) +} + +// DirExists checks whether a directory exists in the given path. It also fails +// if the path is a file rather a directory or there is an error checking whether it exists. +func (a *Assertions) DirExists(path string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return DirExists(a.t, path, msgAndArgs...) +} + +// DirExistsf checks whether a directory exists in the given path. It also fails +// if the path is a file rather a directory or there is an error checking whether it exists. +func (a *Assertions) DirExistsf(path string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return DirExistsf(a.t, path, msg, args...) +} + +// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// a.ElementsMatch([1, 3, 2, 3], [1, 3, 3, 2]) +func (a *Assertions) ElementsMatch(listA interface{}, listB interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return ElementsMatch(a.t, listA, listB, msgAndArgs...) +} + +// ElementsMatchf asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// a.ElementsMatchf([1, 3, 2, 3], [1, 3, 3, 2], "error message %s", "formatted") +func (a *Assertions) ElementsMatchf(listA interface{}, listB interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return ElementsMatchf(a.t, listA, listB, msg, args...) +} + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// a.Empty(obj) +func (a *Assertions) Empty(object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Empty(a.t, object, msgAndArgs...) +} + +// Emptyf asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// a.Emptyf(obj, "error message %s", "formatted") +func (a *Assertions) Emptyf(object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Emptyf(a.t, object, msg, args...) +} + +// Equal asserts that two objects are equal. +// +// a.Equal(123, 123) +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. +func (a *Assertions) Equal(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Equal(a.t, expected, actual, msgAndArgs...) +} + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// a.EqualError(err, expectedErrorString) +func (a *Assertions) EqualError(theError error, errString string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualError(a.t, theError, errString, msgAndArgs...) +} + +// EqualErrorf asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// a.EqualErrorf(err, expectedErrorString, "error message %s", "formatted") +func (a *Assertions) EqualErrorf(theError error, errString string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualErrorf(a.t, theError, errString, msg, args...) +} + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// a.EqualValues(uint32(123), int32(123)) +func (a *Assertions) EqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualValues(a.t, expected, actual, msgAndArgs...) +} + +// EqualValuesf asserts that two objects are equal or convertable to the same types +// and equal. +// +// a.EqualValuesf(uint32(123), int32(123), "error message %s", "formatted") +func (a *Assertions) EqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return EqualValuesf(a.t, expected, actual, msg, args...) +} + +// Equalf asserts that two objects are equal. +// +// a.Equalf(123, 123, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. +func (a *Assertions) Equalf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Equalf(a.t, expected, actual, msg, args...) +} + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if a.Error(err) { +// assert.Equal(t, expectedError, err) +// } +func (a *Assertions) Error(err error, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Error(a.t, err, msgAndArgs...) +} + +// Errorf asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if a.Errorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedErrorf, err) +// } +func (a *Assertions) Errorf(err error, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Errorf(a.t, err, msg, args...) +} + +// Eventually asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. +// +// a.Eventually(func() bool { return true; }, time.Second, 10*time.Millisecond) +func (a *Assertions) Eventually(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Eventually(a.t, condition, waitFor, tick, msgAndArgs...) +} + +// Eventuallyf asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. +// +// a.Eventuallyf(func() bool { return true; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +func (a *Assertions) Eventuallyf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Eventuallyf(a.t, condition, waitFor, tick, msg, args...) +} + +// Exactly asserts that two objects are equal in value and type. +// +// a.Exactly(int32(123), int64(123)) +func (a *Assertions) Exactly(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Exactly(a.t, expected, actual, msgAndArgs...) +} + +// Exactlyf asserts that two objects are equal in value and type. +// +// a.Exactlyf(int32(123), int64(123), "error message %s", "formatted") +func (a *Assertions) Exactlyf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Exactlyf(a.t, expected, actual, msg, args...) +} + +// Fail reports a failure through +func (a *Assertions) Fail(failureMessage string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Fail(a.t, failureMessage, msgAndArgs...) +} + +// FailNow fails test +func (a *Assertions) FailNow(failureMessage string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return FailNow(a.t, failureMessage, msgAndArgs...) +} + +// FailNowf fails test +func (a *Assertions) FailNowf(failureMessage string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return FailNowf(a.t, failureMessage, msg, args...) +} + +// Failf reports a failure through +func (a *Assertions) Failf(failureMessage string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Failf(a.t, failureMessage, msg, args...) +} + +// False asserts that the specified value is false. +// +// a.False(myBool) +func (a *Assertions) False(value bool, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return False(a.t, value, msgAndArgs...) +} + +// Falsef asserts that the specified value is false. +// +// a.Falsef(myBool, "error message %s", "formatted") +func (a *Assertions) Falsef(value bool, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Falsef(a.t, value, msg, args...) +} + +// FileExists checks whether a file exists in the given path. It also fails if +// the path points to a directory or there is an error when trying to check the file. +func (a *Assertions) FileExists(path string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return FileExists(a.t, path, msgAndArgs...) +} + +// FileExistsf checks whether a file exists in the given path. It also fails if +// the path points to a directory or there is an error when trying to check the file. +func (a *Assertions) FileExistsf(path string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return FileExistsf(a.t, path, msg, args...) +} + +// Greater asserts that the first element is greater than the second +// +// a.Greater(2, 1) +// a.Greater(float64(2), float64(1)) +// a.Greater("b", "a") +func (a *Assertions) Greater(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Greater(a.t, e1, e2, msgAndArgs...) +} + +// GreaterOrEqual asserts that the first element is greater than or equal to the second +// +// a.GreaterOrEqual(2, 1) +// a.GreaterOrEqual(2, 2) +// a.GreaterOrEqual("b", "a") +// a.GreaterOrEqual("b", "b") +func (a *Assertions) GreaterOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return GreaterOrEqual(a.t, e1, e2, msgAndArgs...) +} + +// GreaterOrEqualf asserts that the first element is greater than or equal to the second +// +// a.GreaterOrEqualf(2, 1, "error message %s", "formatted") +// a.GreaterOrEqualf(2, 2, "error message %s", "formatted") +// a.GreaterOrEqualf("b", "a", "error message %s", "formatted") +// a.GreaterOrEqualf("b", "b", "error message %s", "formatted") +func (a *Assertions) GreaterOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return GreaterOrEqualf(a.t, e1, e2, msg, args...) +} + +// Greaterf asserts that the first element is greater than the second +// +// a.Greaterf(2, 1, "error message %s", "formatted") +// a.Greaterf(float64(2), float64(1), "error message %s", "formatted") +// a.Greaterf("b", "a", "error message %s", "formatted") +func (a *Assertions) Greaterf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Greaterf(a.t, e1, e2, msg, args...) +} + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// a.HTTPBodyContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPBodyContains(a.t, handler, method, url, values, str, msgAndArgs...) +} + +// HTTPBodyContainsf asserts that a specified handler returns a +// body that contains a string. +// +// a.HTTPBodyContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPBodyContainsf(a.t, handler, method, url, values, str, msg, args...) +} + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// a.HTTPBodyNotContains(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyNotContains(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPBodyNotContains(a.t, handler, method, url, values, str, msgAndArgs...) +} + +// HTTPBodyNotContainsf asserts that a specified handler returns a +// body that does not contain a string. +// +// a.HTTPBodyNotContainsf(myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky", "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPBodyNotContainsf(handler http.HandlerFunc, method string, url string, values url.Values, str interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPBodyNotContainsf(a.t, handler, method, url, values, str, msg, args...) +} + +// HTTPError asserts that a specified handler returns an error status code. +// +// a.HTTPError(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPError(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPError(a.t, handler, method, url, values, msgAndArgs...) +} + +// HTTPErrorf asserts that a specified handler returns an error status code. +// +// a.HTTPErrorf(myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPErrorf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPErrorf(a.t, handler, method, url, values, msg, args...) +} + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// a.HTTPRedirect(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPRedirect(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPRedirect(a.t, handler, method, url, values, msgAndArgs...) +} + +// HTTPRedirectf asserts that a specified handler returns a redirect status code. +// +// a.HTTPRedirectf(myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPRedirectf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPRedirectf(a.t, handler, method, url, values, msg, args...) +} + +// HTTPStatusCode asserts that a specified handler returns a specified status code. +// +// a.HTTPStatusCode(myHandler, "GET", "/notImplemented", nil, 501) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPStatusCode(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPStatusCode(a.t, handler, method, url, values, statuscode, msgAndArgs...) +} + +// HTTPStatusCodef asserts that a specified handler returns a specified status code. +// +// a.HTTPStatusCodef(myHandler, "GET", "/notImplemented", nil, 501, "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPStatusCodef(handler http.HandlerFunc, method string, url string, values url.Values, statuscode int, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPStatusCodef(a.t, handler, method, url, values, statuscode, msg, args...) +} + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// a.HTTPSuccess(myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPSuccess(handler http.HandlerFunc, method string, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPSuccess(a.t, handler, method, url, values, msgAndArgs...) +} + +// HTTPSuccessf asserts that a specified handler returns a success status code. +// +// a.HTTPSuccessf(myHandler, "POST", "http://www.google.com", nil, "error message %s", "formatted") +// +// Returns whether the assertion was successful (true) or not (false). +func (a *Assertions) HTTPSuccessf(handler http.HandlerFunc, method string, url string, values url.Values, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return HTTPSuccessf(a.t, handler, method, url, values, msg, args...) +} + +// Implements asserts that an object is implemented by the specified interface. +// +// a.Implements((*MyInterface)(nil), new(MyObject)) +func (a *Assertions) Implements(interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Implements(a.t, interfaceObject, object, msgAndArgs...) +} + +// Implementsf asserts that an object is implemented by the specified interface. +// +// a.Implementsf((*MyInterface)(nil), new(MyObject), "error message %s", "formatted") +func (a *Assertions) Implementsf(interfaceObject interface{}, object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Implementsf(a.t, interfaceObject, object, msg, args...) +} + +// InDelta asserts that the two numerals are within delta of each other. +// +// a.InDelta(math.Pi, 22/7.0, 0.01) +func (a *Assertions) InDelta(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDelta(a.t, expected, actual, delta, msgAndArgs...) +} + +// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func (a *Assertions) InDeltaMapValues(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDeltaMapValues(a.t, expected, actual, delta, msgAndArgs...) +} + +// InDeltaMapValuesf is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func (a *Assertions) InDeltaMapValuesf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDeltaMapValuesf(a.t, expected, actual, delta, msg, args...) +} + +// InDeltaSlice is the same as InDelta, except it compares two slices. +func (a *Assertions) InDeltaSlice(expected interface{}, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDeltaSlice(a.t, expected, actual, delta, msgAndArgs...) +} + +// InDeltaSlicef is the same as InDelta, except it compares two slices. +func (a *Assertions) InDeltaSlicef(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDeltaSlicef(a.t, expected, actual, delta, msg, args...) +} + +// InDeltaf asserts that the two numerals are within delta of each other. +// +// a.InDeltaf(math.Pi, 22/7.0, 0.01, "error message %s", "formatted") +func (a *Assertions) InDeltaf(expected interface{}, actual interface{}, delta float64, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InDeltaf(a.t, expected, actual, delta, msg, args...) +} + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +func (a *Assertions) InEpsilon(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InEpsilon(a.t, expected, actual, epsilon, msgAndArgs...) +} + +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func (a *Assertions) InEpsilonSlice(expected interface{}, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InEpsilonSlice(a.t, expected, actual, epsilon, msgAndArgs...) +} + +// InEpsilonSlicef is the same as InEpsilon, except it compares each value from two slices. +func (a *Assertions) InEpsilonSlicef(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InEpsilonSlicef(a.t, expected, actual, epsilon, msg, args...) +} + +// InEpsilonf asserts that expected and actual have a relative error less than epsilon +func (a *Assertions) InEpsilonf(expected interface{}, actual interface{}, epsilon float64, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return InEpsilonf(a.t, expected, actual, epsilon, msg, args...) +} + +// IsType asserts that the specified objects are of the same type. +func (a *Assertions) IsType(expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return IsType(a.t, expectedType, object, msgAndArgs...) +} + +// IsTypef asserts that the specified objects are of the same type. +func (a *Assertions) IsTypef(expectedType interface{}, object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return IsTypef(a.t, expectedType, object, msg, args...) +} + +// JSONEq asserts that two JSON strings are equivalent. +// +// a.JSONEq(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +func (a *Assertions) JSONEq(expected string, actual string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return JSONEq(a.t, expected, actual, msgAndArgs...) +} + +// JSONEqf asserts that two JSON strings are equivalent. +// +// a.JSONEqf(`{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`, "error message %s", "formatted") +func (a *Assertions) JSONEqf(expected string, actual string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return JSONEqf(a.t, expected, actual, msg, args...) +} + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// a.Len(mySlice, 3) +func (a *Assertions) Len(object interface{}, length int, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Len(a.t, object, length, msgAndArgs...) +} + +// Lenf asserts that the specified object has specific length. +// Lenf also fails if the object has a type that len() not accept. +// +// a.Lenf(mySlice, 3, "error message %s", "formatted") +func (a *Assertions) Lenf(object interface{}, length int, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Lenf(a.t, object, length, msg, args...) +} + +// Less asserts that the first element is less than the second +// +// a.Less(1, 2) +// a.Less(float64(1), float64(2)) +// a.Less("a", "b") +func (a *Assertions) Less(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Less(a.t, e1, e2, msgAndArgs...) +} + +// LessOrEqual asserts that the first element is less than or equal to the second +// +// a.LessOrEqual(1, 2) +// a.LessOrEqual(2, 2) +// a.LessOrEqual("a", "b") +// a.LessOrEqual("b", "b") +func (a *Assertions) LessOrEqual(e1 interface{}, e2 interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return LessOrEqual(a.t, e1, e2, msgAndArgs...) +} + +// LessOrEqualf asserts that the first element is less than or equal to the second +// +// a.LessOrEqualf(1, 2, "error message %s", "formatted") +// a.LessOrEqualf(2, 2, "error message %s", "formatted") +// a.LessOrEqualf("a", "b", "error message %s", "formatted") +// a.LessOrEqualf("b", "b", "error message %s", "formatted") +func (a *Assertions) LessOrEqualf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return LessOrEqualf(a.t, e1, e2, msg, args...) +} + +// Lessf asserts that the first element is less than the second +// +// a.Lessf(1, 2, "error message %s", "formatted") +// a.Lessf(float64(1), float64(2), "error message %s", "formatted") +// a.Lessf("a", "b", "error message %s", "formatted") +func (a *Assertions) Lessf(e1 interface{}, e2 interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Lessf(a.t, e1, e2, msg, args...) +} + +// Never asserts that the given condition doesn't satisfy in waitFor time, +// periodically checking the target function each tick. +// +// a.Never(func() bool { return false; }, time.Second, 10*time.Millisecond) +func (a *Assertions) Never(condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Never(a.t, condition, waitFor, tick, msgAndArgs...) +} + +// Neverf asserts that the given condition doesn't satisfy in waitFor time, +// periodically checking the target function each tick. +// +// a.Neverf(func() bool { return false; }, time.Second, 10*time.Millisecond, "error message %s", "formatted") +func (a *Assertions) Neverf(condition func() bool, waitFor time.Duration, tick time.Duration, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Neverf(a.t, condition, waitFor, tick, msg, args...) +} + +// Nil asserts that the specified object is nil. +// +// a.Nil(err) +func (a *Assertions) Nil(object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Nil(a.t, object, msgAndArgs...) +} + +// Nilf asserts that the specified object is nil. +// +// a.Nilf(err, "error message %s", "formatted") +func (a *Assertions) Nilf(object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Nilf(a.t, object, msg, args...) +} + +// NoDirExists checks whether a directory does not exist in the given path. +// It fails if the path points to an existing _directory_ only. +func (a *Assertions) NoDirExists(path string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NoDirExists(a.t, path, msgAndArgs...) +} + +// NoDirExistsf checks whether a directory does not exist in the given path. +// It fails if the path points to an existing _directory_ only. +func (a *Assertions) NoDirExistsf(path string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NoDirExistsf(a.t, path, msg, args...) +} + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if a.NoError(err) { +// assert.Equal(t, expectedObj, actualObj) +// } +func (a *Assertions) NoError(err error, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NoError(a.t, err, msgAndArgs...) +} + +// NoErrorf asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if a.NoErrorf(err, "error message %s", "formatted") { +// assert.Equal(t, expectedObj, actualObj) +// } +func (a *Assertions) NoErrorf(err error, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NoErrorf(a.t, err, msg, args...) +} + +// NoFileExists checks whether a file does not exist in a given path. It fails +// if the path points to an existing _file_ only. +func (a *Assertions) NoFileExists(path string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NoFileExists(a.t, path, msgAndArgs...) +} + +// NoFileExistsf checks whether a file does not exist in a given path. It fails +// if the path points to an existing _file_ only. +func (a *Assertions) NoFileExistsf(path string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NoFileExistsf(a.t, path, msg, args...) +} + +// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// a.NotContains("Hello World", "Earth") +// a.NotContains(["Hello", "World"], "Earth") +// a.NotContains({"Hello": "World"}, "Earth") +func (a *Assertions) NotContains(s interface{}, contains interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotContains(a.t, s, contains, msgAndArgs...) +} + +// NotContainsf asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// a.NotContainsf("Hello World", "Earth", "error message %s", "formatted") +// a.NotContainsf(["Hello", "World"], "Earth", "error message %s", "formatted") +// a.NotContainsf({"Hello": "World"}, "Earth", "error message %s", "formatted") +func (a *Assertions) NotContainsf(s interface{}, contains interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotContainsf(a.t, s, contains, msg, args...) +} + +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if a.NotEmpty(obj) { +// assert.Equal(t, "two", obj[1]) +// } +func (a *Assertions) NotEmpty(object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotEmpty(a.t, object, msgAndArgs...) +} + +// NotEmptyf asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if a.NotEmptyf(obj, "error message %s", "formatted") { +// assert.Equal(t, "two", obj[1]) +// } +func (a *Assertions) NotEmptyf(object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotEmptyf(a.t, object, msg, args...) +} + +// NotEqual asserts that the specified values are NOT equal. +// +// a.NotEqual(obj1, obj2) +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). +func (a *Assertions) NotEqual(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotEqual(a.t, expected, actual, msgAndArgs...) +} + +// NotEqualValues asserts that two objects are not equal even when converted to the same type +// +// a.NotEqualValues(obj1, obj2) +func (a *Assertions) NotEqualValues(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotEqualValues(a.t, expected, actual, msgAndArgs...) +} + +// NotEqualValuesf asserts that two objects are not equal even when converted to the same type +// +// a.NotEqualValuesf(obj1, obj2, "error message %s", "formatted") +func (a *Assertions) NotEqualValuesf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotEqualValuesf(a.t, expected, actual, msg, args...) +} + +// NotEqualf asserts that the specified values are NOT equal. +// +// a.NotEqualf(obj1, obj2, "error message %s", "formatted") +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). +func (a *Assertions) NotEqualf(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotEqualf(a.t, expected, actual, msg, args...) +} + +// NotNil asserts that the specified object is not nil. +// +// a.NotNil(err) +func (a *Assertions) NotNil(object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotNil(a.t, object, msgAndArgs...) +} + +// NotNilf asserts that the specified object is not nil. +// +// a.NotNilf(err, "error message %s", "formatted") +func (a *Assertions) NotNilf(object interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotNilf(a.t, object, msg, args...) +} + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// a.NotPanics(func(){ RemainCalm() }) +func (a *Assertions) NotPanics(f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotPanics(a.t, f, msgAndArgs...) +} + +// NotPanicsf asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// a.NotPanicsf(func(){ RemainCalm() }, "error message %s", "formatted") +func (a *Assertions) NotPanicsf(f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotPanicsf(a.t, f, msg, args...) +} + +// NotRegexp asserts that a specified regexp does not match a string. +// +// a.NotRegexp(regexp.MustCompile("starts"), "it's starting") +// a.NotRegexp("^start", "it's not starting") +func (a *Assertions) NotRegexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotRegexp(a.t, rx, str, msgAndArgs...) +} + +// NotRegexpf asserts that a specified regexp does not match a string. +// +// a.NotRegexpf(regexp.MustCompile("starts"), "it's starting", "error message %s", "formatted") +// a.NotRegexpf("^start", "it's not starting", "error message %s", "formatted") +func (a *Assertions) NotRegexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotRegexpf(a.t, rx, str, msg, args...) +} + +// NotSame asserts that two pointers do not reference the same object. +// +// a.NotSame(ptr1, ptr2) +// +// Both arguments must be pointer variables. Pointer variable sameness is +// determined based on the equality of both type and value. +func (a *Assertions) NotSame(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotSame(a.t, expected, actual, msgAndArgs...) +} + +// NotSamef asserts that two pointers do not reference the same object. +// +// a.NotSamef(ptr1, ptr2, "error message %s", "formatted") +// +// Both arguments must be pointer variables. Pointer variable sameness is +// determined based on the equality of both type and value. +func (a *Assertions) NotSamef(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotSamef(a.t, expected, actual, msg, args...) +} + +// NotSubset asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// a.NotSubset([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +func (a *Assertions) NotSubset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotSubset(a.t, list, subset, msgAndArgs...) +} + +// NotSubsetf asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// a.NotSubsetf([1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]", "error message %s", "formatted") +func (a *Assertions) NotSubsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotSubsetf(a.t, list, subset, msg, args...) +} + +// NotZero asserts that i is not the zero value for its type. +func (a *Assertions) NotZero(i interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotZero(a.t, i, msgAndArgs...) +} + +// NotZerof asserts that i is not the zero value for its type. +func (a *Assertions) NotZerof(i interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return NotZerof(a.t, i, msg, args...) +} + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// a.Panics(func(){ GoCrazy() }) +func (a *Assertions) Panics(f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Panics(a.t, f, msgAndArgs...) +} + +// PanicsWithError asserts that the code inside the specified PanicTestFunc +// panics, and that the recovered panic value is an error that satisfies the +// EqualError comparison. +// +// a.PanicsWithError("crazy error", func(){ GoCrazy() }) +func (a *Assertions) PanicsWithError(errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return PanicsWithError(a.t, errString, f, msgAndArgs...) +} + +// PanicsWithErrorf asserts that the code inside the specified PanicTestFunc +// panics, and that the recovered panic value is an error that satisfies the +// EqualError comparison. +// +// a.PanicsWithErrorf("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +func (a *Assertions) PanicsWithErrorf(errString string, f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return PanicsWithErrorf(a.t, errString, f, msg, args...) +} + +// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// a.PanicsWithValue("crazy error", func(){ GoCrazy() }) +func (a *Assertions) PanicsWithValue(expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return PanicsWithValue(a.t, expected, f, msgAndArgs...) +} + +// PanicsWithValuef asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// a.PanicsWithValuef("crazy error", func(){ GoCrazy() }, "error message %s", "formatted") +func (a *Assertions) PanicsWithValuef(expected interface{}, f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return PanicsWithValuef(a.t, expected, f, msg, args...) +} + +// Panicsf asserts that the code inside the specified PanicTestFunc panics. +// +// a.Panicsf(func(){ GoCrazy() }, "error message %s", "formatted") +func (a *Assertions) Panicsf(f PanicTestFunc, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Panicsf(a.t, f, msg, args...) +} + +// Regexp asserts that a specified regexp matches a string. +// +// a.Regexp(regexp.MustCompile("start"), "it's starting") +// a.Regexp("start...$", "it's not starting") +func (a *Assertions) Regexp(rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Regexp(a.t, rx, str, msgAndArgs...) +} + +// Regexpf asserts that a specified regexp matches a string. +// +// a.Regexpf(regexp.MustCompile("start"), "it's starting", "error message %s", "formatted") +// a.Regexpf("start...$", "it's not starting", "error message %s", "formatted") +func (a *Assertions) Regexpf(rx interface{}, str interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Regexpf(a.t, rx, str, msg, args...) +} + +// Same asserts that two pointers reference the same object. +// +// a.Same(ptr1, ptr2) +// +// Both arguments must be pointer variables. Pointer variable sameness is +// determined based on the equality of both type and value. +func (a *Assertions) Same(expected interface{}, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Same(a.t, expected, actual, msgAndArgs...) +} + +// Samef asserts that two pointers reference the same object. +// +// a.Samef(ptr1, ptr2, "error message %s", "formatted") +// +// Both arguments must be pointer variables. Pointer variable sameness is +// determined based on the equality of both type and value. +func (a *Assertions) Samef(expected interface{}, actual interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Samef(a.t, expected, actual, msg, args...) +} + +// Subset asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// a.Subset([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +func (a *Assertions) Subset(list interface{}, subset interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Subset(a.t, list, subset, msgAndArgs...) +} + +// Subsetf asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// a.Subsetf([1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]", "error message %s", "formatted") +func (a *Assertions) Subsetf(list interface{}, subset interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Subsetf(a.t, list, subset, msg, args...) +} + +// True asserts that the specified value is true. +// +// a.True(myBool) +func (a *Assertions) True(value bool, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return True(a.t, value, msgAndArgs...) +} + +// Truef asserts that the specified value is true. +// +// a.Truef(myBool, "error message %s", "formatted") +func (a *Assertions) Truef(value bool, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Truef(a.t, value, msg, args...) +} + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// a.WithinDuration(time.Now(), time.Now(), 10*time.Second) +func (a *Assertions) WithinDuration(expected time.Time, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return WithinDuration(a.t, expected, actual, delta, msgAndArgs...) +} + +// WithinDurationf asserts that the two times are within duration delta of each other. +// +// a.WithinDurationf(time.Now(), time.Now(), 10*time.Second, "error message %s", "formatted") +func (a *Assertions) WithinDurationf(expected time.Time, actual time.Time, delta time.Duration, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return WithinDurationf(a.t, expected, actual, delta, msg, args...) +} + +// YAMLEq asserts that two YAML strings are equivalent. +func (a *Assertions) YAMLEq(expected string, actual string, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return YAMLEq(a.t, expected, actual, msgAndArgs...) +} + +// YAMLEqf asserts that two YAML strings are equivalent. +func (a *Assertions) YAMLEqf(expected string, actual string, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return YAMLEqf(a.t, expected, actual, msg, args...) +} + +// Zero asserts that i is the zero value for its type. +func (a *Assertions) Zero(i interface{}, msgAndArgs ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Zero(a.t, i, msgAndArgs...) +} + +// Zerof asserts that i is the zero value for its type. +func (a *Assertions) Zerof(i interface{}, msg string, args ...interface{}) bool { + if h, ok := a.t.(tHelper); ok { + h.Helper() + } + return Zerof(a.t, i, msg, args...) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl b/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl new file mode 100644 index 0000000000..188bb9e174 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertion_forward.go.tmpl @@ -0,0 +1,5 @@ +{{.CommentWithoutT "a"}} +func (a *Assertions) {{.DocInfo.Name}}({{.Params}}) bool { + if h, ok := a.t.(tHelper); ok { h.Helper() } + return {{.DocInfo.Name}}(a.t, {{.ForwardedParams}}) +} diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go new file mode 100644 index 0000000000..914a10d83a --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -0,0 +1,1695 @@ +package assert + +import ( + "bufio" + "bytes" + "encoding/json" + "errors" + "fmt" + "math" + "os" + "reflect" + "regexp" + "runtime" + "runtime/debug" + "strings" + "time" + "unicode" + "unicode/utf8" + + "github.com/davecgh/go-spew/spew" + "github.com/pmezard/go-difflib/difflib" + yaml "gopkg.in/yaml.v3" +) + +//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_format.go.tmpl" + +// TestingT is an interface wrapper around *testing.T +type TestingT interface { + Errorf(format string, args ...interface{}) +} + +// ComparisonAssertionFunc is a common function prototype when comparing two values. Can be useful +// for table driven tests. +type ComparisonAssertionFunc func(TestingT, interface{}, interface{}, ...interface{}) bool + +// ValueAssertionFunc is a common function prototype when validating a single value. Can be useful +// for table driven tests. +type ValueAssertionFunc func(TestingT, interface{}, ...interface{}) bool + +// BoolAssertionFunc is a common function prototype when validating a bool value. Can be useful +// for table driven tests. +type BoolAssertionFunc func(TestingT, bool, ...interface{}) bool + +// ErrorAssertionFunc is a common function prototype when validating an error value. Can be useful +// for table driven tests. +type ErrorAssertionFunc func(TestingT, error, ...interface{}) bool + +// Comparison is a custom function that returns true on success and false on failure +type Comparison func() (success bool) + +/* + Helper functions +*/ + +// ObjectsAreEqual determines if two objects are considered equal. +// +// This function does no assertion of any kind. +func ObjectsAreEqual(expected, actual interface{}) bool { + if expected == nil || actual == nil { + return expected == actual + } + + exp, ok := expected.([]byte) + if !ok { + return reflect.DeepEqual(expected, actual) + } + + act, ok := actual.([]byte) + if !ok { + return false + } + if exp == nil || act == nil { + return exp == nil && act == nil + } + return bytes.Equal(exp, act) +} + +// ObjectsAreEqualValues gets whether two objects are equal, or if their +// values are equal. +func ObjectsAreEqualValues(expected, actual interface{}) bool { + if ObjectsAreEqual(expected, actual) { + return true + } + + actualType := reflect.TypeOf(actual) + if actualType == nil { + return false + } + expectedValue := reflect.ValueOf(expected) + if expectedValue.IsValid() && expectedValue.Type().ConvertibleTo(actualType) { + // Attempt comparison after type conversion + return reflect.DeepEqual(expectedValue.Convert(actualType).Interface(), actual) + } + + return false +} + +/* CallerInfo is necessary because the assert functions use the testing object +internally, causing it to print the file:line of the assert method, rather than where +the problem actually occurred in calling code.*/ + +// CallerInfo returns an array of strings containing the file and line number +// of each stack frame leading from the current test to the assert call that +// failed. +func CallerInfo() []string { + + var pc uintptr + var ok bool + var file string + var line int + var name string + + callers := []string{} + for i := 0; ; i++ { + pc, file, line, ok = runtime.Caller(i) + if !ok { + // The breaks below failed to terminate the loop, and we ran off the + // end of the call stack. + break + } + + // This is a huge edge case, but it will panic if this is the case, see #180 + if file == "" { + break + } + + f := runtime.FuncForPC(pc) + if f == nil { + break + } + name = f.Name() + + // testing.tRunner is the standard library function that calls + // tests. Subtests are called directly by tRunner, without going through + // the Test/Benchmark/Example function that contains the t.Run calls, so + // with subtests we should break when we hit tRunner, without adding it + // to the list of callers. + if name == "testing.tRunner" { + break + } + + parts := strings.Split(file, "/") + file = parts[len(parts)-1] + if len(parts) > 1 { + dir := parts[len(parts)-2] + if (dir != "assert" && dir != "mock" && dir != "require") || file == "mock_test.go" { + callers = append(callers, fmt.Sprintf("%s:%d", file, line)) + } + } + + // Drop the package + segments := strings.Split(name, ".") + name = segments[len(segments)-1] + if isTest(name, "Test") || + isTest(name, "Benchmark") || + isTest(name, "Example") { + break + } + } + + return callers +} + +// Stolen from the `go test` tool. +// isTest tells whether name looks like a test (or benchmark, according to prefix). +// It is a Test (say) if there is a character after Test that is not a lower-case letter. +// We don't want TesticularCancer. +func isTest(name, prefix string) bool { + if !strings.HasPrefix(name, prefix) { + return false + } + if len(name) == len(prefix) { // "Test" is ok + return true + } + rune, _ := utf8.DecodeRuneInString(name[len(prefix):]) + return !unicode.IsLower(rune) +} + +func messageFromMsgAndArgs(msgAndArgs ...interface{}) string { + if len(msgAndArgs) == 0 || msgAndArgs == nil { + return "" + } + if len(msgAndArgs) == 1 { + msg := msgAndArgs[0] + if msgAsStr, ok := msg.(string); ok { + return msgAsStr + } + return fmt.Sprintf("%+v", msg) + } + if len(msgAndArgs) > 1 { + return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...) + } + return "" +} + +// Aligns the provided message so that all lines after the first line start at the same location as the first line. +// Assumes that the first line starts at the correct location (after carriage return, tab, label, spacer and tab). +// The longestLabelLen parameter specifies the length of the longest label in the output (required becaues this is the +// basis on which the alignment occurs). +func indentMessageLines(message string, longestLabelLen int) string { + outBuf := new(bytes.Buffer) + + for i, scanner := 0, bufio.NewScanner(strings.NewReader(message)); scanner.Scan(); i++ { + // no need to align first line because it starts at the correct location (after the label) + if i != 0 { + // append alignLen+1 spaces to align with "{{longestLabel}}:" before adding tab + outBuf.WriteString("\n\t" + strings.Repeat(" ", longestLabelLen+1) + "\t") + } + outBuf.WriteString(scanner.Text()) + } + + return outBuf.String() +} + +type failNower interface { + FailNow() +} + +// FailNow fails test +func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + Fail(t, failureMessage, msgAndArgs...) + + // We cannot extend TestingT with FailNow() and + // maintain backwards compatibility, so we fallback + // to panicking when FailNow is not available in + // TestingT. + // See issue #263 + + if t, ok := t.(failNower); ok { + t.FailNow() + } else { + panic("test failed and t is missing `FailNow()`") + } + return false +} + +// Fail reports a failure through +func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + content := []labeledContent{ + {"Error Trace", strings.Join(CallerInfo(), "\n\t\t\t")}, + {"Error", failureMessage}, + } + + // Add test name if the Go version supports it + if n, ok := t.(interface { + Name() string + }); ok { + content = append(content, labeledContent{"Test", n.Name()}) + } + + message := messageFromMsgAndArgs(msgAndArgs...) + if len(message) > 0 { + content = append(content, labeledContent{"Messages", message}) + } + + t.Errorf("\n%s", ""+labeledOutput(content...)) + + return false +} + +type labeledContent struct { + label string + content string +} + +// labeledOutput returns a string consisting of the provided labeledContent. Each labeled output is appended in the following manner: +// +// \t{{label}}:{{align_spaces}}\t{{content}}\n +// +// The initial carriage return is required to undo/erase any padding added by testing.T.Errorf. The "\t{{label}}:" is for the label. +// If a label is shorter than the longest label provided, padding spaces are added to make all the labels match in length. Once this +// alignment is achieved, "\t{{content}}\n" is added for the output. +// +// If the content of the labeledOutput contains line breaks, the subsequent lines are aligned so that they start at the same location as the first line. +func labeledOutput(content ...labeledContent) string { + longestLabel := 0 + for _, v := range content { + if len(v.label) > longestLabel { + longestLabel = len(v.label) + } + } + var output string + for _, v := range content { + output += "\t" + v.label + ":" + strings.Repeat(" ", longestLabel-len(v.label)) + "\t" + indentMessageLines(v.content, longestLabel) + "\n" + } + return output +} + +// Implements asserts that an object is implemented by the specified interface. +// +// assert.Implements(t, (*MyInterface)(nil), new(MyObject)) +func Implements(t TestingT, interfaceObject interface{}, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + interfaceType := reflect.TypeOf(interfaceObject).Elem() + + if object == nil { + return Fail(t, fmt.Sprintf("Cannot check if nil implements %v", interfaceType), msgAndArgs...) + } + if !reflect.TypeOf(object).Implements(interfaceType) { + return Fail(t, fmt.Sprintf("%T must implement %v", object, interfaceType), msgAndArgs...) + } + + return true +} + +// IsType asserts that the specified objects are of the same type. +func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if !ObjectsAreEqual(reflect.TypeOf(object), reflect.TypeOf(expectedType)) { + return Fail(t, fmt.Sprintf("Object expected to be of type %v, but was %v", reflect.TypeOf(expectedType), reflect.TypeOf(object)), msgAndArgs...) + } + + return true +} + +// Equal asserts that two objects are equal. +// +// assert.Equal(t, 123, 123) +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). Function equality +// cannot be determined and will always fail. +func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if err := validateEqualArgs(expected, actual); err != nil { + return Fail(t, fmt.Sprintf("Invalid operation: %#v == %#v (%s)", + expected, actual, err), msgAndArgs...) + } + + if !ObjectsAreEqual(expected, actual) { + diff := diff(expected, actual) + expected, actual = formatUnequalValues(expected, actual) + return Fail(t, fmt.Sprintf("Not equal: \n"+ + "expected: %s\n"+ + "actual : %s%s", expected, actual, diff), msgAndArgs...) + } + + return true + +} + +// validateEqualArgs checks whether provided arguments can be safely used in the +// Equal/NotEqual functions. +func validateEqualArgs(expected, actual interface{}) error { + if expected == nil && actual == nil { + return nil + } + + if isFunction(expected) || isFunction(actual) { + return errors.New("cannot take func type as argument") + } + return nil +} + +// Same asserts that two pointers reference the same object. +// +// assert.Same(t, ptr1, ptr2) +// +// Both arguments must be pointer variables. Pointer variable sameness is +// determined based on the equality of both type and value. +func Same(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if !samePointers(expected, actual) { + return Fail(t, fmt.Sprintf("Not same: \n"+ + "expected: %p %#v\n"+ + "actual : %p %#v", expected, expected, actual, actual), msgAndArgs...) + } + + return true +} + +// NotSame asserts that two pointers do not reference the same object. +// +// assert.NotSame(t, ptr1, ptr2) +// +// Both arguments must be pointer variables. Pointer variable sameness is +// determined based on the equality of both type and value. +func NotSame(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if samePointers(expected, actual) { + return Fail(t, fmt.Sprintf( + "Expected and actual point to the same object: %p %#v", + expected, expected), msgAndArgs...) + } + return true +} + +// samePointers compares two generic interface objects and returns whether +// they point to the same object +func samePointers(first, second interface{}) bool { + firstPtr, secondPtr := reflect.ValueOf(first), reflect.ValueOf(second) + if firstPtr.Kind() != reflect.Ptr || secondPtr.Kind() != reflect.Ptr { + return false + } + + firstType, secondType := reflect.TypeOf(first), reflect.TypeOf(second) + if firstType != secondType { + return false + } + + // compare pointer addresses + return first == second +} + +// formatUnequalValues takes two values of arbitrary types and returns string +// representations appropriate to be presented to the user. +// +// If the values are not of like type, the returned strings will be prefixed +// with the type name, and the value will be enclosed in parenthesis similar +// to a type conversion in the Go grammar. +func formatUnequalValues(expected, actual interface{}) (e string, a string) { + if reflect.TypeOf(expected) != reflect.TypeOf(actual) { + return fmt.Sprintf("%T(%s)", expected, truncatingFormat(expected)), + fmt.Sprintf("%T(%s)", actual, truncatingFormat(actual)) + } + switch expected.(type) { + case time.Duration: + return fmt.Sprintf("%v", expected), fmt.Sprintf("%v", actual) + } + return truncatingFormat(expected), truncatingFormat(actual) +} + +// truncatingFormat formats the data and truncates it if it's too long. +// +// This helps keep formatted error messages lines from exceeding the +// bufio.MaxScanTokenSize max line length that the go testing framework imposes. +func truncatingFormat(data interface{}) string { + value := fmt.Sprintf("%#v", data) + max := bufio.MaxScanTokenSize - 100 // Give us some space the type info too if needed. + if len(value) > max { + value = value[0:max] + "<... truncated>" + } + return value +} + +// EqualValues asserts that two objects are equal or convertable to the same types +// and equal. +// +// assert.EqualValues(t, uint32(123), int32(123)) +func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if !ObjectsAreEqualValues(expected, actual) { + diff := diff(expected, actual) + expected, actual = formatUnequalValues(expected, actual) + return Fail(t, fmt.Sprintf("Not equal: \n"+ + "expected: %s\n"+ + "actual : %s%s", expected, actual, diff), msgAndArgs...) + } + + return true + +} + +// Exactly asserts that two objects are equal in value and type. +// +// assert.Exactly(t, int32(123), int64(123)) +func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + aType := reflect.TypeOf(expected) + bType := reflect.TypeOf(actual) + + if aType != bType { + return Fail(t, fmt.Sprintf("Types expected to match exactly\n\t%v != %v", aType, bType), msgAndArgs...) + } + + return Equal(t, expected, actual, msgAndArgs...) + +} + +// NotNil asserts that the specified object is not nil. +// +// assert.NotNil(t, err) +func NotNil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if !isNil(object) { + return true + } + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Fail(t, "Expected value not to be nil.", msgAndArgs...) +} + +// containsKind checks if a specified kind in the slice of kinds. +func containsKind(kinds []reflect.Kind, kind reflect.Kind) bool { + for i := 0; i < len(kinds); i++ { + if kind == kinds[i] { + return true + } + } + + return false +} + +// isNil checks if a specified object is nil or not, without Failing. +func isNil(object interface{}) bool { + if object == nil { + return true + } + + value := reflect.ValueOf(object) + kind := value.Kind() + isNilableKind := containsKind( + []reflect.Kind{ + reflect.Chan, reflect.Func, + reflect.Interface, reflect.Map, + reflect.Ptr, reflect.Slice}, + kind) + + if isNilableKind && value.IsNil() { + return true + } + + return false +} + +// Nil asserts that the specified object is nil. +// +// assert.Nil(t, err) +func Nil(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + if isNil(object) { + return true + } + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Fail(t, fmt.Sprintf("Expected nil, but got: %#v", object), msgAndArgs...) +} + +// isEmpty gets whether the specified object is considered empty or not. +func isEmpty(object interface{}) bool { + + // get nil case out of the way + if object == nil { + return true + } + + objValue := reflect.ValueOf(object) + + switch objValue.Kind() { + // collection types are empty when they have no element + case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: + return objValue.Len() == 0 + // pointers are empty if nil or if the value they point to is empty + case reflect.Ptr: + if objValue.IsNil() { + return true + } + deref := objValue.Elem().Interface() + return isEmpty(deref) + // for all other types, compare against the zero value + default: + zero := reflect.Zero(objValue.Type()) + return reflect.DeepEqual(object, zero.Interface()) + } +} + +// Empty asserts that the specified object is empty. I.e. nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// assert.Empty(t, obj) +func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + pass := isEmpty(object) + if !pass { + if h, ok := t.(tHelper); ok { + h.Helper() + } + Fail(t, fmt.Sprintf("Should be empty, but was %v", object), msgAndArgs...) + } + + return pass + +} + +// NotEmpty asserts that the specified object is NOT empty. I.e. not nil, "", false, 0 or either +// a slice or a channel with len == 0. +// +// if assert.NotEmpty(t, obj) { +// assert.Equal(t, "two", obj[1]) +// } +func NotEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool { + pass := !isEmpty(object) + if !pass { + if h, ok := t.(tHelper); ok { + h.Helper() + } + Fail(t, fmt.Sprintf("Should NOT be empty, but was %v", object), msgAndArgs...) + } + + return pass + +} + +// getLen try to get length of object. +// return (false, 0) if impossible. +func getLen(x interface{}) (ok bool, length int) { + v := reflect.ValueOf(x) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + return true, v.Len() +} + +// Len asserts that the specified object has specific length. +// Len also fails if the object has a type that len() not accept. +// +// assert.Len(t, mySlice, 3) +func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + ok, l := getLen(object) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", object), msgAndArgs...) + } + + if l != length { + return Fail(t, fmt.Sprintf("\"%s\" should have %d item(s), but has %d", object, length, l), msgAndArgs...) + } + return true +} + +// True asserts that the specified value is true. +// +// assert.True(t, myBool) +func True(t TestingT, value bool, msgAndArgs ...interface{}) bool { + if !value { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Fail(t, "Should be true", msgAndArgs...) + } + + return true + +} + +// False asserts that the specified value is false. +// +// assert.False(t, myBool) +func False(t TestingT, value bool, msgAndArgs ...interface{}) bool { + if value { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Fail(t, "Should be false", msgAndArgs...) + } + + return true + +} + +// NotEqual asserts that the specified values are NOT equal. +// +// assert.NotEqual(t, obj1, obj2) +// +// Pointer variable equality is determined based on the equality of the +// referenced values (as opposed to the memory addresses). +func NotEqual(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if err := validateEqualArgs(expected, actual); err != nil { + return Fail(t, fmt.Sprintf("Invalid operation: %#v != %#v (%s)", + expected, actual, err), msgAndArgs...) + } + + if ObjectsAreEqual(expected, actual) { + return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + } + + return true + +} + +// NotEqualValues asserts that two objects are not equal even when converted to the same type +// +// assert.NotEqualValues(t, obj1, obj2) +func NotEqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if ObjectsAreEqualValues(expected, actual) { + return Fail(t, fmt.Sprintf("Should not be: %#v\n", actual), msgAndArgs...) + } + + return true +} + +// containsElement try loop over the list check if the list includes the element. +// return (false, false) if impossible. +// return (true, false) if element was not found. +// return (true, true) if element was found. +func includeElement(list interface{}, element interface{}) (ok, found bool) { + + listValue := reflect.ValueOf(list) + listKind := reflect.TypeOf(list).Kind() + defer func() { + if e := recover(); e != nil { + ok = false + found = false + } + }() + + if listKind == reflect.String { + elementValue := reflect.ValueOf(element) + return true, strings.Contains(listValue.String(), elementValue.String()) + } + + if listKind == reflect.Map { + mapKeys := listValue.MapKeys() + for i := 0; i < len(mapKeys); i++ { + if ObjectsAreEqual(mapKeys[i].Interface(), element) { + return true, true + } + } + return true, false + } + + for i := 0; i < listValue.Len(); i++ { + if ObjectsAreEqual(listValue.Index(i).Interface(), element) { + return true, true + } + } + return true, false + +} + +// Contains asserts that the specified string, list(array, slice...) or map contains the +// specified substring or element. +// +// assert.Contains(t, "Hello World", "World") +// assert.Contains(t, ["Hello", "World"], "World") +// assert.Contains(t, {"Hello": "World"}, "Hello") +func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + ok, found := includeElement(s, contains) + if !ok { + return Fail(t, fmt.Sprintf("%#v could not be applied builtin len()", s), msgAndArgs...) + } + if !found { + return Fail(t, fmt.Sprintf("%#v does not contain %#v", s, contains), msgAndArgs...) + } + + return true + +} + +// NotContains asserts that the specified string, list(array, slice...) or map does NOT contain the +// specified substring or element. +// +// assert.NotContains(t, "Hello World", "Earth") +// assert.NotContains(t, ["Hello", "World"], "Earth") +// assert.NotContains(t, {"Hello": "World"}, "Earth") +func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + ok, found := includeElement(s, contains) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", s), msgAndArgs...) + } + if found { + return Fail(t, fmt.Sprintf("\"%s\" should not contain \"%s\"", s, contains), msgAndArgs...) + } + + return true + +} + +// Subset asserts that the specified list(array, slice...) contains all +// elements given in the specified subset(array, slice...). +// +// assert.Subset(t, [1, 2, 3], [1, 2], "But [1, 2, 3] does contain [1, 2]") +func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if subset == nil { + return true // we consider nil to be equal to the nil set + } + + subsetValue := reflect.ValueOf(subset) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + + listKind := reflect.TypeOf(list).Kind() + subsetKind := reflect.TypeOf(subset).Kind() + + if listKind != reflect.Array && listKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) + } + + if subsetKind != reflect.Array && subsetKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) + } + + for i := 0; i < subsetValue.Len(); i++ { + element := subsetValue.Index(i).Interface() + ok, found := includeElement(list, element) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) + } + if !found { + return Fail(t, fmt.Sprintf("\"%s\" does not contain \"%s\"", list, element), msgAndArgs...) + } + } + + return true +} + +// NotSubset asserts that the specified list(array, slice...) contains not all +// elements given in the specified subset(array, slice...). +// +// assert.NotSubset(t, [1, 3, 4], [1, 2], "But [1, 3, 4] does not contain [1, 2]") +func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if subset == nil { + return Fail(t, fmt.Sprintf("nil is the empty set which is a subset of every set"), msgAndArgs...) + } + + subsetValue := reflect.ValueOf(subset) + defer func() { + if e := recover(); e != nil { + ok = false + } + }() + + listKind := reflect.TypeOf(list).Kind() + subsetKind := reflect.TypeOf(subset).Kind() + + if listKind != reflect.Array && listKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", list, listKind), msgAndArgs...) + } + + if subsetKind != reflect.Array && subsetKind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...) + } + + for i := 0; i < subsetValue.Len(); i++ { + element := subsetValue.Index(i).Interface() + ok, found := includeElement(list, element) + if !ok { + return Fail(t, fmt.Sprintf("\"%s\" could not be applied builtin len()", list), msgAndArgs...) + } + if !found { + return true + } + } + + return Fail(t, fmt.Sprintf("%q is a subset of %q", subset, list), msgAndArgs...) +} + +// ElementsMatch asserts that the specified listA(array, slice...) is equal to specified +// listB(array, slice...) ignoring the order of the elements. If there are duplicate elements, +// the number of appearances of each of them in both lists should match. +// +// assert.ElementsMatch(t, [1, 3, 2, 3], [1, 3, 3, 2]) +func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool) { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if isEmpty(listA) && isEmpty(listB) { + return true + } + + if !isList(t, listA, msgAndArgs...) || !isList(t, listB, msgAndArgs...) { + return false + } + + extraA, extraB := diffLists(listA, listB) + + if len(extraA) == 0 && len(extraB) == 0 { + return true + } + + return Fail(t, formatListDiff(listA, listB, extraA, extraB), msgAndArgs...) +} + +// isList checks that the provided value is array or slice. +func isList(t TestingT, list interface{}, msgAndArgs ...interface{}) (ok bool) { + kind := reflect.TypeOf(list).Kind() + if kind != reflect.Array && kind != reflect.Slice { + return Fail(t, fmt.Sprintf("%q has an unsupported type %s, expecting array or slice", list, kind), + msgAndArgs...) + } + return true +} + +// diffLists diffs two arrays/slices and returns slices of elements that are only in A and only in B. +// If some element is present multiple times, each instance is counted separately (e.g. if something is 2x in A and +// 5x in B, it will be 0x in extraA and 3x in extraB). The order of items in both lists is ignored. +func diffLists(listA, listB interface{}) (extraA, extraB []interface{}) { + aValue := reflect.ValueOf(listA) + bValue := reflect.ValueOf(listB) + + aLen := aValue.Len() + bLen := bValue.Len() + + // Mark indexes in bValue that we already used + visited := make([]bool, bLen) + for i := 0; i < aLen; i++ { + element := aValue.Index(i).Interface() + found := false + for j := 0; j < bLen; j++ { + if visited[j] { + continue + } + if ObjectsAreEqual(bValue.Index(j).Interface(), element) { + visited[j] = true + found = true + break + } + } + if !found { + extraA = append(extraA, element) + } + } + + for j := 0; j < bLen; j++ { + if visited[j] { + continue + } + extraB = append(extraB, bValue.Index(j).Interface()) + } + + return +} + +func formatListDiff(listA, listB interface{}, extraA, extraB []interface{}) string { + var msg bytes.Buffer + + msg.WriteString("elements differ") + if len(extraA) > 0 { + msg.WriteString("\n\nextra elements in list A:\n") + msg.WriteString(spewConfig.Sdump(extraA)) + } + if len(extraB) > 0 { + msg.WriteString("\n\nextra elements in list B:\n") + msg.WriteString(spewConfig.Sdump(extraB)) + } + msg.WriteString("\n\nlistA:\n") + msg.WriteString(spewConfig.Sdump(listA)) + msg.WriteString("\n\nlistB:\n") + msg.WriteString(spewConfig.Sdump(listB)) + + return msg.String() +} + +// Condition uses a Comparison to assert a complex condition. +func Condition(t TestingT, comp Comparison, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + result := comp() + if !result { + Fail(t, "Condition failed!", msgAndArgs...) + } + return result +} + +// PanicTestFunc defines a func that should be passed to the assert.Panics and assert.NotPanics +// methods, and represents a simple func that takes no arguments, and returns nothing. +type PanicTestFunc func() + +// didPanic returns true if the function passed to it panics. Otherwise, it returns false. +func didPanic(f PanicTestFunc) (bool, interface{}, string) { + + didPanic := false + var message interface{} + var stack string + func() { + + defer func() { + if message = recover(); message != nil { + didPanic = true + stack = string(debug.Stack()) + } + }() + + // call the target function + f() + + }() + + return didPanic, message, stack + +} + +// Panics asserts that the code inside the specified PanicTestFunc panics. +// +// assert.Panics(t, func(){ GoCrazy() }) +func Panics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if funcDidPanic, panicValue, _ := didPanic(f); !funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) + } + + return true +} + +// PanicsWithValue asserts that the code inside the specified PanicTestFunc panics, and that +// the recovered panic value equals the expected panic value. +// +// assert.PanicsWithValue(t, "crazy error", func(){ GoCrazy() }) +func PanicsWithValue(t TestingT, expected interface{}, f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + funcDidPanic, panicValue, panickedStack := didPanic(f) + if !funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) + } + if panicValue != expected { + return Fail(t, fmt.Sprintf("func %#v should panic with value:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, expected, panicValue, panickedStack), msgAndArgs...) + } + + return true +} + +// PanicsWithError asserts that the code inside the specified PanicTestFunc +// panics, and that the recovered panic value is an error that satisfies the +// EqualError comparison. +// +// assert.PanicsWithError(t, "crazy error", func(){ GoCrazy() }) +func PanicsWithError(t TestingT, errString string, f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + funcDidPanic, panicValue, panickedStack := didPanic(f) + if !funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should panic\n\tPanic value:\t%#v", f, panicValue), msgAndArgs...) + } + panicErr, ok := panicValue.(error) + if !ok || panicErr.Error() != errString { + return Fail(t, fmt.Sprintf("func %#v should panic with error message:\t%#v\n\tPanic value:\t%#v\n\tPanic stack:\t%s", f, errString, panicValue, panickedStack), msgAndArgs...) + } + + return true +} + +// NotPanics asserts that the code inside the specified PanicTestFunc does NOT panic. +// +// assert.NotPanics(t, func(){ RemainCalm() }) +func NotPanics(t TestingT, f PanicTestFunc, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + if funcDidPanic, panicValue, panickedStack := didPanic(f); funcDidPanic { + return Fail(t, fmt.Sprintf("func %#v should not panic\n\tPanic value:\t%v\n\tPanic stack:\t%s", f, panicValue, panickedStack), msgAndArgs...) + } + + return true +} + +// WithinDuration asserts that the two times are within duration delta of each other. +// +// assert.WithinDuration(t, time.Now(), time.Now(), 10*time.Second) +func WithinDuration(t TestingT, expected, actual time.Time, delta time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + dt := expected.Sub(actual) + if dt < -delta || dt > delta { + return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) + } + + return true +} + +func toFloat(x interface{}) (float64, bool) { + var xf float64 + xok := true + + switch xn := x.(type) { + case uint: + xf = float64(xn) + case uint8: + xf = float64(xn) + case uint16: + xf = float64(xn) + case uint32: + xf = float64(xn) + case uint64: + xf = float64(xn) + case int: + xf = float64(xn) + case int8: + xf = float64(xn) + case int16: + xf = float64(xn) + case int32: + xf = float64(xn) + case int64: + xf = float64(xn) + case float32: + xf = float64(xn) + case float64: + xf = xn + case time.Duration: + xf = float64(xn) + default: + xok = false + } + + return xf, xok +} + +// InDelta asserts that the two numerals are within delta of each other. +// +// assert.InDelta(t, math.Pi, 22/7.0, 0.01) +func InDelta(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + af, aok := toFloat(expected) + bf, bok := toFloat(actual) + + if !aok || !bok { + return Fail(t, fmt.Sprintf("Parameters must be numerical"), msgAndArgs...) + } + + if math.IsNaN(af) { + return Fail(t, fmt.Sprintf("Expected must not be NaN"), msgAndArgs...) + } + + if math.IsNaN(bf) { + return Fail(t, fmt.Sprintf("Expected %v with delta %v, but was NaN", expected, delta), msgAndArgs...) + } + + dt := af - bf + if dt < -delta || dt > delta { + return Fail(t, fmt.Sprintf("Max difference between %v and %v allowed is %v, but difference was %v", expected, actual, delta, dt), msgAndArgs...) + } + + return true +} + +// InDeltaSlice is the same as InDelta, except it compares two slices. +func InDeltaSlice(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Slice || + reflect.TypeOf(expected).Kind() != reflect.Slice { + return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) + } + + actualSlice := reflect.ValueOf(actual) + expectedSlice := reflect.ValueOf(expected) + + for i := 0; i < actualSlice.Len(); i++ { + result := InDelta(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), delta, msgAndArgs...) + if !result { + return result + } + } + + return true +} + +// InDeltaMapValues is the same as InDelta, but it compares all values between two maps. Both maps must have exactly the same keys. +func InDeltaMapValues(t TestingT, expected, actual interface{}, delta float64, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Map || + reflect.TypeOf(expected).Kind() != reflect.Map { + return Fail(t, "Arguments must be maps", msgAndArgs...) + } + + expectedMap := reflect.ValueOf(expected) + actualMap := reflect.ValueOf(actual) + + if expectedMap.Len() != actualMap.Len() { + return Fail(t, "Arguments must have the same number of keys", msgAndArgs...) + } + + for _, k := range expectedMap.MapKeys() { + ev := expectedMap.MapIndex(k) + av := actualMap.MapIndex(k) + + if !ev.IsValid() { + return Fail(t, fmt.Sprintf("missing key %q in expected map", k), msgAndArgs...) + } + + if !av.IsValid() { + return Fail(t, fmt.Sprintf("missing key %q in actual map", k), msgAndArgs...) + } + + if !InDelta( + t, + ev.Interface(), + av.Interface(), + delta, + msgAndArgs..., + ) { + return false + } + } + + return true +} + +func calcRelativeError(expected, actual interface{}) (float64, error) { + af, aok := toFloat(expected) + if !aok { + return 0, fmt.Errorf("expected value %q cannot be converted to float", expected) + } + if math.IsNaN(af) { + return 0, errors.New("expected value must not be NaN") + } + if af == 0 { + return 0, fmt.Errorf("expected value must have a value other than zero to calculate the relative error") + } + bf, bok := toFloat(actual) + if !bok { + return 0, fmt.Errorf("actual value %q cannot be converted to float", actual) + } + if math.IsNaN(bf) { + return 0, errors.New("actual value must not be NaN") + } + + return math.Abs(af-bf) / math.Abs(af), nil +} + +// InEpsilon asserts that expected and actual have a relative error less than epsilon +func InEpsilon(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if math.IsNaN(epsilon) { + return Fail(t, "epsilon must not be NaN") + } + actualEpsilon, err := calcRelativeError(expected, actual) + if err != nil { + return Fail(t, err.Error(), msgAndArgs...) + } + if actualEpsilon > epsilon { + return Fail(t, fmt.Sprintf("Relative error is too high: %#v (expected)\n"+ + " < %#v (actual)", epsilon, actualEpsilon), msgAndArgs...) + } + + return true +} + +// InEpsilonSlice is the same as InEpsilon, except it compares each value from two slices. +func InEpsilonSlice(t TestingT, expected, actual interface{}, epsilon float64, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if expected == nil || actual == nil || + reflect.TypeOf(actual).Kind() != reflect.Slice || + reflect.TypeOf(expected).Kind() != reflect.Slice { + return Fail(t, fmt.Sprintf("Parameters must be slice"), msgAndArgs...) + } + + actualSlice := reflect.ValueOf(actual) + expectedSlice := reflect.ValueOf(expected) + + for i := 0; i < actualSlice.Len(); i++ { + result := InEpsilon(t, actualSlice.Index(i).Interface(), expectedSlice.Index(i).Interface(), epsilon) + if !result { + return result + } + } + + return true +} + +/* + Errors +*/ + +// NoError asserts that a function returned no error (i.e. `nil`). +// +// actualObj, err := SomeFunction() +// if assert.NoError(t, err) { +// assert.Equal(t, expectedObj, actualObj) +// } +func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool { + if err != nil { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Fail(t, fmt.Sprintf("Received unexpected error:\n%+v", err), msgAndArgs...) + } + + return true +} + +// Error asserts that a function returned an error (i.e. not `nil`). +// +// actualObj, err := SomeFunction() +// if assert.Error(t, err) { +// assert.Equal(t, expectedError, err) +// } +func Error(t TestingT, err error, msgAndArgs ...interface{}) bool { + if err == nil { + if h, ok := t.(tHelper); ok { + h.Helper() + } + return Fail(t, "An error is expected but got nil.", msgAndArgs...) + } + + return true +} + +// EqualError asserts that a function returned an error (i.e. not `nil`) +// and that it is equal to the provided error. +// +// actualObj, err := SomeFunction() +// assert.EqualError(t, err, expectedErrorString) +func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if !Error(t, theError, msgAndArgs...) { + return false + } + expected := errString + actual := theError.Error() + // don't need to use deep equals here, we know they are both strings + if expected != actual { + return Fail(t, fmt.Sprintf("Error message not equal:\n"+ + "expected: %q\n"+ + "actual : %q", expected, actual), msgAndArgs...) + } + return true +} + +// matchRegexp return true if a specified regexp matches a string. +func matchRegexp(rx interface{}, str interface{}) bool { + + var r *regexp.Regexp + if rr, ok := rx.(*regexp.Regexp); ok { + r = rr + } else { + r = regexp.MustCompile(fmt.Sprint(rx)) + } + + return (r.FindStringIndex(fmt.Sprint(str)) != nil) + +} + +// Regexp asserts that a specified regexp matches a string. +// +// assert.Regexp(t, regexp.MustCompile("start"), "it's starting") +// assert.Regexp(t, "start...$", "it's not starting") +func Regexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + match := matchRegexp(rx, str) + + if !match { + Fail(t, fmt.Sprintf("Expect \"%v\" to match \"%v\"", str, rx), msgAndArgs...) + } + + return match +} + +// NotRegexp asserts that a specified regexp does not match a string. +// +// assert.NotRegexp(t, regexp.MustCompile("starts"), "it's starting") +// assert.NotRegexp(t, "^start", "it's not starting") +func NotRegexp(t TestingT, rx interface{}, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + match := matchRegexp(rx, str) + + if match { + Fail(t, fmt.Sprintf("Expect \"%v\" to NOT match \"%v\"", str, rx), msgAndArgs...) + } + + return !match + +} + +// Zero asserts that i is the zero value for its type. +func Zero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if i != nil && !reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { + return Fail(t, fmt.Sprintf("Should be zero, but was %v", i), msgAndArgs...) + } + return true +} + +// NotZero asserts that i is not the zero value for its type. +func NotZero(t TestingT, i interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + if i == nil || reflect.DeepEqual(i, reflect.Zero(reflect.TypeOf(i)).Interface()) { + return Fail(t, fmt.Sprintf("Should not be zero, but was %v", i), msgAndArgs...) + } + return true +} + +// FileExists checks whether a file exists in the given path. It also fails if +// the path points to a directory or there is an error when trying to check the file. +func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + info, err := os.Lstat(path) + if err != nil { + if os.IsNotExist(err) { + return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) + } + return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) + } + if info.IsDir() { + return Fail(t, fmt.Sprintf("%q is a directory", path), msgAndArgs...) + } + return true +} + +// NoFileExists checks whether a file does not exist in a given path. It fails +// if the path points to an existing _file_ only. +func NoFileExists(t TestingT, path string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + info, err := os.Lstat(path) + if err != nil { + return true + } + if info.IsDir() { + return true + } + return Fail(t, fmt.Sprintf("file %q exists", path), msgAndArgs...) +} + +// DirExists checks whether a directory exists in the given path. It also fails +// if the path is a file rather a directory or there is an error checking whether it exists. +func DirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + info, err := os.Lstat(path) + if err != nil { + if os.IsNotExist(err) { + return Fail(t, fmt.Sprintf("unable to find file %q", path), msgAndArgs...) + } + return Fail(t, fmt.Sprintf("error when running os.Lstat(%q): %s", path, err), msgAndArgs...) + } + if !info.IsDir() { + return Fail(t, fmt.Sprintf("%q is a file", path), msgAndArgs...) + } + return true +} + +// NoDirExists checks whether a directory does not exist in the given path. +// It fails if the path points to an existing _directory_ only. +func NoDirExists(t TestingT, path string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + info, err := os.Lstat(path) + if err != nil { + if os.IsNotExist(err) { + return true + } + return true + } + if !info.IsDir() { + return true + } + return Fail(t, fmt.Sprintf("directory %q exists", path), msgAndArgs...) +} + +// JSONEq asserts that two JSON strings are equivalent. +// +// assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) +func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + var expectedJSONAsInterface, actualJSONAsInterface interface{} + + if err := json.Unmarshal([]byte(expected), &expectedJSONAsInterface); err != nil { + return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid json.\nJSON parsing error: '%s'", expected, err.Error()), msgAndArgs...) + } + + if err := json.Unmarshal([]byte(actual), &actualJSONAsInterface); err != nil { + return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid json.\nJSON parsing error: '%s'", actual, err.Error()), msgAndArgs...) + } + + return Equal(t, expectedJSONAsInterface, actualJSONAsInterface, msgAndArgs...) +} + +// YAMLEq asserts that two YAML strings are equivalent. +func YAMLEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + var expectedYAMLAsInterface, actualYAMLAsInterface interface{} + + if err := yaml.Unmarshal([]byte(expected), &expectedYAMLAsInterface); err != nil { + return Fail(t, fmt.Sprintf("Expected value ('%s') is not valid yaml.\nYAML parsing error: '%s'", expected, err.Error()), msgAndArgs...) + } + + if err := yaml.Unmarshal([]byte(actual), &actualYAMLAsInterface); err != nil { + return Fail(t, fmt.Sprintf("Input ('%s') needs to be valid yaml.\nYAML error: '%s'", actual, err.Error()), msgAndArgs...) + } + + return Equal(t, expectedYAMLAsInterface, actualYAMLAsInterface, msgAndArgs...) +} + +func typeAndKind(v interface{}) (reflect.Type, reflect.Kind) { + t := reflect.TypeOf(v) + k := t.Kind() + + if k == reflect.Ptr { + t = t.Elem() + k = t.Kind() + } + return t, k +} + +// diff returns a diff of both values as long as both are of the same type and +// are a struct, map, slice, array or string. Otherwise it returns an empty string. +func diff(expected interface{}, actual interface{}) string { + if expected == nil || actual == nil { + return "" + } + + et, ek := typeAndKind(expected) + at, _ := typeAndKind(actual) + + if et != at { + return "" + } + + if ek != reflect.Struct && ek != reflect.Map && ek != reflect.Slice && ek != reflect.Array && ek != reflect.String { + return "" + } + + var e, a string + if et != reflect.TypeOf("") { + e = spewConfig.Sdump(expected) + a = spewConfig.Sdump(actual) + } else { + e = reflect.ValueOf(expected).String() + a = reflect.ValueOf(actual).String() + } + + diff, _ := difflib.GetUnifiedDiffString(difflib.UnifiedDiff{ + A: difflib.SplitLines(e), + B: difflib.SplitLines(a), + FromFile: "Expected", + FromDate: "", + ToFile: "Actual", + ToDate: "", + Context: 1, + }) + + return "\n\nDiff:\n" + diff +} + +func isFunction(arg interface{}) bool { + if arg == nil { + return false + } + return reflect.TypeOf(arg).Kind() == reflect.Func +} + +var spewConfig = spew.ConfigState{ + Indent: " ", + DisablePointerAddresses: true, + DisableCapacities: true, + SortKeys: true, + DisableMethods: true, +} + +type tHelper interface { + Helper() +} + +// Eventually asserts that given condition will be met in waitFor time, +// periodically checking target function each tick. +// +// assert.Eventually(t, func() bool { return true; }, time.Second, 10*time.Millisecond) +func Eventually(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + ch := make(chan bool, 1) + + timer := time.NewTimer(waitFor) + defer timer.Stop() + + ticker := time.NewTicker(tick) + defer ticker.Stop() + + for tick := ticker.C; ; { + select { + case <-timer.C: + return Fail(t, "Condition never satisfied", msgAndArgs...) + case <-tick: + tick = nil + go func() { ch <- condition() }() + case v := <-ch: + if v { + return true + } + tick = ticker.C + } + } +} + +// Never asserts that the given condition doesn't satisfy in waitFor time, +// periodically checking the target function each tick. +// +// assert.Never(t, func() bool { return false; }, time.Second, 10*time.Millisecond) +func Never(t TestingT, condition func() bool, waitFor time.Duration, tick time.Duration, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + + ch := make(chan bool, 1) + + timer := time.NewTimer(waitFor) + defer timer.Stop() + + ticker := time.NewTicker(tick) + defer ticker.Stop() + + for tick := ticker.C; ; { + select { + case <-timer.C: + return true + case <-tick: + tick = nil + go func() { ch <- condition() }() + case v := <-ch: + if v { + return Fail(t, "Condition satisfied", msgAndArgs...) + } + tick = ticker.C + } + } +} diff --git a/vendor/github.com/stretchr/testify/assert/doc.go b/vendor/github.com/stretchr/testify/assert/doc.go new file mode 100644 index 0000000000..c9dccc4d6c --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/doc.go @@ -0,0 +1,45 @@ +// Package assert provides a set of comprehensive testing tools for use with the normal Go testing system. +// +// Example Usage +// +// The following is a complete example using assert in a standard test function: +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) +// +// func TestSomething(t *testing.T) { +// +// var a string = "Hello" +// var b string = "Hello" +// +// assert.Equal(t, a, b, "The two words should be the same.") +// +// } +// +// if you assert many times, use the format below: +// +// import ( +// "testing" +// "github.com/stretchr/testify/assert" +// ) +// +// func TestSomething(t *testing.T) { +// assert := assert.New(t) +// +// var a string = "Hello" +// var b string = "Hello" +// +// assert.Equal(a, b, "The two words should be the same.") +// } +// +// Assertions +// +// Assertions allow you to easily write test code, and are global funcs in the `assert` package. +// All assertion functions take, as the first argument, the `*testing.T` object provided by the +// testing framework. This allows the assertion funcs to write the failings and other details to +// the correct place. +// +// Every assertion function also takes an optional string message as the final argument, +// allowing custom error messages to be appended to the message the assertion method outputs. +package assert diff --git a/vendor/github.com/stretchr/testify/assert/errors.go b/vendor/github.com/stretchr/testify/assert/errors.go new file mode 100644 index 0000000000..ac9dc9d1d6 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/errors.go @@ -0,0 +1,10 @@ +package assert + +import ( + "errors" +) + +// AnError is an error instance useful for testing. If the code does not care +// about error specifics, and only needs to return the error for example, this +// error should be used to make the test code more readable. +var AnError = errors.New("assert.AnError general error for testing") diff --git a/vendor/github.com/stretchr/testify/assert/forward_assertions.go b/vendor/github.com/stretchr/testify/assert/forward_assertions.go new file mode 100644 index 0000000000..df189d2348 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/forward_assertions.go @@ -0,0 +1,16 @@ +package assert + +// Assertions provides assertion methods around the +// TestingT interface. +type Assertions struct { + t TestingT +} + +// New makes a new Assertions object for the specified TestingT. +func New(t TestingT) *Assertions { + return &Assertions{ + t: t, + } +} + +//go:generate sh -c "cd ../_codegen && go build && cd - && ../_codegen/_codegen -output-package=assert -template=assertion_forward.go.tmpl -include-format-funcs" diff --git a/vendor/github.com/stretchr/testify/assert/http_assertions.go b/vendor/github.com/stretchr/testify/assert/http_assertions.go new file mode 100644 index 0000000000..4ed341dd28 --- /dev/null +++ b/vendor/github.com/stretchr/testify/assert/http_assertions.go @@ -0,0 +1,162 @@ +package assert + +import ( + "fmt" + "net/http" + "net/http/httptest" + "net/url" + "strings" +) + +// httpCode is a helper that returns HTTP code of the response. It returns -1 and +// an error if building a new request fails. +func httpCode(handler http.HandlerFunc, method, url string, values url.Values) (int, error) { + w := httptest.NewRecorder() + req, err := http.NewRequest(method, url, nil) + if err != nil { + return -1, err + } + req.URL.RawQuery = values.Encode() + handler(w, req) + return w.Code, nil +} + +// HTTPSuccess asserts that a specified handler returns a success status code. +// +// assert.HTTPSuccess(t, myHandler, "POST", "http://www.google.com", nil) +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPSuccess(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + code, err := httpCode(handler, method, url, values) + if err != nil { + Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) + } + + isSuccessCode := code >= http.StatusOK && code <= http.StatusPartialContent + if !isSuccessCode { + Fail(t, fmt.Sprintf("Expected HTTP success status code for %q but received %d", url+"?"+values.Encode(), code)) + } + + return isSuccessCode +} + +// HTTPRedirect asserts that a specified handler returns a redirect status code. +// +// assert.HTTPRedirect(t, myHandler, "GET", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPRedirect(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + code, err := httpCode(handler, method, url, values) + if err != nil { + Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) + } + + isRedirectCode := code >= http.StatusMultipleChoices && code <= http.StatusTemporaryRedirect + if !isRedirectCode { + Fail(t, fmt.Sprintf("Expected HTTP redirect status code for %q but received %d", url+"?"+values.Encode(), code)) + } + + return isRedirectCode +} + +// HTTPError asserts that a specified handler returns an error status code. +// +// assert.HTTPError(t, myHandler, "POST", "/a/b/c", url.Values{"a": []string{"b", "c"}} +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPError(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + code, err := httpCode(handler, method, url, values) + if err != nil { + Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) + } + + isErrorCode := code >= http.StatusBadRequest + if !isErrorCode { + Fail(t, fmt.Sprintf("Expected HTTP error status code for %q but received %d", url+"?"+values.Encode(), code)) + } + + return isErrorCode +} + +// HTTPStatusCode asserts that a specified handler returns a specified status code. +// +// assert.HTTPStatusCode(t, myHandler, "GET", "/notImplemented", nil, 501) +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPStatusCode(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, statuscode int, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + code, err := httpCode(handler, method, url, values) + if err != nil { + Fail(t, fmt.Sprintf("Failed to build test request, got error: %s", err)) + } + + successful := code == statuscode + if !successful { + Fail(t, fmt.Sprintf("Expected HTTP status code %d for %q but received %d", statuscode, url+"?"+values.Encode(), code)) + } + + return successful +} + +// HTTPBody is a helper that returns HTTP body of the response. It returns +// empty string if building a new request fails. +func HTTPBody(handler http.HandlerFunc, method, url string, values url.Values) string { + w := httptest.NewRecorder() + req, err := http.NewRequest(method, url+"?"+values.Encode(), nil) + if err != nil { + return "" + } + handler(w, req) + return w.Body.String() +} + +// HTTPBodyContains asserts that a specified handler returns a +// body that contains a string. +// +// assert.HTTPBodyContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + body := HTTPBody(handler, method, url, values) + + contains := strings.Contains(body, fmt.Sprint(str)) + if !contains { + Fail(t, fmt.Sprintf("Expected response body for \"%s\" to contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) + } + + return contains +} + +// HTTPBodyNotContains asserts that a specified handler returns a +// body that does not contain a string. +// +// assert.HTTPBodyNotContains(t, myHandler, "GET", "www.google.com", nil, "I'm Feeling Lucky") +// +// Returns whether the assertion was successful (true) or not (false). +func HTTPBodyNotContains(t TestingT, handler http.HandlerFunc, method, url string, values url.Values, str interface{}, msgAndArgs ...interface{}) bool { + if h, ok := t.(tHelper); ok { + h.Helper() + } + body := HTTPBody(handler, method, url, values) + + contains := strings.Contains(body, fmt.Sprint(str)) + if contains { + Fail(t, fmt.Sprintf("Expected response body for \"%s\" to NOT contain \"%s\" but found \"%s\"", url+"?"+values.Encode(), str, body)) + } + + return !contains +} diff --git a/vendor/gopkg.in/yaml.v2/apic.go b/vendor/gopkg.in/yaml.v2/apic.go index 1f7e87e672..d2c2308f1f 100644 --- a/vendor/gopkg.in/yaml.v2/apic.go +++ b/vendor/gopkg.in/yaml.v2/apic.go @@ -86,6 +86,7 @@ func yaml_emitter_initialize(emitter *yaml_emitter_t) { raw_buffer: make([]byte, 0, output_raw_buffer_size), states: make([]yaml_emitter_state_t, 0, initial_stack_size), events: make([]yaml_event_t, 0, initial_queue_size), + best_width: -1, } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 4f24461df8..674cd76a56 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -400,7 +400,7 @@ github.com/coreos/go-systemd/v22/daemon github.com/coreos/go-systemd/v22/dbus # github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f github.com/coreos/pkg/capnslog -# github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d +# github.com/cpuguy83/go-md2man/v2 v2.0.0 github.com/cpuguy83/go-md2man/v2/md2man # github.com/cyphar/filepath-securejoin v0.2.2 github.com/cyphar/filepath-securejoin @@ -759,6 +759,8 @@ github.com/pierrec/lz4 github.com/pierrec/lz4/internal/xxh32 # github.com/pkg/errors v0.9.1 github.com/pkg/errors +# github.com/pmezard/go-difflib v1.0.0 +github.com/pmezard/go-difflib/difflib # github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021 github.com/pquerna/cachecontrol github.com/pquerna/cachecontrol/cacheobject @@ -911,6 +913,8 @@ github.com/spf13/afero/mem github.com/spf13/cobra # github.com/spf13/pflag v1.0.5 github.com/spf13/pflag +# github.com/stretchr/testify v1.6.1 +github.com/stretchr/testify/assert # github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2 github.com/syndtr/gocapability/capability # github.com/tchap/go-patricia v2.3.0+incompatible @@ -1287,7 +1291,7 @@ gopkg.in/square/go-jose.v2/json gopkg.in/square/go-jose.v2/jwt # gopkg.in/warnings.v0 v0.1.1 gopkg.in/warnings.v0 -# gopkg.in/yaml.v2 v2.2.8 +# gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v2 # gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 gopkg.in/yaml.v3 From 7657ed2e1336da733173225e4dbec2b623a60220 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 1 Sep 2020 10:43:19 -0700 Subject: [PATCH 4/5] Update pkg/cli/server/server.go Co-authored-by: Jacob Blain Christen --- pkg/cli/server/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cli/server/server.go b/pkg/cli/server/server.go index 56c2ac7166..6eb6c933ed 100644 --- a/pkg/cli/server/server.go +++ b/pkg/cli/server/server.go @@ -266,7 +266,7 @@ func run(app *cli.Context, cfg *cmds.Server) error { } agentConfig := cmds.AgentConfig - agentConfig.Debug = app.GlobalBool("bool") + agentConfig.Debug = app.GlobalBool("debug") agentConfig.DataDir = filepath.Dir(serverConfig.ControlConfig.DataDir) agentConfig.ServerURL = url agentConfig.Token = token From 551a1842ada1d5e1d3502e139f86847a13431112 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Tue, 1 Sep 2020 10:43:28 -0700 Subject: [PATCH 5/5] Update pkg/cli/cmds/config.go Co-authored-by: Jacob Blain Christen --- pkg/cli/cmds/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cli/cmds/config.go b/pkg/cli/cmds/config.go index 1b05078efe..f539e767d9 100644 --- a/pkg/cli/cmds/config.go +++ b/pkg/cli/cmds/config.go @@ -11,7 +11,7 @@ var ( ConfigFlag = cli.StringFlag{ Name: "config,c", Usage: "(config) Load configuration from `FILE`", - EnvVar: "K3S_CONFIG_FILE", + EnvVar: version.ProgramUpper + "_CONFIG_FILE", Value: "/etc/rancher/" + version.Program + "/config.yaml", } )