mirror of
https://github.com/k3s-io/k3s.git
synced 2024-06-07 19:41:36 +00:00
Merge pull request #2180 from ibuildthecloud/configfile
Go back to urfave v1
This commit is contained in:
commit
53b3d0fc56
@ -5,17 +5,18 @@ import (
|
||||
|
||||
"github.com/rancher/k3s/pkg/cli/agent"
|
||||
"github.com/rancher/k3s/pkg/cli/cmds"
|
||||
"github.com/rancher/spur/cli"
|
||||
"github.com/rancher/k3s/pkg/configfilearg"
|
||||
"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),
|
||||
}
|
||||
|
||||
err := app.Run(os.Args)
|
||||
err := app.Run(configfilearg.MustParse(os.Args))
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -12,11 +12,12 @@ 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"
|
||||
"github.com/rancher/spur/cli"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -35,7 +36,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),
|
||||
@ -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)
|
||||
}
|
||||
|
2
go.mod
2
go.mod
@ -86,13 +86,13 @@ 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
|
||||
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
|
||||
|
13
go.sum
13
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=
|
||||
|
7
main.go
7
main.go
@ -14,20 +14,21 @@ 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/rancher/k3s/pkg/configfilearg"
|
||||
"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),
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
|
@ -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,62 @@ 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: SetupDebug(CheckSELinuxFlags),
|
||||
Action: action,
|
||||
Flags: []cli.Flag{
|
||||
&ConfigFlag,
|
||||
&DebugFlag,
|
||||
&VLevel,
|
||||
&VModule,
|
||||
&LogFile,
|
||||
&AlsoLogToStderr,
|
||||
&cli.StringFlag{
|
||||
ConfigFlag,
|
||||
DebugFlag,
|
||||
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 +232,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",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,17 @@
|
||||
package cmds
|
||||
|
||||
import (
|
||||
"github.com/rancher/spur/cli"
|
||||
"github.com/rancher/k3s/pkg/version"
|
||||
"github.com/urfave/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,
|
||||
// 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: version.ProgramUpper + "_CONFIG_FILE",
|
||||
Value: "/etc/rancher/" + version.Program + "/config.yaml",
|
||||
}
|
||||
)
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -5,7 +5,18 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/rancher/k3s/pkg/version"
|
||||
"github.com/rancher/spur/cli"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var (
|
||||
Debug bool
|
||||
DebugFlag = cli.BoolFlag{
|
||||
Name: "debug",
|
||||
Usage: "Turn on debug logs",
|
||||
Destination: &Debug,
|
||||
EnvVar: version.ProgramUpper + "_DEBUG",
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -23,8 +34,22 @@ 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{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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: SetupDebug(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,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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("debug")
|
||||
agentConfig.DataDir = filepath.Dir(serverConfig.ControlConfig.DataDir)
|
||||
agentConfig.ServerURL = url
|
||||
agentConfig.Token = token
|
||||
|
20
pkg/configfilearg/defaultparser.go
Normal file
20
pkg/configfilearg/defaultparser.go
Normal file
@ -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
|
||||
}
|
139
pkg/configfilearg/parser.go
Normal file
139
pkg/configfilearg/parser.go
Normal file
@ -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)
|
||||
}
|
||||
}
|
233
pkg/configfilearg/parser_test.go
Normal file
233
pkg/configfilearg/parser_test.go
Normal file
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
9
pkg/configfilearg/testdata/data.yaml
vendored
Normal file
9
pkg/configfilearg/testdata/data.yaml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
foo-bar: baz
|
||||
a-slice:
|
||||
- 1
|
||||
- "2"
|
||||
- ""
|
||||
- three
|
||||
isempty:
|
||||
c: b
|
||||
islast: true
|
27
vendor/github.com/pmezard/go-difflib/LICENSE
generated
vendored
Normal file
27
vendor/github.com/pmezard/go-difflib/LICENSE
generated
vendored
Normal file
@ -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.
|
772
vendor/github.com/pmezard/go-difflib/difflib/difflib.go
generated
vendored
Normal file
772
vendor/github.com/pmezard/go-difflib/difflib/difflib.go
generated
vendored
Normal file
@ -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 "<P>" lines in HTML files). That may be
|
||||
// because this is the only method of the 3 that has a *concept* of
|
||||
// "junk" <wink>.
|
||||
//
|
||||
// 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
|
||||
}
|
201
vendor/github.com/rancher/spur/LICENSE
generated
vendored
201
vendor/github.com/rancher/spur/LICENSE
generated
vendored
@ -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.
|
2
vendor/github.com/rancher/spur/cli/.flake8
generated
vendored
2
vendor/github.com/rancher/spur/cli/.flake8
generated
vendored
@ -1,2 +0,0 @@
|
||||
[flake8]
|
||||
max-line-length = 120
|
7
vendor/github.com/rancher/spur/cli/.gitignore
generated
vendored
7
vendor/github.com/rancher/spur/cli/.gitignore
generated
vendored
@ -1,7 +0,0 @@
|
||||
*.coverprofile
|
||||
*.orig
|
||||
node_modules/
|
||||
vendor
|
||||
.idea
|
||||
internal/*/built-example
|
||||
coverage.txt
|
40
vendor/github.com/rancher/spur/cli/_flag.template.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/_flag.template.go
generated
vendored
@ -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__)
|
||||
}
|
23
vendor/github.com/rancher/spur/cli/altsrc/conf_file_loader.go
generated
vendored
23
vendor/github.com/rancher/spur/cli/altsrc/conf_file_loader.go
generated
vendored
@ -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
|
||||
}
|
||||
}
|
49
vendor/github.com/rancher/spur/cli/altsrc/map_input_source.go
generated
vendored
49
vendor/github.com/rancher/spur/cli/altsrc/map_input_source.go
generated
vendored
@ -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
|
||||
}
|
56
vendor/github.com/rancher/spur/cli/altsrc/yaml_file_loader.go
generated
vendored
56
vendor/github.com/rancher/spur/cli/altsrc/yaml_file_loader.go
generated
vendored
@ -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)
|
||||
}
|
540
vendor/github.com/rancher/spur/cli/app.go
generated
vendored
540
vendor/github.com/rancher/spur/cli/app.go
generated
vendored
@ -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))
|
||||
}
|
54
vendor/github.com/rancher/spur/cli/args.go
generated
vendored
54
vendor/github.com/rancher/spur/cli/args.go
generated
vendored
@ -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
|
||||
}
|
79
vendor/github.com/rancher/spur/cli/category.go
generated
vendored
79
vendor/github.com/rancher/spur/cli/category.go
generated
vendored
@ -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
|
||||
}
|
301
vendor/github.com/rancher/spur/cli/command.go
generated
vendored
301
vendor/github.com/rancher/spur/cli/command.go
generated
vendored
@ -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
|
||||
}
|
275
vendor/github.com/rancher/spur/cli/context.go
generated
vendored
275
vendor/github.com/rancher/spur/cli/context.go
generated
vendored
@ -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
|
||||
}
|
160
vendor/github.com/rancher/spur/cli/docs.go
generated
vendored
160
vendor/github.com/rancher/spur/cli/docs.go
generated
vendored
@ -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
|
||||
}
|
141
vendor/github.com/rancher/spur/cli/errors.go
generated
vendored
141
vendor/github.com/rancher/spur/cli/errors.go
generated
vendored
@ -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
|
||||
}
|
178
vendor/github.com/rancher/spur/cli/fish.go
generated
vendored
178
vendor/github.com/rancher/spur/cli/fish.go
generated
vendored
@ -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)
|
||||
}
|
318
vendor/github.com/rancher/spur/cli/flag.go
generated
vendored
318
vendor/github.com/rancher/spur/cli/flag.go
generated
vendored
@ -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
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_bool.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_bool.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_boolSlice.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_boolSlice.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_duration.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_duration.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_durationSlice.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_durationSlice.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_float64.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_float64.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_float64Slice.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_float64Slice.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_int.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_int.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_int64.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_int64.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_int64Slice.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_int64Slice.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_intSlice.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_intSlice.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_string.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_string.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_stringSlice.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_stringSlice.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_time.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_time.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_timeSlice.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_timeSlice.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_uint.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_uint.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64Slice.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_uint64Slice.go
generated
vendored
@ -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)
|
||||
}
|
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_uintSlice.go
generated
vendored
40
vendor/github.com/rancher/spur/cli/flag.zz_generated_uintSlice.go
generated
vendored
@ -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)
|
||||
}
|
105
vendor/github.com/rancher/spur/cli/flag_apply.go
generated
vendored
105
vendor/github.com/rancher/spur/cli/flag_apply.go
generated
vendored
@ -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
|
||||
}
|
92
vendor/github.com/rancher/spur/cli/flag_fields.go
generated
vendored
92
vendor/github.com/rancher/spur/cli/flag_fields.go
generated
vendored
@ -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
|
||||
}
|
36
vendor/github.com/rancher/spur/cli/flag_generic.go
generated
vendored
36
vendor/github.com/rancher/spur/cli/flag_generic.go
generated
vendored
@ -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)
|
||||
}
|
44
vendor/github.com/rancher/spur/cli/funcs.go
generated
vendored
44
vendor/github.com/rancher/spur/cli/funcs.go
generated
vendored
@ -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
|
378
vendor/github.com/rancher/spur/cli/help.go
generated
vendored
378
vendor/github.com/rancher/spur/cli/help.go
generated
vendored
@ -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
|
||||
}
|
79
vendor/github.com/rancher/spur/cli/input_source.go
generated
vendored
79
vendor/github.com/rancher/spur/cli/input_source.go
generated
vendored
@ -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())
|
||||
}
|
||||
}
|
95
vendor/github.com/rancher/spur/cli/parse.go
generated
vendored
95
vendor/github.com/rancher/spur/cli/parse.go
generated
vendored
@ -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
|
||||
}
|
29
vendor/github.com/rancher/spur/cli/sort.go
generated
vendored
29
vendor/github.com/rancher/spur/cli/sort.go
generated
vendored
@ -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
|
||||
}
|
120
vendor/github.com/rancher/spur/cli/template.go
generated
vendored
120
vendor/github.com/rancher/spur/cli/template.go
generated
vendored
@ -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 }}`
|
27
vendor/github.com/rancher/spur/flag/LICENSE
generated
vendored
27
vendor/github.com/rancher/spur/flag/LICENSE
generated
vendored
@ -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.
|
35
vendor/github.com/rancher/spur/flag/_flag.template.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/_flag.template.go
generated
vendored
@ -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__)
|
||||
}
|
661
vendor/github.com/rancher/spur/flag/flag.go
generated
vendored
661
vendor/github.com/rancher/spur/flag/flag.go
generated
vendored
@ -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
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_bool.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_bool.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_boolSlice.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_boolSlice.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_duration.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_duration.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_durationSlice.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_durationSlice.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_float64.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_float64.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_float64Slice.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_float64Slice.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_int.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_int.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_int64.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_int64.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_int64Slice.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_int64Slice.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_intSlice.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_intSlice.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_string.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_string.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_stringSlice.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_stringSlice.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_time.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_time.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_timeSlice.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_timeSlice.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_uint.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_uint.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64Slice.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_uint64Slice.go
generated
vendored
@ -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)
|
||||
}
|
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_uintSlice.go
generated
vendored
35
vendor/github.com/rancher/spur/flag/flag.zz_generated_uintSlice.go
generated
vendored
@ -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)
|
||||
}
|
83
vendor/github.com/rancher/spur/flag/flag_generic.go
generated
vendored
83
vendor/github.com/rancher/spur/flag/flag_generic.go
generated
vendored
@ -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)
|
||||
}
|
32
vendor/github.com/rancher/spur/generic/error.go
generated
vendored
32
vendor/github.com/rancher/spur/generic/error.go
generated
vendored
@ -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
|
||||
}
|
241
vendor/github.com/rancher/spur/generic/generic.go
generated
vendored
241
vendor/github.com/rancher/spur/generic/generic.go
generated
vendored
@ -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)
|
||||
}
|
57
vendor/github.com/rancher/spur/generic/string_from.go
generated
vendored
57
vendor/github.com/rancher/spur/generic/string_from.go
generated
vendored
@ -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
|
||||
}
|
||||
}
|
43
vendor/github.com/rancher/spur/generic/string_to.go
generated
vendored
43
vendor/github.com/rancher/spur/generic/string_to.go
generated
vendored
@ -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
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 Jeremy Saenz & Contributors
|
||||
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
|
274
vendor/github.com/stretchr/testify/assert/assertion_compare.go
generated
vendored
Normal file
274
vendor/github.com/stretchr/testify/assert/assertion_compare.go
generated
vendored
Normal file
@ -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
|
||||
}
|
644
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
Normal file
644
vendor/github.com/stretchr/testify/assert/assertion_format.go
generated
vendored
Normal file
@ -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...)...)
|
||||
}
|
5
vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
generated
vendored
Normal file
5
vendor/github.com/stretchr/testify/assert/assertion_format.go.tmpl
generated
vendored
Normal file
@ -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}})
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user