From 4bb6a5fa355c7da2cf58a51bee098d970821d322 Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Wed, 4 Sep 2019 17:31:55 +0200 Subject: [PATCH 1/2] Pin k8s.io/{component-base,apiextensions-apiserver} --- glide.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/glide.yaml b/glide.yaml index fb2f8b27d..40a66bea0 100644 --- a/glide.yaml +++ b/glide.yaml @@ -10,6 +10,10 @@ import: version: kubernetes-1.14.0 - package: k8s.io/kube-aggregator version: kubernetes-1.14.0 +- package: k8s.io/apiextensions-apiserver + version: kubernetes-1.14.0 +- package: k8s.io/component-base + version: kubernetes-1.14.0 - package: github.com/openshift/api version: master - package: github.com/openshift/client-go From 0bcf0b9be762149836bf552ac3752893f6ed89f7 Mon Sep 17 00:00:00 2001 From: "Dr. Stefan Schimanski" Date: Wed, 4 Sep 2019 17:28:35 +0200 Subject: [PATCH 2/2] bump(*): to get library-go with fixed secret logging --- glide.lock | 20 +- .../getsentry/raven-go/Dockerfile.test | 13 + .../test/library-example-with-ext.text.out | 234 +++++++++ .../test/v2.0/yaml/sample-petstore.out | 14 + .../openshift/api/apps/v1/generated.pb.go | 26 +- .../api/authorization/v1/generated.pb.go | 25 +- .../openshift/api/build/v1/generated.pb.go | 26 +- .../openshift/api/config/v1/register.go | 2 + .../openshift/api/config/v1/types_build.go | 9 +- .../openshift/api/config/v1/types_image.go | 7 +- .../openshift/api/config/v1/types_ingress.go | 11 +- .../openshift/api/config/v1/types_network.go | 15 +- .../api/config/v1/types_operatorhub.go | 78 +++ .../openshift/api/config/v1/types_proxy.go | 16 +- .../api/config/v1/types_scheduling.go | 3 +- .../api/config/v1/zz_generated.deepcopy.go | 136 +++++ .../v1/zz_generated.swagger_doc_generated.go | 81 ++- .../openshift/api/image/v1/generated.pb.go | 24 +- .../openshift/api/network/v1/generated.pb.go | 17 +- .../openshift/api/oauth/v1/generated.pb.go | 17 +- .../api/operator/v1/types_network.go | 14 + .../v1/zz_generated.swagger_doc_generated.go | 7 +- .../openshift/api/project/v1/generated.pb.go | 19 +- .../openshift/api/quota/v1/generated.pb.go | 21 +- .../openshift/api/route/v1/generated.pb.go | 21 +- .../openshift/api/security/v1/generated.pb.go | 19 +- .../openshift/api/template/v1/generated.pb.go | 23 +- .../openshift/api/user/v1/generated.pb.go | 19 +- .../github.com/openshift/client-go/glide.lock | 6 +- .../github.com/openshift/library-go/Makefile | 2 +- .../library-go/alpha-build-machinery/doc.go | 14 + .../alpha-build-machinery/make/doc.go | 3 + .../examples/multiple-binaries/Makefile.test | 53 ++ .../alpha-build-machinery/make/lib/doc.go | 3 + .../alpha-build-machinery/make/lib/golang.mk | 5 +- .../alpha-build-machinery/make/targets/doc.go | 3 + .../make/targets/golang/doc.go | 3 + .../make/targets/openshift/doc.go | 3 + .../make/targets/openshift/operator/doc.go | 3 + .../alpha-build-machinery/scripts/doc.go | 3 + .../cmd/crd-schema-gen/generator/generator.go | 391 --------------- .../library-go/cmd/crd-schema-gen/main.go | 15 - .../openshift/library-go/glide.lock | 76 +-- .../openshift/library-go/glide.yaml | 8 - .../pkg/controller/controllercmd/cmd.go | 19 +- .../pkg/controller/controllercmd/flags.go | 3 + .../pkg/controller/fileobserver/observer.go | 22 +- .../fileobserver/observer_polling.go | 4 +- .../oauthclientregistry_test.go | 4 +- .../cloudprovider/observe_cloudprovider.go | 2 +- .../configobserver/proxy/observe_proxy.go | 12 +- .../proxy/observe_proxy_test.go | 26 +- .../dynamic_operator_client.go | 83 ++- .../dynamic_operator_client_test.go | 91 +++- .../operator/resource/resourceapply/core.go | 12 + .../resource/resourceapply/core_test.go | 46 ++ .../staticpod/certsyncpod/certsync_cmd.go | 8 +- .../installer/installer_controller.go | 4 +- .../pkg/operator/staticpod/prune/cmd.go | 2 +- .../library-go/pkg/operator/watchdog/cmd.go | 64 ++- .../pkg/operator/watchdog/cmd_test.go | 1 + .../spf13/cobra/.circleci/config.yml | 73 +-- vendor/github.com/spf13/cobra/.gitignore | 2 + vendor/github.com/spf13/cobra/.travis.yml | 26 +- vendor/github.com/spf13/cobra/README.md | 61 +-- vendor/github.com/spf13/cobra/args.go | 12 + vendor/github.com/spf13/cobra/args_test.go | 46 ++ .../spf13/cobra/bash_completions.go | 92 ++-- .../spf13/cobra/bash_completions.md | 41 +- .../spf13/cobra/bash_completions_test.go | 26 +- vendor/github.com/spf13/cobra/cobra.go | 7 + .../github.com/spf13/cobra/cobra/cmd/add.go | 122 ++--- .../spf13/cobra/cobra/cmd/add_test.go | 92 +--- .../spf13/cobra/cobra/cmd/golden_test.go | 7 +- .../github.com/spf13/cobra/cobra/cmd/init.go | 229 ++------- .../spf13/cobra/cobra/cmd/init_test.go | 87 +--- .../spf13/cobra/cobra/cmd/project.go | 222 +++----- .../spf13/cobra/cobra/cmd/project_test.go | 23 +- .../github.com/spf13/cobra/cobra/cmd/root.go | 3 +- .../cobra/cobra/cmd/testdata/main.go.golden | 29 +- .../cobra/cobra/cmd/testdata/root.go.golden | 124 ++--- .../cobra/cobra/cmd/testdata/test.go.golden | 27 +- .../github.com/spf13/cobra/cobra/tpl/main.go | 153 ++++++ vendor/github.com/spf13/cobra/command.go | 113 ++++- vendor/github.com/spf13/cobra/command_test.go | 171 ++++++- vendor/github.com/spf13/cobra/command_win.go | 8 +- vendor/github.com/spf13/cobra/doc/man_docs.go | 21 +- .../spf13/cobra/doc/man_docs_test.go | 36 ++ vendor/github.com/spf13/cobra/doc/md_docs.go | 4 +- .../spf13/cobra/doc/md_docs_test.go | 24 + .../github.com/spf13/cobra/doc/rest_docs.go | 4 +- .../spf13/cobra/doc/rest_docs_test.go | 23 + vendor/github.com/spf13/cobra/go.mod | 13 + vendor/github.com/spf13/cobra/go.sum | 51 ++ .../spf13/cobra/powershell_completions.go | 100 ++++ .../spf13/cobra/powershell_completions.md | 14 + .../cobra/powershell_completions_test.go | 122 +++++ .../spf13/cobra/shell_completions.go | 85 ++++ .../github.com/spf13/cobra/zsh_completions.go | 358 ++++++++++--- .../github.com/spf13/cobra/zsh_completions.md | 39 ++ .../spf13/cobra/zsh_completions_test.go | 472 ++++++++++++++++-- vendor/github.com/spf13/pflag/bytes.go | 104 ++++ vendor/github.com/spf13/pflag/bytes_test.go | 64 ++- vendor/github.com/spf13/pflag/flag.go | 10 +- vendor/github.com/spf13/pflag/flag_test.go | 5 + .../github.com/spf13/pflag/string_to_int.go | 149 ++++++ .../spf13/pflag/string_to_int_test.go | 156 ++++++ .../spf13/pflag/string_to_string.go | 160 ++++++ .../spf13/pflag/string_to_string_test.go | 162 ++++++ vendor/google.golang.org/appengine/README.md | 27 - .../appengine/capability/capability.go | 17 +- .../datastore/internal/cloudkey/cloudkey.go | 120 ----- .../datastore/internal/cloudpb/entity.pb.go | 344 ------------- .../appengine/datastore/key.go | 4 - .../appengine/datastore/keycompat.go | 89 ---- .../appengine/datastore/keycompat_test.go | 89 ---- .../google.golang.org/appengine/file/file.go | 2 +- vendor/google.golang.org/appengine/go.mod | 9 +- vendor/google.golang.org/appengine/go.sum | 16 - .../k8s.io/component-base/Godeps/Godeps.json | 2 +- vendor/sigs.k8s.io/yaml/.travis.yml | 12 +- vendor/sigs.k8s.io/yaml/OWNERS | 2 - vendor/sigs.k8s.io/yaml/README.md | 12 +- vendor/sigs.k8s.io/yaml/go.mod | 8 - vendor/sigs.k8s.io/yaml/go.sum | 5 - vendor/sigs.k8s.io/yaml/yaml.go | 61 --- vendor/sigs.k8s.io/yaml/yaml_test.go | 122 ----- 127 files changed, 4274 insertions(+), 2550 deletions(-) create mode 100644 vendor/github.com/getsentry/raven-go/Dockerfile.test create mode 100644 vendor/github.com/googleapis/gnostic/test/library-example-with-ext.text.out create mode 100644 vendor/github.com/googleapis/gnostic/test/v2.0/yaml/sample-petstore.out create mode 100644 vendor/github.com/openshift/api/config/v1/types_operatorhub.go create mode 100644 vendor/github.com/openshift/library-go/alpha-build-machinery/doc.go create mode 100644 vendor/github.com/openshift/library-go/alpha-build-machinery/make/doc.go create mode 100644 vendor/github.com/openshift/library-go/alpha-build-machinery/make/examples/multiple-binaries/Makefile.test create mode 100644 vendor/github.com/openshift/library-go/alpha-build-machinery/make/lib/doc.go create mode 100644 vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/doc.go create mode 100644 vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/golang/doc.go create mode 100644 vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/openshift/doc.go create mode 100644 vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/openshift/operator/doc.go create mode 100644 vendor/github.com/openshift/library-go/alpha-build-machinery/scripts/doc.go delete mode 100755 vendor/github.com/openshift/library-go/cmd/crd-schema-gen/generator/generator.go delete mode 100755 vendor/github.com/openshift/library-go/cmd/crd-schema-gen/main.go create mode 100644 vendor/github.com/spf13/cobra/cobra/tpl/main.go create mode 100644 vendor/github.com/spf13/cobra/go.mod create mode 100644 vendor/github.com/spf13/cobra/go.sum create mode 100644 vendor/github.com/spf13/cobra/powershell_completions.go create mode 100644 vendor/github.com/spf13/cobra/powershell_completions.md create mode 100644 vendor/github.com/spf13/cobra/powershell_completions_test.go create mode 100644 vendor/github.com/spf13/cobra/shell_completions.go create mode 100644 vendor/github.com/spf13/cobra/zsh_completions.md create mode 100644 vendor/github.com/spf13/pflag/string_to_int.go create mode 100644 vendor/github.com/spf13/pflag/string_to_int_test.go create mode 100644 vendor/github.com/spf13/pflag/string_to_string.go create mode 100644 vendor/github.com/spf13/pflag/string_to_string_test.go delete mode 100644 vendor/google.golang.org/appengine/datastore/internal/cloudkey/cloudkey.go delete mode 100644 vendor/google.golang.org/appengine/datastore/internal/cloudpb/entity.pb.go delete mode 100644 vendor/google.golang.org/appengine/datastore/keycompat.go delete mode 100644 vendor/google.golang.org/appengine/datastore/keycompat_test.go delete mode 100644 vendor/sigs.k8s.io/yaml/go.mod delete mode 100644 vendor/sigs.k8s.io/yaml/go.sum diff --git a/glide.lock b/glide.lock index 5aa139052..bd6f2f098 100644 --- a/glide.lock +++ b/glide.lock @@ -1,5 +1,5 @@ -hash: 32473b8e5dd398c8f3e2f9089895e9bee8e6312092e0b2b352bbae0290f035a7 -updated: 2019-08-01T23:14:23.721975874-04:00 +hash: 56d1e300bef9eb8c730080f589e3b2d6762644d2ab859b340161f78c869ef319 +updated: 2019-09-04T17:31:26.474804+02:00 imports: - name: github.com/beorn7/perks version: 3ac7bf7a47d159a033b107610db8a1b6575507a4 @@ -104,7 +104,7 @@ imports: - name: github.com/NYTimes/gziphandler version: 56545f4a5d46df9a6648819d1664c3a03a13ffdb - name: github.com/openshift/api - version: 0922aa5a655be314e20a3e0e94f4f2b105100154 + version: 922d36944de3ed37a938bf5d609acfa700d53f7c subpackages: - apps - apps/v1 @@ -150,7 +150,7 @@ imports: - webconsole - webconsole/v1 - name: github.com/openshift/client-go - version: a85ea6a6b3a5d2dbe41582ee35695dd4683e1f02 + version: 5a5508328169b8a6992ea4ef711add89ddce3c6d subpackages: - config/clientset/versioned - config/clientset/versioned/scheme @@ -172,7 +172,7 @@ imports: - operator/listers/operator/v1 - operator/listers/operator/v1alpha1 - name: github.com/openshift/library-go - version: 1810ce5f54ff4a1a4fea05e06024896a4885eb05 + version: 7d4acc018c610623ee1413b1e7aebe2ac675d35f subpackages: - pkg/config/client - pkg/config/clusteroperator/v1helpers @@ -224,9 +224,9 @@ imports: - name: github.com/sirupsen/logrus version: 89742aefa4b206dcf400792f3bd35b542998eb3b - name: github.com/spf13/cobra - version: c439c4fa093711d42e1b01acb1235b52004753c1 + version: f2b07da1e2c38d5f12845a4f607e2e1018cbb1f5 - name: github.com/spf13/pflag - version: 583c0c0531f06d5278b7d917446061adc344b5cd + version: 298182f68c66c05229eb03ac171abe6e309ee79a - name: golang.org/x/crypto version: de0752318171da717af4ce24d0a2e8626afaeb11 subpackages: @@ -270,7 +270,7 @@ imports: subpackages: - rate - name: google.golang.org/appengine - version: fb139bde60fa77cede04f226b4d5a3cf68dcce27 + version: 54a98f90d1c46b7731eb8fb305d2a321c30ef610 subpackages: - internal - internal/base @@ -708,7 +708,7 @@ imports: - util/retry - util/workqueue - name: k8s.io/component-base - version: f0322db00a103489b85cb3835886741a3911636b + version: 4a91899592f42b2f5859587cc5a676a5b94d2ee3 subpackages: - cli/flag - logs @@ -764,5 +764,5 @@ imports: - typed - value - name: sigs.k8s.io/yaml - version: 4cd0c284b15f1735b8cc247df097d262b8903f9f + version: fd68e9863619f6ec2fdd8625fe1f02e7c877e480 testImports: [] diff --git a/vendor/github.com/getsentry/raven-go/Dockerfile.test b/vendor/github.com/getsentry/raven-go/Dockerfile.test new file mode 100644 index 000000000..5089c13c9 --- /dev/null +++ b/vendor/github.com/getsentry/raven-go/Dockerfile.test @@ -0,0 +1,13 @@ +FROM golang:1.7 + +RUN mkdir -p /go/src/github.com/getsentry/raven-go +WORKDIR /go/src/github.com/getsentry/raven-go +ENV GOPATH /go + +RUN go install -race std && go get golang.org/x/tools/cmd/cover + +COPY . /go/src/github.com/getsentry/raven-go + +RUN go get -v ./... + +CMD ["./runtests.sh"] diff --git a/vendor/github.com/googleapis/gnostic/test/library-example-with-ext.text.out b/vendor/github.com/googleapis/gnostic/test/library-example-with-ext.text.out new file mode 100644 index 000000000..b12e8f081 --- /dev/null +++ b/vendor/github.com/googleapis/gnostic/test/library-example-with-ext.text.out @@ -0,0 +1,234 @@ +swagger: "2.0" +info: < + title: "Google Example Library API" + version: "v1" + description: "A simple Google Example Library API." +> +host: "library-example.googleapis.com" +paths: < + path: < + name: "/v1/{sharedParameter}/pets" + value: < + post: < + operation_id: "simpleMethod" + parameters: < + parameter: < + body_parameter: < + name: "myBodyRef" + in: "body" + schema: < + properties: < + additional_properties: < + name: "myStringA" + value: < + type: < + value: "string" + > + > + > + > + > + > + > + > + parameters: < + parameter: < + non_body_parameter: < + query_parameter_sub_schema: < + required: true + in: "query" + description: "New description" + name: "paramToOverride" + type: "string" + > + > + > + > + parameters: < + parameter: < + non_body_parameter: < + query_parameter_sub_schema: < + required: true + in: "query" + description: "test" + name: "paramAtSwaggerScope" + type: "integer" + format: "int32" + > + > + > + > + responses: < + response_code: < + name: "default" + value: < + response: < + description: "successful operation" + schema: < + schema: < + properties: < + additional_properties: < + name: "myStringA" + value: < + type: < + value: "string" + > + > + > + > + > + > + > + > + > + > + > + parameters: < + parameter: < + non_body_parameter: < + path_parameter_sub_schema: < + required: true + in: "path" + description: "Shared parameter" + name: "sharedParameter" + type: "string" + > + > + > + > + parameters: < + parameter: < + non_body_parameter: < + query_parameter_sub_schema: < + required: true + in: "query" + description: "Description to override" + name: "paramToOverride" + type: "string" + > + > + > + > + > + > +> +definitions: < + additional_properties: < + name: "SimpleDef" + value: < + properties: < + additional_properties: < + name: "myStringA" + value: < + type: < + value: "string" + > + > + > + > + > + > +> +parameters: < + additional_properties: < + name: "paramAtSwaggerScope" + value: < + non_body_parameter: < + query_parameter_sub_schema: < + required: true + in: "query" + description: "test" + name: "paramAtSwaggerScope" + type: "integer" + format: "int32" + > + > + > + > +> +vendor_extension: < + name: "x-sampleone-book" + value: < + value: < + type_url: "type.googleapis.com/sampleone.Book" + value: "\010{\020\347\007" + > + yaml: "code: 123\nmessage: 999\n" + > +> +vendor_extension: < + name: "x-sampleone-shelf" + value: < + value: < + type_url: "type.googleapis.com/sampleone.Shelf" + value: "\010{\020\347\007" + > + yaml: "foo1: 123\nbar: 999\n" + > +> +vendor_extension: < + name: "x-sampleone-mysimplestring" + value: < + value: < + type_url: "type.googleapis.com/google.protobuf.StringValue" + value: "\n\013hello world" + > + yaml: "hello world\n" + > +> +vendor_extension: < + name: "x-sampleone-mysimpleint64" + value: < + value: < + type_url: "type.googleapis.com/google.protobuf.StringValue" + value: "\n\00512345" + > + yaml: "12345\n" + > +> +vendor_extension: < + name: "x-sampleone-mysimplenumber" + value: < + value: < + type_url: "type.googleapis.com/google.protobuf.DoubleValue" + value: "\t\221\355|?5\316[@" + > + yaml: "111.222\n" + > +> +vendor_extension: < + name: "x-sampleone-mysimpleboolean" + value: < + value: < + type_url: "type.googleapis.com/google.protobuf.BoolValue" + value: "\010\001" + > + yaml: "true\n" + > +> +vendor_extension: < + name: "x-sampletwo-book" + value: < + value: < + type_url: "type.googleapis.com/sampletwo.Book" + value: "\010{\020\347\007" + > + yaml: "code: 123\nmessage: 999\n" + > +> +vendor_extension: < + name: "x-sampletwo-shelf" + value: < + value: < + type_url: "type.googleapis.com/sampletwo.Shelf" + value: "\010{\020\347\007" + > + yaml: "foo1: 123\nbar: 999\n" + > +> +vendor_extension: < + name: "x-unhandled" + value: < + yaml: "code: 123\nmessage: 999\n" + > +> diff --git a/vendor/github.com/googleapis/gnostic/test/v2.0/yaml/sample-petstore.out b/vendor/github.com/googleapis/gnostic/test/v2.0/yaml/sample-petstore.out new file mode 100644 index 000000000..016b9b60d --- /dev/null +++ b/vendor/github.com/googleapis/gnostic/test/v2.0/yaml/sample-petstore.out @@ -0,0 +1,14 @@ + + +report.txt -------------------- +READING examples/v2.0/yaml/petstore.yaml (v2) +Swagger: 2.0 +Host: petstore.swagger.io +BasePath: /v1 +Info: + Title: Swagger Petstore + Version: 1.0.0 +Paths: + GET /pets + POST /pets + GET /pets/{petId} diff --git a/vendor/github.com/openshift/api/apps/v1/generated.pb.go b/vendor/github.com/openshift/api/apps/v1/generated.pb.go index ae3080093..fd7e79fa0 100644 --- a/vendor/github.com/openshift/api/apps/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/apps/v1/generated.pb.go @@ -34,21 +34,27 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import k8s_io_api_core_v1 "k8s.io/api/core/v1" -import k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + proto "github.com/gogo/protobuf/proto" -import k8s_io_apimachinery_pkg_util_intstr "k8s.io/apimachinery/pkg/util/intstr" + math "math" -import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + k8s_io_api_core_v1 "k8s.io/api/core/v1" -import strings "strings" -import reflect "reflect" + k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -import io "io" + k8s_io_apimachinery_pkg_util_intstr "k8s.io/apimachinery/pkg/util/intstr" + + github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/authorization/v1/generated.pb.go b/vendor/github.com/openshift/api/authorization/v1/generated.pb.go index c8e008826..245fffeaf 100644 --- a/vendor/github.com/openshift/api/authorization/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/authorization/v1/generated.pb.go @@ -46,18 +46,25 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import k8s_io_api_core_v1 "k8s.io/api/core/v1" -import k8s_io_api_rbac_v1 "k8s.io/api/rbac/v1" -import k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + proto "github.com/gogo/protobuf/proto" -import strings "strings" -import reflect "reflect" + math "math" -import io "io" + k8s_io_api_core_v1 "k8s.io/api/core/v1" + + k8s_io_api_rbac_v1 "k8s.io/api/rbac/v1" + + k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/build/v1/generated.pb.go b/vendor/github.com/openshift/api/build/v1/generated.pb.go index bcec53e13..83221ca91 100644 --- a/vendor/github.com/openshift/api/build/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/build/v1/generated.pb.go @@ -65,21 +65,27 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import k8s_io_api_core_v1 "k8s.io/api/core/v1" -import k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + proto "github.com/gogo/protobuf/proto" -import time "time" + math "math" -import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + k8s_io_api_core_v1 "k8s.io/api/core/v1" -import strings "strings" -import reflect "reflect" + k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -import io "io" + time "time" + + github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/config/v1/register.go b/vendor/github.com/openshift/api/config/v1/register.go index 66c342569..35eace370 100644 --- a/vendor/github.com/openshift/api/config/v1/register.go +++ b/vendor/github.com/openshift/api/config/v1/register.go @@ -56,6 +56,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &NetworkList{}, &OAuth{}, &OAuthList{}, + &OperatorHub{}, + &OperatorHubList{}, &Project{}, &ProjectList{}, &Proxy{}, diff --git a/vendor/github.com/openshift/api/config/v1/types_build.go b/vendor/github.com/openshift/api/config/v1/types_build.go index c7ed7e958..fa4088ca7 100644 --- a/vendor/github.com/openshift/api/config/v1/types_build.go +++ b/vendor/github.com/openshift/api/config/v1/types_build.go @@ -9,7 +9,10 @@ import ( // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// Build holds cluster-wide information on how to handle builds. The canonical name is `cluster` +// Build configures the behavior of OpenShift builds for the entire cluster. +// This includes default settings that can be overridden in BuildConfig objects, and overrides which are applied to all builds. +// +// The canonical name is "cluster" type Build struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` @@ -23,6 +26,10 @@ type BuildSpec struct { // AdditionalTrustedCA is a reference to a ConfigMap containing additional CAs that // should be trusted for image pushes and pulls during builds. // The namespace for this config map is openshift-config. + // + // DEPRECATED: Additional CAs for image pull and push should be set on + // image.config.openshift.io/cluster instead. + // // +optional AdditionalTrustedCA ConfigMapNameReference `json:"additionalTrustedCA"` // BuildDefaults controls the default information for Builds diff --git a/vendor/github.com/openshift/api/config/v1/types_image.go b/vendor/github.com/openshift/api/config/v1/types_image.go index f0cf220d3..606ce7229 100644 --- a/vendor/github.com/openshift/api/config/v1/types_image.go +++ b/vendor/github.com/openshift/api/config/v1/types_image.go @@ -6,7 +6,12 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// Image holds cluster-wide information about how to handle images. The canonical name is `cluster` +// Image governs policies related to imagestream imports and runtime configuration +// for external registries. It allows cluster admins to configure which registries +// OpenShift is allowed to import images from, extra CA trust bundles for external +// registries, and policies to blacklist/whitelist registry hostnames. +// When exposing OpenShift's image registry to the public, this also lets cluster +// admins specify the external hostname. type Image struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. diff --git a/vendor/github.com/openshift/api/config/v1/types_ingress.go b/vendor/github.com/openshift/api/config/v1/types_ingress.go index 484a1af0b..d161eb847 100644 --- a/vendor/github.com/openshift/api/config/v1/types_ingress.go +++ b/vendor/github.com/openshift/api/config/v1/types_ingress.go @@ -6,8 +6,8 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// Ingress holds cluster-wide information about Ingress. The canonical name is `cluster` -// TODO this object is an example of a possible grouping and is subject to change or removal +// Ingress holds cluster-wide information about ingress, including the default ingress domain +// used for routes. The canonical name is `cluster`. type Ingress struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. @@ -24,8 +24,13 @@ type Ingress struct { type IngressSpec struct { // domain is used to generate a default host name for a route when the - // route's host name is empty. The generated host name will follow this + // route's host name is empty. The generated host name will follow this // pattern: "..". + // + // It is also used as the default wildcard domain suffix for ingress. The + // default ingresscontroller domain will follow this pattern: "*.". + // + // Once set, changing domain is not currently supported. Domain string `json:"domain"` } diff --git a/vendor/github.com/openshift/api/config/v1/types_network.go b/vendor/github.com/openshift/api/config/v1/types_network.go index a60c5f7dc..615a6a0d2 100644 --- a/vendor/github.com/openshift/api/config/v1/types_network.go +++ b/vendor/github.com/openshift/api/config/v1/types_network.go @@ -6,14 +6,17 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// Network holds cluster-wide information about Network. The canonical name is `cluster` -// TODO this object is an example of a possible grouping and is subject to change or removal +// Network holds cluster-wide information about Network. The canonical name is `cluster`. It is used to configure the desired network configuration, such as: IP address pools for services/pod IPs, network plugin, etc. +// Please view network.spec for an explanation on what applies when configuring this resource. type Network struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. metav1.ObjectMeta `json:"metadata,omitempty"` // spec holds user settable values for configuration. + // As a general rule, this SHOULD NOT be read directly. Instead, you should + // consume the NetworkStatus, as it indicates the currently deployed configuration. + // Currently, most spec fields are immutable after installation. Please view the individual ones for further details on each. // +kubebuilder:validation:Required // +required Spec NetworkSpec `json:"spec"` @@ -25,14 +28,15 @@ type Network struct { // NetworkSpec is the desired network configuration. // As a general rule, this SHOULD NOT be read directly. Instead, you should // consume the NetworkStatus, as it indicates the currently deployed configuration. -// Currently, changing ClusterNetwork, ServiceNetwork, or NetworkType after -// installation is not supported. +// Currently, most spec fields are immutable after installation. Please view the individual ones for further details on each. type NetworkSpec struct { - // IP address pool to use for pod IPs. + // IP address pool to use for pod IPs. + // This field is immutable after installation. ClusterNetwork []ClusterNetworkEntry `json:"clusterNetwork"` // IP address pool for services. // Currently, we only support a single entry here. + // This field is immutable after installation. ServiceNetwork []string `json:"serviceNetwork"` // NetworkType is the plugin that is to be deployed (e.g. OpenShiftSDN). @@ -40,6 +44,7 @@ type NetworkSpec struct { // or else no networking will be installed. // Currently supported values are: // - OpenShiftSDN + // This field is immutable after installation. NetworkType string `json:"networkType"` // externalIP defines configuration for controllers that diff --git a/vendor/github.com/openshift/api/config/v1/types_operatorhub.go b/vendor/github.com/openshift/api/config/v1/types_operatorhub.go new file mode 100644 index 000000000..31291dec2 --- /dev/null +++ b/vendor/github.com/openshift/api/config/v1/types_operatorhub.go @@ -0,0 +1,78 @@ +package v1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// OperatorHubSpec defines the desired state of OperatorHub +type OperatorHubSpec struct { + // disableAllDefaultSources allows you to disable all the default hub + // sources. If this is true, a specific entry in sources can be used to + // enable a default source. If this is false, a specific entry in + // sources can be used to disable or enable a default source. + // +optional + DisableAllDefaultSources bool `json:"disableAllDefaultSources,omitempty"` + // sources is the list of default hub sources and their configuration. + // If the list is empty, it implies that the default hub sources are + // enabled on the cluster unless disableAllDefaultSources is true. + // If disableAllDefaultSources is true and sources is not empty, + // the configuration present in sources will take precedence. The list of + // default hub sources and their current state will always be reflected in + // the status block. + // +optional + Sources []HubSource `json:"sources,omitempty"` +} + +// OperatorHubStatus defines the observed state of OperatorHub. The current +// state of the default hub sources will always be reflected here. +type OperatorHubStatus struct { + // sources encapsulates the result of applying the configuration for each + // hub source + Sources []HubSourceStatus `json:"sources,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// OperatorHub is the Schema for the operatorhubs API. It can be used to change +// the state of the default hub sources for OperatorHub on the cluster from +// enabled to disabled and vice versa. +// +kubebuilder:subresource:status +// +genclient:nonNamespaced +type OperatorHub struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata"` + + Spec OperatorHubSpec `json:"spec"` + Status OperatorHubStatus `json:"status"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// OperatorHubList contains a list of OperatorHub +type OperatorHubList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata"` + Items []OperatorHub `json:"items"` +} + +// HubSource is used to specify the hub source and its configuration +type HubSource struct { + // name is the name of one of the default hub sources + // +kubebuilder:validation:MaxLength=253 + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:Required + Name string `json:"name"` + // disabled is used to disable a default hub source on cluster + // +kubebuilder:Required + Disabled bool `json:"disabled"` +} + +// HubSourceStatus is used to reflect the current state of applying the +// configuration to a default source +type HubSourceStatus struct { + HubSource `json:"",omitempty` + // status indicates success or failure in applying the configuration + Status string `json:"status,omitempty"` + // message provides more information regarding failures + Message string `json:"message,omitempty"` +} diff --git a/vendor/github.com/openshift/api/config/v1/types_proxy.go b/vendor/github.com/openshift/api/config/v1/types_proxy.go index 821ae8975..1413a48ca 100644 --- a/vendor/github.com/openshift/api/config/v1/types_proxy.go +++ b/vendor/github.com/openshift/api/config/v1/types_proxy.go @@ -42,18 +42,18 @@ type ProxySpec struct { // trustedCA is a reference to a ConfigMap containing a CA certificate bundle used // for client egress HTTPS connections. The certificate bundle must be from the CA - // that signed the proxy's certificate and be signed for everything. trustedCA should - // only be consumed by a proxy validator. The validator is responsible for reading - // ConfigMapNameReference, validating the certificate and copying "ca-bundle.crt" - // from data to a ConfigMap in the namespace of an operator configured for proxy. - // The namespace for this ConfigMap is "openshift-config-managed". Here is an example - // ConfigMap (in yaml): + // that signed the proxy's certificate and be signed for everything. The trustedCA + // field should only be consumed by a proxy validator. The validator is responsible + // for reading the certificate bundle from required key "ca-bundle.crt" and copying + // it to a ConfigMap named "trusted-ca-bundle" in the "openshift-config-managed" + // namespace. The namespace for the ConfigMap referenced by trustedCA is + // "openshift-config". Here is an example ConfigMap (in yaml): // // apiVersion: v1 // kind: ConfigMap // metadata: - // name: proxy-ca - // namespace: openshift-config-managed + // name: user-ca-bundle + // namespace: openshift-config // data: // ca-bundle.crt: | // -----BEGIN CERTIFICATE----- diff --git a/vendor/github.com/openshift/api/config/v1/types_scheduling.go b/vendor/github.com/openshift/api/config/v1/types_scheduling.go index 4a6bfba6f..9b8fa3a52 100644 --- a/vendor/github.com/openshift/api/config/v1/types_scheduling.go +++ b/vendor/github.com/openshift/api/config/v1/types_scheduling.go @@ -6,7 +6,8 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" // +genclient:nonNamespaced // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -// Scheduler holds cluster-wide information about Scheduler. The canonical name is `cluster` +// Scheduler holds cluster-wide config information to run the Kubernetes Scheduler +// and influence its placement decisions. The canonical name for this config is `cluster`. type Scheduler struct { metav1.TypeMeta `json:",inline"` // Standard object's metadata. diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go index 4fa507b16..3d44627f9 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go @@ -1571,6 +1571,39 @@ func (in *HTTPServingInfo) DeepCopy() *HTTPServingInfo { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HubSource) DeepCopyInto(out *HubSource) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HubSource. +func (in *HubSource) DeepCopy() *HubSource { + if in == nil { + return nil + } + out := new(HubSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HubSourceStatus) DeepCopyInto(out *HubSourceStatus) { + *out = *in + out.HubSource = in.HubSource + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HubSourceStatus. +func (in *HubSourceStatus) DeepCopy() *HubSourceStatus { + if in == nil { + return nil + } + out := new(HubSourceStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IdentityProvider) DeepCopyInto(out *IdentityProvider) { *out = *in @@ -2465,6 +2498,109 @@ func (in *OperandVersion) DeepCopy() *OperandVersion { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OperatorHub) DeepCopyInto(out *OperatorHub) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperatorHub. +func (in *OperatorHub) DeepCopy() *OperatorHub { + if in == nil { + return nil + } + out := new(OperatorHub) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OperatorHub) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OperatorHubList) DeepCopyInto(out *OperatorHubList) { + *out = *in + out.TypeMeta = in.TypeMeta + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]OperatorHub, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperatorHubList. +func (in *OperatorHubList) DeepCopy() *OperatorHubList { + if in == nil { + return nil + } + out := new(OperatorHubList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *OperatorHubList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OperatorHubSpec) DeepCopyInto(out *OperatorHubSpec) { + *out = *in + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make([]HubSource, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperatorHubSpec. +func (in *OperatorHubSpec) DeepCopy() *OperatorHubSpec { + if in == nil { + return nil + } + out := new(OperatorHubSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OperatorHubStatus) DeepCopyInto(out *OperatorHubStatus) { + *out = *in + if in.Sources != nil { + in, out := &in.Sources, &out.Sources + *out = make([]HubSourceStatus, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OperatorHubStatus. +func (in *OperatorHubStatus) DeepCopy() *OperatorHubStatus { + if in == nil { + return nil + } + out := new(OperatorHubStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PlatformStatus) DeepCopyInto(out *PlatformStatus) { *out = *in diff --git a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go index 3a5c9df37..6003bbe4c 100644 --- a/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go @@ -326,7 +326,7 @@ func (WebhookTokenAuthenticator) SwaggerDoc() map[string]string { } var map_Build = map[string]string{ - "": "Build holds cluster-wide information on how to handle builds. The canonical name is `cluster`", + "": "Build configures the behavior of OpenShift builds for the entire cluster. This includes default settings that can be overridden in BuildConfig objects, and overrides which are applied to all builds.\n\nThe canonical name is \"cluster\"", "spec": "Spec holds user-settable values for the build controller configuration", } @@ -365,7 +365,7 @@ func (BuildOverrides) SwaggerDoc() map[string]string { } var map_BuildSpec = map[string]string{ - "additionalTrustedCA": "AdditionalTrustedCA is a reference to a ConfigMap containing additional CAs that should be trusted for image pushes and pulls during builds. The namespace for this config map is openshift-config.", + "additionalTrustedCA": "AdditionalTrustedCA is a reference to a ConfigMap containing additional CAs that should be trusted for image pushes and pulls during builds. The namespace for this config map is openshift-config.\n\nDEPRECATED: Additional CAs for image pull and push should be set on image.config.openshift.io/cluster instead.", "buildDefaults": "BuildDefaults controls the default information for Builds", "buildOverrides": "BuildOverrides controls override settings for builds", } @@ -660,7 +660,7 @@ func (FeatureGateSelection) SwaggerDoc() map[string]string { } var map_Image = map[string]string{ - "": "Image holds cluster-wide information about how to handle images. The canonical name is `cluster`", + "": "Image governs policies related to imagestream imports and runtime configuration for external registries. It allows cluster admins to configure which registries OpenShift is allowed to import images from, extra CA trust bundles for external registries, and policies to blacklist/whitelist registry hostnames. When exposing OpenShift's image registry to the public, this also lets cluster admins specify the external hostname.", "metadata": "Standard object's metadata.", "spec": "spec holds user settable values for configuration", "status": "status holds observed values from the cluster. They may not be overridden.", @@ -828,7 +828,7 @@ func (PlatformStatus) SwaggerDoc() map[string]string { } var map_Ingress = map[string]string{ - "": "Ingress holds cluster-wide information about Ingress. The canonical name is `cluster`", + "": "Ingress holds cluster-wide information about ingress, including the default ingress domain used for routes. The canonical name is `cluster`.", "metadata": "Standard object's metadata.", "spec": "spec holds user settable values for configuration", "status": "status holds observed values from the cluster. They may not be overridden.", @@ -847,7 +847,7 @@ func (IngressList) SwaggerDoc() map[string]string { } var map_IngressSpec = map[string]string{ - "domain": "domain is used to generate a default host name for a route when the route's host name is empty. The generated host name will follow this pattern: \"..\".", + "domain": "domain is used to generate a default host name for a route when the route's host name is empty. The generated host name will follow this pattern: \"..\".\n\nIt is also used as the default wildcard domain suffix for ingress. The default ingresscontroller domain will follow this pattern: \"*.\".\n\nOnce set, changing domain is not currently supported.", } func (IngressSpec) SwaggerDoc() map[string]string { @@ -885,9 +885,9 @@ func (ExternalIPPolicy) SwaggerDoc() map[string]string { } var map_Network = map[string]string{ - "": "Network holds cluster-wide information about Network. The canonical name is `cluster`", + "": "Network holds cluster-wide information about Network. The canonical name is `cluster`. It is used to configure the desired network configuration, such as: IP address pools for services/pod IPs, network plugin, etc. Please view network.spec for an explanation on what applies when configuring this resource.", "metadata": "Standard object's metadata.", - "spec": "spec holds user settable values for configuration.", + "spec": "spec holds user settable values for configuration. As a general rule, this SHOULD NOT be read directly. Instead, you should consume the NetworkStatus, as it indicates the currently deployed configuration. Currently, most spec fields are immutable after installation. Please view the individual ones for further details on each.", "status": "status holds observed values from the cluster. They may not be overridden.", } @@ -904,10 +904,10 @@ func (NetworkList) SwaggerDoc() map[string]string { } var map_NetworkSpec = map[string]string{ - "": "NetworkSpec is the desired network configuration. As a general rule, this SHOULD NOT be read directly. Instead, you should consume the NetworkStatus, as it indicates the currently deployed configuration. Currently, changing ClusterNetwork, ServiceNetwork, or NetworkType after installation is not supported.", - "clusterNetwork": "IP address pool to use for pod IPs.", - "serviceNetwork": "IP address pool for services. Currently, we only support a single entry here.", - "networkType": "NetworkType is the plugin that is to be deployed (e.g. OpenShiftSDN). This should match a value that the cluster-network-operator understands, or else no networking will be installed. Currently supported values are: - OpenShiftSDN", + "": "NetworkSpec is the desired network configuration. As a general rule, this SHOULD NOT be read directly. Instead, you should consume the NetworkStatus, as it indicates the currently deployed configuration. Currently, most spec fields are immutable after installation. Please view the individual ones for further details on each.", + "clusterNetwork": "IP address pool to use for pod IPs. This field is immutable after installation.", + "serviceNetwork": "IP address pool for services. Currently, we only support a single entry here. This field is immutable after installation.", + "networkType": "NetworkType is the plugin that is to be deployed (e.g. OpenShiftSDN). This should match a value that the cluster-network-operator understands, or else no networking will be installed. Currently supported values are: - OpenShiftSDN This field is immutable after installation.", "externalIP": "externalIP defines configuration for controllers that affect Service.ExternalIP", } @@ -1146,6 +1146,61 @@ func (TokenConfig) SwaggerDoc() map[string]string { return map_TokenConfig } +var map_HubSource = map[string]string{ + "": "HubSource is used to specify the hub source and its configuration", + "name": "name is the name of one of the default hub sources", + "disabled": "disabled is used to disable a default hub source on cluster", +} + +func (HubSource) SwaggerDoc() map[string]string { + return map_HubSource +} + +var map_HubSourceStatus = map[string]string{ + "": "HubSourceStatus is used to reflect the current state of applying the configuration to a default source", + "status": "status indicates success or failure in applying the configuration", + "message": "message provides more information regarding failures", +} + +func (HubSourceStatus) SwaggerDoc() map[string]string { + return map_HubSourceStatus +} + +var map_OperatorHub = map[string]string{ + "": "OperatorHub is the Schema for the operatorhubs API. It can be used to change the state of the default hub sources for OperatorHub on the cluster from enabled to disabled and vice versa.", +} + +func (OperatorHub) SwaggerDoc() map[string]string { + return map_OperatorHub +} + +var map_OperatorHubList = map[string]string{ + "": "OperatorHubList contains a list of OperatorHub", +} + +func (OperatorHubList) SwaggerDoc() map[string]string { + return map_OperatorHubList +} + +var map_OperatorHubSpec = map[string]string{ + "": "OperatorHubSpec defines the desired state of OperatorHub", + "disableAllDefaultSources": "disableAllDefaultSources allows you to disable all the default hub sources. If this is true, a specific entry in sources can be used to enable a default source. If this is false, a specific entry in sources can be used to disable or enable a default source.", + "sources": "sources is the list of default hub sources and their configuration. If the list is empty, it implies that the default hub sources are enabled on the cluster unless disableAllDefaultSources is true. If disableAllDefaultSources is true and sources is not empty, the configuration present in sources will take precedence. The list of default hub sources and their current state will always be reflected in the status block.", +} + +func (OperatorHubSpec) SwaggerDoc() map[string]string { + return map_OperatorHubSpec +} + +var map_OperatorHubStatus = map[string]string{ + "": "OperatorHubStatus defines the observed state of OperatorHub. The current state of the default hub sources will always be reflected here.", + "sources": "sources encapsulates the result of applying the configuration for each hub source", +} + +func (OperatorHubStatus) SwaggerDoc() map[string]string { + return map_OperatorHubStatus +} + var map_Project = map[string]string{ "": "Project holds cluster-wide information about Project. The canonical name is `cluster`", "metadata": "Standard object's metadata.", @@ -1208,7 +1263,7 @@ var map_ProxySpec = map[string]string{ "httpsProxy": "httpsProxy is the URL of the proxy for HTTPS requests. Empty means unset and will not result in an env var.", "noProxy": "noProxy is a comma-separated list of hostnames and/or CIDRs for which the proxy should not be used. Empty means unset and will not result in an env var.", "readinessEndpoints": "readinessEndpoints is a list of endpoints used to verify readiness of the proxy.", - "trustedCA": "trustedCA is a reference to a ConfigMap containing a CA certificate bundle used for client egress HTTPS connections. The certificate bundle must be from the CA that signed the proxy's certificate and be signed for everything. trustedCA should only be consumed by a proxy validator. The validator is responsible for reading ConfigMapNameReference, validating the certificate and copying \"ca-bundle.crt\" from data to a ConfigMap in the namespace of an operator configured for proxy. The namespace for this ConfigMap is \"openshift-config-managed\". Here is an example ConfigMap (in yaml):\n\napiVersion: v1 kind: ConfigMap metadata:\n name: proxy-ca\n namespace: openshift-config-managed\n data:\n ca-bundle.crt: |", + "trustedCA": "trustedCA is a reference to a ConfigMap containing a CA certificate bundle used for client egress HTTPS connections. The certificate bundle must be from the CA that signed the proxy's certificate and be signed for everything. The trustedCA field should only be consumed by a proxy validator. The validator is responsible for reading the certificate bundle from required key \"ca-bundle.crt\" and copying it to a ConfigMap named \"trusted-ca-bundle\" in the \"openshift-config-managed\" namespace. The namespace for the ConfigMap referenced by trustedCA is \"openshift-config\". Here is an example ConfigMap (in yaml):\n\napiVersion: v1 kind: ConfigMap metadata:\n name: user-ca-bundle\n namespace: openshift-config\n data:\n ca-bundle.crt: |", } func (ProxySpec) SwaggerDoc() map[string]string { @@ -1227,7 +1282,7 @@ func (ProxyStatus) SwaggerDoc() map[string]string { } var map_Scheduler = map[string]string{ - "": "Scheduler holds cluster-wide information about Scheduler. The canonical name is `cluster`", + "": "Scheduler holds cluster-wide config information to run the Kubernetes Scheduler and influence its placement decisions. The canonical name for this config is `cluster`.", "metadata": "Standard object's metadata.", "spec": "spec holds user settable values for configuration", "status": "status holds observed values from the cluster. They may not be overridden.", diff --git a/vendor/github.com/openshift/api/image/v1/generated.pb.go b/vendor/github.com/openshift/api/image/v1/generated.pb.go index ae113b7d3..f985843fd 100644 --- a/vendor/github.com/openshift/api/image/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/image/v1/generated.pb.go @@ -45,19 +45,25 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import k8s_io_api_core_v1 "k8s.io/api/core/v1" -import k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + proto "github.com/gogo/protobuf/proto" -import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + math "math" -import strings "strings" -import reflect "reflect" + k8s_io_api_core_v1 "k8s.io/api/core/v1" -import io "io" + k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/network/v1/generated.pb.go b/vendor/github.com/openshift/api/network/v1/generated.pb.go index 9264f7664..34a5dabb9 100644 --- a/vendor/github.com/openshift/api/network/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/network/v1/generated.pb.go @@ -23,14 +23,19 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import strings "strings" -import reflect "reflect" + proto "github.com/gogo/protobuf/proto" -import io "io" + math "math" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/oauth/v1/generated.pb.go b/vendor/github.com/openshift/api/oauth/v1/generated.pb.go index 0a4f507f1..13ce3d911 100644 --- a/vendor/github.com/openshift/api/oauth/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/oauth/v1/generated.pb.go @@ -23,14 +23,19 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import strings "strings" -import reflect "reflect" + proto "github.com/gogo/protobuf/proto" -import io "io" + math "math" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/operator/v1/types_network.go b/vendor/github.com/openshift/api/operator/v1/types_network.go index cdc3fd0f9..953b30f8d 100644 --- a/vendor/github.com/openshift/api/operator/v1/types_network.go +++ b/vendor/github.com/openshift/api/operator/v1/types_network.go @@ -236,6 +236,20 @@ type KuryrConfig struct { // The port kuryr-controller will listen for readiness and liveness requests. // +optional ControllerProbesPort *uint32 `json:"controllerProbesPort,omitempty"` + + // openStackServiceNetwork contains the CIDR of network from which to allocate IPs for + // OpenStack Octavia's Amphora VMs. Please note that with Amphora driver Octavia uses + // two IPs from that network for each loadbalancer - one given by OpenShift and second + // for VRRP connections. As the first one is managed by OpenShift's and second by Neutron's + // IPAMs, those need to come from different pools. Therefore `openStackServiceNetwork` + // needs to be at least twice the size of `serviceNetwork`, and whole `serviceNetwork` + // must be overlapping with `openStackServiceNetwork`. cluster-network-operator will then + // make sure VRRP IPs are taken from the ranges inside `openStackServiceNetwork` that + // are not overlapping with `serviceNetwork`, effectivly preventing conflicts. If not set + // cluster-network-operator will use `serviceNetwork` expanded by decrementing the prefix + // size by 1. + // +optional + OpenStackServiceNetwork string `json:"openStackServiceNetwork,omitempty"` } // ovnKubernetesConfig is the proposed configuration parameters for networks diff --git a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go index feee6b548..6427b6a28 100644 --- a/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go +++ b/vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go @@ -401,9 +401,10 @@ func (IPAMConfig) SwaggerDoc() map[string]string { } var map_KuryrConfig = map[string]string{ - "": "KuryrConfig configures the Kuryr-Kubernetes SDN", - "daemonProbesPort": "The port kuryr-daemon will listen for readiness and liveness requests.", - "controllerProbesPort": "The port kuryr-controller will listen for readiness and liveness requests.", + "": "KuryrConfig configures the Kuryr-Kubernetes SDN", + "daemonProbesPort": "The port kuryr-daemon will listen for readiness and liveness requests.", + "controllerProbesPort": "The port kuryr-controller will listen for readiness and liveness requests.", + "openStackServiceNetwork": "openStackServiceNetwork contains the CIDR of network from which to allocate IPs for OpenStack Octavia's Amphora VMs. Please note that with Amphora driver Octavia uses two IPs from that network for each loadbalancer - one given by OpenShift and second for VRRP connections. As the first one is managed by OpenShift's and second by Neutron's IPAMs, those need to come from different pools. Therefore `openStackServiceNetwork` needs to be at least twice the size of `serviceNetwork`, and whole `serviceNetwork` must be overlapping with `openStackServiceNetwork`. cluster-network-operator will then make sure VRRP IPs are taken from the ranges inside `openStackServiceNetwork` that are not overlapping with `serviceNetwork`, effectivly preventing conflicts. If not set cluster-network-operator will use `serviceNetwork` expanded by decrementing the prefix size by 1.", } func (KuryrConfig) SwaggerDoc() map[string]string { diff --git a/vendor/github.com/openshift/api/project/v1/generated.pb.go b/vendor/github.com/openshift/api/project/v1/generated.pb.go index 018c6acd1..712479812 100644 --- a/vendor/github.com/openshift/api/project/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/project/v1/generated.pb.go @@ -16,16 +16,21 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import k8s_io_api_core_v1 "k8s.io/api/core/v1" + proto "github.com/gogo/protobuf/proto" -import strings "strings" -import reflect "reflect" + math "math" -import io "io" + k8s_io_api_core_v1 "k8s.io/api/core/v1" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/quota/v1/generated.pb.go b/vendor/github.com/openshift/api/quota/v1/generated.pb.go index 94ff47237..3c6dedc78 100644 --- a/vendor/github.com/openshift/api/quota/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/quota/v1/generated.pb.go @@ -19,18 +19,23 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + proto "github.com/gogo/protobuf/proto" -import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + math "math" -import strings "strings" -import reflect "reflect" + k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -import io "io" + github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/route/v1/generated.pb.go b/vendor/github.com/openshift/api/route/v1/generated.pb.go index dde33a994..6210b9ff7 100644 --- a/vendor/github.com/openshift/api/route/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/route/v1/generated.pb.go @@ -21,18 +21,23 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + proto "github.com/gogo/protobuf/proto" -import k8s_io_api_core_v1 "k8s.io/api/core/v1" + math "math" -import strings "strings" -import reflect "reflect" + k8s_io_apimachinery_pkg_apis_meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" -import io "io" + k8s_io_api_core_v1 "k8s.io/api/core/v1" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/security/v1/generated.pb.go b/vendor/github.com/openshift/api/security/v1/generated.pb.go index 02fbad99b..4d73de075 100644 --- a/vendor/github.com/openshift/api/security/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/security/v1/generated.pb.go @@ -30,16 +30,21 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import k8s_io_api_core_v1 "k8s.io/api/core/v1" + proto "github.com/gogo/protobuf/proto" -import strings "strings" -import reflect "reflect" + math "math" -import io "io" + k8s_io_api_core_v1 "k8s.io/api/core/v1" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/template/v1/generated.pb.go b/vendor/github.com/openshift/api/template/v1/generated.pb.go index 1de3d1417..a497b86e2 100644 --- a/vendor/github.com/openshift/api/template/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/template/v1/generated.pb.go @@ -25,20 +25,25 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import k8s_io_api_core_v1 "k8s.io/api/core/v1" + proto "github.com/gogo/protobuf/proto" -import k8s_io_apimachinery_pkg_runtime "k8s.io/apimachinery/pkg/runtime" + math "math" -import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + k8s_io_api_core_v1 "k8s.io/api/core/v1" -import strings "strings" -import reflect "reflect" + k8s_io_apimachinery_pkg_runtime "k8s.io/apimachinery/pkg/runtime" -import io "io" + github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/api/user/v1/generated.pb.go b/vendor/github.com/openshift/api/user/v1/generated.pb.go index 172e4a7cb..796f47553 100644 --- a/vendor/github.com/openshift/api/user/v1/generated.pb.go +++ b/vendor/github.com/openshift/api/user/v1/generated.pb.go @@ -19,16 +19,21 @@ */ package v1 -import proto "github.com/gogo/protobuf/proto" -import fmt "fmt" -import math "math" +import ( + fmt "fmt" -import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + proto "github.com/gogo/protobuf/proto" -import strings "strings" -import reflect "reflect" + math "math" -import io "io" + github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys" + + strings "strings" + + reflect "reflect" + + io "io" +) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal diff --git a/vendor/github.com/openshift/client-go/glide.lock b/vendor/github.com/openshift/client-go/glide.lock index b3739d131..1608395ba 100644 --- a/vendor/github.com/openshift/client-go/glide.lock +++ b/vendor/github.com/openshift/client-go/glide.lock @@ -1,5 +1,5 @@ hash: 595563cffda70c75833adcf07415011d115db7218cbbddc4c14f1684ad39638a -updated: 2019-07-20T21:53:33.024857-04:00 +updated: 2019-08-13T12:05:19.648281606-04:00 imports: - name: github.com/davecgh/go-spew version: 782f4967f2dc4564575ca782fe2d04090b5faca8 @@ -41,7 +41,7 @@ imports: - name: github.com/modern-go/reflect2 version: 94122c33edd36123c84d5368cfb2b69df93a0ec8 - name: github.com/openshift/api - version: 9525304a0adb725ab4a4a54539a1a6bf6cc343d3 + version: b5570061b31fed3b06c24077c534b1a1bf7ecf8b subpackages: - apps/v1 - authorization/v1 @@ -105,7 +105,7 @@ imports: subpackages: - imports - name: google.golang.org/appengine - version: b2f4a3cf3c67576a2ee09e1fe62656a5086ce880 + version: fb139bde60fa77cede04f226b4d5a3cf68dcce27 subpackages: - internal - internal/base diff --git a/vendor/github.com/openshift/library-go/Makefile b/vendor/github.com/openshift/library-go/Makefile index c7f0ce5df..2704d89e4 100644 --- a/vendor/github.com/openshift/library-go/Makefile +++ b/vendor/github.com/openshift/library-go/Makefile @@ -2,7 +2,7 @@ all: build .PHONY: all # All the go packages (e.g. for verfy) -GO_PACKAGES :=./pkg/... ./cmd/... +GO_PACKAGES :=./pkg/... # Packages to be compiled GO_BUILD_PACKAGES :=$(GO_PACKAGES) # Do not auto-expand packages for libraries or it would compile them separately diff --git a/vendor/github.com/openshift/library-go/alpha-build-machinery/doc.go b/vendor/github.com/openshift/library-go/alpha-build-machinery/doc.go new file mode 100644 index 000000000..a093b4bd1 --- /dev/null +++ b/vendor/github.com/openshift/library-go/alpha-build-machinery/doc.go @@ -0,0 +1,14 @@ +// required for gomod to pull in packages. + +package alpha_build_machinery + +// this is a dependency magnet to make it easier to pull in the build-machinery. We want a single import to pull all of it in. +import ( + _ "github.com/openshift/library-go/alpha-build-machinery/make" + _ "github.com/openshift/library-go/alpha-build-machinery/make/lib" + _ "github.com/openshift/library-go/alpha-build-machinery/make/targets" + _ "github.com/openshift/library-go/alpha-build-machinery/make/targets/golang" + _ "github.com/openshift/library-go/alpha-build-machinery/make/targets/openshift" + _ "github.com/openshift/library-go/alpha-build-machinery/make/targets/openshift/operator" + _ "github.com/openshift/library-go/alpha-build-machinery/scripts" +) diff --git a/vendor/github.com/openshift/library-go/alpha-build-machinery/make/doc.go b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/doc.go new file mode 100644 index 000000000..66ba5512e --- /dev/null +++ b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/doc.go @@ -0,0 +1,3 @@ +// required for gomod to pull in packages. + +package alpha_build_machinery diff --git a/vendor/github.com/openshift/library-go/alpha-build-machinery/make/examples/multiple-binaries/Makefile.test b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/examples/multiple-binaries/Makefile.test new file mode 100644 index 000000000..f933ce024 --- /dev/null +++ b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/examples/multiple-binaries/Makefile.test @@ -0,0 +1,53 @@ +SHELL :=/bin/bash -euo pipefail + +test: | test-build test-cross-build test-rpm +.PHONY: test + +test-build: + $(MAKE) build + [[ -f ./openshift ]] + [[ -f ./oc ]] + + # test version is set correctly when linking + # majorFromGit, minorFromGit are deprecated upstream and set to empty value + # we avoid comparing time to avoid flakes + # we avoid comparing git tree state + diff <( ./oc | grep -v -e 'clean' -e 'dirty' | sed '$$d' ) <( \ + echo ""; \ + echo ""; \ + git rev-parse --short "HEAD^{commit}" 2>/dev/null; \ + git describe --long --tags --abbrev=7 --match 'v[0-9]*' || echo 'v0.0.0-unknown'; \ + ) + + $(MAKE) clean + [[ ! -f ./openshift ]] + [[ ! -f ./oc ]] + $(MAKE) clean +.PHONY: test-build + +test-cross-build: + [[ ! -d ./_output/ ]] + $(MAKE) cross-build + [[ ! -f ./openshift ]] + [[ ! -f ./oc ]] + [[ -f ./_output/bin/darwin_amd64/openshift ]] + [[ -f ./_output/bin/darwin_amd64/oc ]] + [[ -f ./_output/bin/windows_amd64/openshift.exe ]] + [[ -f ./_output/bin/windows_amd64/oc.exe ]] + + $(MAKE) clean + [[ ! -d ./_output/ ]] + $(MAKE) clean +.PHONY: test-cross-build + +test-rpm: + [[ ! -d ./_output/ ]] + + $(MAKE) rpm-build + [[ -f ./_output/rpms/x86_64/openshift-2.42.0-6.el7.x86_64.rpm ]] + [[ -f ./_output/srpms/openshift-2.42.0-6.el7.src.rpm ]] + + $(MAKE) clean + [[ ! -d ./_output/ ]] + $(MAKE) clean +.PHONY: test-rpm diff --git a/vendor/github.com/openshift/library-go/alpha-build-machinery/make/lib/doc.go b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/lib/doc.go new file mode 100644 index 000000000..66ba5512e --- /dev/null +++ b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/lib/doc.go @@ -0,0 +1,3 @@ +// required for gomod to pull in packages. + +package alpha_build_machinery diff --git a/vendor/github.com/openshift/library-go/alpha-build-machinery/make/lib/golang.mk b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/lib/golang.mk index 5d59e70f9..2184f1748 100644 --- a/vendor/github.com/openshift/library-go/alpha-build-machinery/make/lib/golang.mk +++ b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/lib/golang.mk @@ -1,9 +1,6 @@ GO ?=go GOPATH ?=$(shell $(GO) env GOPATH) -gopath_list :=$(subst :, ,$(strip $(GOPATH))) -# Use every path in GOPATH to try to remove it as a prefix of current dir to determine the package name. -# If the prefix is not removed on subtitution, filter-out unchanged paths. -GO_PACKAGE ?=$(strip $(filter-out $(abspath .),$(foreach p,$(gopath_list),$(patsubst $(p)/src/%,%,$(abspath .))))) +GO_PACKAGE ?=$(shell $(GO) list -e -f '{{ .ImportPath }}' . || echo 'no_package_detected') GOOS ?=$(shell $(GO) env GOOS) GOHOSTOS ?=$(shell $(GO) env GOHOSTOS) diff --git a/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/doc.go b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/doc.go new file mode 100644 index 000000000..66ba5512e --- /dev/null +++ b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/doc.go @@ -0,0 +1,3 @@ +// required for gomod to pull in packages. + +package alpha_build_machinery diff --git a/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/golang/doc.go b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/golang/doc.go new file mode 100644 index 000000000..66ba5512e --- /dev/null +++ b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/golang/doc.go @@ -0,0 +1,3 @@ +// required for gomod to pull in packages. + +package alpha_build_machinery diff --git a/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/openshift/doc.go b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/openshift/doc.go new file mode 100644 index 000000000..66ba5512e --- /dev/null +++ b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/openshift/doc.go @@ -0,0 +1,3 @@ +// required for gomod to pull in packages. + +package alpha_build_machinery diff --git a/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/openshift/operator/doc.go b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/openshift/operator/doc.go new file mode 100644 index 000000000..66ba5512e --- /dev/null +++ b/vendor/github.com/openshift/library-go/alpha-build-machinery/make/targets/openshift/operator/doc.go @@ -0,0 +1,3 @@ +// required for gomod to pull in packages. + +package alpha_build_machinery diff --git a/vendor/github.com/openshift/library-go/alpha-build-machinery/scripts/doc.go b/vendor/github.com/openshift/library-go/alpha-build-machinery/scripts/doc.go new file mode 100644 index 000000000..66ba5512e --- /dev/null +++ b/vendor/github.com/openshift/library-go/alpha-build-machinery/scripts/doc.go @@ -0,0 +1,3 @@ +// required for gomod to pull in packages. + +package alpha_build_machinery diff --git a/vendor/github.com/openshift/library-go/cmd/crd-schema-gen/generator/generator.go b/vendor/github.com/openshift/library-go/cmd/crd-schema-gen/generator/generator.go deleted file mode 100755 index cb37958a2..000000000 --- a/vendor/github.com/openshift/library-go/cmd/crd-schema-gen/generator/generator.go +++ /dev/null @@ -1,391 +0,0 @@ -package generator - -import ( - "flag" - "fmt" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "reflect" - "strings" - - "github.com/evanphx/json-patch" - "gopkg.in/yaml.v2" - - "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/serializer" - utilyaml "k8s.io/apimachinery/pkg/util/yaml" - crdgenerator "sigs.k8s.io/controller-tools/pkg/crd/generator" -) - -var ( - scheme = runtime.NewScheme() - codecs = serializer.NewCodecFactory(scheme) -) - -func init() { - v1beta1.AddToScheme(scheme) -} - -func Run() error { - apisDir := flag.String("apis-dir", "pkg/apis", "the (relative) path to the package with API definitions") - apis := flag.String("apis", "*", "the apis to generate from the apis-dir, in bash glob syntax") - manifestDir := flag.String("manifests-dir", "manifests", "the directory with existing CRD manifests") - outputDir := flag.String("output-dir", "", "optional directory to output the kubebuilder CRDs. By default a temporary directory is used.") - verifyOnly := flag.Bool("verify-only", false, "do not write files, only compare and return with return code 1 if dirty") - domain := flag.String("domain", "", "the domain appended to group names.") - repo := flag.String("repo", "", "the repository package name (optional).") - - flag.Parse() - - // load existing manifests from manifests/ dir - existing, err := crdsFromDirectory(*manifestDir) - if err != nil { - return err - } - - // create temp dir - pwd, err := os.Getwd() - if err != nil { - return err - } - tmpDir, err := ioutil.TempDir(pwd, "") - if err != nil { - return fmt.Errorf("error creating temp directory: %v\n", err) - } - defer os.RemoveAll(tmpDir) - relTmpDir := tmpDir[len(pwd)+1:] - - // find repo in GOPATH - sep := string([]rune{os.PathSeparator}) - GOPATH := strings.TrimRight(os.Getenv("GOPATH"), sep) - if len(*repo) == 0 && len(GOPATH) > 0 && strings.HasPrefix(pwd, filepath.Join(GOPATH, "src")+sep) { - *repo = pwd[len(filepath.Join(GOPATH, "src")+sep):] - fmt.Printf("Derived repo %q from GOPATH and working directory.\n", *repo) - } - - // validate params - if len(*repo) == 0 { - return fmt.Errorf("repo cannot be empty. Run crd-schema-gen in GOPATH or specify repo explicitly.") - } - if len(*domain) == 0 { - return fmt.Errorf("domain cannot be empty.") - } - - // copy APIs to temp dir - fmt.Printf("Copying vendor/github.com/openshift/api/config to temporary pkg/apis...\n") - if err := os.MkdirAll(filepath.Join(tmpDir, "pkg/apis"), 0755); err != nil { - return err - } - cmd := fmt.Sprintf("cp -av \"%s/\"%s \"%s\"", *apisDir, *apis, filepath.Join(tmpDir, "pkg/apis")) - out, err := exec.Command("/bin/bash", "-c", cmd).CombinedOutput() - if err != nil { - fmt.Print(string(out)) - return err - } - if err := ioutil.WriteFile(filepath.Join(tmpDir, "PROJECT"), []byte(fmt.Sprintf(` -domain: %s -repo: %s/%s -`, *domain, *repo, relTmpDir)), 0644); err != nil { - return err - } - - // generate kubebuilder KindGroupYaml manifests into temp dir - g := crdgenerator.Generator{ - RootPath: tmpDir, - OutputDir: filepath.Join(tmpDir, "manifests"), - SkipMapValidation: true, - } - - if len(*outputDir) != 0 { - g.OutputDir = *outputDir - fmt.Printf("Creating kubebuilder manifests %q ...\n", *outputDir) - } else { - fmt.Printf("Creating kubebuilder manifests ...\n") - } - - if err := g.ValidateAndInitFields(); err != nil { - return err - } - if err := g.Do(); err != nil { - return err - } - - // the generator changes the directory for some reason - os.Chdir(pwd) - - // load kubebuilder manifests from temp dir - fromKubebuilder, err := crdsFromDirectory(g.OutputDir) - if err != nil { - return err - } - - existingFileNames := map[string]string{} - for fn, crd := range existing { - existingFileNames[crd.KindGroup] = fn - } - - // update existing manifests with validations of kubebuilder output - dirty := false - noneFound := true - for fn, withValidation := range fromKubebuilder { - existingFileName, ok := existingFileNames[withValidation.KindGroup] - if !ok { - continue - } - noneFound = false - - crd := existing[existingFileName] - - // TODO: support multiple versions - validation, _, err := nested(withValidation.Yaml, "spec", "validation") - if err != nil { - return fmt.Errorf("failed to access spec.validation in %s: %v", fn, err) - } - - // yaml merge patch exists? - patchFileName := existingFileName + "-merge-patch" - if _, err := os.Stat(patchFileName); err == nil { - fmt.Printf("Applying patch %q ...\n", patchFileName) - - yamlPatch, err := ioutil.ReadFile(patchFileName) - if err != nil { - return fmt.Errorf("failed to read yaml-merge-patch %q: %v", patchFileName, err) - } - var patch yaml.MapSlice - if err := yaml.Unmarshal(yamlPatch, &patch); err != nil { - return fmt.Errorf("failed to unmarshal yaml merge patch %q: %v", patchFileName, err) - } - if !onlyHasNoneOr(patch, "spec", "validation") { - return fmt.Errorf("patch in %q can only have spec.validation", patchFileName) - } - validationPatch, _, err := nested(patch, "spec", "validation") - if err != nil { - return fmt.Errorf("failed to get spec.validation from %q: %v", patchFileName, err) - } - if yamlPatch, err = yaml.Marshal(validationPatch); err != nil { - return fmt.Errorf("failed to marshal spec.validation of %q: %v", patchFileName, err) - } - jsonPatch, err := utilyaml.ToJSON(yamlPatch) - if err != nil { - return fmt.Errorf("failed to convert yaml of %q to json: %v", patchFileName, err) - } - yamlValidation, err := yaml.Marshal(validation) - if err != nil { - return fmt.Errorf("failed to marshal generated validation schema of %q: %v", existingFileName, err) - } - jsonValidation, err := utilyaml.ToJSON(yamlValidation) - if err != nil { - return fmt.Errorf("failed to convert yaml validation of %q to json: %v", existingFileName, err) - } - if jsonValidation, err = jsonpatch.MergePatch(jsonValidation, jsonPatch); err != nil { - return fmt.Errorf("failed to patch %q with %q: %v", existingFileName, patchFileName, err) - } - if err := yaml.Unmarshal(jsonValidation, &validation); err != nil { - return fmt.Errorf("failed to unmarshal patched validation schema of %q: %v", existingFileName, err) - } - } - - if validation == nil { - continue - } - - updated, err := set(crd.Yaml, validation, "spec", "validation") - if err != nil { - return fmt.Errorf("failed to set spec.validation in %s: %v", existingFileName, err) - } - if reflect.DeepEqual(updated, crd.Yaml) { - fmt.Printf("Validation of %s in %s did not change.\n", crd.KindGroup, existingFileName) - continue - } - - bs, err := yaml.Marshal(updated) - if err != nil { - return err - } - - // write updated file, either to old location, or to temp dir in verify mode - newFn := existingFileName - if *verifyOnly { - newFn = filepath.Join(tmpDir, filepath.Base(existingFileName)) - } else { - fmt.Printf("Updating validation of %s in %s.\n", crd.KindGroup, existingFileName) - } - if err := ioutil.WriteFile(newFn, bs, 0644); err != nil { - return err - } - - // compare old and new file - if *verifyOnly { - out, err := exec.Command("diff", "-u", existingFileName, newFn).CombinedOutput() - if err != nil { - fmt.Println(string(out)) - dirty = true - } - } - } - - if noneFound { - fmt.Printf("None of the found API types has a corresponding CRD manifest. These API types where found:\n\n") - for _, withValidation := range fromKubebuilder { - fmt.Printf(" %s\n", withValidation.KindGroup) - } - fmt.Printf("These CRDs were found:\n\n") - for existingKindGroup := range existingFileNames { - fmt.Printf(" %s\n", existingKindGroup) - } - return fmt.Errorf("no API type for found CRD manifests") - } - - if *verifyOnly && dirty { - return fmt.Errorf("verification failed") - } - - return nil -} - -func nested(x interface{}, pth ...string) (interface{}, bool, error) { - if len(pth) == 0 { - return x, true, nil - } - m, ok := x.(yaml.MapSlice) - if !ok { - return nil, false, fmt.Errorf("%s is not an object, but %T", strings.Join(pth, "."), x) - } - for _, item := range m { - s, ok := item.Key.(string) - if !ok { - continue - } - if s == pth[0] { - ret, found, err := nested(item.Value, pth[1:]...) - if err != nil { - return ret, found, fmt.Errorf("%s.%s", pth[0], err) - } - return ret, found, nil - } - } - return nil, false, nil -} - -func set(x interface{}, v interface{}, pth ...string) (interface{}, error) { - if len(pth) == 0 { - return v, nil - } - - if x == nil { - result, err := set(nil, v, pth[1:]...) - if err != nil { - return nil, fmt.Errorf("%s.%s", pth[0], err) - } - return yaml.MapSlice{yaml.MapItem{Key: pth[0], Value: result}}, nil - } - - m, ok := x.(yaml.MapSlice) - if !ok { - return nil, fmt.Errorf("%s is not an object", strings.Join(pth, ".")) - } - - foundAt := -1 - for i, item := range m { - s, ok := item.Key.(string) - if !ok { - continue - } - if s == pth[0] { - foundAt = i - break - } - } - - if foundAt < 0 { - ret := make(yaml.MapSlice, len(m), len(m)+1) - copy(ret, m) - result, err := set(nil, v, pth[1:]...) - if err != nil { - return nil, fmt.Errorf("%s.%s", pth[0], err) - } - return append(ret, yaml.MapItem{Key: pth[0], Value: result}), nil - } - - result, err := set(m[foundAt].Value, v, pth[1:]...) - ret := make(yaml.MapSlice, len(m)) - copy(ret, m) - if err != nil { - return nil, fmt.Errorf("%s.%s", pth[0], err) - } - ret[foundAt].Value = result - return ret, nil -} - -// onlyHasNoneOr checks for existance of the given path, but nothing next to it is allowed -func onlyHasNoneOr(x interface{}, pth ...string) bool { - if len(pth) == 0 { - return true - } - m, ok := x.(yaml.MapSlice) - if !ok { - return false - } - switch len(m) { - case 0: - return true - case 1: - s, ok := m[0].Key.(string) - if !ok || s != pth[0] { - return false - } - return onlyHasNoneOr(m[0].Value, pth[1:]...) - default: - return false - } -} - -type KindGroupYaml struct { - KindGroup string - Yaml interface{} -} - -// crdsFromDirectory returns CRDs by file path -func crdsFromDirectory(dir string) (map[string]KindGroupYaml, error) { - ret := map[string]KindGroupYaml{} - infos, err := ioutil.ReadDir(dir) - if err != nil { - return nil, err - } - for _, info := range infos { - if info.IsDir() { - continue - } - if !strings.HasSuffix(info.Name(), ".yaml") { - continue - } - bs, err := ioutil.ReadFile(filepath.Join(dir, info.Name())) - if err != nil { - return nil, err - } - - obj, _, err := codecs.UniversalDeserializer().Decode(bs, nil, nil) - if err != nil { - continue - } - crd, ok := obj.(*v1beta1.CustomResourceDefinition) - if !ok { - continue - } - - var y yaml.MapSlice - if err := yaml.Unmarshal(bs, &y); err != nil { - fmt.Printf("Warning: failed to unmarshal %q, skipping\n", info.Name()) - continue - } - key := crd.Spec.Names.Kind + "." + crd.Spec.Group - ret[filepath.Join(dir, info.Name())] = KindGroupYaml{key, y} - } - if err != nil { - return nil, err - } - return ret, err -} diff --git a/vendor/github.com/openshift/library-go/cmd/crd-schema-gen/main.go b/vendor/github.com/openshift/library-go/cmd/crd-schema-gen/main.go deleted file mode 100755 index 228a800cc..000000000 --- a/vendor/github.com/openshift/library-go/cmd/crd-schema-gen/main.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "fmt" - "os" - - "github.com/openshift/library-go/cmd/crd-schema-gen/generator" -) - -func main() { - if err := generator.Run(); err != nil { - fmt.Println(err) - os.Exit(1) - } -} diff --git a/vendor/github.com/openshift/library-go/glide.lock b/vendor/github.com/openshift/library-go/glide.lock index 2c67dcfaf..f448210d4 100644 --- a/vendor/github.com/openshift/library-go/glide.lock +++ b/vendor/github.com/openshift/library-go/glide.lock @@ -1,5 +1,5 @@ -hash: 14182a87b2489ea8cd2db705bf09aad592752d9c9f7cc6cc840a76bcb179a2e8 -updated: 2019-07-14T22:28:29.452706+02:00 +hash: 4812b0cc8114a9f73471b786f4f760b3c363b7fa56a0f8fd83b56d263bc2e616 +updated: 2019-08-15T14:58:38.31621537-04:00 imports: - name: bitbucket.org/ww/goautoneg version: 75cd24fc2f2c2a2088577d12123ddee5f54e0675 @@ -17,7 +17,7 @@ imports: - name: github.com/certifi/gocertifi version: ee1a9a0726d2ae45f54118cac878c990d4016ded - name: github.com/containerd/continuity - version: aaeac12a7ffcd198ae25440a9dff125c2e2703a7 + version: f2a389ac0a02ce21c09edd7344677a601970f41c subpackages: - pathdriver - name: github.com/coreos/etcd @@ -159,7 +159,7 @@ imports: - name: github.com/docker/go-units version: 519db1ee28dcc9fd2474ae59fca29a810482bfb1 - name: github.com/docker/libnetwork - version: 14f9d751adc2d51b38d14b4e14419b76466d3b94 + version: 7f13a5c99f4bb76a4122035d495984b6a09739bb subpackages: - ipamutils - name: github.com/docker/libtrust @@ -175,7 +175,7 @@ imports: - name: github.com/getsentry/raven-go version: c977f96e109525a5d8fa10a19165341f601f38b0 - name: github.com/ghodss/yaml - version: c7ce16629ff4cd059ed96ed06419dd3856fd3577 + version: 25d852aebe32c875e9c044af3eef9c7dc6bc777f - name: github.com/go-openapi/jsonpointer version: ef5f0afec364d3b9396b7b77b43dbe26bf1f8004 - name: github.com/go-openapi/jsonreference @@ -184,8 +184,6 @@ imports: version: 5bae59e25b21498baea7f9d46e9c147ec106a42e - name: github.com/go-openapi/swag version: 5899d5c5e619fda5fa86e14795a835f473ca284c -- name: github.com/gobuffalo/envy - version: 043cb4b8af871b49563291e32c66bb84378a60ac - name: github.com/gogo/protobuf version: 342cbe0a04158f6dcb03ca0079991a51a4248c02 subpackages: @@ -200,12 +198,10 @@ imports: - name: github.com/golang/protobuf version: b4deda0973fb4c70b50d226b1af49f3da59f5265 subpackages: - - jsonpb - proto - ptypes - ptypes/any - ptypes/duration - - ptypes/struct - ptypes/timestamp - name: github.com/gonum/blas version: f22b278b28ac9805aadd613a754a60c35b24ae69 @@ -251,7 +247,7 @@ imports: - compiler - extensions - name: github.com/gorilla/mux - version: d83b6ffe499a29cc05fc977988d0392851779620 + version: e67b3c02c7195c052acff13261f0c9fd1ba53011 - name: github.com/grpc-ecosystem/go-grpc-prometheus version: 2500245aa6110c562d17020fb31a2c133d737799 - name: github.com/hashicorp/golang-lru @@ -262,8 +258,6 @@ imports: version: 9316a62528ac99aaecb4e47eadd6dc8aa6533d58 - name: github.com/inconshreveable/mousetrap version: 76626ae9c91c4f2a10f34cad8ce83ea42c93bb75 -- name: github.com/joho/godotenv - version: 5c0e6c6ab1a0a9ef0a8822cba3a05d62f7dad941 - name: github.com/json-iterator/go version: ab8a2e0c74be9d3be70b3184d9acc634935ded82 - name: github.com/jteeuwen/go-bindata @@ -274,14 +268,12 @@ imports: - buffer - jlexer - jwriter -- name: github.com/markbates/inflect - version: d582c680dc4d29c2279628ae00e743005bfcd4fe - name: github.com/matttproud/golang_protobuf_extensions version: c12348ce28de40eed0136aa2b644d0ee0650e56c subpackages: - pbutil - name: github.com/Microsoft/go-winio - version: 881e3d46423d592d11da9873ff6581dc577a1d0f + version: 6c72808b55902eae4c5943626030429ff20f3b63 subpackages: - pkg/guid - name: github.com/modern-go/concurrent @@ -302,12 +294,12 @@ imports: - specs-go - specs-go/v1 - name: github.com/opencontainers/runc - version: 6cccc1760d57d9e1bc856b96eeb7ee02b7b8101d + version: 2e94378464ae22b92e1335c200edb37ebc94a1b7 subpackages: - libcontainer/system - libcontainer/user - name: github.com/openshift/api - version: f15120709e0ac8de84e11616d8f0cac54e8f52e3 + version: a94e914914f4228d0bcba6fc8a22614c5f5e2dad subpackages: - apps - apps/v1 @@ -354,7 +346,7 @@ imports: - webconsole - webconsole/v1 - name: github.com/openshift/client-go - version: c44a8b61b9f46cd9e802384dfeda0bc9942db68a + version: 5a5508328169b8a6992ea4ef711add89ddce3c6d subpackages: - apps/clientset/versioned/scheme - apps/clientset/versioned/typed/apps/v1 @@ -411,20 +403,10 @@ imports: version: 8a290539e2e8629dbc4e6bad948158f790ec31f4 - name: github.com/PuerkitoBio/urlesc version: 5bd2802263f21d8788851d5305584c82a5c75d7e -- name: github.com/rogpeppe/go-internal - version: 6f68bf1e81f8552c7dbd47f3bc4371c2db0941a6 - subpackages: - - modfile - - module - - semver - name: github.com/sigma/go-inotify version: c87b6cf5033d2c6486046f045eeebdc3d910fd38 - name: github.com/sirupsen/logrus version: 89742aefa4b206dcf400792f3bd35b542998eb3b -- name: github.com/spf13/afero - version: 588a75ec4f32903aa5e39a2619ba6a4631e28424 - subpackages: - - mem - name: github.com/spf13/cobra version: c439c4fa093711d42e1b01acb1235b52004753c1 - name: github.com/spf13/pflag @@ -434,12 +416,22 @@ imports: subpackages: - bcrypt - blowfish + - cryptobyte + - cryptobyte/asn1 + - ed25519 + - ed25519/internal/edwards25519 + - internal/subtle + - nacl/secretbox + - poly1305 + - salsa20/salsa - ssh/terminal - name: golang.org/x/net version: 65e2d4e15006aab9813ff8769e768bbf4bb667a0 subpackages: - context - context/ctxhttp + - html + - html/atom - http/httpguts - http2 - http2/hpack @@ -478,10 +470,9 @@ imports: version: 2382e3994d48b1d22acc2c86bcad0a2aff028e32 subpackages: - container/intsets - - go/ast/astutil - imports - name: google.golang.org/appengine - version: b2f4a3cf3c67576a2ee09e1fe62656a5086ce880 + version: 54a98f90d1c46b7731eb8fb305d2a321c30ef610 subpackages: - internal - internal/base @@ -532,7 +523,7 @@ imports: - name: gopkg.in/natefinch/lumberjack.v2 version: 20b71e5b60d756d3d2f80def009790325acc2b23 - name: gopkg.in/yaml.v2 - version: 51d6538a90f86fe93ac480b35f37b2be17fef232 + version: 5420a8b6744d3b0345ab293f6fcba19c978f1183 - name: k8s.io/api version: 40a48860b5abbba9aa891b02b32da429b08d96a0 subpackages: @@ -737,6 +728,8 @@ imports: - discovery - discovery/fake - dynamic + - dynamic/dynamicinformer + - dynamic/dynamiclister - dynamic/fake - informers - informers/admissionregistration @@ -942,14 +935,6 @@ imports: subpackages: - cli/flag - logs -- name: k8s.io/gengo - version: e17681d19d3ac4837a019ece36c2a0ec31ffe985 - subpackages: - - args - - generator - - namer - - parser - - types - name: k8s.io/klog version: 8e90cee79f823779174776412c13478955131846 - name: k8s.io/kube-aggregator @@ -973,18 +958,11 @@ imports: version: c2654d5206da6b7b6ace12841e8f359bb89b443c subpackages: - buffer + - diff + - field - integer + - pointer - trace -- name: sigs.k8s.io/controller-tools - version: 72ae52c08b9dd626cfb64ebef0fbf40ce667939b - repo: https://github.com/openshift/kubernetes-sigs-controller-tools - subpackages: - - pkg/crd/generator - - pkg/crd/util - - pkg/internal/codegen - - pkg/internal/codegen/parse - - pkg/internal/general - - pkg/util - name: sigs.k8s.io/structured-merge-diff version: e85c7b244fd2cc57bb829d73a061f93a441e63ce subpackages: diff --git a/vendor/github.com/openshift/library-go/glide.yaml b/vendor/github.com/openshift/library-go/glide.yaml index 920b7ca6e..6d08aa413 100644 --- a/vendor/github.com/openshift/library-go/glide.yaml +++ b/vendor/github.com/openshift/library-go/glide.yaml @@ -17,14 +17,6 @@ import: - package: github.com/openshift/client-go version: master -# crd-schema-gen - # TODO: we need to this to get nullable patch, but we will replace this with new repo soon. -- package: sigs.k8s.io/controller-tools - repo: https://github.com/openshift/kubernetes-sigs-controller-tools - version: origin-4.1-kubernetes-1.13.4 -- package: k8s.io/gengo - version: e17681d19d3ac4837a019ece36c2a0ec31ffe985 - # sig-master - needed for file observer - package: github.com/sigma/go-inotify version: c87b6cf5033d2c6486046f045eeebdc3d910fd38 diff --git a/vendor/github.com/openshift/library-go/pkg/controller/controllercmd/cmd.go b/vendor/github.com/openshift/library-go/pkg/controller/controllercmd/cmd.go index ff4f89792..96e5277e6 100644 --- a/vendor/github.com/openshift/library-go/pkg/controller/controllercmd/cmd.go +++ b/vendor/github.com/openshift/library-go/pkg/controller/controllercmd/cmd.go @@ -23,6 +23,7 @@ import ( operatorv1alpha1 "github.com/openshift/api/operator/v1alpha1" "github.com/openshift/library-go/pkg/config/configdefaults" + "github.com/openshift/library-go/pkg/controller/fileobserver" "github.com/openshift/library-go/pkg/crypto" "github.com/openshift/library-go/pkg/serviceability" @@ -88,7 +89,23 @@ func (c *ControllerCommandConfig) NewCommandWithContext(ctx context.Context) *co klog.Fatal(err) } - if err := c.StartController(shutdownCtx); err != nil { + // setup file observer to terminate when given files change + obs, err := fileobserver.NewObserver(10 * time.Second) + if err != nil { + klog.Fatal(err) + } + ctx, terminate := context.WithCancel(shutdownCtx) + files := map[string][]byte{} + for _, fn := range c.basicFlags.TerminateOnFiles { + files[fn], _ = ioutil.ReadFile(fn) // intentionally ignore error + } + obs.AddReactor(func(filename string, action fileobserver.ActionType) error { + klog.Infof("exiting because %q changed", filename) + terminate() + return nil + }, files, c.basicFlags.TerminateOnFiles...) + + if err := c.StartController(ctx); err != nil { klog.Fatal(err) } }, diff --git a/vendor/github.com/openshift/library-go/pkg/controller/controllercmd/flags.go b/vendor/github.com/openshift/library-go/pkg/controller/controllercmd/flags.go index 5cdb4190b..fe33b4351 100644 --- a/vendor/github.com/openshift/library-go/pkg/controller/controllercmd/flags.go +++ b/vendor/github.com/openshift/library-go/pkg/controller/controllercmd/flags.go @@ -22,6 +22,8 @@ type ControllerFlags struct { ConfigFile string // KubeConfigFile points to a kubeconfig file if you don't want to use the in cluster config KubeConfigFile string + // TerminateOnFiles is a list of files. If any of these changes, the process terminates. + TerminateOnFiles []string } // NewControllerFlags returns flags with default values set @@ -43,6 +45,7 @@ func (f *ControllerFlags) AddFlags(cmd *cobra.Command) { cmd.MarkFlagFilename("config", "yaml", "yml") flags.StringVar(&f.KubeConfigFile, "kubeconfig", f.KubeConfigFile, "Location of the master configuration file to run from.") cmd.MarkFlagFilename("kubeconfig", "kubeconfig") + flags.StringArrayVar(&f.TerminateOnFiles, "terminate-on-files", f.TerminateOnFiles, "A list of files. If one of them changes, the process will terminate.") } // ToConfigObj given completed flags, returns a config object for the flag that was specified. diff --git a/vendor/github.com/openshift/library-go/pkg/controller/fileobserver/observer.go b/vendor/github.com/openshift/library-go/pkg/controller/fileobserver/observer.go index 781afa5cb..98798e096 100644 --- a/vendor/github.com/openshift/library-go/pkg/controller/fileobserver/observer.go +++ b/vendor/github.com/openshift/library-go/pkg/controller/fileobserver/observer.go @@ -10,7 +10,7 @@ import ( type Observer interface { Run(stopChan <-chan struct{}) - AddReactor(reaction reactorFn, startingFileContent map[string][]byte, files ...string) Observer + AddReactor(reaction ReactorFn, startingFileContent map[string][]byte, files ...string) Observer } // ActionType define a type of action observed on the file @@ -40,20 +40,26 @@ func (t ActionType) String(filename string) string { return "" } -// reactorFn define a reaction function called when an observed file is modified. -type reactorFn func(file string, action ActionType) error +// ReactorFn define a reaction function called when an observed file is modified. +type ReactorFn func(file string, action ActionType) error // ExitOnChangeReactor provides reactor function that causes the process to exit when the change is detected. -var ExitOnChangeReactor reactorFn = func(filename string, action ActionType) error { - klog.Infof("exiting because %q changed", filename) - os.Exit(0) - return nil +// DEPRECATED: Using this function cause process to exit immediately without proper shutdown (context close/etc.) +// Use the TerminateOnChangeReactor() instead. +var ExitOnChangeReactor = TerminateOnChangeReactor(func() { os.Exit(0) }) + +func TerminateOnChangeReactor(terminateFn func()) ReactorFn { + return func(filename string, action ActionType) error { + klog.Infof("Triggering shutdown because %s", action.String(filename)) + terminateFn() + return nil + } } func NewObserver(interval time.Duration) (Observer, error) { return &pollingObserver{ interval: interval, - reactors: map[string][]reactorFn{}, + reactors: map[string][]ReactorFn{}, files: map[string]string{}, }, nil } diff --git a/vendor/github.com/openshift/library-go/pkg/controller/fileobserver/observer_polling.go b/vendor/github.com/openshift/library-go/pkg/controller/fileobserver/observer_polling.go index 0f3ca8ec8..e15b981da 100644 --- a/vendor/github.com/openshift/library-go/pkg/controller/fileobserver/observer_polling.go +++ b/vendor/github.com/openshift/library-go/pkg/controller/fileobserver/observer_polling.go @@ -16,14 +16,14 @@ import ( type pollingObserver struct { interval time.Duration - reactors map[string][]reactorFn + reactors map[string][]ReactorFn files map[string]string reactorsMutex sync.RWMutex } // AddReactor will add new reactor to this observer. -func (o *pollingObserver) AddReactor(reaction reactorFn, startingFileContent map[string][]byte, files ...string) Observer { +func (o *pollingObserver) AddReactor(reaction ReactorFn, startingFileContent map[string][]byte, files ...string) Observer { o.reactorsMutex.Lock() defer o.reactorsMutex.Unlock() for _, f := range files { diff --git a/vendor/github.com/openshift/library-go/pkg/oauth/oauthserviceaccountclient/oauthclientregistry_test.go b/vendor/github.com/openshift/library-go/pkg/oauth/oauthserviceaccountclient/oauthclientregistry_test.go index 4566271de..8402b755e 100644 --- a/vendor/github.com/openshift/library-go/pkg/oauth/oauthserviceaccountclient/oauthclientregistry_test.go +++ b/vendor/github.com/openshift/library-go/pkg/oauth/oauthserviceaccountclient/oauthclientregistry_test.go @@ -761,7 +761,7 @@ func TestParseModelsMap(t *testing.T) { OAuthRedirectModelAnnotationURIPrefix + "two": "justapath", OAuthRedirectModelAnnotationURIPrefix + "three": "http://redhat.com", OAuthRedirectModelAnnotationURIPrefix + "four": "http://hello:90/world", - OAuthRedirectModelAnnotationURIPrefix + "five": "scheme0://host0:port0/path0", + OAuthRedirectModelAnnotationURIPrefix + "five": "scheme0://host0:5000/path0", OAuthRedirectModelAnnotationReferencePrefix + "five": buildRedirectObjectReferenceString("kind0", "name0", "group0"), }, expected: map[string]model{ @@ -802,7 +802,7 @@ func TestParseModelsMap(t *testing.T) { }, "five": { scheme: "scheme0", - port: "port0", + port: "5000", path: "/path0", group: "group0", kind: "kind0", diff --git a/vendor/github.com/openshift/library-go/pkg/operator/configobserver/cloudprovider/observe_cloudprovider.go b/vendor/github.com/openshift/library-go/pkg/operator/configobserver/cloudprovider/observe_cloudprovider.go index a465636bc..f0e5c252f 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/configobserver/cloudprovider/observe_cloudprovider.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/configobserver/cloudprovider/observe_cloudprovider.go @@ -96,7 +96,7 @@ func (c *cloudProviderObserver) ObserveCloudProviderNames(genericListers configo } // we set cloudprovider configmap values only for some cloud providers. - validCloudProviders := sets.NewString("azure", "gce", "vsphere") + validCloudProviders := sets.NewString("azure", "gce", "openstack", "vsphere") if !validCloudProviders.Has(cloudProvider) { sourceCloudConfigMap = "" } diff --git a/vendor/github.com/openshift/library-go/pkg/operator/configobserver/proxy/observe_proxy.go b/vendor/github.com/openshift/library-go/pkg/operator/configobserver/proxy/observe_proxy.go index 53988d6b8..4231de358 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/configobserver/proxy/observe_proxy.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/configobserver/proxy/observe_proxy.go @@ -56,7 +56,7 @@ func (f *observeProxyFlags) ObserveProxyConfig(genericListers configobserver.Lis } newProxyMap := proxyToMap(proxyConfig) - if len(newProxyMap) > 0 { + if newProxyMap != nil { if err := unstructured.SetNestedStringMap(observedConfig, newProxyMap, f.configPath...); err != nil { errs = append(errs, err) } @@ -72,17 +72,21 @@ func (f *observeProxyFlags) ObserveProxyConfig(genericListers configobserver.Lis func proxyToMap(proxy *configv1.Proxy) map[string]string { proxyMap := map[string]string{} - if noProxy := proxy.Spec.NoProxy; len(noProxy) > 0 { + if noProxy := proxy.Status.NoProxy; len(noProxy) > 0 { proxyMap["NO_PROXY"] = noProxy } - if httpProxy := proxy.Spec.HTTPProxy; len(httpProxy) > 0 { + if httpProxy := proxy.Status.HTTPProxy; len(httpProxy) > 0 { proxyMap["HTTP_PROXY"] = httpProxy } - if httpsProxy := proxy.Spec.HTTPSProxy; len(httpsProxy) > 0 { + if httpsProxy := proxy.Status.HTTPSProxy; len(httpsProxy) > 0 { proxyMap["HTTPS_PROXY"] = httpsProxy } + if len(proxyMap) == 0 { + return nil + } + return proxyMap } diff --git a/vendor/github.com/openshift/library-go/pkg/operator/configobserver/proxy/observe_proxy_test.go b/vendor/github.com/openshift/library-go/pkg/operator/configobserver/proxy/observe_proxy_test.go index 4909ea8fc..ef5a7e302 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/configobserver/proxy/observe_proxy_test.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/configobserver/proxy/observe_proxy_test.go @@ -33,14 +33,18 @@ func TestObserveProxyConfig(t *testing.T) { configPath := []string{"openshift", "proxy"} tests := []struct { - name string - proxySpec configv1.ProxySpec - expected map[string]interface{} - expectedError []error + name string + proxySpec configv1.ProxySpec + proxyStatus configv1.ProxyStatus + previous map[string]string + expected map[string]interface{} + expectedError []error + eventsExpected int }{ { name: "all unset", proxySpec: configv1.ProxySpec{}, + proxyStatus: configv1.ProxyStatus{}, expected: map[string]interface{}{}, expectedError: []error{}, }, @@ -51,16 +55,22 @@ func TestObserveProxyConfig(t *testing.T) { HTTPSProxy: "https://someplace.it", NoProxy: "127.0.0.1", }, + proxyStatus: configv1.ProxyStatus{ + HTTPProxy: "http://someplace.it", + HTTPSProxy: "https://someplace.it", + NoProxy: "127.0.0.1,incluster.address.it", + }, expected: map[string]interface{}{ "openshift": map[string]interface{}{ "proxy": map[string]interface{}{ "HTTP_PROXY": "http://someplace.it", "HTTPS_PROXY": "https://someplace.it", - "NO_PROXY": "127.0.0.1", + "NO_PROXY": "127.0.0.1,incluster.address.it", }, }, }, - expectedError: []error{}, + expectedError: []error{}, + eventsExpected: 1, }, } for _, tt := range tests { @@ -69,6 +79,7 @@ func TestObserveProxyConfig(t *testing.T) { indexer.Add(&configv1.Proxy{ ObjectMeta: metav1.ObjectMeta{Name: "cluster"}, Spec: tt.proxySpec, + Status: tt.proxyStatus, }) listers := testLister{ lister: configlistersv1.NewProxyLister(indexer), @@ -86,6 +97,9 @@ func TestObserveProxyConfig(t *testing.T) { if !reflect.DeepEqual(errorsGot, tt.expectedError) { t.Errorf("observeProxyFlags.ObserveProxyConfig() errorsGot = %v, want %v", errorsGot, tt.expectedError) } + if events := eventRecorder.Events(); len(events) != tt.eventsExpected { + t.Errorf("expected %d events, but got %d: %v", tt.eventsExpected, len(events), events) + } }) } } diff --git a/vendor/github.com/openshift/library-go/pkg/operator/genericoperatorclient/dynamic_operator_client.go b/vendor/github.com/openshift/library-go/pkg/operator/genericoperatorclient/dynamic_operator_client.go index e15a691a4..e93572cdc 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/genericoperatorclient/dynamic_operator_client.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/genericoperatorclient/dynamic_operator_client.go @@ -1,10 +1,10 @@ package genericoperatorclient import ( + "reflect" + "strings" "time" - "github.com/imdario/mergo" - "k8s.io/apimachinery/pkg/runtime" operatorv1 "github.com/openshift/api/operator/v1" @@ -65,6 +65,9 @@ func (c dynamicOperatorClient) GetOperatorState() (*operatorv1.OperatorSpec, *op return spec, status, instance.GetResourceVersion(), nil } +// UpdateOperatorSpec overwrites the operator object spec with the values given +// in operatorv1.OperatorSpec while preserving pre-existing spec fields that have +// no correspondence in operatorv1.OperatorSpec. func (c dynamicOperatorClient) UpdateOperatorSpec(resourceVersion string, spec *operatorv1.OperatorSpec) (*operatorv1.OperatorSpec, string, error) { uncastOriginal, err := c.informer.Lister().Get(globalConfigName) if err != nil { @@ -90,6 +93,9 @@ func (c dynamicOperatorClient) UpdateOperatorSpec(resourceVersion string, spec * return retSpec, ret.GetResourceVersion(), nil } +// UpdateOperatorStatus overwrites the operator object status with the values given +// in operatorv1.OperatorStatus while preserving pre-existing status fields that have +// no correspondence in operatorv1.OperatorStatus. func (c dynamicOperatorClient) UpdateOperatorStatus(resourceVersion string, status *operatorv1.OperatorStatus) (*operatorv1.OperatorStatus, error) { uncastOriginal, err := c.informer.Lister().Get(globalConfigName) if err != nil { @@ -132,24 +138,28 @@ func getOperatorSpecFromUnstructured(obj map[string]interface{}) (*operatorv1.Op } func setOperatorSpecFromUnstructured(obj map[string]interface{}, spec *operatorv1.OperatorSpec) error { - // we cannot simply set the entire map because doing so would stomp unknown fields, like say a static pod operator spec when cast as an operator spec - newUnstructuredSpec, err := runtime.DefaultUnstructuredConverter.ToUnstructured(spec) + // we cannot simply set the entire map because doing so would stomp unknown fields, + // like say a static pod operator spec when cast as an operator spec + newSpec, err := runtime.DefaultUnstructuredConverter.ToUnstructured(spec) if err != nil { return err } - originalUnstructuredSpec, exists, err := unstructured.NestedMap(obj, "spec") - if !exists { - return unstructured.SetNestedMap(obj, newUnstructuredSpec, "spec") - } + origSpec, preExistingSpec, err := unstructured.NestedMap(obj, "spec") if err != nil { return err } - if err := mergo.Merge(&originalUnstructuredSpec, newUnstructuredSpec, mergo.WithOverride); err != nil { - return err - } - - return unstructured.SetNestedMap(obj, originalUnstructuredSpec, "spec") + if preExistingSpec { + flds := topLevelFields(*spec) + for k, v := range origSpec { + if !flds[k] { + if err := unstructured.SetNestedField(newSpec, v, k); err != nil { + return err + } + } + } + } + return unstructured.SetNestedMap(obj, newSpec, "spec") } func getOperatorStatusFromUnstructured(obj map[string]interface{}) (*operatorv1.OperatorStatus, error) { @@ -168,23 +178,48 @@ func getOperatorStatusFromUnstructured(obj map[string]interface{}) (*operatorv1. return ret, nil } -func setOperatorStatusFromUnstructured(obj map[string]interface{}, spec *operatorv1.OperatorStatus) error { - // we cannot simply set the entire map because doing so would stomp unknown fields, like say a static pod operator spec when cast as an operator spec - newUnstructuredStatus, err := runtime.DefaultUnstructuredConverter.ToUnstructured(spec) +func setOperatorStatusFromUnstructured(obj map[string]interface{}, status *operatorv1.OperatorStatus) error { + // we cannot simply set the entire map because doing so would stomp unknown fields, + // like say a static pod operator status when cast as an operator status + newStatus, err := runtime.DefaultUnstructuredConverter.ToUnstructured(status) if err != nil { return err } - originalUnstructuredStatus, exists, err := unstructured.NestedMap(obj, "status") - if !exists { - return unstructured.SetNestedMap(obj, newUnstructuredStatus, "status") - } + origStatus, preExistingStatus, err := unstructured.NestedMap(obj, "status") if err != nil { return err } - if err := mergo.Merge(&originalUnstructuredStatus, newUnstructuredStatus, mergo.WithOverride); err != nil { - return err - } + if preExistingStatus { + flds := topLevelFields(*status) + for k, v := range origStatus { + if !flds[k] { + if err := unstructured.SetNestedField(newStatus, v, k); err != nil { + return err + } + } + } + } + return unstructured.SetNestedMap(obj, newStatus, "status") +} - return unstructured.SetNestedMap(obj, originalUnstructuredStatus, "status") +func topLevelFields(obj interface{}) map[string]bool { + ret := map[string]bool{} + t := reflect.TypeOf(obj) + for i := 0; i < t.NumField(); i++ { + fld := t.Field(i) + fieldName := fld.Name + if jsonTag := fld.Tag.Get("json"); jsonTag == "-" { + continue + } else if jsonTag != "" { + // check for possible comma as in "...,omitempty" + var commaIdx int + if commaIdx = strings.Index(jsonTag, ","); commaIdx < 0 { + commaIdx = len(jsonTag) + } + fieldName = jsonTag[:commaIdx] + } + ret[fieldName] = true + } + return ret } diff --git a/vendor/github.com/openshift/library-go/pkg/operator/genericoperatorclient/dynamic_operator_client_test.go b/vendor/github.com/openshift/library-go/pkg/operator/genericoperatorclient/dynamic_operator_client_test.go index 15e39e896..df2550573 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/genericoperatorclient/dynamic_operator_client_test.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/genericoperatorclient/dynamic_operator_client_test.go @@ -4,6 +4,7 @@ import ( "reflect" "testing" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/utils/diff" operatorv1 "github.com/openshift/api/operator/v1" @@ -29,10 +30,74 @@ func TestSetOperatorSpecFromUnstructured(t *testing.T) { }, expected: map[string]interface{}{ "spec": map[string]interface{}{ - "non-standard-field": "value", - "logLevel": "Trace", - "managementState": "", - "operatorLogLevel": "", + "non-standard-field": "value", + "logLevel": "Trace", + "managementState": "", + "operatorLogLevel": "", + "unsupportedConfigOverrides": nil, + "observedConfig": nil, + }, + }, + }, + { + name: "keep-everything-outside-of-spec", + in: map[string]interface{}{ + "kind": "Foo", + "apiVersion": "bar/v1", + "status": map[string]interface{}{"foo": "bar"}, + "spec": map[string]interface{}{}, + }, + spec: &operatorv1.OperatorSpec{}, + expected: map[string]interface{}{ + "kind": "Foo", + "apiVersion": "bar/v1", + "status": map[string]interface{}{"foo": "bar"}, + "spec": map[string]interface{}{ + "logLevel": "", + "managementState": "", + "operatorLogLevel": "", + "unsupportedConfigOverrides": nil, + "observedConfig": nil, + }, + }, + }, + { + name: "replace-rawextensions", + in: map[string]interface{}{ + "spec": map[string]interface{}{ + "unsupportedConfigOverrides": map[string]interface{}{"foo": "bar"}, + }, + }, + spec: &operatorv1.OperatorSpec{ + LogLevel: operatorv1.Trace, + }, + expected: map[string]interface{}{ + "spec": map[string]interface{}{ + "logLevel": "Trace", + "managementState": "", + "operatorLogLevel": "", + "unsupportedConfigOverrides": nil, + "observedConfig": nil, + }, + }, + }, + { + name: "remove-observed-fields", + in: map[string]interface{}{ + "spec": map[string]interface{}{ + "observedConfig": map[string]interface{}{"a": "1", "b": "2"}, + }, + }, + spec: &operatorv1.OperatorSpec{ + ObservedConfig: runtime.RawExtension{Raw: []byte(`{"a":1}`)}, + }, + expected: map[string]interface{}{ + "spec": map[string]interface{}{ + "logLevel": "", + "managementState": "", + "operatorLogLevel": "", + "unsupportedConfigOverrides": nil, + "observedConfig": map[string]interface{}{"a": int64(1)}, }, }, }, @@ -87,6 +152,24 @@ func TestSetOperatorStatusFromUnstructured(t *testing.T) { }, }, }, + { + name: "keep-everything-outside-of-status", + in: map[string]interface{}{ + "kind": "Foo", + "apiVersion": "bar/v1", + "spec": map[string]interface{}{"foo": "bar"}, + "status": map[string]interface{}{}, + }, + status: &operatorv1.OperatorStatus{}, + expected: map[string]interface{}{ + "kind": "Foo", + "apiVersion": "bar/v1", + "spec": map[string]interface{}{"foo": "bar"}, + "status": map[string]interface{}{ + "readyReplicas": int64(0), + }, + }, + }, { name: "replace-condition", in: map[string]interface{}{ diff --git a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/core.go b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/core.go index 36777d6eb..b4f11db96 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/core.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/core.go @@ -1,6 +1,7 @@ package resourceapply import ( + "bytes" "fmt" "sort" "strings" @@ -168,17 +169,28 @@ func ApplyConfigMap(client coreclientv1.ConfigMapsGetter, recorder events.Record modifiedKeys = append(modifiedKeys, "data."+existingCopyKey) } } + for existingCopyKey, existingCopyBinValue := range existingCopy.BinaryData { + if requiredBinValue, ok := required.BinaryData[existingCopyKey]; !ok || !bytes.Equal(existingCopyBinValue, requiredBinValue) { + modifiedKeys = append(modifiedKeys, "binaryData."+existingCopyKey) + } + } for requiredKey := range required.Data { if _, ok := existingCopy.Data[requiredKey]; !ok { modifiedKeys = append(modifiedKeys, "data."+requiredKey) } } + for requiredBinKey := range required.BinaryData { + if _, ok := existingCopy.BinaryData[requiredBinKey]; !ok { + modifiedKeys = append(modifiedKeys, "binaryData."+requiredBinKey) + } + } dataSame := len(modifiedKeys) == 0 if dataSame && !*modified { return existingCopy, false, nil } existingCopy.Data = required.Data + existingCopy.BinaryData = required.BinaryData actual, err := client.ConfigMaps(required.Namespace).Update(existingCopy) diff --git a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/core_test.go b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/core_test.go index 7b520ca2f..c1723626e 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/core_test.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/resource/resourceapply/core_test.go @@ -139,6 +139,52 @@ func TestApplyConfigMap(t *testing.T) { } }, }, + { + name: "update on mismatch binary data", + existing: []runtime.Object{ + &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{Namespace: "one-ns", Name: "foo", Labels: map[string]string{"extra": "leave-alone"}}, + Data: map[string]string{ + "configmap": "value", + }, + }, + }, + input: &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{Namespace: "one-ns", Name: "foo"}, + Data: map[string]string{ + "configmap": "value", + }, + BinaryData: map[string][]byte{ + "binconfigmap": []byte("value"), + }, + }, + + expectedModified: true, + verifyActions: func(actions []clienttesting.Action, t *testing.T) { + if len(actions) != 2 { + t.Fatal(spew.Sdump(actions)) + } + if !actions[0].Matches("get", "configmaps") || actions[0].(clienttesting.GetAction).GetName() != "foo" { + t.Error(spew.Sdump(actions)) + } + if !actions[1].Matches("update", "configmaps") { + t.Error(spew.Sdump(actions)) + } + expected := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{Namespace: "one-ns", Name: "foo", Labels: map[string]string{"extra": "leave-alone"}}, + Data: map[string]string{ + "configmap": "value", + }, + BinaryData: map[string][]byte{ + "binconfigmap": []byte("value"), + }, + } + actual := actions[1].(clienttesting.UpdateAction).GetObject().(*corev1.ConfigMap) + if !equality.Semantic.DeepEqual(expected, actual) { + t.Error(JSONPatch(expected, actual)) + } + }, + }, } for _, test := range tests { diff --git a/vendor/github.com/openshift/library-go/pkg/operator/staticpod/certsyncpod/certsync_cmd.go b/vendor/github.com/openshift/library-go/pkg/operator/staticpod/certsyncpod/certsync_cmd.go index f62218ac3..9513078ed 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/staticpod/certsyncpod/certsync_cmd.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/staticpod/certsyncpod/certsync_cmd.go @@ -62,11 +62,13 @@ func (o *CertSyncControllerOptions) Run() error { return err } - initialContent, _ := ioutil.ReadFile(o.KubeConfigFile) - observer.AddReactor(fileobserver.ExitOnChangeReactor, map[string][]byte{o.KubeConfigFile: initialContent}, o.KubeConfigFile) - stopCh := make(chan struct{}) + initialContent, _ := ioutil.ReadFile(o.KubeConfigFile) + observer.AddReactor(fileobserver.TerminateOnChangeReactor(func() { + close(stopCh) + }), map[string][]byte{o.KubeConfigFile: initialContent}, o.KubeConfigFile) + kubeInformers := informers.NewSharedInformerFactoryWithOptions(o.kubeClient, 10*time.Minute, informers.WithNamespace(o.Namespace)) eventRecorder := events.NewKubeRecorder(o.kubeClient.CoreV1().Events(o.Namespace), "cert-syncer", diff --git a/vendor/github.com/openshift/library-go/pkg/operator/staticpod/controller/installer/installer_controller.go b/vendor/github.com/openshift/library-go/pkg/operator/staticpod/controller/installer/installer_controller.go index c8821a00e..04cfeab28 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/staticpod/controller/installer/installer_controller.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/staticpod/controller/installer/installer_controller.go @@ -540,7 +540,7 @@ func (c *InstallerController) newNodeStateForInstallInProgress(currNodeState *op // stop early, don't wait for ready static pod because a new revision is waiting ret.LastFailedRevision = currNodeState.TargetRevision ret.TargetRevision = 0 - ret.LastFailedRevisionErrors = []string{"static pod of revision has been installed, but is not ready while new revision % is pending"} + ret.LastFailedRevisionErrors = []string{fmt.Sprintf("static pod of revision has been installed, but is not ready while new revision %d is pending", currNodeState.TargetRevision)} return ret, false, "new revision pending", nil } @@ -600,7 +600,7 @@ func (c *InstallerController) newNodeStateForInstallInProgress(currNodeState *op ret.LastFailedRevision = currNodeState.TargetRevision ret.TargetRevision = 0 if len(errors) == 0 { - errors = append(errors, "no detailed termination message, see `oc get -n %q pods/%q -oyaml`", installerPod.Namespace, installerPod.Name) + errors = append(errors, fmt.Sprintf("no detailed termination message, see `oc get -n %q pods/%q -oyaml`", installerPod.Namespace, installerPod.Name)) } ret.LastFailedRevisionErrors = errors return ret, false, "installer pod failed", nil diff --git a/vendor/github.com/openshift/library-go/pkg/operator/staticpod/prune/cmd.go b/vendor/github.com/openshift/library-go/pkg/operator/staticpod/prune/cmd.go index 2db8cda74..18ba33178 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/staticpod/prune/cmd.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/staticpod/prune/cmd.go @@ -64,7 +64,7 @@ func (o *PruneOptions) Validate() error { return fmt.Errorf("--resource-dir is required") } if o.MaxEligibleRevision == 0 { - return fmt.Errorf("--max-eligible-id is required") + return fmt.Errorf("--max-eligible-revision is required") } if len(o.StaticPodName) == 0 { return fmt.Errorf("--static-pod-name is required") diff --git a/vendor/github.com/openshift/library-go/pkg/operator/watchdog/cmd.go b/vendor/github.com/openshift/library-go/pkg/operator/watchdog/cmd.go index c0d64b7b2..4c2597e46 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/watchdog/cmd.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/watchdog/cmd.go @@ -6,6 +6,8 @@ import ( "io/ioutil" "os" "path/filepath" + "strconv" + "strings" "syscall" "time" @@ -26,8 +28,11 @@ import ( ) type FileWatcherOptions struct { - // ProcessName is the name of the process we will send SIGTERM + // ProcessName is the name of the process to look for in /proc if non-empty, + // indentifying the process to send SIGTERM to. ProcessName string + // PidFile contains the pid of the process to send SIGTERM to. Can be empty. + PidFile string // Files lists all files we want to monitor for changes Files []string @@ -43,6 +48,9 @@ type FileWatcherOptions struct { // Time to give the process to terminate gracefully TerminationGracePeriod time.Duration + // ReadyFile is touched when the watched files have been initially read + ReadyFile string + // for unit-test to mock getting the process PID (unit-test) findPidByNameFn func(name string) (int, bool, error) @@ -119,12 +127,14 @@ func NewFileWatcherWatchdog() *cobra.Command { } func (o *FileWatcherOptions) AddFlags(fs *pflag.FlagSet) { - fs.StringVar(&o.ProcessName, "process-name", "", "name of the process to send TERM signal to on file change (eg. 'hyperkube').") + fs.StringVar(&o.ProcessName, "process-name", "", "base name of the binary to send the TERM signal to on file change (eg. 'hyperkube').") + fs.StringVar(&o.PidFile, "pid-file", "", "file with the pid to send the TERM signal to on file change.") fs.StringSliceVar(&o.Files, "files", o.Files, "comma separated list of file names to monitor for changes") fs.StringVar(&o.KubeConfig, "kubeconfig", o.KubeConfig, "kubeconfig file or empty") fs.StringVar(&o.Namespace, "namespace", o.Namespace, "namespace to report the watchdog events") fs.DurationVar(&o.Interval, "interval", 5*time.Second, "interval specifying how aggressive the file checks should be") fs.DurationVar(&o.TerminationGracePeriod, "termination-grace-period", 30*time.Second, "interval specifying how long to wait until sending KILL signal to the process") + fs.StringVar(&o.ReadyFile, "ready-file", o.ReadyFile, "this file is touched when the watched files have been read initially (to avoid race between watchee and watcher)") } func (o *FileWatcherOptions) Complete() error { @@ -160,8 +170,8 @@ func (o *FileWatcherOptions) Complete() error { } func (o *FileWatcherOptions) Validate() error { - if len(o.ProcessName) == 0 { - return fmt.Errorf("process name must be specified") + if len(o.ProcessName) == 0 && len(o.PidFile) == 0 { + return fmt.Errorf("process name or pid file must be specified") } if len(o.Files) == 0 { return fmt.Errorf("at least one file to observe must be specified") @@ -179,10 +189,32 @@ func (o *FileWatcherOptions) runPidObserver(ctx context.Context, pidObservedCh c retries := 0 pollErr := wait.PollImmediateUntil(1*time.Second, func() (done bool, err error) { retries++ - // attempt to find the PID by process name via /proc - observedPID, found, err := o.findPidByNameFn(o.ProcessName) - if !found || err != nil { - klog.Warningf("Unable to determine PID for %q (retry: %d, err: %v)", o.ProcessName, retries, err) + observedPID := -1 + if len(o.ProcessName) > 0 { + // attempt to find the PID by process name via /proc + pid, found, err := o.findPidByNameFn(o.ProcessName) + if !found || err != nil { + klog.Warningf("Unable to determine PID for %q (retry: %d, err: %v)", o.ProcessName, retries, err) + } else { + observedPID = pid + } + } + if len(o.PidFile) > 0 { + // attempt to find the PID by pid file + bs, err := ioutil.ReadFile(o.PidFile) + if err != nil { + klog.Warningf("Unable to read pid file %s: %v", o.PidFile, err) + } else { + lines := strings.SplitN(string(bs), "\n", 2) + i, err := strconv.Atoi(lines[0]) + if err != nil { + klog.Warningf("Unable to parse pid file %s: %v", o.PidFile, err) + } else { + observedPID = i + } + } + } + if observedPID < 0 { return false, nil } @@ -293,7 +325,13 @@ func (o *FileWatcherOptions) runWatchdog(ctx context.Context) error { go o.runPidObserver(watchdogCtx, pidObservedCh) // Wait while we get the initial PID for the process - klog.Infof("Waiting for process %q PID ...", o.ProcessName) + if len(o.ProcessName) > 0 && len(o.PidFile) > 0 { + klog.Infof("Waiting for process with name %q or PID file %q...", o.ProcessName, o.PidFile) + } else if len(o.ProcessName) > 0 { + klog.Infof("Waiting for process with process name %q ...", o.ProcessName) + } else if len(o.PidFile) > 0 { + klog.Infof("Waiting for process PID file %q ...", o.PidFile) + } currentPID := <-pidObservedCh // Mutate path for specified files as '/proc/PID/root/' @@ -312,6 +350,14 @@ func (o *FileWatcherOptions) runWatchdog(ctx context.Context) error { o.recorder.Eventf("FileChangeWatchdogStarted", "Started watching files for process %s[%d]", o.ProcessName, currentPID) + if len(o.ReadyFile) > 0 { + f, err := os.Create(o.ReadyFile) + if err != nil { + return fmt.Errorf("cannot touch ready file %q: %v", o.ReadyFile, err) + } + f.Close() + } + observer, err := fileobserver.NewObserver(o.Interval) if err != nil { o.recorder.Warningf("ObserverFailed", "Failed to start to file observer: %v", err) diff --git a/vendor/github.com/openshift/library-go/pkg/operator/watchdog/cmd_test.go b/vendor/github.com/openshift/library-go/pkg/operator/watchdog/cmd_test.go index 8821e6457..a3f302570 100644 --- a/vendor/github.com/openshift/library-go/pkg/operator/watchdog/cmd_test.go +++ b/vendor/github.com/openshift/library-go/pkg/operator/watchdog/cmd_test.go @@ -23,6 +23,7 @@ func TestPidObserver(t *testing.T) { } watcher := &FileWatcherOptions{ + ProcessName: "foo", findPidByNameFn: getProcessPIDByName, } diff --git a/vendor/github.com/spf13/cobra/.circleci/config.yml b/vendor/github.com/spf13/cobra/.circleci/config.yml index 136e17f0e..819446439 100644 --- a/vendor/github.com/spf13/cobra/.circleci/config.yml +++ b/vendor/github.com/spf13/cobra/.circleci/config.yml @@ -1,38 +1,53 @@ -workflows: - version: 2 - main: - jobs: - - go-current - - go-previous - - go-latest -base: &base - working_directory: /go/src/github.com/spf13/cobra - steps: - - checkout - - run: - name: "All Commands" - command: | - mkdir -p bin - curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.4.3/shellcheck - chmod +x bin/shellcheck - go get -t -v ./... - PATH=$PATH:$PWD/bin go test -v ./... - go build - diff -u <(echo -n) <(gofmt -d -s .) - if [ -z $NOVET ]; then - diff -u <(echo -n) <(go tool vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint'); - fi version: 2 + +references: + workspace: &workspace + /go/src/github.com/spf13/cobra + + run_tests: &run_tests + run: + name: "All Commands" + command: | + mkdir -p bin + curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.4.6/shellcheck + chmod +x bin/shellcheck + go get -t -v ./... + PATH=$PATH:$PWD/bin go test -v ./... + go build + if [ -z $NOVET ]; then + diff -u <(echo -n) <(go vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint'); + fi + jobs: go-current: docker: - - image: circleci/golang:1.8.3 - <<: *base + - image: circleci/golang:1.12 + working_directory: *workspace + steps: + - checkout + - *run_tests + - run: + name: "Check formatting" + command: diff -u <(echo -n) <(gofmt -d -s .) go-previous: docker: - - image: circleci/golang:1.7.6 - <<: *base + - image: circleci/golang:1.11 + working_directory: *workspace + steps: + - checkout + - *run_tests go-latest: docker: - image: circleci/golang:latest - <<: *base + working_directory: *workspace + steps: + - checkout + - *run_tests + +workflows: + version: 2 + main: + jobs: + - go-current + - go-previous + - go-latest diff --git a/vendor/github.com/spf13/cobra/.gitignore b/vendor/github.com/spf13/cobra/.gitignore index 1b8c7c261..3b053c59e 100644 --- a/vendor/github.com/spf13/cobra/.gitignore +++ b/vendor/github.com/spf13/cobra/.gitignore @@ -34,3 +34,5 @@ tags *.exe cobra.test + +.idea/* diff --git a/vendor/github.com/spf13/cobra/.travis.yml b/vendor/github.com/spf13/cobra/.travis.yml index 68efa1363..38b85f499 100644 --- a/vendor/github.com/spf13/cobra/.travis.yml +++ b/vendor/github.com/spf13/cobra/.travis.yml @@ -1,21 +1,31 @@ language: go +stages: + - diff + - test + +go: + - 1.10.x + - 1.11.x + - 1.12.x + - tip + matrix: - include: - - go: 1.7.6 - - go: 1.8.3 - - go: tip allow_failures: - go: tip + include: + - stage: diff + go: 1.12.x + script: diff -u <(echo -n) <(gofmt -d -s .) before_install: - mkdir -p bin - - curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.4.3/shellcheck + - curl -Lso bin/shellcheck https://github.com/caarlos0/shellcheck-docker/releases/download/v0.6.0/shellcheck - chmod +x bin/shellcheck + - go get -u github.com/kyoh86/richgo script: - - PATH=$PATH:$PWD/bin go test -v ./... + - PATH=$PATH:$PWD/bin richgo test -v ./... - go build - - diff -u <(echo -n) <(gofmt -d -s .) - if [ -z $NOVET ]; then - diff -u <(echo -n) <(go tool vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint'); + diff -u <(echo -n) <(go vet . 2>&1 | grep -vE 'ExampleCommand|bash_completions.*Fprint'); fi diff --git a/vendor/github.com/spf13/cobra/README.md b/vendor/github.com/spf13/cobra/README.md index 851fcc087..60c5a425b 100644 --- a/vendor/github.com/spf13/cobra/README.md +++ b/vendor/github.com/spf13/cobra/README.md @@ -2,25 +2,29 @@ Cobra is both a library for creating powerful modern CLI applications as well as a program to generate applications and command files. -Many of the most widely used Go projects are built using Cobra including: - -* [Kubernetes](http://kubernetes.io/) -* [Hugo](http://gohugo.io) -* [rkt](https://github.com/coreos/rkt) -* [etcd](https://github.com/coreos/etcd) -* [Moby (former Docker)](https://github.com/moby/moby) -* [Docker (distribution)](https://github.com/docker/distribution) -* [OpenShift](https://www.openshift.com/) -* [Delve](https://github.com/derekparker/delve) -* [GopherJS](http://www.gopherjs.org/) -* [CockroachDB](http://www.cockroachlabs.com/) -* [Bleve](http://www.blevesearch.com/) -* [ProjectAtomic (enterprise)](http://www.projectatomic.io/) -* [GiantSwarm's swarm](https://github.com/giantswarm/cli) -* [Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack) -* [rclone](http://rclone.org/) -* [nehm](https://github.com/bogem/nehm) -* [Pouch](https://github.com/alibaba/pouch) +Many of the most widely used Go projects are built using Cobra, such as: +[Kubernetes](http://kubernetes.io/), +[Hugo](http://gohugo.io), +[rkt](https://github.com/coreos/rkt), +[etcd](https://github.com/coreos/etcd), +[Moby (former Docker)](https://github.com/moby/moby), +[Docker (distribution)](https://github.com/docker/distribution), +[OpenShift](https://www.openshift.com/), +[Delve](https://github.com/derekparker/delve), +[GopherJS](http://www.gopherjs.org/), +[CockroachDB](http://www.cockroachlabs.com/), +[Bleve](http://www.blevesearch.com/), +[ProjectAtomic (enterprise)](http://www.projectatomic.io/), +[Giant Swarm's gsctl](https://github.com/giantswarm/gsctl), +[Nanobox](https://github.com/nanobox-io/nanobox)/[Nanopack](https://github.com/nanopack), +[rclone](http://rclone.org/), +[nehm](https://github.com/bogem/nehm), +[Pouch](https://github.com/alibaba/pouch), +[Istio](https://istio.io), +[Prototool](https://github.com/uber/prototool), +[mattermost-server](https://github.com/mattermost/mattermost-server), +[Gardener](https://github.com/gardener/gardenctl), +etc. [![Build Status](https://travis-ci.org/spf13/cobra.svg "Travis CI status")](https://travis-ci.org/spf13/cobra) [![CircleCI status](https://circleci.com/gh/spf13/cobra.png?circle-token=:circle-token "CircleCI status")](https://circleci.com/gh/spf13/cobra) @@ -45,6 +49,7 @@ Many of the most widely used Go projects are built using Cobra including: * [Suggestions when "unknown command" happens](#suggestions-when-unknown-command-happens) * [Generating documentation for your command](#generating-documentation-for-your-command) * [Generating bash completions](#generating-bash-completions) + * [Generating zsh completions](#generating-zsh-completions) - [Contributing](#contributing) - [License](#license) @@ -152,9 +157,6 @@ In a Cobra app, typically the main.go file is very bare. It serves one purpose: package main import ( - "fmt" - "os" - "{pathToYourApp}/cmd" ) @@ -265,9 +267,6 @@ In a Cobra app, typically the main.go file is very bare. It serves, one purpose, package main import ( - "fmt" - "os" - "{pathToYourApp}/cmd" ) @@ -339,7 +338,7 @@ rootCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose out A flag can also be assigned locally which will only apply to that specific command. ```go -rootCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from") +localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from") ``` ### Local Flag on Parent Commands @@ -395,6 +394,7 @@ The following validators are built in: - `MinimumNArgs(int)` - the command will report an error if there are not at least N positional args. - `MaximumNArgs(int)` - the command will report an error if there are more than N positional args. - `ExactArgs(int)` - the command will report an error if there are not exactly N positional args. +- `ExactValidArgs(int)` - the command will report an error if there are not exactly N positional args OR if there are any positional args that are not in the `ValidArgs` field of `Command` - `RangeArgs(min, max)` - the command will report an error if the number of args is not between the minimum and maximum number of expected args. An example of setting the custom validator: @@ -404,7 +404,7 @@ var cmd = &cobra.Command{ Short: "hello", Args: func(cmd *cobra.Command, args []string) error { if len(args) < 1 { - return errors.New("requires at least one arg") + return errors.New("requires a color argument") } if myapp.IsValidColor(args[0]) { return nil @@ -464,7 +464,7 @@ Echo works a lot like print, except it has a child command.`, } var cmdTimes = &cobra.Command{ - Use: "times [# times] [string to echo]", + Use: "times [string to echo]", Short: "Echo anything to the screen more times", Long: `echo things multiple times back to the user by providing a count and a string.`, @@ -721,6 +721,11 @@ Cobra can generate documentation based on subcommands, flags, etc. in the follow Cobra can generate a bash-completion file. If you add more information to your command, these completions can be amazingly powerful and flexible. Read more about it in [Bash Completions](bash_completions.md). +## Generating zsh completions + +Cobra can generate zsh-completion file. Read more about it in +[Zsh Completions](zsh_completions.md). + # Contributing 1. Fork it diff --git a/vendor/github.com/spf13/cobra/args.go b/vendor/github.com/spf13/cobra/args.go index a5d8a9273..c4d820b85 100644 --- a/vendor/github.com/spf13/cobra/args.go +++ b/vendor/github.com/spf13/cobra/args.go @@ -78,6 +78,18 @@ func ExactArgs(n int) PositionalArgs { } } +// ExactValidArgs returns an error if +// there are not exactly N positional args OR +// there are any positional args that are not in the `ValidArgs` field of `Command` +func ExactValidArgs(n int) PositionalArgs { + return func(cmd *Command, args []string) error { + if err := ExactArgs(n)(cmd, args); err != nil { + return err + } + return OnlyValidArgs(cmd, args) + } +} + // RangeArgs returns an error if the number of args is not within the expected range. func RangeArgs(min int, max int) PositionalArgs { return func(cmd *Command, args []string) error { diff --git a/vendor/github.com/spf13/cobra/args_test.go b/vendor/github.com/spf13/cobra/args_test.go index d797b6f58..c81b212ec 100644 --- a/vendor/github.com/spf13/cobra/args_test.go +++ b/vendor/github.com/spf13/cobra/args_test.go @@ -158,6 +158,52 @@ func TestExactArgsWithInvalidCount(t *testing.T) { } } +func TestExactValidArgs(t *testing.T) { + c := &Command{Use: "c", Args: ExactValidArgs(3), ValidArgs: []string{"a", "b", "c"}, Run: emptyRun} + output, err := executeCommand(c, "a", "b", "c") + if output != "" { + t.Errorf("Unexpected output: %v", output) + } + if err != nil { + t.Errorf("Unexpected error: %v", err) + } +} + +func TestExactValidArgsWithInvalidCount(t *testing.T) { + c := &Command{Use: "c", Args: ExactValidArgs(2), Run: emptyRun} + _, err := executeCommand(c, "a", "b", "c") + + if err == nil { + t.Fatal("Expected an error") + } + + got := err.Error() + expected := "accepts 2 arg(s), received 3" + if got != expected { + t.Fatalf("Expected %q, got %q", expected, got) + } +} + +func TestExactValidArgsWithInvalidArgs(t *testing.T) { + c := &Command{ + Use: "c", + Args: ExactValidArgs(1), + ValidArgs: []string{"one", "two"}, + Run: emptyRun, + } + + _, err := executeCommand(c, "three") + if err == nil { + t.Fatal("Expected an error") + } + + got := err.Error() + expected := `invalid argument "three" for "c"` + if got != expected { + t.Errorf("Expected: %q, got: %q", expected, got) + } +} + func TestRangeArgs(t *testing.T) { c := &Command{Use: "c", Args: RangeArgs(2, 4), Run: emptyRun} output, err := executeCommand(c, "a", "b", "c") diff --git a/vendor/github.com/spf13/cobra/bash_completions.go b/vendor/github.com/spf13/cobra/bash_completions.go index 291eae7d8..57bb8e1b3 100644 --- a/vendor/github.com/spf13/cobra/bash_completions.go +++ b/vendor/github.com/spf13/cobra/bash_completions.go @@ -129,7 +129,13 @@ __%[1]s_handle_reply() fi if [[ ${#COMPREPLY[@]} -eq 0 ]]; then - declare -F __custom_func >/dev/null && __custom_func + if declare -F __%[1]s_custom_func >/dev/null; then + # try command name qualified custom func + __%[1]s_custom_func + else + # otherwise fall back to unqualified for compatibility + declare -F __custom_func >/dev/null && __custom_func + fi fi # available in bash-completion >= 2, not always present on macOS @@ -193,7 +199,8 @@ __%[1]s_handle_flag() fi # skip the argument to a two word flag - if __%[1]s_contains_word "${words[c]}" "${two_word_flags[@]}"; then + if [[ ${words[c]} != *"="* ]] && __%[1]s_contains_word "${words[c]}" "${two_word_flags[@]}"; then + __%[1]s_debug "${FUNCNAME[0]}: found a flag ${words[c]}, skip the next argument" c=$((c+1)) # if we are looking for a flags value, don't show commands if [[ $c -eq $cword ]]; then @@ -251,6 +258,14 @@ __%[1]s_handle_word() __%[1]s_handle_command elif [[ $c -eq 0 ]]; then __%[1]s_handle_command + elif __%[1]s_contains_word "${words[c]}" "${command_aliases[@]}"; then + # aliashash variable is an associative array which is only supported in bash > 3. + if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then + words[c]=${aliashash[${words[c]}]} + __%[1]s_handle_command + else + __%[1]s_handle_noun + fi else __%[1]s_handle_noun fi @@ -266,6 +281,7 @@ func writePostscript(buf *bytes.Buffer, name string) { buf.WriteString(fmt.Sprintf(`{ local cur prev words cword declare -A flaghash 2>/dev/null || : + declare -A aliashash 2>/dev/null || : if declare -F _init_completion >/dev/null 2>&1; then _init_completion -s || return else @@ -305,6 +321,7 @@ func writeCommands(buf *bytes.Buffer, cmd *Command) { continue } buf.WriteString(fmt.Sprintf(" commands+=(%q)\n", c.Name())) + writeCmdAliases(buf, c) } buf.WriteString("\n") } @@ -363,6 +380,10 @@ func writeFlag(buf *bytes.Buffer, flag *pflag.Flag, cmd *Command) { } format += "\")\n" buf.WriteString(fmt.Sprintf(format, name)) + if len(flag.NoOptDefVal) == 0 { + format = " two_word_flags+=(\"--%s\")\n" + buf.WriteString(fmt.Sprintf(format, name)) + } writeFlagHandler(buf, "--"+name, flag.Annotations, cmd) } @@ -443,6 +464,21 @@ func writeRequiredNouns(buf *bytes.Buffer, cmd *Command) { } } +func writeCmdAliases(buf *bytes.Buffer, cmd *Command) { + if len(cmd.Aliases) == 0 { + return + } + + sort.Sort(sort.StringSlice(cmd.Aliases)) + + buf.WriteString(fmt.Sprint(` if [[ -z "${BASH_VERSION}" || "${BASH_VERSINFO[0]}" -gt 3 ]]; then`, "\n")) + for _, value := range cmd.Aliases { + buf.WriteString(fmt.Sprintf(" command_aliases+=(%q)\n", value)) + buf.WriteString(fmt.Sprintf(" aliashash[%q]=%q\n", value, cmd.Name())) + } + buf.WriteString(` fi`) + buf.WriteString("\n") +} func writeArgAliases(buf *bytes.Buffer, cmd *Command) { buf.WriteString(" noun_aliases=()\n") sort.Sort(sort.StringSlice(cmd.ArgAliases)) @@ -469,6 +505,10 @@ func gen(buf *bytes.Buffer, cmd *Command) { } buf.WriteString(fmt.Sprintf(" last_command=%q\n", commandName)) + buf.WriteString("\n") + buf.WriteString(" command_aliases=()\n") + buf.WriteString("\n") + writeCommands(buf, cmd) writeFlags(buf, cmd) writeRequiredFlag(buf, cmd) @@ -505,51 +545,3 @@ func (c *Command) GenBashCompletionFile(filename string) error { return c.GenBashCompletion(outFile) } - -// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists, -// and causes your command to report an error if invoked without the flag. -func (c *Command) MarkFlagRequired(name string) error { - return MarkFlagRequired(c.Flags(), name) -} - -// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists, -// and causes your command to report an error if invoked without the flag. -func (c *Command) MarkPersistentFlagRequired(name string) error { - return MarkFlagRequired(c.PersistentFlags(), name) -} - -// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists, -// and causes your command to report an error if invoked without the flag. -func MarkFlagRequired(flags *pflag.FlagSet, name string) error { - return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"}) -} - -// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists. -// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided. -func (c *Command) MarkFlagFilename(name string, extensions ...string) error { - return MarkFlagFilename(c.Flags(), name, extensions...) -} - -// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists. -// Generated bash autocompletion will call the bash function f for the flag. -func (c *Command) MarkFlagCustom(name string, f string) error { - return MarkFlagCustom(c.Flags(), name, f) -} - -// MarkPersistentFlagFilename adds the BashCompFilenameExt annotation to the named persistent flag, if it exists. -// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided. -func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error { - return MarkFlagFilename(c.PersistentFlags(), name, extensions...) -} - -// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag in the flag set, if it exists. -// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided. -func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error { - return flags.SetAnnotation(name, BashCompFilenameExt, extensions) -} - -// MarkFlagCustom adds the BashCompCustom annotation to the named flag in the flag set, if it exists. -// Generated bash autocompletion will call the bash function f for the flag. -func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error { - return flags.SetAnnotation(name, BashCompCustom, []string{f}) -} diff --git a/vendor/github.com/spf13/cobra/bash_completions.md b/vendor/github.com/spf13/cobra/bash_completions.md index 8d01f456f..4ac61ee13 100644 --- a/vendor/github.com/spf13/cobra/bash_completions.md +++ b/vendor/github.com/spf13/cobra/bash_completions.md @@ -1,5 +1,40 @@ # Generating Bash Completions For Your Own cobra.Command +If you are using the generator you can create a completion command by running + +```bash +cobra add completion +``` + +Update the help text show how to install the bash_completion Linux show here [Kubectl docs show mac options](https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion) + +Writing the shell script to stdout allows the most flexible use. + +```go +// completionCmd represents the completion command +var completionCmd = &cobra.Command{ + Use: "completion", + Short: "Generates bash completion scripts", + Long: `To load completion run + +. <(bitbucket completion) + +To configure your bash shell to load completions for each session add to your bashrc + +# ~/.bashrc or ~/.profile +. <(bitbucket completion) +`, + Run: func(cmd *cobra.Command, args []string) { + rootCmd.GenBashCompletion(os.Stdout); + }, +} +``` + +**Note:** The cobra generator may include messages printed to stdout for example if the config file is loaded, this will break the auto complete script + + +## Example from kubectl + Generating bash completions from a cobra command is incredibly easy. An actual program which does so for the kubernetes kubectl binary is as follows: ```go @@ -47,7 +82,7 @@ __kubectl_get_resource() fi } -__custom_func() { +__kubectl_custom_func() { case ${last_command} in kubectl_get | kubectl_describe | kubectl_delete | kubectl_stop) __kubectl_get_resource @@ -74,7 +109,7 @@ Find more information at https://github.com/GoogleCloudPlatform/kubernetes.`, } ``` -The `BashCompletionFunction` option is really only valid/useful on the root command. Doing the above will cause `__custom_func()` to be called when the built in processor was unable to find a solution. In the case of kubernetes a valid command might look something like `kubectl get pod [mypod]`. If you type `kubectl get pod [tab][tab]` the `__customc_func()` will run because the cobra.Command only understood "kubectl" and "get." `__custom_func()` will see that the cobra.Command is "kubectl_get" and will thus call another helper `__kubectl_get_resource()`. `__kubectl_get_resource` will look at the 'nouns' collected. In our example the only noun will be `pod`. So it will call `__kubectl_parse_get pod`. `__kubectl_parse_get` will actually call out to kubernetes and get any pods. It will then set `COMPREPLY` to valid pods! +The `BashCompletionFunction` option is really only valid/useful on the root command. Doing the above will cause `__kubectl_custom_func()` (`___custom_func()`) to be called when the built in processor was unable to find a solution. In the case of kubernetes a valid command might look something like `kubectl get pod [mypod]`. If you type `kubectl get pod [tab][tab]` the `__kubectl_customc_func()` will run because the cobra.Command only understood "kubectl" and "get." `__kubectl_custom_func()` will see that the cobra.Command is "kubectl_get" and will thus call another helper `__kubectl_get_resource()`. `__kubectl_get_resource` will look at the 'nouns' collected. In our example the only noun will be `pod`. So it will call `__kubectl_parse_get pod`. `__kubectl_parse_get` will actually call out to kubernetes and get any pods. It will then set `COMPREPLY` to valid pods! ## Have the completions code complete your 'nouns' @@ -181,7 +216,7 @@ a custom flag completion function with cobra.BashCompCustom: ```go annotation := make(map[string][]string) - annotation[cobra.BashCompFilenameExt] = []string{"__kubectl_get_namespaces"} + annotation[cobra.BashCompCustom] = []string{"__kubectl_get_namespaces"} flag := &pflag.Flag{ Name: "namespace", diff --git a/vendor/github.com/spf13/cobra/bash_completions_test.go b/vendor/github.com/spf13/cobra/bash_completions_test.go index 02a4f15ba..eefa3de07 100644 --- a/vendor/github.com/spf13/cobra/bash_completions_test.go +++ b/vendor/github.com/spf13/cobra/bash_completions_test.go @@ -22,6 +22,13 @@ func check(t *testing.T, found, expected string) { } } +func checkNumOccurrences(t *testing.T, found, expected string, expectedOccurrences int) { + numOccurrences := strings.Count(found, expected) + if numOccurrences != expectedOccurrences { + t.Errorf("Expecting to contain %d occurrences of: \n %q\nGot %d:\n %q\n", expectedOccurrences, expected, numOccurrences, found) + } +} + func checkRegex(t *testing.T, found, pattern string) { matched, err := regexp.MatchString(pattern, found) if err != nil { @@ -53,7 +60,7 @@ func runShellCheck(s string) error { } // World worst custom function, just keep telling you to enter hello! -const bashCompletionFunc = `__custom_func() { +const bashCompletionFunc = `__root_custom_func() { COMPREPLY=( "hello" ) } ` @@ -64,7 +71,7 @@ func TestBashCompletions(t *testing.T) { ArgAliases: []string{"pods", "nodes", "services", "replicationcontrollers", "po", "no", "svc", "rc"}, ValidArgs: []string{"pod", "node", "service", "replicationcontroller"}, BashCompletionFunction: bashCompletionFunc, - Run: emptyRun, + Run: emptyRun, } rootCmd.Flags().IntP("introot", "i", -1, "help message for flag introot") rootCmd.MarkFlagRequired("introot") @@ -88,6 +95,10 @@ func TestBashCompletions(t *testing.T) { rootCmd.Flags().String("theme", "", "theme to use (located in /themes/THEMENAME/)") rootCmd.Flags().SetAnnotation("theme", BashCompSubdirsInDir, []string{"themes"}) + // For two word flags check + rootCmd.Flags().StringP("two", "t", "", "this is two word flags") + rootCmd.Flags().BoolP("two-w-default", "T", false, "this is not two word flags") + echoCmd := &Command{ Use: "echo [string to echo]", Aliases: []string{"say"}, @@ -150,7 +161,10 @@ func TestBashCompletions(t *testing.T) { // check for required flags check(t, output, `must_have_one_flag+=("--introot=")`) check(t, output, `must_have_one_flag+=("--persistent-filename=")`) - // check for custom completion function + // check for custom completion function with both qualified and unqualified name + checkNumOccurrences(t, output, `__custom_func`, 2) // 1. check existence, 2. invoke + checkNumOccurrences(t, output, `__root_custom_func`, 3) // 1. check existence, 2. invoke, 3. actual definition + // check for custom completion function body check(t, output, `COMPREPLY=( "hello" )`) // check for required nouns check(t, output, `must_have_one_noun+=("pod")`) @@ -173,6 +187,12 @@ func TestBashCompletions(t *testing.T) { // check for subdirs_in_dir flags in a subcommand checkRegex(t, output, fmt.Sprintf(`_root_echo\(\)\n{[^}]*flags_completion\+=\("__%s_handle_subdirs_in_dir_flag config"\)`, rootCmd.Name())) + // check two word flags + check(t, output, `two_word_flags+=("--two")`) + check(t, output, `two_word_flags+=("-t")`) + checkOmit(t, output, `two_word_flags+=("--two-w-default")`) + checkOmit(t, output, `two_word_flags+=("-T")`) + checkOmit(t, output, deprecatedCmd.Name()) // If available, run shellcheck against the script. diff --git a/vendor/github.com/spf13/cobra/cobra.go b/vendor/github.com/spf13/cobra/cobra.go index 7010fd15b..6505c070b 100644 --- a/vendor/github.com/spf13/cobra/cobra.go +++ b/vendor/github.com/spf13/cobra/cobra.go @@ -23,6 +23,7 @@ import ( "strconv" "strings" "text/template" + "time" "unicode" ) @@ -56,6 +57,12 @@ var MousetrapHelpText string = `This is a command line tool. You need to open cmd.exe and run it from there. ` +// MousetrapDisplayDuration controls how long the MousetrapHelpText message is displayed on Windows +// if the CLI is started from explorer.exe. Set to 0 to wait for the return key to be pressed. +// To disable the mousetrap, just set MousetrapHelpText to blank string (""). +// Works only on Microsoft Windows. +var MousetrapDisplayDuration time.Duration = 5 * time.Second + // AddTemplateFunc adds a template function that's available to Usage and Help // template generation. func AddTemplateFunc(name string, tmplFunc interface{}) { diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/add.go b/vendor/github.com/spf13/cobra/cobra/cmd/add.go index fb22096a3..2d240b8a8 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/add.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/add.go @@ -16,24 +16,20 @@ package cmd import ( "fmt" "os" - "path/filepath" "unicode" "github.com/spf13/cobra" ) -func init() { - addCmd.Flags().StringVarP(&packageName, "package", "t", "", "target package name (e.g. github.com/spf13/hugo)") - addCmd.Flags().StringVarP(&parentName, "parent", "p", "rootCmd", "variable name of parent command for this command") -} - -var packageName, parentName string +var ( + packageName string + parentName string -var addCmd = &cobra.Command{ - Use: "add [command name]", - Aliases: []string{"command"}, - Short: "Add a command to a Cobra Application", - Long: `Add (cobra add) will create a new command, with a license and + addCmd = &cobra.Command{ + Use: "add [command name]", + Aliases: []string{"command"}, + Short: "Add a command to a Cobra Application", + Long: `Add (cobra add) will create a new command, with a license and the appropriate structure for a Cobra-based CLI application, and register it to its parent (default rootCmd). @@ -42,28 +38,41 @@ with an initial uppercase letter. Example: cobra add server -> resulting in a new cmd/server.go`, - Run: func(cmd *cobra.Command, args []string) { - if len(args) < 1 { - er("add needs a name for the command") - } + Run: func(cmd *cobra.Command, args []string) { + if len(args) < 1 { + er("add needs a name for the command") + } - var project *Project - if packageName != "" { - project = NewProject(packageName) - } else { wd, err := os.Getwd() if err != nil { er(err) } - project = NewProjectFromPath(wd) - } - cmdName := validateCmdName(args[0]) - cmdPath := filepath.Join(project.CmdPath(), cmdName+".go") - createCmdFile(project.License(), cmdPath, cmdName) + commandName := validateCmdName(args[0]) + command := &Command{ + CmdName: commandName, + CmdParent: parentName, + Project: &Project{ + AbsolutePath: wd, + Legal: getLicense(), + Copyright: copyrightLine(), + }, + } - fmt.Fprintln(cmd.OutOrStdout(), cmdName, "created at", cmdPath) - }, + err = command.Create() + if err != nil { + er(err) + } + + fmt.Printf("%s created at %s", command.CmdName, command.AbsolutePath) + }, + } +) + +func init() { + addCmd.Flags().StringVarP(&packageName, "package", "t", "", "target package name (e.g. github.com/spf13/hugo)") + addCmd.Flags().StringVarP(&parentName, "parent", "p", "rootCmd", "variable name of parent command for this command") + addCmd.Flags().MarkDeprecated("package", "this operation has been removed.") } // validateCmdName returns source without any dashes and underscore. @@ -118,62 +127,3 @@ func validateCmdName(source string) string { } return output } - -func createCmdFile(license License, path, cmdName string) { - template := `{{comment .copyright}} -{{if .license}}{{comment .license}}{{end}} - -package {{.cmdPackage}} - -import ( - "fmt" - - "github.com/spf13/cobra" -) - -// {{.cmdName}}Cmd represents the {{.cmdName}} command -var {{.cmdName}}Cmd = &cobra.Command{ - Use: "{{.cmdName}}", - Short: "A brief description of your command", - Long: ` + "`" + `A longer description that spans multiple lines and likely contains examples -and usage of using your command. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.` + "`" + `, - Run: func(cmd *cobra.Command, args []string) { - fmt.Println("{{.cmdName}} called") - }, -} - -func init() { - {{.parentName}}.AddCommand({{.cmdName}}Cmd) - - // Here you will define your flags and configuration settings. - - // Cobra supports Persistent Flags which will work for this command - // and all subcommands, e.g.: - // {{.cmdName}}Cmd.PersistentFlags().String("foo", "", "A help for foo") - - // Cobra supports local flags which will only run when this command - // is called directly, e.g.: - // {{.cmdName}}Cmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") -} -` - - data := make(map[string]interface{}) - data["copyright"] = copyrightLine() - data["license"] = license.Header - data["cmdPackage"] = filepath.Base(filepath.Dir(path)) // last dir of path - data["parentName"] = parentName - data["cmdName"] = cmdName - - cmdScript, err := executeTemplate(template, data) - if err != nil { - er(err) - } - err = writeStringToFile(path, cmdScript) - if err != nil { - er(err) - } -} diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go index b920e2b9d..0de1d221f 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/add_test.go @@ -1,85 +1,45 @@ package cmd import ( - "errors" - "io/ioutil" + "fmt" "os" - "path/filepath" "testing" - - "github.com/spf13/viper" ) -// TestGoldenAddCmd initializes the project "github.com/spf13/testproject" -// in GOPATH, adds "test" command -// and compares the content of all files in cmd directory of testproject -// with appropriate golden files. -// Use -update to update existing golden files. func TestGoldenAddCmd(t *testing.T) { - projectName := "github.com/spf13/testproject" - project := NewProject(projectName) - defer os.RemoveAll(project.AbsPath()) - - viper.Set("author", "NAME HERE ") - viper.Set("license", "apache") - viper.Set("year", 2017) - defer viper.Set("author", nil) - defer viper.Set("license", nil) - defer viper.Set("year", nil) - - // Initialize the project first. - initializeProject(project) - // Then add the "test" command. - cmdName := "test" - cmdPath := filepath.Join(project.CmdPath(), cmdName+".go") - createCmdFile(project.License(), cmdPath, cmdName) + wd, _ := os.Getwd() + command := &Command{ + CmdName: "test", + CmdParent: parentName, + Project: &Project{ + AbsolutePath: fmt.Sprintf("%s/testproject", wd), + Legal: getLicense(), + Copyright: copyrightLine(), - expectedFiles := []string{".", "root.go", "test.go"} - gotFiles := []string{} - - // Check project file hierarchy and compare the content of every single file - // with appropriate golden file. - err := filepath.Walk(project.CmdPath(), func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } + // required to init + AppName: "testproject", + PkgName: "github.com/spf13/testproject", + Viper: true, + }, + } - // Make path relative to project.CmdPath(). - // E.g. path = "/home/user/go/src/github.com/spf13/testproject/cmd/root.go" - // then it returns just "root.go". - relPath, err := filepath.Rel(project.CmdPath(), path) - if err != nil { - return err + // init project first + command.Project.Create() + defer func() { + if _, err := os.Stat(command.AbsolutePath); err == nil { + os.RemoveAll(command.AbsolutePath) } - relPath = filepath.ToSlash(relPath) - gotFiles = append(gotFiles, relPath) - goldenPath := filepath.Join("testdata", filepath.Base(path)+".golden") + }() - switch relPath { - // Known directories. - case ".": - return nil - // Known files. - case "root.go", "test.go": - if *update { - got, err := ioutil.ReadFile(path) - if err != nil { - return err - } - ioutil.WriteFile(goldenPath, got, 0644) - } - return compareFiles(path, goldenPath) - } - // Unknown file. - return errors.New("unknown file: " + path) - }) - if err != nil { + if err := command.Create(); err != nil { t.Fatal(err) } - // Check if some files lack. - if err := checkLackFiles(expectedFiles, gotFiles); err != nil { + generatedFile := fmt.Sprintf("%s/cmd/%s.go", command.AbsolutePath, command.CmdName) + goldenFile := fmt.Sprintf("testdata/%s.go.golden", command.CmdName) + err := compareFiles(generatedFile, goldenFile) + if err != nil { t.Fatal(err) } } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go index 59a5a1c9f..9010caa13 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/golden_test.go @@ -17,6 +17,11 @@ func init() { initCmd.SetOutput(new(bytes.Buffer)) } +// ensureLF converts any \r\n to \n +func ensureLF(content []byte) []byte { + return bytes.Replace(content, []byte("\r\n"), []byte("\n"), -1) +} + // compareFiles compares the content of files with pathA and pathB. // If contents are equal, it returns nil. // If not, it returns which files are not equal @@ -30,7 +35,7 @@ func compareFiles(pathA, pathB string) error { if err != nil { return err } - if !bytes.Equal(contentA, contentB) { + if !bytes.Equal(ensureLF(contentA), ensureLF(contentB)) { output := new(bytes.Buffer) output.WriteString(fmt.Sprintf("%q and %q are not equal!\n\n", pathA, pathB)) diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/init.go b/vendor/github.com/spf13/cobra/cobra/cmd/init.go index 244137015..63397d119 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/init.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/init.go @@ -15,19 +15,20 @@ package cmd import ( "fmt" - "os" - "path" - "path/filepath" - "github.com/spf13/cobra" "github.com/spf13/viper" + "os" + "path" ) -var initCmd = &cobra.Command{ - Use: "init [name]", - Aliases: []string{"initialize", "initialise", "create"}, - Short: "Initialize a Cobra Application", - Long: `Initialize (cobra init) will create a new application, with a license +var ( + pkgName string + + initCmd = &cobra.Command{ + Use: "init [name]", + Aliases: []string{"initialize", "initialise", "create"}, + Short: "Initialize a Cobra Application", + Long: `Initialize (cobra init) will create a new application, with a license and the appropriate structure for a Cobra-based CLI application. * If a name is provided, it will be created in the current directory; @@ -39,196 +40,38 @@ and the appropriate structure for a Cobra-based CLI application. Init will not use an existing directory with contents.`, - Run: func(cmd *cobra.Command, args []string) { - wd, err := os.Getwd() - if err != nil { - er(err) - } + Run: func(cmd *cobra.Command, args []string) { - var project *Project - if len(args) == 0 { - project = NewProjectFromPath(wd) - } else if len(args) == 1 { - arg := args[0] - if arg[0] == '.' { - arg = filepath.Join(wd, arg) + wd, err := os.Getwd() + if err != nil { + er(err) } - if filepath.IsAbs(arg) { - project = NewProjectFromPath(arg) - } else { - project = NewProject(arg) - } - } else { - er("please provide only one argument") - } - - initializeProject(project) - - fmt.Fprintln(cmd.OutOrStdout(), `Your Cobra application is ready at -`+project.AbsPath()+`. - -Give it a try by going there and running `+"`go run main.go`."+` -Add commands to it by running `+"`cobra add [cmdname]`.") - }, -} - -func initializeProject(project *Project) { - if !exists(project.AbsPath()) { // If path doesn't yet exist, create it - err := os.MkdirAll(project.AbsPath(), os.ModePerm) - if err != nil { - er(err) - } - } else if !isEmpty(project.AbsPath()) { // If path exists and is not empty don't use it - er("Cobra will not create a new project in a non empty directory: " + project.AbsPath()) - } - - // We have a directory and it's empty. Time to initialize it. - createLicenseFile(project.License(), project.AbsPath()) - createMainFile(project) - createRootCmdFile(project) -} -func createLicenseFile(license License, path string) { - data := make(map[string]interface{}) - data["copyright"] = copyrightLine() - - // Generate license template from text and data. - text, err := executeTemplate(license.Text, data) - if err != nil { - er(err) - } - - // Write license text to LICENSE file. - err = writeStringToFile(filepath.Join(path, "LICENSE"), text) - if err != nil { - er(err) - } -} - -func createMainFile(project *Project) { - mainTemplate := `{{ comment .copyright }} -{{if .license}}{{ comment .license }}{{end}} - -package main - -import "{{ .importpath }}" - -func main() { - cmd.Execute() -} -` - data := make(map[string]interface{}) - data["copyright"] = copyrightLine() - data["license"] = project.License().Header - data["importpath"] = path.Join(project.Name(), filepath.Base(project.CmdPath())) - - mainScript, err := executeTemplate(mainTemplate, data) - if err != nil { - er(err) - } - - err = writeStringToFile(filepath.Join(project.AbsPath(), "main.go"), mainScript) - if err != nil { - er(err) - } -} - -func createRootCmdFile(project *Project) { - template := `{{comment .copyright}} -{{if .license}}{{comment .license}}{{end}} - -package cmd - -import ( - "fmt" - "os" -{{if .viper}} - homedir "github.com/mitchellh/go-homedir"{{end}} - "github.com/spf13/cobra"{{if .viper}} - "github.com/spf13/viper"{{end}} -){{if .viper}} - -var cfgFile string{{end}} - -// rootCmd represents the base command when called without any subcommands -var rootCmd = &cobra.Command{ - Use: "{{.appName}}", - Short: "A brief description of your application", - Long: ` + "`" + `A longer description that spans multiple lines and likely contains -examples and usage of using your application. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.` + "`" + `, - // Uncomment the following line if your bare application - // has an action associated with it: - // Run: func(cmd *cobra.Command, args []string) { }, -} - -// Execute adds all child commands to the root command and sets flags appropriately. -// This is called by main.main(). It only needs to happen once to the rootCmd. -func Execute() { - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } -} - -func init() { {{- if .viper}} - cobra.OnInitialize(initConfig) -{{end}} - // Here you will define your flags and configuration settings. - // Cobra supports persistent flags, which, if defined here, - // will be global for your application.{{ if .viper }} - rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)"){{ else }} - // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .appName }}.yaml)"){{ end }} - - // Cobra also supports local flags, which will only run - // when this action is called directly. - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") -}{{ if .viper }} - -// initConfig reads in config file and ENV variables if set. -func initConfig() { - if cfgFile != "" { - // Use config file from the flag. - viper.SetConfigFile(cfgFile) - } else { - // Find home directory. - home, err := homedir.Dir() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - // Search config in home directory with name ".{{ .appName }}" (without extension). - viper.AddConfigPath(home) - viper.SetConfigName(".{{ .appName }}") - } - - viper.AutomaticEnv() // read in environment variables that match - - // If a config file is found, read it in. - if err := viper.ReadInConfig(); err == nil { - fmt.Println("Using config file:", viper.ConfigFileUsed()) - } -}{{ end }} -` + if len(args) > 0 { + if args[0] != "." { + wd = fmt.Sprintf("%s/%s", wd, args[0]) + } + } - data := make(map[string]interface{}) - data["copyright"] = copyrightLine() - data["viper"] = viper.GetBool("useViper") - data["license"] = project.License().Header - data["appName"] = path.Base(project.Name()) + project := &Project{ + AbsolutePath: wd, + PkgName: pkgName, + Legal: getLicense(), + Copyright: copyrightLine(), + Viper: viper.GetBool("useViper"), + AppName: path.Base(pkgName), + } - rootCmdScript, err := executeTemplate(template, data) - if err != nil { - er(err) - } + if err := project.Create(); err != nil { + er(err) + } - err = writeStringToFile(filepath.Join(project.CmdPath(), "root.go"), rootCmdScript) - if err != nil { - er(err) + fmt.Printf("Your Cobra applicaton is ready at\n%s\n", project.AbsolutePath) + }, } +) +func init() { + initCmd.Flags().StringVar(&pkgName, "pkg-name", "", "fully qualified pkg name") + initCmd.MarkFlagRequired("pkg-name") } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go index 40eb4038e..9540b2d30 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/init_test.go @@ -1,83 +1,42 @@ package cmd import ( - "errors" - "io/ioutil" + "fmt" "os" "path/filepath" "testing" - - "github.com/spf13/viper" ) -// TestGoldenInitCmd initializes the project "github.com/spf13/testproject" -// in GOPATH and compares the content of files in initialized project with -// appropriate golden files ("testdata/*.golden"). -// Use -update to update existing golden files. func TestGoldenInitCmd(t *testing.T) { - projectName := "github.com/spf13/testproject" - project := NewProject(projectName) - defer os.RemoveAll(project.AbsPath()) - - viper.Set("author", "NAME HERE ") - viper.Set("license", "apache") - viper.Set("year", 2017) - defer viper.Set("author", nil) - defer viper.Set("license", nil) - defer viper.Set("year", nil) - os.Args = []string{"cobra", "init", projectName} - if err := rootCmd.Execute(); err != nil { - t.Fatal("Error by execution:", err) + wd, _ := os.Getwd() + project := &Project{ + AbsolutePath: fmt.Sprintf("%s/testproject", wd), + PkgName: "github.com/spf13/testproject", + Legal: getLicense(), + Copyright: copyrightLine(), + Viper: true, + AppName: "testproject", } - expectedFiles := []string{".", "cmd", "LICENSE", "main.go", "cmd/root.go"} - gotFiles := []string{} + err := project.Create() + if err != nil { + t.Fatal(err) + } - // Check project file hierarchy and compare the content of every single file - // with appropriate golden file. - err := filepath.Walk(project.AbsPath(), func(path string, info os.FileInfo, err error) error { - if err != nil { - return err + defer func() { + if _, err := os.Stat(project.AbsolutePath); err == nil { + os.RemoveAll(project.AbsolutePath) } + }() - // Make path relative to project.AbsPath(). - // E.g. path = "/home/user/go/src/github.com/spf13/testproject/cmd/root.go" - // then it returns just "cmd/root.go". - relPath, err := filepath.Rel(project.AbsPath(), path) + expectedFiles := []string{"LICENSE", "main.go", "cmd/root.go"} + for _, f := range expectedFiles { + generatedFile := fmt.Sprintf("%s/%s", project.AbsolutePath, f) + goldenFile := fmt.Sprintf("testdata/%s.golden", filepath.Base(f)) + err := compareFiles(generatedFile, goldenFile) if err != nil { - return err + t.Fatal(err) } - relPath = filepath.ToSlash(relPath) - gotFiles = append(gotFiles, relPath) - goldenPath := filepath.Join("testdata", filepath.Base(path)+".golden") - - switch relPath { - // Known directories. - case ".", "cmd": - return nil - // Known files. - case "LICENSE", "main.go", "cmd/root.go": - if *update { - got, err := ioutil.ReadFile(path) - if err != nil { - return err - } - if err := ioutil.WriteFile(goldenPath, got, 0644); err != nil { - t.Fatal("Error while updating file:", err) - } - } - return compareFiles(path, goldenPath) - } - // Unknown file. - return errors.New("unknown file: " + path) - }) - if err != nil { - t.Fatal(err) - } - - // Check if some files lack. - if err := checkLackFiles(expectedFiles, gotFiles); err != nil { - t.Fatal(err) } } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/project.go b/vendor/github.com/spf13/cobra/cobra/cmd/project.go index 7ddb82585..dd2f7ea2f 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/project.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/project.go @@ -1,200 +1,96 @@ package cmd import ( + "fmt" + "github.com/spf13/cobra/cobra/tpl" "os" - "path/filepath" - "runtime" - "strings" + "text/template" ) // Project contains name, license and paths to projects. type Project struct { - absPath string - cmdPath string - srcPath string - license License - name string + // v2 + PkgName string + Copyright string + AbsolutePath string + Legal License + Viper bool + AppName string } -// NewProject returns Project with specified project name. -func NewProject(projectName string) *Project { - if projectName == "" { - er("can't create project with blank name") - } - - p := new(Project) - p.name = projectName - - // 1. Find already created protect. - p.absPath = findPackage(projectName) - - // 2. If there are no created project with this path, and user is in GOPATH, - // then use GOPATH/src/projectName. - if p.absPath == "" { - wd, err := os.Getwd() - if err != nil { - er(err) - } - for _, srcPath := range srcPaths { - goPath := filepath.Dir(srcPath) - if filepathHasPrefix(wd, goPath) { - p.absPath = filepath.Join(srcPath, projectName) - break - } - } - } - - // 3. If user is not in GOPATH, then use (first GOPATH)/src/projectName. - if p.absPath == "" { - p.absPath = filepath.Join(srcPaths[0], projectName) - } - - return p +type Command struct { + CmdName string + CmdParent string + *Project } -// findPackage returns full path to existing go package in GOPATHs. -func findPackage(packageName string) string { - if packageName == "" { - return "" - } +func (p *Project) Create() error { - for _, srcPath := range srcPaths { - packagePath := filepath.Join(srcPath, packageName) - if exists(packagePath) { - return packagePath + // check if AbsolutePath exists + if _, err := os.Stat(p.AbsolutePath); os.IsNotExist(err) { + // create directory + if err := os.Mkdir(p.AbsolutePath, 0754); err != nil { + return err } } - return "" -} - -// NewProjectFromPath returns Project with specified absolute path to -// package. -func NewProjectFromPath(absPath string) *Project { - if absPath == "" { - er("can't create project: absPath can't be blank") - } - if !filepath.IsAbs(absPath) { - er("can't create project: absPath is not absolute") - } - - // If absPath is symlink, use its destination. - fi, err := os.Lstat(absPath) + // create main.go + mainFile, err := os.Create(fmt.Sprintf("%s/main.go", p.AbsolutePath)) if err != nil { - er("can't read path info: " + err.Error()) - } - if fi.Mode()&os.ModeSymlink != 0 { - path, err := os.Readlink(absPath) - if err != nil { - er("can't read the destination of symlink: " + err.Error()) - } - absPath = path + return err } + defer mainFile.Close() - p := new(Project) - p.absPath = strings.TrimSuffix(absPath, findCmdDir(absPath)) - p.name = filepath.ToSlash(trimSrcPath(p.absPath, p.SrcPath())) - return p -} - -// trimSrcPath trims at the beginning of absPath the srcPath. -func trimSrcPath(absPath, srcPath string) string { - relPath, err := filepath.Rel(srcPath, absPath) + mainTemplate := template.Must(template.New("main").Parse(string(tpl.MainTemplate()))) + err = mainTemplate.Execute(mainFile, p) if err != nil { - er(err) - } - return relPath -} - -// License returns the License object of project. -func (p *Project) License() License { - if p.license.Text == "" && p.license.Name != "None" { - p.license = getLicense() - } - return p.license -} - -// Name returns the name of project, e.g. "github.com/spf13/cobra" -func (p Project) Name() string { - return p.name -} - -// CmdPath returns absolute path to directory, where all commands are located. -func (p *Project) CmdPath() string { - if p.absPath == "" { - return "" - } - if p.cmdPath == "" { - p.cmdPath = filepath.Join(p.absPath, findCmdDir(p.absPath)) - } - return p.cmdPath -} - -// findCmdDir checks if base of absPath is cmd dir and returns it or -// looks for existing cmd dir in absPath. -func findCmdDir(absPath string) string { - if !exists(absPath) || isEmpty(absPath) { - return "cmd" + return err } - if isCmdDir(absPath) { - return filepath.Base(absPath) + // create cmd/root.go + if _, err = os.Stat(fmt.Sprintf("%s/cmd", p.AbsolutePath)); os.IsNotExist(err) { + os.Mkdir(fmt.Sprintf("%s/cmd", p.AbsolutePath), 0751) } - - files, _ := filepath.Glob(filepath.Join(absPath, "c*")) - for _, file := range files { - if isCmdDir(file) { - return filepath.Base(file) - } + rootFile, err := os.Create(fmt.Sprintf("%s/cmd/root.go", p.AbsolutePath)) + if err != nil { + return err } + defer rootFile.Close() - return "cmd" -} - -// isCmdDir checks if base of name is one of cmdDir. -func isCmdDir(name string) bool { - name = filepath.Base(name) - for _, cmdDir := range []string{"cmd", "cmds", "command", "commands"} { - if name == cmdDir { - return true - } + rootTemplate := template.Must(template.New("root").Parse(string(tpl.RootTemplate()))) + err = rootTemplate.Execute(rootFile, p) + if err != nil { + return err } - return false -} -// AbsPath returns absolute path of project. -func (p Project) AbsPath() string { - return p.absPath + // create license + return p.createLicenseFile() } -// SrcPath returns absolute path to $GOPATH/src where project is located. -func (p *Project) SrcPath() string { - if p.srcPath != "" { - return p.srcPath - } - if p.absPath == "" { - p.srcPath = srcPaths[0] - return p.srcPath +func (p *Project) createLicenseFile() error { + data := map[string]interface{}{ + "copyright": copyrightLine(), } - - for _, srcPath := range srcPaths { - if filepathHasPrefix(p.absPath, srcPath) { - p.srcPath = srcPath - break - } + licenseFile, err := os.Create(fmt.Sprintf("%s/LICENSE", p.AbsolutePath)) + if err != nil { + return err } - return p.srcPath + licenseTemplate := template.Must(template.New("license").Parse(p.Legal.Text)) + return licenseTemplate.Execute(licenseFile, data) } -func filepathHasPrefix(path string, prefix string) bool { - if len(path) <= len(prefix) { - return false - } - if runtime.GOOS == "windows" { - // Paths in windows are case-insensitive. - return strings.EqualFold(path[0:len(prefix)], prefix) +func (c *Command) Create() error { + cmdFile, err := os.Create(fmt.Sprintf("%s/cmd/%s.go", c.AbsolutePath, c.CmdName)) + if err != nil { + return err } - return path[0:len(prefix)] == prefix + defer cmdFile.Close() + commandTemplate := template.Must(template.New("sub").Parse(string(tpl.AddCommandTemplate()))) + err = commandTemplate.Execute(cmdFile, c) + if err != nil { + return err + } + return nil } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/project_test.go b/vendor/github.com/spf13/cobra/cobra/cmd/project_test.go index 037f7c554..ed5b054a2 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/project_test.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/project_test.go @@ -1,24 +1,3 @@ package cmd -import ( - "testing" -) - -func TestFindExistingPackage(t *testing.T) { - path := findPackage("github.com/spf13/cobra") - if path == "" { - t.Fatal("findPackage didn't find the existing package") - } - if !hasGoPathPrefix(path) { - t.Fatalf("%q is not in GOPATH, but must be", path) - } -} - -func hasGoPathPrefix(path string) bool { - for _, srcPath := range srcPaths { - if filepathHasPrefix(path, srcPath) { - return true - } - } - return false -} +/* todo: write tests */ diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/root.go b/vendor/github.com/spf13/cobra/cobra/cmd/root.go index 19568f980..624c717c1 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/root.go +++ b/vendor/github.com/spf13/cobra/cobra/cmd/root.go @@ -23,7 +23,8 @@ import ( var ( // Used for flags. - cfgFile, userLicense string + cfgFile string + userLicense string rootCmd = &cobra.Command{ Use: "cobra", diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/main.go.golden b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/main.go.golden index cdbe38d70..4ad570c54 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/main.go.golden +++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/main.go.golden @@ -1,21 +1,22 @@ -// Copyright © 2017 NAME HERE -// -// 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. +/* +Copyright © 2019 NAME HERE +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ package main import "github.com/spf13/testproject/cmd" func main() { - cmd.Execute() + cmd.Execute() } diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/root.go.golden b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/root.go.golden index d74f4cd45..d3b889baa 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/root.go.golden +++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/root.go.golden @@ -1,89 +1,97 @@ -// Copyright © 2017 NAME HERE -// -// 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. +/* +Copyright © 2019 NAME HERE +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ package cmd import ( - "fmt" - "os" + "fmt" + "os" + "github.com/spf13/cobra" + + homedir "github.com/mitchellh/go-homedir" + "github.com/spf13/viper" - homedir "github.com/mitchellh/go-homedir" - "github.com/spf13/cobra" - "github.com/spf13/viper" ) + var cfgFile string + // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ - Use: "testproject", - Short: "A brief description of your application", - Long: `A longer description that spans multiple lines and likely contains + Use: "testproject", + Short: "A brief description of your application", + Long: `A longer description that spans multiple lines and likely contains examples and usage of using your application. For example: Cobra is a CLI library for Go that empowers applications. This application is a tool to generate the needed files to quickly create a Cobra application.`, - // Uncomment the following line if your bare application - // has an action associated with it: - // Run: func(cmd *cobra.Command, args []string) { }, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, } // Execute adds all child commands to the root command and sets flags appropriately. // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { - if err := rootCmd.Execute(); err != nil { - fmt.Println(err) - os.Exit(1) - } + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } } func init() { - cobra.OnInitialize(initConfig) + cobra.OnInitialize(initConfig) + + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. - // Here you will define your flags and configuration settings. - // Cobra supports persistent flags, which, if defined here, - // will be global for your application. - rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.testproject.yaml)") + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.testproject.yaml)") - // Cobra also supports local flags, which will only run - // when this action is called directly. - rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + + // Cobra also supports local flags, which will only run + // when this action is called directly. + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") } + // initConfig reads in config file and ENV variables if set. func initConfig() { - if cfgFile != "" { - // Use config file from the flag. - viper.SetConfigFile(cfgFile) - } else { - // Find home directory. - home, err := homedir.Dir() - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - // Search config in home directory with name ".testproject" (without extension). - viper.AddConfigPath(home) - viper.SetConfigName(".testproject") - } - - viper.AutomaticEnv() // read in environment variables that match - - // If a config file is found, read it in. - if err := viper.ReadInConfig(); err == nil { - fmt.Println("Using config file:", viper.ConfigFileUsed()) - } + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := homedir.Dir() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Search config in home directory with name ".testproject" (without extension). + viper.AddConfigPath(home) + viper.SetConfigName(".testproject") + } + + viper.AutomaticEnv() // read in environment variables that match + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + fmt.Println("Using config file:", viper.ConfigFileUsed()) + } } + diff --git a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/test.go.golden b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/test.go.golden index ed6442755..fb8e0fa90 100644 --- a/vendor/github.com/spf13/cobra/cobra/cmd/testdata/test.go.golden +++ b/vendor/github.com/spf13/cobra/cobra/cmd/testdata/test.go.golden @@ -1,17 +1,18 @@ -// Copyright © 2017 NAME HERE -// -// 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. +/* +Copyright © 2019 NAME HERE +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ package cmd import ( diff --git a/vendor/github.com/spf13/cobra/cobra/tpl/main.go b/vendor/github.com/spf13/cobra/cobra/tpl/main.go new file mode 100644 index 000000000..5e5a0fae2 --- /dev/null +++ b/vendor/github.com/spf13/cobra/cobra/tpl/main.go @@ -0,0 +1,153 @@ +package tpl + +func MainTemplate() []byte { + return []byte(`/* +{{ .Copyright }} +{{ if .Legal.Header }}{{ .Legal.Header }}{{ end }} +*/ +package main + +import "{{ .PkgName }}/cmd" + +func main() { + cmd.Execute() +} +`) +} + +func RootTemplate() []byte { + return []byte(`/* +{{ .Copyright }} +{{ if .Legal.Header }}{{ .Legal.Header }}{{ end }} +*/ +package cmd + +import ( + "fmt" + "os" + "github.com/spf13/cobra" +{{ if .Viper }} + homedir "github.com/mitchellh/go-homedir" + "github.com/spf13/viper" +{{ end }} +) + +{{ if .Viper }} +var cfgFile string +{{ end }} + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "{{ .AppName }}", + Short: "A brief description of your application", + Long: ` + "`" + `A longer description that spans multiple lines and likely contains +examples and usage of using your application. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.` + "`" + `, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func init() { +{{- if .Viper }} + cobra.OnInitialize(initConfig) +{{ end }} + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. +{{ if .Viper }} + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .AppName }}.yaml)") +{{ else }} + // rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.{{ .AppName }}.yaml)") +{{ end }} + + // Cobra also supports local flags, which will only run + // when this action is called directly. + rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} + +{{ if .Viper }} +// initConfig reads in config file and ENV variables if set. +func initConfig() { + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := homedir.Dir() + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + // Search config in home directory with name ".{{ .AppName }}" (without extension). + viper.AddConfigPath(home) + viper.SetConfigName(".{{ .AppName }}") + } + + viper.AutomaticEnv() // read in environment variables that match + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + fmt.Println("Using config file:", viper.ConfigFileUsed()) + } +} +{{ end }} +`) +} + +func AddCommandTemplate() []byte { + return []byte(`/* +{{ .Project.Copyright }} +{{ if .Legal.Header }}{{ .Legal.Header }}{{ end }} +*/ +package cmd + +import ( + "fmt" + + "github.com/spf13/cobra" +) + +// {{ .CmdName }}Cmd represents the {{ .CmdName }} command +var {{ .CmdName }}Cmd = &cobra.Command{ + Use: "{{ .CmdName }}", + Short: "A brief description of your command", + Long: ` + "`" + `A longer description that spans multiple lines and likely contains examples +and usage of using your command. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.` + "`" + `, + Run: func(cmd *cobra.Command, args []string) { + fmt.Println("{{ .CmdName }} called") + }, +} + +func init() { + {{ .CmdParent }}.AddCommand({{ .CmdName }}Cmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // {{ .CmdName }}Cmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // {{ .CmdName }}Cmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") +} +`) +} diff --git a/vendor/github.com/spf13/cobra/command.go b/vendor/github.com/spf13/cobra/command.go index 15b811279..c7e898303 100644 --- a/vendor/github.com/spf13/cobra/command.go +++ b/vendor/github.com/spf13/cobra/command.go @@ -27,6 +27,9 @@ import ( flag "github.com/spf13/pflag" ) +// FParseErrWhitelist configures Flag parse errors to be ignored +type FParseErrWhitelist flag.ParseErrorsWhitelist + // Command is just that, a command for your application. // E.g. 'go run ...' - 'run' is the command. Cobra requires // you to define the usage and description as part of your command @@ -137,6 +140,9 @@ type Command struct { // TraverseChildren parses flags on all parents before executing child command. TraverseChildren bool + //FParseErrWhitelist flag parse errors to be ignored + FParseErrWhitelist FParseErrWhitelist + // commands is the list of commands supported by this program. commands []*Command // parent is a parent command for this command. @@ -171,8 +177,6 @@ type Command struct { // that we can use on every pflag set and children commands globNormFunc func(f *flag.FlagSet, name string) flag.NormalizedName - // output is an output writer defined by user. - output io.Writer // usageFunc is usage func defined by user. usageFunc func(*Command) error // usageTemplate is usage template defined by user. @@ -189,6 +193,13 @@ type Command struct { helpCommand *Command // versionTemplate is the version template defined by user. versionTemplate string + + // inReader is a reader defined by the user that replaces stdin + inReader io.Reader + // outWriter is a writer defined by the user that replaces stdout + outWriter io.Writer + // errWriter is a writer defined by the user that replaces stderr + errWriter io.Writer } // SetArgs sets arguments for the command. It is set to os.Args[1:] by default, if desired, can be overridden @@ -199,8 +210,28 @@ func (c *Command) SetArgs(a []string) { // SetOutput sets the destination for usage and error messages. // If output is nil, os.Stderr is used. +// Deprecated: Use SetOut and/or SetErr instead func (c *Command) SetOutput(output io.Writer) { - c.output = output + c.outWriter = output + c.errWriter = output +} + +// SetOut sets the destination for usage messages. +// If newOut is nil, os.Stdout is used. +func (c *Command) SetOut(newOut io.Writer) { + c.outWriter = newOut +} + +// SetErr sets the destination for error messages. +// If newErr is nil, os.Stderr is used. +func (c *Command) SetErr(newErr io.Writer) { + c.errWriter = newErr +} + +// SetOut sets the source for input data +// If newIn is nil, os.Stdin is used. +func (c *Command) SetIn(newIn io.Reader) { + c.inReader = newIn } // SetUsageFunc sets usage function. Usage can be defined by application. @@ -261,9 +292,19 @@ func (c *Command) OutOrStderr() io.Writer { return c.getOut(os.Stderr) } +// ErrOrStderr returns output to stderr +func (c *Command) ErrOrStderr() io.Writer { + return c.getErr(os.Stderr) +} + +// ErrOrStderr returns output to stderr +func (c *Command) InOrStdin() io.Reader { + return c.getIn(os.Stdin) +} + func (c *Command) getOut(def io.Writer) io.Writer { - if c.output != nil { - return c.output + if c.outWriter != nil { + return c.outWriter } if c.HasParent() { return c.parent.getOut(def) @@ -271,6 +312,26 @@ func (c *Command) getOut(def io.Writer) io.Writer { return def } +func (c *Command) getErr(def io.Writer) io.Writer { + if c.errWriter != nil { + return c.errWriter + } + if c.HasParent() { + return c.parent.getErr(def) + } + return def +} + +func (c *Command) getIn(def io.Reader) io.Reader { + if c.inReader != nil { + return c.inReader + } + if c.HasParent() { + return c.parent.getIn(def) + } + return def +} + // UsageFunc returns either the function set by SetUsageFunc for this command // or a parent, or it returns a default usage function. func (c *Command) UsageFunc() (f func(*Command) error) { @@ -323,13 +384,22 @@ func (c *Command) Help() error { return nil } -// UsageString return usage string. +// UsageString returns usage string. func (c *Command) UsageString() string { - tmpOutput := c.output + // Storing normal writers + tmpOutput := c.outWriter + tmpErr := c.errWriter + bb := new(bytes.Buffer) - c.SetOutput(bb) + c.outWriter = bb + c.errWriter = bb + c.Usage() - c.output = tmpOutput + + // Setting things back to normal + c.outWriter = tmpOutput + c.errWriter = tmpErr + return bb.String() } @@ -811,13 +881,11 @@ func (c *Command) ExecuteC() (cmd *Command, err error) { // overriding c.InitDefaultHelpCmd() - var args []string + args := c.args // Workaround FAIL with "go test -v" or "cobra.test -test.v", see #155 if c.args == nil && filepath.Base(os.Args[0]) != "cobra.test" { args = os.Args[1:] - } else { - args = c.args } var flags []string @@ -1064,6 +1132,21 @@ func (c *Command) Printf(format string, i ...interface{}) { c.Print(fmt.Sprintf(format, i...)) } +// PrintErr is a convenience method to Print to the defined Err output, fallback to Stderr if not set. +func (c *Command) PrintErr(i ...interface{}) { + fmt.Fprint(c.ErrOrStderr(), i...) +} + +// PrintErrln is a convenience method to Println to the defined Err output, fallback to Stderr if not set. +func (c *Command) PrintErrln(i ...interface{}) { + c.Print(fmt.Sprintln(i...)) +} + +// PrintErrf is a convenience method to Printf to the defined Err output, fallback to Stderr if not set. +func (c *Command) PrintErrf(format string, i ...interface{}) { + c.Print(fmt.Sprintf(format, i...)) +} + // CommandPath returns the full path to this command. func (c *Command) CommandPath() string { if c.HasParent() { @@ -1329,7 +1412,7 @@ func (c *Command) LocalFlags() *flag.FlagSet { return c.lflags } -// InheritedFlags returns all flags which were inherited from parents commands. +// InheritedFlags returns all flags which were inherited from parent commands. func (c *Command) InheritedFlags() *flag.FlagSet { c.mergePersistentFlags() @@ -1463,6 +1546,10 @@ func (c *Command) ParseFlags(args []string) error { } beforeErrorBufLen := c.flagErrorBuf.Len() c.mergePersistentFlags() + + //do it here after merging all flags and just before parse + c.Flags().ParseErrorsWhitelist = flag.ParseErrorsWhitelist(c.FParseErrWhitelist) + err := c.Flags().Parse(args) // Print warnings if they occurred (e.g. deprecated flag messages). if c.flagErrorBuf.Len()-beforeErrorBufLen > 0 && err == nil { diff --git a/vendor/github.com/spf13/cobra/command_test.go b/vendor/github.com/spf13/cobra/command_test.go index d874a9a51..2fa2003cb 100644 --- a/vendor/github.com/spf13/cobra/command_test.go +++ b/vendor/github.com/spf13/cobra/command_test.go @@ -1164,12 +1164,13 @@ func TestPersistentHooks(t *testing.T) { t.Errorf("Unexpected error: %v", err) } - // TODO: This test fails, but should not. - // Related to https://github.com/spf13/cobra/issues/252. - // - // if parentPersPreArgs != "one two" { - // t.Errorf("Expected parentPersPreArgs %q, got %q", "one two", parentPersPreArgs) - // } + // TODO: currently PersistenPreRun* defined in parent does not + // run if the matchin child subcommand has PersistenPreRun. + // If the behavior changes (https://github.com/spf13/cobra/issues/252) + // this test must be fixed. + if parentPersPreArgs != "" { + t.Errorf("Expected blank parentPersPreArgs, got %q", parentPersPreArgs) + } if parentPreArgs != "" { t.Errorf("Expected blank parentPreArgs, got %q", parentPreArgs) } @@ -1179,12 +1180,13 @@ func TestPersistentHooks(t *testing.T) { if parentPostArgs != "" { t.Errorf("Expected blank parentPostArgs, got %q", parentPostArgs) } - // TODO: This test fails, but should not. - // Related to https://github.com/spf13/cobra/issues/252. - // - // if parentPersPostArgs != "one two" { - // t.Errorf("Expected parentPersPostArgs %q, got %q", "one two", parentPersPostArgs) - // } + // TODO: currently PersistenPostRun* defined in parent does not + // run if the matchin child subcommand has PersistenPostRun. + // If the behavior changes (https://github.com/spf13/cobra/issues/252) + // this test must be fixed. + if parentPersPostArgs != "" { + t.Errorf("Expected blank parentPersPostArgs, got %q", parentPersPostArgs) + } if childPersPreArgs != "one two" { t.Errorf("Expected childPersPreArgs %q, got %q", "one two", childPersPreArgs) @@ -1379,6 +1381,46 @@ func TestSetOutput(t *testing.T) { } } +func TestSetOut(t *testing.T) { + c := &Command{} + c.SetOut(nil) + if out := c.OutOrStdout(); out != os.Stdout { + t.Errorf("Expected setting output to nil to revert back to stdout") + } +} + +func TestSetErr(t *testing.T) { + c := &Command{} + c.SetErr(nil) + if out := c.ErrOrStderr(); out != os.Stderr { + t.Errorf("Expected setting error to nil to revert back to stderr") + } +} + +func TestSetIn(t *testing.T) { + c := &Command{} + c.SetIn(nil) + if out := c.InOrStdin(); out != os.Stdin { + t.Errorf("Expected setting input to nil to revert back to stdin") + } +} + +func TestUsageStringRedirected(t *testing.T) { + c := &Command{} + + c.usageFunc = func(cmd *Command) error { + cmd.Print("[stdout1]") + cmd.PrintErr("[stderr2]") + cmd.Print("[stdout3]") + return nil + } + + expected := "[stdout1][stderr2][stdout3]" + if got := c.UsageString(); got != expected { + t.Errorf("Expected usage string to consider both stdout and stderr") + } +} + func TestFlagErrorFunc(t *testing.T) { c := &Command{Use: "c", Run: emptyRun} @@ -1626,3 +1668,108 @@ func TestCalledAs(t *testing.T) { t.Run(name, tc.test) } } + +func TestFParseErrWhitelistBackwardCompatibility(t *testing.T) { + c := &Command{Use: "c", Run: emptyRun} + c.Flags().BoolP("boola", "a", false, "a boolean flag") + + output, err := executeCommand(c, "c", "-a", "--unknown", "flag") + if err == nil { + t.Error("expected unknown flag error") + } + checkStringContains(t, output, "unknown flag: --unknown") +} + +func TestFParseErrWhitelistSameCommand(t *testing.T) { + c := &Command{ + Use: "c", + Run: emptyRun, + FParseErrWhitelist: FParseErrWhitelist{ + UnknownFlags: true, + }, + } + c.Flags().BoolP("boola", "a", false, "a boolean flag") + + _, err := executeCommand(c, "c", "-a", "--unknown", "flag") + if err != nil { + t.Error("unexpected error: ", err) + } +} + +func TestFParseErrWhitelistParentCommand(t *testing.T) { + root := &Command{ + Use: "root", + Run: emptyRun, + FParseErrWhitelist: FParseErrWhitelist{ + UnknownFlags: true, + }, + } + + c := &Command{ + Use: "child", + Run: emptyRun, + } + c.Flags().BoolP("boola", "a", false, "a boolean flag") + + root.AddCommand(c) + + output, err := executeCommand(root, "child", "-a", "--unknown", "flag") + if err == nil { + t.Error("expected unknown flag error") + } + checkStringContains(t, output, "unknown flag: --unknown") +} + +func TestFParseErrWhitelistChildCommand(t *testing.T) { + root := &Command{ + Use: "root", + Run: emptyRun, + } + + c := &Command{ + Use: "child", + Run: emptyRun, + FParseErrWhitelist: FParseErrWhitelist{ + UnknownFlags: true, + }, + } + c.Flags().BoolP("boola", "a", false, "a boolean flag") + + root.AddCommand(c) + + _, err := executeCommand(root, "child", "-a", "--unknown", "flag") + if err != nil { + t.Error("unexpected error: ", err.Error()) + } +} + +func TestFParseErrWhitelistSiblingCommand(t *testing.T) { + root := &Command{ + Use: "root", + Run: emptyRun, + } + + c := &Command{ + Use: "child", + Run: emptyRun, + FParseErrWhitelist: FParseErrWhitelist{ + UnknownFlags: true, + }, + } + c.Flags().BoolP("boola", "a", false, "a boolean flag") + + s := &Command{ + Use: "sibling", + Run: emptyRun, + } + s.Flags().BoolP("boolb", "b", false, "a boolean flag") + + root.AddCommand(c) + root.AddCommand(s) + + output, err := executeCommand(root, "sibling", "-b", "--unknown", "flag") + if err == nil { + t.Error("expected unknown flag error") + } + checkStringContains(t, output, "unknown flag: --unknown") +} diff --git a/vendor/github.com/spf13/cobra/command_win.go b/vendor/github.com/spf13/cobra/command_win.go index edec728e4..8768b1736 100644 --- a/vendor/github.com/spf13/cobra/command_win.go +++ b/vendor/github.com/spf13/cobra/command_win.go @@ -3,6 +3,7 @@ package cobra import ( + "fmt" "os" "time" @@ -14,7 +15,12 @@ var preExecHookFn = preExecHook func preExecHook(c *Command) { if MousetrapHelpText != "" && mousetrap.StartedByExplorer() { c.Print(MousetrapHelpText) - time.Sleep(5 * time.Second) + if MousetrapDisplayDuration > 0 { + time.Sleep(MousetrapDisplayDuration) + } else { + c.Println("Press return to continue...") + fmt.Scanln() + } os.Exit(1) } } diff --git a/vendor/github.com/spf13/cobra/doc/man_docs.go b/vendor/github.com/spf13/cobra/doc/man_docs.go index ce92332dd..4a0623393 100644 --- a/vendor/github.com/spf13/cobra/doc/man_docs.go +++ b/vendor/github.com/spf13/cobra/doc/man_docs.go @@ -20,6 +20,7 @@ import ( "os" "path/filepath" "sort" + "strconv" "strings" "time" @@ -87,7 +88,7 @@ type GenManTreeOptions struct { // GenManHeader is a lot like the .TH header at the start of man pages. These // include the title, section, date, source, and manual. We will use the -// current time if Date if unset and will use "Auto generated by spf13/cobra" +// current time if Date is unset and will use "Auto generated by spf13/cobra" // if the Source is unset. type GenManHeader struct { Title string @@ -104,14 +105,16 @@ func GenMan(cmd *cobra.Command, header *GenManHeader, w io.Writer) error { if header == nil { header = &GenManHeader{} } - fillHeader(header, cmd.CommandPath()) + if err := fillHeader(header, cmd.CommandPath()); err != nil { + return err + } b := genMan(cmd, header) _, err := w.Write(md2man.Render(b)) return err } -func fillHeader(header *GenManHeader, name string) { +func fillHeader(header *GenManHeader, name string) error { if header.Title == "" { header.Title = strings.ToUpper(strings.Replace(name, " ", "\\-", -1)) } @@ -120,12 +123,20 @@ func fillHeader(header *GenManHeader, name string) { } if header.Date == nil { now := time.Now() + if epoch := os.Getenv("SOURCE_DATE_EPOCH"); epoch != "" { + unixEpoch, err := strconv.ParseInt(epoch, 10, 64) + if err != nil { + return fmt.Errorf("invalid SOURCE_DATE_EPOCH: %v", err) + } + now = time.Unix(unixEpoch, 0) + } header.Date = &now } header.date = (*header.Date).Format("Jan 2006") if header.Source == "" { header.Source = "Auto generated by spf13/cobra" } + return nil } func manPreamble(buf *bytes.Buffer, header *GenManHeader, cmd *cobra.Command, dashedName string) { @@ -176,13 +187,13 @@ func manPrintFlags(buf *bytes.Buffer, flags *pflag.FlagSet) { func manPrintOptions(buf *bytes.Buffer, command *cobra.Command) { flags := command.NonInheritedFlags() - if flags.HasFlags() { + if flags.HasAvailableFlags() { buf.WriteString("# OPTIONS\n") manPrintFlags(buf, flags) buf.WriteString("\n") } flags = command.InheritedFlags() - if flags.HasFlags() { + if flags.HasAvailableFlags() { buf.WriteString("# OPTIONS INHERITED FROM PARENT COMMANDS\n") manPrintFlags(buf, flags) buf.WriteString("\n") diff --git a/vendor/github.com/spf13/cobra/doc/man_docs_test.go b/vendor/github.com/spf13/cobra/doc/man_docs_test.go index 62f85e47f..2c400f5df 100644 --- a/vendor/github.com/spf13/cobra/doc/man_docs_test.go +++ b/vendor/github.com/spf13/cobra/doc/man_docs_test.go @@ -47,6 +47,42 @@ func TestGenManDoc(t *testing.T) { checkStringContains(t, output, translate("Auto generated")) } +func TestGenManNoHiddenParents(t *testing.T) { + header := &GenManHeader{ + Title: "Project", + Section: "2", + } + + // We generate on a subcommand so we have both subcommands and parents + for _, name := range []string{"rootflag", "strtwo"} { + f := rootCmd.PersistentFlags().Lookup(name) + f.Hidden = true + defer func() { f.Hidden = false }() + } + buf := new(bytes.Buffer) + if err := GenMan(echoCmd, header, buf); err != nil { + t.Fatal(err) + } + output := buf.String() + + // Make sure parent has - in CommandPath() in SEE ALSO: + parentPath := echoCmd.Parent().CommandPath() + dashParentPath := strings.Replace(parentPath, " ", "-", -1) + expected := translate(dashParentPath) + expected = expected + "(" + header.Section + ")" + checkStringContains(t, output, expected) + + checkStringContains(t, output, translate(echoCmd.Name())) + checkStringContains(t, output, translate(echoCmd.Name())) + checkStringContains(t, output, "boolone") + checkStringOmits(t, output, "rootflag") + checkStringContains(t, output, translate(rootCmd.Name())) + checkStringContains(t, output, translate(echoSubCmd.Name())) + checkStringOmits(t, output, translate(deprecatedCmd.Name())) + checkStringContains(t, output, translate("Auto generated")) + checkStringOmits(t, output, "OPTIONS INHERITED FROM PARENT COMMANDS") +} + func TestGenManNoGenTag(t *testing.T) { echoCmd.DisableAutoGenTag = true defer func() { echoCmd.DisableAutoGenTag = false }() diff --git a/vendor/github.com/spf13/cobra/doc/md_docs.go b/vendor/github.com/spf13/cobra/doc/md_docs.go index d7a2c2b62..d76f6d5ec 100644 --- a/vendor/github.com/spf13/cobra/doc/md_docs.go +++ b/vendor/github.com/spf13/cobra/doc/md_docs.go @@ -29,7 +29,7 @@ import ( func printOptions(buf *bytes.Buffer, cmd *cobra.Command, name string) error { flags := cmd.NonInheritedFlags() flags.SetOutput(buf) - if flags.HasFlags() { + if flags.HasAvailableFlags() { buf.WriteString("### Options\n\n```\n") flags.PrintDefaults() buf.WriteString("```\n\n") @@ -37,7 +37,7 @@ func printOptions(buf *bytes.Buffer, cmd *cobra.Command, name string) error { parentFlags := cmd.InheritedFlags() parentFlags.SetOutput(buf) - if parentFlags.HasFlags() { + if parentFlags.HasAvailableFlags() { buf.WriteString("### Options inherited from parent commands\n\n```\n") parentFlags.PrintDefaults() buf.WriteString("```\n\n") diff --git a/vendor/github.com/spf13/cobra/doc/md_docs_test.go b/vendor/github.com/spf13/cobra/doc/md_docs_test.go index b0fa68c0b..c060f32f7 100644 --- a/vendor/github.com/spf13/cobra/doc/md_docs_test.go +++ b/vendor/github.com/spf13/cobra/doc/md_docs_test.go @@ -25,6 +25,30 @@ func TestGenMdDoc(t *testing.T) { checkStringContains(t, output, rootCmd.Short) checkStringContains(t, output, echoSubCmd.Short) checkStringOmits(t, output, deprecatedCmd.Short) + checkStringContains(t, output, "Options inherited from parent commands") +} + +func TestGenMdNoHiddenParents(t *testing.T) { + // We generate on subcommand so we have both subcommands and parents. + for _, name := range []string{"rootflag", "strtwo"} { + f := rootCmd.PersistentFlags().Lookup(name) + f.Hidden = true + defer func() { f.Hidden = false }() + } + buf := new(bytes.Buffer) + if err := GenMarkdown(echoCmd, buf); err != nil { + t.Fatal(err) + } + output := buf.String() + + checkStringContains(t, output, echoCmd.Long) + checkStringContains(t, output, echoCmd.Example) + checkStringContains(t, output, "boolone") + checkStringOmits(t, output, "rootflag") + checkStringContains(t, output, rootCmd.Short) + checkStringContains(t, output, echoSubCmd.Short) + checkStringOmits(t, output, deprecatedCmd.Short) + checkStringOmits(t, output, "Options inherited from parent commands") } func TestGenMdNoTag(t *testing.T) { diff --git a/vendor/github.com/spf13/cobra/doc/rest_docs.go b/vendor/github.com/spf13/cobra/doc/rest_docs.go index 4913e3ee2..051d8dc83 100644 --- a/vendor/github.com/spf13/cobra/doc/rest_docs.go +++ b/vendor/github.com/spf13/cobra/doc/rest_docs.go @@ -29,7 +29,7 @@ import ( func printOptionsReST(buf *bytes.Buffer, cmd *cobra.Command, name string) error { flags := cmd.NonInheritedFlags() flags.SetOutput(buf) - if flags.HasFlags() { + if flags.HasAvailableFlags() { buf.WriteString("Options\n") buf.WriteString("~~~~~~~\n\n::\n\n") flags.PrintDefaults() @@ -38,7 +38,7 @@ func printOptionsReST(buf *bytes.Buffer, cmd *cobra.Command, name string) error parentFlags := cmd.InheritedFlags() parentFlags.SetOutput(buf) - if parentFlags.HasFlags() { + if parentFlags.HasAvailableFlags() { buf.WriteString("Options inherited from parent commands\n") buf.WriteString("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n::\n\n") parentFlags.PrintDefaults() diff --git a/vendor/github.com/spf13/cobra/doc/rest_docs_test.go b/vendor/github.com/spf13/cobra/doc/rest_docs_test.go index aa3186e8f..330a2e5e7 100644 --- a/vendor/github.com/spf13/cobra/doc/rest_docs_test.go +++ b/vendor/github.com/spf13/cobra/doc/rest_docs_test.go @@ -27,6 +27,29 @@ func TestGenRSTDoc(t *testing.T) { checkStringOmits(t, output, deprecatedCmd.Short) } +func TestGenRSTNoHiddenParents(t *testing.T) { + // We generate on a subcommand so we have both subcommands and parents + for _, name := range []string{"rootflag", "strtwo"} { + f := rootCmd.PersistentFlags().Lookup(name) + f.Hidden = true + defer func() { f.Hidden = false }() + } + buf := new(bytes.Buffer) + if err := GenReST(echoCmd, buf); err != nil { + t.Fatal(err) + } + output := buf.String() + + checkStringContains(t, output, echoCmd.Long) + checkStringContains(t, output, echoCmd.Example) + checkStringContains(t, output, "boolone") + checkStringOmits(t, output, "rootflag") + checkStringContains(t, output, rootCmd.Short) + checkStringContains(t, output, echoSubCmd.Short) + checkStringOmits(t, output, deprecatedCmd.Short) + checkStringOmits(t, output, "Options inherited from parent commands") +} + func TestGenRSTNoTag(t *testing.T) { rootCmd.DisableAutoGenTag = true defer func() { rootCmd.DisableAutoGenTag = false }() diff --git a/vendor/github.com/spf13/cobra/go.mod b/vendor/github.com/spf13/cobra/go.mod new file mode 100644 index 000000000..9a9eb65a3 --- /dev/null +++ b/vendor/github.com/spf13/cobra/go.mod @@ -0,0 +1,13 @@ +module github.com/spf13/cobra + +go 1.12 + +require ( + github.com/BurntSushi/toml v0.3.1 // indirect + github.com/cpuguy83/go-md2man v1.0.10 + github.com/inconshreveable/mousetrap v1.0.0 + github.com/mitchellh/go-homedir v1.1.0 + github.com/spf13/pflag v1.0.3 + github.com/spf13/viper v1.3.2 + gopkg.in/yaml.v2 v2.2.2 +) diff --git a/vendor/github.com/spf13/cobra/go.sum b/vendor/github.com/spf13/cobra/go.sum new file mode 100644 index 000000000..9761f4d03 --- /dev/null +++ b/vendor/github.com/spf13/cobra/go.sum @@ -0,0 +1,51 @@ +github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/spf13/cobra/powershell_completions.go b/vendor/github.com/spf13/cobra/powershell_completions.go new file mode 100644 index 000000000..756c61b9d --- /dev/null +++ b/vendor/github.com/spf13/cobra/powershell_completions.go @@ -0,0 +1,100 @@ +// PowerShell completions are based on the amazing work from clap: +// https://github.com/clap-rs/clap/blob/3294d18efe5f264d12c9035f404c7d189d4824e1/src/completions/powershell.rs +// +// The generated scripts require PowerShell v5.0+ (which comes Windows 10, but +// can be downloaded separately for windows 7 or 8.1). + +package cobra + +import ( + "bytes" + "fmt" + "io" + "os" + "strings" + + "github.com/spf13/pflag" +) + +var powerShellCompletionTemplate = `using namespace System.Management.Automation +using namespace System.Management.Automation.Language +Register-ArgumentCompleter -Native -CommandName '%s' -ScriptBlock { + param($wordToComplete, $commandAst, $cursorPosition) + $commandElements = $commandAst.CommandElements + $command = @( + '%s' + for ($i = 1; $i -lt $commandElements.Count; $i++) { + $element = $commandElements[$i] + if ($element -isnot [StringConstantExpressionAst] -or + $element.StringConstantType -ne [StringConstantType]::BareWord -or + $element.Value.StartsWith('-')) { + break + } + $element.Value + } + ) -join ';' + $completions = @(switch ($command) {%s + }) + $completions.Where{ $_.CompletionText -like "$wordToComplete*" } | + Sort-Object -Property ListItemText +}` + +func generatePowerShellSubcommandCases(out io.Writer, cmd *Command, previousCommandName string) { + var cmdName string + if previousCommandName == "" { + cmdName = cmd.Name() + } else { + cmdName = fmt.Sprintf("%s;%s", previousCommandName, cmd.Name()) + } + + fmt.Fprintf(out, "\n '%s' {", cmdName) + + cmd.Flags().VisitAll(func(flag *pflag.Flag) { + if nonCompletableFlag(flag) { + return + } + usage := escapeStringForPowerShell(flag.Usage) + if len(flag.Shorthand) > 0 { + fmt.Fprintf(out, "\n [CompletionResult]::new('-%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Shorthand, flag.Shorthand, usage) + } + fmt.Fprintf(out, "\n [CompletionResult]::new('--%s', '%s', [CompletionResultType]::ParameterName, '%s')", flag.Name, flag.Name, usage) + }) + + for _, subCmd := range cmd.Commands() { + usage := escapeStringForPowerShell(subCmd.Short) + fmt.Fprintf(out, "\n [CompletionResult]::new('%s', '%s', [CompletionResultType]::ParameterValue, '%s')", subCmd.Name(), subCmd.Name(), usage) + } + + fmt.Fprint(out, "\n break\n }") + + for _, subCmd := range cmd.Commands() { + generatePowerShellSubcommandCases(out, subCmd, cmdName) + } +} + +func escapeStringForPowerShell(s string) string { + return strings.Replace(s, "'", "''", -1) +} + +// GenPowerShellCompletion generates PowerShell completion file and writes to the passed writer. +func (c *Command) GenPowerShellCompletion(w io.Writer) error { + buf := new(bytes.Buffer) + + var subCommandCases bytes.Buffer + generatePowerShellSubcommandCases(&subCommandCases, c, "") + fmt.Fprintf(buf, powerShellCompletionTemplate, c.Name(), c.Name(), subCommandCases.String()) + + _, err := buf.WriteTo(w) + return err +} + +// GenPowerShellCompletionFile generates PowerShell completion file. +func (c *Command) GenPowerShellCompletionFile(filename string) error { + outFile, err := os.Create(filename) + if err != nil { + return err + } + defer outFile.Close() + + return c.GenPowerShellCompletion(outFile) +} diff --git a/vendor/github.com/spf13/cobra/powershell_completions.md b/vendor/github.com/spf13/cobra/powershell_completions.md new file mode 100644 index 000000000..afed80240 --- /dev/null +++ b/vendor/github.com/spf13/cobra/powershell_completions.md @@ -0,0 +1,14 @@ +# Generating PowerShell Completions For Your Own cobra.Command + +Cobra can generate PowerShell completion scripts. Users need PowerShell version 5.0 or above, which comes with Windows 10 and can be downloaded separately for Windows 7 or 8.1. They can then write the completions to a file and source this file from their PowerShell profile, which is referenced by the `$Profile` environment variable. See `Get-Help about_Profiles` for more info about PowerShell profiles. + +# What's supported + +- Completion for subcommands using their `.Short` description +- Completion for non-hidden flags using their `.Name` and `.Shorthand` + +# What's not yet supported + +- Command aliases +- Required, filename or custom flags (they will work like normal flags) +- Custom completion scripts diff --git a/vendor/github.com/spf13/cobra/powershell_completions_test.go b/vendor/github.com/spf13/cobra/powershell_completions_test.go new file mode 100644 index 000000000..29b609de0 --- /dev/null +++ b/vendor/github.com/spf13/cobra/powershell_completions_test.go @@ -0,0 +1,122 @@ +package cobra + +import ( + "bytes" + "strings" + "testing" +) + +func TestPowerShellCompletion(t *testing.T) { + tcs := []struct { + name string + root *Command + expectedExpressions []string + }{ + { + name: "trivial", + root: &Command{Use: "trivialapp"}, + expectedExpressions: []string{ + "Register-ArgumentCompleter -Native -CommandName 'trivialapp' -ScriptBlock", + "$command = @(\n 'trivialapp'\n", + }, + }, + { + name: "tree", + root: func() *Command { + r := &Command{Use: "tree"} + + sub1 := &Command{Use: "sub1"} + r.AddCommand(sub1) + + sub11 := &Command{Use: "sub11"} + sub12 := &Command{Use: "sub12"} + + sub1.AddCommand(sub11) + sub1.AddCommand(sub12) + + sub2 := &Command{Use: "sub2"} + r.AddCommand(sub2) + + sub21 := &Command{Use: "sub21"} + sub22 := &Command{Use: "sub22"} + + sub2.AddCommand(sub21) + sub2.AddCommand(sub22) + + return r + }(), + expectedExpressions: []string{ + "'tree'", + "[CompletionResult]::new('sub1', 'sub1', [CompletionResultType]::ParameterValue, '')", + "[CompletionResult]::new('sub2', 'sub2', [CompletionResultType]::ParameterValue, '')", + "'tree;sub1'", + "[CompletionResult]::new('sub11', 'sub11', [CompletionResultType]::ParameterValue, '')", + "[CompletionResult]::new('sub12', 'sub12', [CompletionResultType]::ParameterValue, '')", + "'tree;sub1;sub11'", + "'tree;sub1;sub12'", + "'tree;sub2'", + "[CompletionResult]::new('sub21', 'sub21', [CompletionResultType]::ParameterValue, '')", + "[CompletionResult]::new('sub22', 'sub22', [CompletionResultType]::ParameterValue, '')", + "'tree;sub2;sub21'", + "'tree;sub2;sub22'", + }, + }, + { + name: "flags", + root: func() *Command { + r := &Command{Use: "flags"} + r.Flags().StringP("flag1", "a", "", "") + r.Flags().String("flag2", "", "") + + sub1 := &Command{Use: "sub1"} + sub1.Flags().StringP("flag3", "c", "", "") + r.AddCommand(sub1) + + return r + }(), + expectedExpressions: []string{ + "'flags'", + "[CompletionResult]::new('-a', 'a', [CompletionResultType]::ParameterName, '')", + "[CompletionResult]::new('--flag1', 'flag1', [CompletionResultType]::ParameterName, '')", + "[CompletionResult]::new('--flag2', 'flag2', [CompletionResultType]::ParameterName, '')", + "[CompletionResult]::new('sub1', 'sub1', [CompletionResultType]::ParameterValue, '')", + "'flags;sub1'", + "[CompletionResult]::new('-c', 'c', [CompletionResultType]::ParameterName, '')", + "[CompletionResult]::new('--flag3', 'flag3', [CompletionResultType]::ParameterName, '')", + }, + }, + { + name: "usage", + root: func() *Command { + r := &Command{Use: "usage"} + r.Flags().String("flag", "", "this describes the usage of the 'flag' flag") + + sub1 := &Command{ + Use: "sub1", + Short: "short describes 'sub1'", + } + r.AddCommand(sub1) + + return r + }(), + expectedExpressions: []string{ + "[CompletionResult]::new('--flag', 'flag', [CompletionResultType]::ParameterName, 'this describes the usage of the ''flag'' flag')", + "[CompletionResult]::new('sub1', 'sub1', [CompletionResultType]::ParameterValue, 'short describes ''sub1''')", + }, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + buf := new(bytes.Buffer) + tc.root.GenPowerShellCompletion(buf) + output := buf.String() + + for _, expectedExpression := range tc.expectedExpressions { + if !strings.Contains(output, expectedExpression) { + t.Errorf("Expected completion to contain %q somewhere; got %q", expectedExpression, output) + } + } + }) + } +} diff --git a/vendor/github.com/spf13/cobra/shell_completions.go b/vendor/github.com/spf13/cobra/shell_completions.go new file mode 100644 index 000000000..ba0af9cb5 --- /dev/null +++ b/vendor/github.com/spf13/cobra/shell_completions.go @@ -0,0 +1,85 @@ +package cobra + +import ( + "github.com/spf13/pflag" +) + +// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists, +// and causes your command to report an error if invoked without the flag. +func (c *Command) MarkFlagRequired(name string) error { + return MarkFlagRequired(c.Flags(), name) +} + +// MarkPersistentFlagRequired adds the BashCompOneRequiredFlag annotation to the named persistent flag if it exists, +// and causes your command to report an error if invoked without the flag. +func (c *Command) MarkPersistentFlagRequired(name string) error { + return MarkFlagRequired(c.PersistentFlags(), name) +} + +// MarkFlagRequired adds the BashCompOneRequiredFlag annotation to the named flag if it exists, +// and causes your command to report an error if invoked without the flag. +func MarkFlagRequired(flags *pflag.FlagSet, name string) error { + return flags.SetAnnotation(name, BashCompOneRequiredFlag, []string{"true"}) +} + +// MarkFlagFilename adds the BashCompFilenameExt annotation to the named flag, if it exists. +// Generated bash autocompletion will select filenames for the flag, limiting to named extensions if provided. +func (c *Command) MarkFlagFilename(name string, extensions ...string) error { + return MarkFlagFilename(c.Flags(), name, extensions...) +} + +// MarkFlagCustom adds the BashCompCustom annotation to the named flag, if it exists. +// Generated bash autocompletion will call the bash function f for the flag. +func (c *Command) MarkFlagCustom(name string, f string) error { + return MarkFlagCustom(c.Flags(), name, f) +} + +// MarkPersistentFlagFilename instructs the various shell completion +// implementations to limit completions for this persistent flag to the +// specified extensions (patterns). +// +// Shell Completion compatibility matrix: bash, zsh +func (c *Command) MarkPersistentFlagFilename(name string, extensions ...string) error { + return MarkFlagFilename(c.PersistentFlags(), name, extensions...) +} + +// MarkFlagFilename instructs the various shell completion implementations to +// limit completions for this flag to the specified extensions (patterns). +// +// Shell Completion compatibility matrix: bash, zsh +func MarkFlagFilename(flags *pflag.FlagSet, name string, extensions ...string) error { + return flags.SetAnnotation(name, BashCompFilenameExt, extensions) +} + +// MarkFlagCustom instructs the various shell completion implementations to +// limit completions for this flag to the specified extensions (patterns). +// +// Shell Completion compatibility matrix: bash, zsh +func MarkFlagCustom(flags *pflag.FlagSet, name string, f string) error { + return flags.SetAnnotation(name, BashCompCustom, []string{f}) +} + +// MarkFlagDirname instructs the various shell completion implementations to +// complete only directories with this named flag. +// +// Shell Completion compatibility matrix: zsh +func (c *Command) MarkFlagDirname(name string) error { + return MarkFlagDirname(c.Flags(), name) +} + +// MarkPersistentFlagDirname instructs the various shell completion +// implementations to complete only directories with this persistent named flag. +// +// Shell Completion compatibility matrix: zsh +func (c *Command) MarkPersistentFlagDirname(name string) error { + return MarkFlagDirname(c.PersistentFlags(), name) +} + +// MarkFlagDirname instructs the various shell completion implementations to +// complete only directories with this specified flag. +// +// Shell Completion compatibility matrix: zsh +func MarkFlagDirname(flags *pflag.FlagSet, name string) error { + zshPattern := "-(/)" + return flags.SetAnnotation(name, zshCompDirname, []string{zshPattern}) +} diff --git a/vendor/github.com/spf13/cobra/zsh_completions.go b/vendor/github.com/spf13/cobra/zsh_completions.go index 889c22e27..12755482f 100644 --- a/vendor/github.com/spf13/cobra/zsh_completions.go +++ b/vendor/github.com/spf13/cobra/zsh_completions.go @@ -1,13 +1,102 @@ package cobra import ( - "bytes" + "encoding/json" "fmt" "io" "os" + "sort" "strings" + "text/template" + + "github.com/spf13/pflag" +) + +const ( + zshCompArgumentAnnotation = "cobra_annotations_zsh_completion_argument_annotation" + zshCompArgumentFilenameComp = "cobra_annotations_zsh_completion_argument_file_completion" + zshCompArgumentWordComp = "cobra_annotations_zsh_completion_argument_word_completion" + zshCompDirname = "cobra_annotations_zsh_dirname" +) + +var ( + zshCompFuncMap = template.FuncMap{ + "genZshFuncName": zshCompGenFuncName, + "extractFlags": zshCompExtractFlag, + "genFlagEntryForZshArguments": zshCompGenFlagEntryForArguments, + "extractArgsCompletions": zshCompExtractArgumentCompletionHintsForRendering, + } + zshCompletionText = ` +{{/* should accept Command (that contains subcommands) as parameter */}} +{{define "argumentsC" -}} +{{ $cmdPath := genZshFuncName .}} +function {{$cmdPath}} { + local -a commands + + _arguments -C \{{- range extractFlags .}} + {{genFlagEntryForZshArguments .}} \{{- end}} + "1: :->cmnds" \ + "*::arg:->args" + + case $state in + cmnds) + commands=({{range .Commands}}{{if not .Hidden}} + "{{.Name}}:{{.Short}}"{{end}}{{end}} + ) + _describe "command" commands + ;; + esac + + case "$words[1]" in {{- range .Commands}}{{if not .Hidden}} + {{.Name}}) + {{$cmdPath}}_{{.Name}} + ;;{{end}}{{end}} + esac +} +{{range .Commands}}{{if not .Hidden}} +{{template "selectCmdTemplate" .}} +{{- end}}{{end}} +{{- end}} + +{{/* should accept Command without subcommands as parameter */}} +{{define "arguments" -}} +function {{genZshFuncName .}} { +{{" _arguments"}}{{range extractFlags .}} \ + {{genFlagEntryForZshArguments . -}} +{{end}}{{range extractArgsCompletions .}} \ + {{.}}{{end}} +} +{{end}} + +{{/* dispatcher for commands with or without subcommands */}} +{{define "selectCmdTemplate" -}} +{{if .Hidden}}{{/* ignore hidden*/}}{{else -}} +{{if .Commands}}{{template "argumentsC" .}}{{else}}{{template "arguments" .}}{{end}} +{{- end}} +{{- end}} + +{{/* template entry point */}} +{{define "Main" -}} +#compdef _{{.Name}} {{.Name}} + +{{template "selectCmdTemplate" .}} +{{end}} +` ) +// zshCompArgsAnnotation is used to encode/decode zsh completion for +// arguments to/from Command.Annotations. +type zshCompArgsAnnotation map[int]zshCompArgHint + +type zshCompArgHint struct { + // Indicates the type of the completion to use. One of: + // zshCompArgumentFilenameComp or zshCompArgumentWordComp + Tipe string `json:"type"` + + // A value for the type above (globs for file completion or words) + Options []string `json:"options"` +} + // GenZshCompletionFile generates zsh completion file. func (c *Command) GenZshCompletionFile(filename string) error { outFile, err := os.Create(filename) @@ -19,108 +108,229 @@ func (c *Command) GenZshCompletionFile(filename string) error { return c.GenZshCompletion(outFile) } -// GenZshCompletion generates a zsh completion file and writes to the passed writer. +// GenZshCompletion generates a zsh completion file and writes to the passed +// writer. The completion always run on the root command regardless of the +// command it was called from. func (c *Command) GenZshCompletion(w io.Writer) error { - buf := new(bytes.Buffer) - - writeHeader(buf, c) - maxDepth := maxDepth(c) - writeLevelMapping(buf, maxDepth) - writeLevelCases(buf, maxDepth, c) + tmpl, err := template.New("Main").Funcs(zshCompFuncMap).Parse(zshCompletionText) + if err != nil { + return fmt.Errorf("error creating zsh completion template: %v", err) + } + return tmpl.Execute(w, c.Root()) +} - _, err := buf.WriteTo(w) - return err +// MarkZshCompPositionalArgumentFile marks the specified argument (first +// argument is 1) as completed by file selection. patterns (e.g. "*.txt") are +// optional - if not provided the completion will search for all files. +func (c *Command) MarkZshCompPositionalArgumentFile(argPosition int, patterns ...string) error { + if argPosition < 1 { + return fmt.Errorf("Invalid argument position (%d)", argPosition) + } + annotation, err := c.zshCompGetArgsAnnotations() + if err != nil { + return err + } + if c.zshcompArgsAnnotationnIsDuplicatePosition(annotation, argPosition) { + return fmt.Errorf("Duplicate annotation for positional argument at index %d", argPosition) + } + annotation[argPosition] = zshCompArgHint{ + Tipe: zshCompArgumentFilenameComp, + Options: patterns, + } + return c.zshCompSetArgsAnnotations(annotation) } -func writeHeader(w io.Writer, cmd *Command) { - fmt.Fprintf(w, "#compdef %s\n\n", cmd.Name()) +// MarkZshCompPositionalArgumentWords marks the specified positional argument +// (first argument is 1) as completed by the provided words. At east one word +// must be provided, spaces within words will be offered completion with +// "word\ word". +func (c *Command) MarkZshCompPositionalArgumentWords(argPosition int, words ...string) error { + if argPosition < 1 { + return fmt.Errorf("Invalid argument position (%d)", argPosition) + } + if len(words) == 0 { + return fmt.Errorf("Trying to set empty word list for positional argument %d", argPosition) + } + annotation, err := c.zshCompGetArgsAnnotations() + if err != nil { + return err + } + if c.zshcompArgsAnnotationnIsDuplicatePosition(annotation, argPosition) { + return fmt.Errorf("Duplicate annotation for positional argument at index %d", argPosition) + } + annotation[argPosition] = zshCompArgHint{ + Tipe: zshCompArgumentWordComp, + Options: words, + } + return c.zshCompSetArgsAnnotations(annotation) } -func maxDepth(c *Command) int { - if len(c.Commands()) == 0 { - return 0 +func zshCompExtractArgumentCompletionHintsForRendering(c *Command) ([]string, error) { + var result []string + annotation, err := c.zshCompGetArgsAnnotations() + if err != nil { + return nil, err } - maxDepthSub := 0 - for _, s := range c.Commands() { - subDepth := maxDepth(s) - if subDepth > maxDepthSub { - maxDepthSub = subDepth + for k, v := range annotation { + s, err := zshCompRenderZshCompArgHint(k, v) + if err != nil { + return nil, err } + result = append(result, s) } - return 1 + maxDepthSub + if len(c.ValidArgs) > 0 { + if _, positionOneExists := annotation[1]; !positionOneExists { + s, err := zshCompRenderZshCompArgHint(1, zshCompArgHint{ + Tipe: zshCompArgumentWordComp, + Options: c.ValidArgs, + }) + if err != nil { + return nil, err + } + result = append(result, s) + } + } + sort.Strings(result) + return result, nil } -func writeLevelMapping(w io.Writer, numLevels int) { - fmt.Fprintln(w, `_arguments \`) - for i := 1; i <= numLevels; i++ { - fmt.Fprintf(w, ` '%d: :->level%d' \`, i, i) - fmt.Fprintln(w) +func zshCompRenderZshCompArgHint(i int, z zshCompArgHint) (string, error) { + switch t := z.Tipe; t { + case zshCompArgumentFilenameComp: + var globs []string + for _, g := range z.Options { + globs = append(globs, fmt.Sprintf(`-g "%s"`, g)) + } + return fmt.Sprintf(`'%d: :_files %s'`, i, strings.Join(globs, " ")), nil + case zshCompArgumentWordComp: + var words []string + for _, w := range z.Options { + words = append(words, fmt.Sprintf("%q", w)) + } + return fmt.Sprintf(`'%d: :(%s)'`, i, strings.Join(words, " ")), nil + default: + return "", fmt.Errorf("Invalid zsh argument completion annotation: %s", t) } - fmt.Fprintf(w, ` '%d: :%s'`, numLevels+1, "_files") - fmt.Fprintln(w) } -func writeLevelCases(w io.Writer, maxDepth int, root *Command) { - fmt.Fprintln(w, "case $state in") - defer fmt.Fprintln(w, "esac") +func (c *Command) zshcompArgsAnnotationnIsDuplicatePosition(annotation zshCompArgsAnnotation, position int) bool { + _, dup := annotation[position] + return dup +} - for i := 1; i <= maxDepth; i++ { - fmt.Fprintf(w, " level%d)\n", i) - writeLevel(w, root, i) - fmt.Fprintln(w, " ;;") +func (c *Command) zshCompGetArgsAnnotations() (zshCompArgsAnnotation, error) { + annotation := make(zshCompArgsAnnotation) + annotationString, ok := c.Annotations[zshCompArgumentAnnotation] + if !ok { + return annotation, nil + } + err := json.Unmarshal([]byte(annotationString), &annotation) + if err != nil { + return annotation, fmt.Errorf("Error unmarshaling zsh argument annotation: %v", err) } - fmt.Fprintln(w, " *)") - fmt.Fprintln(w, " _arguments '*: :_files'") - fmt.Fprintln(w, " ;;") + return annotation, nil } -func writeLevel(w io.Writer, root *Command, i int) { - fmt.Fprintf(w, " case $words[%d] in\n", i) - defer fmt.Fprintln(w, " esac") - - commands := filterByLevel(root, i) - byParent := groupByParent(commands) +func (c *Command) zshCompSetArgsAnnotations(annotation zshCompArgsAnnotation) error { + jsn, err := json.Marshal(annotation) + if err != nil { + return fmt.Errorf("Error marshaling zsh argument annotation: %v", err) + } + if c.Annotations == nil { + c.Annotations = make(map[string]string) + } + c.Annotations[zshCompArgumentAnnotation] = string(jsn) + return nil +} - for p, c := range byParent { - names := names(c) - fmt.Fprintf(w, " %s)\n", p) - fmt.Fprintf(w, " _arguments '%d: :(%s)'\n", i, strings.Join(names, " ")) - fmt.Fprintln(w, " ;;") +func zshCompGenFuncName(c *Command) string { + if c.HasParent() { + return zshCompGenFuncName(c.Parent()) + "_" + c.Name() } - fmt.Fprintln(w, " *)") - fmt.Fprintln(w, " _arguments '*: :_files'") - fmt.Fprintln(w, " ;;") + return "_" + c.Name() +} +func zshCompExtractFlag(c *Command) []*pflag.Flag { + var flags []*pflag.Flag + c.LocalFlags().VisitAll(func(f *pflag.Flag) { + if !f.Hidden { + flags = append(flags, f) + } + }) + c.InheritedFlags().VisitAll(func(f *pflag.Flag) { + if !f.Hidden { + flags = append(flags, f) + } + }) + return flags } -func filterByLevel(c *Command, l int) []*Command { - cs := make([]*Command, 0) - if l == 0 { - cs = append(cs, c) - return cs +// zshCompGenFlagEntryForArguments returns an entry that matches _arguments +// zsh-completion parameters. It's too complicated to generate in a template. +func zshCompGenFlagEntryForArguments(f *pflag.Flag) string { + if f.Name == "" || f.Shorthand == "" { + return zshCompGenFlagEntryForSingleOptionFlag(f) } - for _, s := range c.Commands() { - cs = append(cs, filterByLevel(s, l-1)...) + return zshCompGenFlagEntryForMultiOptionFlag(f) +} + +func zshCompGenFlagEntryForSingleOptionFlag(f *pflag.Flag) string { + var option, multiMark, extras string + + if zshCompFlagCouldBeSpecifiedMoreThenOnce(f) { + multiMark = "*" } - return cs + + option = "--" + f.Name + if option == "--" { + option = "-" + f.Shorthand + } + extras = zshCompGenFlagEntryExtras(f) + + return fmt.Sprintf(`'%s%s[%s]%s'`, multiMark, option, zshCompQuoteFlagDescription(f.Usage), extras) } -func groupByParent(commands []*Command) map[string][]*Command { - m := make(map[string][]*Command) - for _, c := range commands { - parent := c.Parent() - if parent == nil { - continue - } - m[parent.Name()] = append(m[parent.Name()], c) +func zshCompGenFlagEntryForMultiOptionFlag(f *pflag.Flag) string { + var options, parenMultiMark, curlyMultiMark, extras string + + if zshCompFlagCouldBeSpecifiedMoreThenOnce(f) { + parenMultiMark = "*" + curlyMultiMark = "\\*" } - return m + + options = fmt.Sprintf(`'(%s-%s %s--%s)'{%s-%s,%s--%s}`, + parenMultiMark, f.Shorthand, parenMultiMark, f.Name, curlyMultiMark, f.Shorthand, curlyMultiMark, f.Name) + extras = zshCompGenFlagEntryExtras(f) + + return fmt.Sprintf(`%s'[%s]%s'`, options, zshCompQuoteFlagDescription(f.Usage), extras) } -func names(commands []*Command) []string { - ns := make([]string, len(commands)) - for i, c := range commands { - ns[i] = c.Name() +func zshCompGenFlagEntryExtras(f *pflag.Flag) string { + if f.NoOptDefVal != "" { + return "" } - return ns + + extras := ":" // allow options for flag (even without assistance) + for key, values := range f.Annotations { + switch key { + case zshCompDirname: + extras = fmt.Sprintf(":filename:_files -g %q", values[0]) + case BashCompFilenameExt: + extras = ":filename:_files" + for _, pattern := range values { + extras = extras + fmt.Sprintf(` -g "%s"`, pattern) + } + } + } + + return extras +} + +func zshCompFlagCouldBeSpecifiedMoreThenOnce(f *pflag.Flag) bool { + return strings.Contains(f.Value.Type(), "Slice") || + strings.Contains(f.Value.Type(), "Array") +} + +func zshCompQuoteFlagDescription(s string) string { + return strings.Replace(s, "'", `'\''`, -1) } diff --git a/vendor/github.com/spf13/cobra/zsh_completions.md b/vendor/github.com/spf13/cobra/zsh_completions.md new file mode 100644 index 000000000..df9c2eac9 --- /dev/null +++ b/vendor/github.com/spf13/cobra/zsh_completions.md @@ -0,0 +1,39 @@ +## Generating Zsh Completion for your cobra.Command + +Cobra supports native Zsh completion generated from the root `cobra.Command`. +The generated completion script should be put somewhere in your `$fpath` named +`_`. + +### What's Supported + +* Completion for all non-hidden subcommands using their `.Short` description. +* Completion for all non-hidden flags using the following rules: + * Filename completion works by marking the flag with `cmd.MarkFlagFilename...` + family of commands. + * The requirement for argument to the flag is decided by the `.NoOptDefVal` + flag value - if it's empty then completion will expect an argument. + * Flags of one of the various `*Array` and `*Slice` types supports multiple + specifications (with or without argument depending on the specific type). +* Completion of positional arguments using the following rules: + * Argument position for all options below starts at `1`. If argument position + `0` is requested it will raise an error. + * Use `command.MarkZshCompPositionalArgumentFile` to complete filenames. Glob + patterns (e.g. `"*.log"`) are optional - if not specified it will offer to + complete all file types. + * Use `command.MarkZshCompPositionalArgumentWords` to offer specific words for + completion. At least one word is required. + * It's possible to specify completion for some arguments and leave some + unspecified (e.g. offer words for second argument but nothing for first + argument). This will cause no completion for first argument but words + completion for second argument. + * If no argument completion was specified for 1st argument (but optionally was + specified for 2nd) and the command has `ValidArgs` it will be used as + completion options for 1st argument. + * Argument completions only offered for commands with no subcommands. + +### What's not yet Supported + +* Custom completion scripts are not supported yet (We should probably create zsh + specific one, doesn't make sense to re-use the bash one as the functions will + be different). +* Whatever other feature you're looking for and doesn't exist :) diff --git a/vendor/github.com/spf13/cobra/zsh_completions_test.go b/vendor/github.com/spf13/cobra/zsh_completions_test.go index 34e69496f..e53fa886e 100644 --- a/vendor/github.com/spf13/cobra/zsh_completions_test.go +++ b/vendor/github.com/spf13/cobra/zsh_completions_test.go @@ -2,88 +2,474 @@ package cobra import ( "bytes" + "regexp" "strings" "testing" ) -func TestZshCompletion(t *testing.T) { +func TestGenZshCompletion(t *testing.T) { + var debug bool + var option string + tcs := []struct { name string root *Command expectedExpressions []string + invocationArgs []string + skip string }{ { - name: "trivial", - root: &Command{Use: "trivialapp"}, - expectedExpressions: []string{"#compdef trivial"}, + name: "simple command", + root: func() *Command { + r := &Command{ + Use: "mycommand", + Long: "My Command long description", + Run: emptyRun, + } + r.Flags().BoolVar(&debug, "debug", debug, "description") + return r + }(), + expectedExpressions: []string{ + `(?s)function _mycommand {\s+_arguments \\\s+'--debug\[description\]'.*--help.*}`, + "#compdef _mycommand mycommand", + }, }, { - name: "linear", + name: "flags with both long and short flags", root: func() *Command { - r := &Command{Use: "linear"} - - sub1 := &Command{Use: "sub1"} - r.AddCommand(sub1) - - sub2 := &Command{Use: "sub2"} - sub1.AddCommand(sub2) - - sub3 := &Command{Use: "sub3"} - sub2.AddCommand(sub3) + r := &Command{ + Use: "testcmd", + Long: "long description", + Run: emptyRun, + } + r.Flags().BoolVarP(&debug, "debug", "d", debug, "debug description") return r }(), - expectedExpressions: []string{"sub1", "sub2", "sub3"}, + expectedExpressions: []string{ + `'\(-d --debug\)'{-d,--debug}'\[debug description\]'`, + }, }, { - name: "flat", + name: "command with subcommands and flags with values", root: func() *Command { - r := &Command{Use: "flat"} - r.AddCommand(&Command{Use: "c1"}) - r.AddCommand(&Command{Use: "c2"}) + r := &Command{ + Use: "rootcmd", + Long: "Long rootcmd description", + } + d := &Command{ + Use: "subcmd1", + Short: "Subcmd1 short description", + Run: emptyRun, + } + e := &Command{ + Use: "subcmd2", + Long: "Subcmd2 short description", + Run: emptyRun, + } + r.PersistentFlags().BoolVar(&debug, "debug", debug, "description") + d.Flags().StringVarP(&option, "option", "o", option, "option description") + r.AddCommand(d, e) return r }(), - expectedExpressions: []string{"(c1 c2)"}, + expectedExpressions: []string{ + `commands=\(\n\s+"help:.*\n\s+"subcmd1:.*\n\s+"subcmd2:.*\n\s+\)`, + `_arguments \\\n.*'--debug\[description]'`, + `_arguments -C \\\n.*'--debug\[description]'`, + `function _rootcmd_subcmd1 {`, + `function _rootcmd_subcmd1 {`, + `_arguments \\\n.*'\(-o --option\)'{-o,--option}'\[option description]:' \\\n`, + }, }, { - name: "tree", + name: "filename completion with and without globs", root: func() *Command { - r := &Command{Use: "tree"} - - sub1 := &Command{Use: "sub1"} - r.AddCommand(sub1) - - sub11 := &Command{Use: "sub11"} - sub12 := &Command{Use: "sub12"} - - sub1.AddCommand(sub11) - sub1.AddCommand(sub12) + var file string + r := &Command{ + Use: "mycmd", + Short: "my command short description", + Run: emptyRun, + } + r.Flags().StringVarP(&file, "config", "c", file, "config file") + r.MarkFlagFilename("config") + r.Flags().String("output", "", "output file") + r.MarkFlagFilename("output", "*.log", "*.txt") + return r + }(), + expectedExpressions: []string{ + `\n +'\(-c --config\)'{-c,--config}'\[config file]:filename:_files'`, + `:_files -g "\*.log" -g "\*.txt"`, + }, + }, + { + name: "repeated variables both with and without value", + root: func() *Command { + r := genTestCommand("mycmd", true) + _ = r.Flags().BoolSliceP("debug", "d", []bool{}, "debug usage") + _ = r.Flags().StringArray("option", []string{}, "options") + return r + }(), + expectedExpressions: []string{ + `'\*--option\[options]`, + `'\(\*-d \*--debug\)'{\\\*-d,\\\*--debug}`, + }, + }, + { + name: "generated flags --help and --version should be created even when not executing root cmd", + root: func() *Command { + r := &Command{ + Use: "mycmd", + Short: "mycmd short description", + Version: "myversion", + } + s := genTestCommand("sub1", true) + r.AddCommand(s) + return s + }(), + expectedExpressions: []string{ + "--version", + "--help", + }, + invocationArgs: []string{ + "sub1", + }, + skip: "--version and --help are currently not generated when not running on root command", + }, + { + name: "zsh generation should run on root command", + root: func() *Command { + r := genTestCommand("root", false) + s := genTestCommand("sub1", true) + r.AddCommand(s) + return s + }(), + expectedExpressions: []string{ + "function _root {", + }, + }, + { + name: "flag description with single quote (') shouldn't break quotes in completion file", + root: func() *Command { + r := genTestCommand("root", true) + r.Flags().Bool("private", false, "Don't show public info") + return r + }(), + expectedExpressions: []string{ + `--private\[Don'\\''t show public info]`, + }, + }, + { + name: "argument completion for file with and without patterns", + root: func() *Command { + r := genTestCommand("root", true) + r.MarkZshCompPositionalArgumentFile(1, "*.log") + r.MarkZshCompPositionalArgumentFile(2) + return r + }(), + expectedExpressions: []string{ + `'1: :_files -g "\*.log"' \\\n\s+'2: :_files`, + }, + }, + { + name: "argument zsh completion for words", + root: func() *Command { + r := genTestCommand("root", true) + r.MarkZshCompPositionalArgumentWords(1, "word1", "word2") + return r + }(), + expectedExpressions: []string{ + `'1: :\("word1" "word2"\)`, + }, + }, + { + name: "argument completion for words with spaces", + root: func() *Command { + r := genTestCommand("root", true) + r.MarkZshCompPositionalArgumentWords(1, "single", "multiple words") + return r + }(), + expectedExpressions: []string{ + `'1: :\("single" "multiple words"\)'`, + }, + }, + { + name: "argument completion when command has ValidArgs and no annotation for argument completion", + root: func() *Command { + r := genTestCommand("root", true) + r.ValidArgs = []string{"word1", "word2"} + return r + }(), + expectedExpressions: []string{ + `'1: :\("word1" "word2"\)'`, + }, + }, + { + name: "argument completion when command has ValidArgs and no annotation for argument at argPosition 1", + root: func() *Command { + r := genTestCommand("root", true) + r.ValidArgs = []string{"word1", "word2"} + r.MarkZshCompPositionalArgumentFile(2) + return r + }(), + expectedExpressions: []string{ + `'1: :\("word1" "word2"\)' \\`, + }, + }, + { + name: "directory completion for flag", + root: func() *Command { + r := genTestCommand("root", true) + r.Flags().String("test", "", "test") + r.PersistentFlags().String("ptest", "", "ptest") + r.MarkFlagDirname("test") + r.MarkPersistentFlagDirname("ptest") + return r + }(), + expectedExpressions: []string{ + `--test\[test]:filename:_files -g "-\(/\)"`, + `--ptest\[ptest]:filename:_files -g "-\(/\)"`, + }, + }, + } - sub2 := &Command{Use: "sub2"} - r.AddCommand(sub2) + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + if tc.skip != "" { + t.Skip(tc.skip) + } + tc.root.Root().SetArgs(tc.invocationArgs) + tc.root.Execute() + buf := new(bytes.Buffer) + if err := tc.root.GenZshCompletion(buf); err != nil { + t.Error(err) + } + output := buf.Bytes() - sub21 := &Command{Use: "sub21"} - sub22 := &Command{Use: "sub22"} + for _, expr := range tc.expectedExpressions { + rgx, err := regexp.Compile(expr) + if err != nil { + t.Errorf("error compiling expression (%s): %v", expr, err) + } + if !rgx.Match(output) { + t.Errorf("expected completion (%s) to match '%s'", buf.String(), expr) + } + } + }) + } +} - sub2.AddCommand(sub21) - sub2.AddCommand(sub22) +func TestGenZshCompletionHidden(t *testing.T) { + tcs := []struct { + name string + root *Command + expectedExpressions []string + }{ + { + name: "hidden commands", + root: func() *Command { + r := &Command{ + Use: "main", + Short: "main short description", + } + s1 := &Command{ + Use: "sub1", + Hidden: true, + Run: emptyRun, + } + s2 := &Command{ + Use: "sub2", + Short: "short sub2 description", + Run: emptyRun, + } + r.AddCommand(s1, s2) return r }(), - expectedExpressions: []string{"(sub11 sub12)", "(sub21 sub22)"}, + expectedExpressions: []string{ + "sub1", + }, + }, + { + name: "hidden flags", + root: func() *Command { + var hidden string + r := &Command{ + Use: "root", + Short: "root short description", + Run: emptyRun, + } + r.Flags().StringVarP(&hidden, "hidden", "H", hidden, "hidden usage") + if err := r.Flags().MarkHidden("hidden"); err != nil { + t.Errorf("Error setting flag hidden: %v\n", err) + } + return r + }(), + expectedExpressions: []string{ + "--hidden", + }, }, } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { + tc.root.Execute() buf := new(bytes.Buffer) - tc.root.GenZshCompletion(buf) + if err := tc.root.GenZshCompletion(buf); err != nil { + t.Error(err) + } output := buf.String() - for _, expectedExpression := range tc.expectedExpressions { - if !strings.Contains(output, expectedExpression) { - t.Errorf("Expected completion to contain %q somewhere; got %q", expectedExpression, output) + for _, expr := range tc.expectedExpressions { + if strings.Contains(output, expr) { + t.Errorf("Expected completion (%s) not to contain '%s' but it does", output, expr) } } }) } } + +func TestMarkZshCompPositionalArgumentFile(t *testing.T) { + t.Run("Doesn't allow overwriting existing positional argument", func(t *testing.T) { + c := &Command{} + if err := c.MarkZshCompPositionalArgumentFile(1, "*.log"); err != nil { + t.Errorf("Received error when we shouldn't have: %v\n", err) + } + if err := c.MarkZshCompPositionalArgumentFile(1); err == nil { + t.Error("Didn't receive an error when trying to overwrite argument position") + } + }) + + t.Run("Refuses to accept argPosition less then 1", func(t *testing.T) { + c := &Command{} + err := c.MarkZshCompPositionalArgumentFile(0, "*") + if err == nil { + t.Fatal("Error was not thrown when indicating argument position 0") + } + if !strings.Contains(err.Error(), "position") { + t.Errorf("expected error message '%s' to contain 'position'", err.Error()) + } + }) +} + +func TestMarkZshCompPositionalArgumentWords(t *testing.T) { + t.Run("Doesn't allow overwriting existing positional argument", func(t *testing.T) { + c := &Command{} + if err := c.MarkZshCompPositionalArgumentFile(1, "*.log"); err != nil { + t.Errorf("Received error when we shouldn't have: %v\n", err) + } + if err := c.MarkZshCompPositionalArgumentWords(1, "hello"); err == nil { + t.Error("Didn't receive an error when trying to overwrite argument position") + } + }) + + t.Run("Doesn't allow calling without words", func(t *testing.T) { + c := &Command{} + if err := c.MarkZshCompPositionalArgumentWords(0); err == nil { + t.Error("Should not allow saving empty word list for annotation") + } + }) + + t.Run("Refuses to accept argPosition less then 1", func(t *testing.T) { + c := &Command{} + err := c.MarkZshCompPositionalArgumentWords(0, "word") + if err == nil { + t.Fatal("Should not allow setting argument position less then 1") + } + if !strings.Contains(err.Error(), "position") { + t.Errorf("Expected error '%s' to contain 'position' but didn't", err.Error()) + } + }) +} + +func BenchmarkMediumSizeConstruct(b *testing.B) { + root := constructLargeCommandHierarchy() + // if err := root.GenZshCompletionFile("_mycmd"); err != nil { + // b.Error(err) + // } + + for i := 0; i < b.N; i++ { + buf := new(bytes.Buffer) + err := root.GenZshCompletion(buf) + if err != nil { + b.Error(err) + } + } +} + +func TestExtractFlags(t *testing.T) { + var debug, cmdc, cmdd bool + c := &Command{ + Use: "cmdC", + Long: "Command C", + } + c.PersistentFlags().BoolVarP(&debug, "debug", "d", debug, "debug mode") + c.Flags().BoolVar(&cmdc, "cmd-c", cmdc, "Command C") + d := &Command{ + Use: "CmdD", + Long: "Command D", + } + d.Flags().BoolVar(&cmdd, "cmd-d", cmdd, "Command D") + c.AddCommand(d) + + resC := zshCompExtractFlag(c) + resD := zshCompExtractFlag(d) + + if len(resC) != 2 { + t.Errorf("expected Command C to return 2 flags, got %d", len(resC)) + } + if len(resD) != 2 { + t.Errorf("expected Command D to return 2 flags, got %d", len(resD)) + } +} + +func constructLargeCommandHierarchy() *Command { + var config, st1, st2 string + var long, debug bool + var in1, in2 int + var verbose []bool + + r := genTestCommand("mycmd", false) + r.PersistentFlags().StringVarP(&config, "config", "c", config, "config usage") + if err := r.MarkPersistentFlagFilename("config", "*"); err != nil { + panic(err) + } + s1 := genTestCommand("sub1", true) + s1.Flags().BoolVar(&long, "long", long, "long description") + s1.Flags().BoolSliceVar(&verbose, "verbose", verbose, "verbose description") + s1.Flags().StringArray("option", []string{}, "various options") + s2 := genTestCommand("sub2", true) + s2.PersistentFlags().BoolVar(&debug, "debug", debug, "debug description") + s3 := genTestCommand("sub3", true) + s3.Hidden = true + s1_1 := genTestCommand("sub1sub1", true) + s1_1.Flags().StringVar(&st1, "st1", st1, "st1 description") + s1_1.Flags().StringVar(&st2, "st2", st2, "st2 description") + s1_2 := genTestCommand("sub1sub2", true) + s1_3 := genTestCommand("sub1sub3", true) + s1_3.Flags().IntVar(&in1, "int1", in1, "int1 description") + s1_3.Flags().IntVar(&in2, "int2", in2, "int2 description") + s1_3.Flags().StringArrayP("option", "O", []string{}, "more options") + s2_1 := genTestCommand("sub2sub1", true) + s2_2 := genTestCommand("sub2sub2", true) + s2_3 := genTestCommand("sub2sub3", true) + s2_4 := genTestCommand("sub2sub4", true) + s2_5 := genTestCommand("sub2sub5", true) + + s1.AddCommand(s1_1, s1_2, s1_3) + s2.AddCommand(s2_1, s2_2, s2_3, s2_4, s2_5) + r.AddCommand(s1, s2, s3) + r.Execute() + return r +} + +func genTestCommand(name string, withRun bool) *Command { + r := &Command{ + Use: name, + Short: name + " short description", + Long: "Long description for " + name, + } + if withRun { + r.Run = emptyRun + } + + return r +} diff --git a/vendor/github.com/spf13/pflag/bytes.go b/vendor/github.com/spf13/pflag/bytes.go index 12c58db9f..67d530457 100644 --- a/vendor/github.com/spf13/pflag/bytes.go +++ b/vendor/github.com/spf13/pflag/bytes.go @@ -1,6 +1,7 @@ package pflag import ( + "encoding/base64" "encoding/hex" "fmt" "strings" @@ -9,10 +10,12 @@ import ( // BytesHex adapts []byte for use as a flag. Value of flag is HEX encoded type bytesHexValue []byte +// String implements pflag.Value.String. func (bytesHex bytesHexValue) String() string { return fmt.Sprintf("%X", []byte(bytesHex)) } +// Set implements pflag.Value.Set. func (bytesHex *bytesHexValue) Set(value string) error { bin, err := hex.DecodeString(strings.TrimSpace(value)) @@ -25,6 +28,7 @@ func (bytesHex *bytesHexValue) Set(value string) error { return nil } +// Type implements pflag.Value.Type. func (*bytesHexValue) Type() string { return "bytesHex" } @@ -103,3 +107,103 @@ func BytesHex(name string, value []byte, usage string) *[]byte { func BytesHexP(name, shorthand string, value []byte, usage string) *[]byte { return CommandLine.BytesHexP(name, shorthand, value, usage) } + +// BytesBase64 adapts []byte for use as a flag. Value of flag is Base64 encoded +type bytesBase64Value []byte + +// String implements pflag.Value.String. +func (bytesBase64 bytesBase64Value) String() string { + return base64.StdEncoding.EncodeToString([]byte(bytesBase64)) +} + +// Set implements pflag.Value.Set. +func (bytesBase64 *bytesBase64Value) Set(value string) error { + bin, err := base64.StdEncoding.DecodeString(strings.TrimSpace(value)) + + if err != nil { + return err + } + + *bytesBase64 = bin + + return nil +} + +// Type implements pflag.Value.Type. +func (*bytesBase64Value) Type() string { + return "bytesBase64" +} + +func newBytesBase64Value(val []byte, p *[]byte) *bytesBase64Value { + *p = val + return (*bytesBase64Value)(p) +} + +func bytesBase64ValueConv(sval string) (interface{}, error) { + + bin, err := base64.StdEncoding.DecodeString(sval) + if err == nil { + return bin, nil + } + + return nil, fmt.Errorf("invalid string being converted to Bytes: %s %s", sval, err) +} + +// GetBytesBase64 return the []byte value of a flag with the given name +func (f *FlagSet) GetBytesBase64(name string) ([]byte, error) { + val, err := f.getFlagType(name, "bytesBase64", bytesBase64ValueConv) + + if err != nil { + return []byte{}, err + } + + return val.([]byte), nil +} + +// BytesBase64Var defines an []byte flag with specified name, default value, and usage string. +// The argument p points to an []byte variable in which to store the value of the flag. +func (f *FlagSet) BytesBase64Var(p *[]byte, name string, value []byte, usage string) { + f.VarP(newBytesBase64Value(value, p), name, "", usage) +} + +// BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) { + f.VarP(newBytesBase64Value(value, p), name, shorthand, usage) +} + +// BytesBase64Var defines an []byte flag with specified name, default value, and usage string. +// The argument p points to an []byte variable in which to store the value of the flag. +func BytesBase64Var(p *[]byte, name string, value []byte, usage string) { + CommandLine.VarP(newBytesBase64Value(value, p), name, "", usage) +} + +// BytesBase64VarP is like BytesBase64Var, but accepts a shorthand letter that can be used after a single dash. +func BytesBase64VarP(p *[]byte, name, shorthand string, value []byte, usage string) { + CommandLine.VarP(newBytesBase64Value(value, p), name, shorthand, usage) +} + +// BytesBase64 defines an []byte flag with specified name, default value, and usage string. +// The return value is the address of an []byte variable that stores the value of the flag. +func (f *FlagSet) BytesBase64(name string, value []byte, usage string) *[]byte { + p := new([]byte) + f.BytesBase64VarP(p, name, "", value, usage) + return p +} + +// BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte { + p := new([]byte) + f.BytesBase64VarP(p, name, shorthand, value, usage) + return p +} + +// BytesBase64 defines an []byte flag with specified name, default value, and usage string. +// The return value is the address of an []byte variable that stores the value of the flag. +func BytesBase64(name string, value []byte, usage string) *[]byte { + return CommandLine.BytesBase64P(name, "", value, usage) +} + +// BytesBase64P is like BytesBase64, but accepts a shorthand letter that can be used after a single dash. +func BytesBase64P(name, shorthand string, value []byte, usage string) *[]byte { + return CommandLine.BytesBase64P(name, shorthand, value, usage) +} diff --git a/vendor/github.com/spf13/pflag/bytes_test.go b/vendor/github.com/spf13/pflag/bytes_test.go index cc4a769d9..5251f347c 100644 --- a/vendor/github.com/spf13/pflag/bytes_test.go +++ b/vendor/github.com/spf13/pflag/bytes_test.go @@ -1,6 +1,7 @@ package pflag import ( + "encoding/base64" "fmt" "os" "testing" @@ -61,7 +62,7 @@ func TestBytesHex(t *testing.T) { } else if tc.success { bytesHex, err := f.GetBytesHex("bytes") if err != nil { - t.Errorf("Got error trying to fetch the IP flag: %v", err) + t.Errorf("Got error trying to fetch the 'bytes' flag: %v", err) } if fmt.Sprintf("%X", bytesHex) != tc.expected { t.Errorf("expected %q, got '%X'", tc.expected, bytesHex) @@ -70,3 +71,64 @@ func TestBytesHex(t *testing.T) { } } } + +func setUpBytesBase64(bytesBase64 *[]byte) *FlagSet { + f := NewFlagSet("test", ContinueOnError) + f.BytesBase64Var(bytesBase64, "bytes", []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, "Some bytes in Base64") + f.BytesBase64VarP(bytesBase64, "bytes2", "B", []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}, "Some bytes in Base64") + return f +} + +func TestBytesBase64(t *testing.T) { + testCases := []struct { + input string + success bool + expected string + }{ + /// Positive cases + {"", true, ""}, // Is empty string OK ? + {"AQ==", true, "AQ=="}, + + // Negative cases + {"AQ", false, ""}, // Padding removed + {"ï", false, ""}, // non-base64 characters + } + + devnull, _ := os.Open(os.DevNull) + os.Stderr = devnull + + for i := range testCases { + var bytesBase64 []byte + f := setUpBytesBase64(&bytesBase64) + + tc := &testCases[i] + + // --bytes + args := []string{ + fmt.Sprintf("--bytes=%s", tc.input), + fmt.Sprintf("-B %s", tc.input), + fmt.Sprintf("--bytes2=%s", tc.input), + } + + for _, arg := range args { + err := f.Parse([]string{arg}) + + if err != nil && tc.success == true { + t.Errorf("expected success, got %q", err) + continue + } else if err == nil && tc.success == false { + // bytesBase64, err := f.GetBytesBase64("bytes") + t.Errorf("expected failure while processing %q", tc.input) + continue + } else if tc.success { + bytesBase64, err := f.GetBytesBase64("bytes") + if err != nil { + t.Errorf("Got error trying to fetch the 'bytes' flag: %v", err) + } + if base64.StdEncoding.EncodeToString(bytesBase64) != tc.expected { + t.Errorf("expected %q, got '%X'", tc.expected, bytesBase64) + } + } + } + } +} diff --git a/vendor/github.com/spf13/pflag/flag.go b/vendor/github.com/spf13/pflag/flag.go index 5eadc84e3..9beeda8ec 100644 --- a/vendor/github.com/spf13/pflag/flag.go +++ b/vendor/github.com/spf13/pflag/flag.go @@ -925,13 +925,16 @@ func stripUnknownFlagValue(args []string) []string { } first := args[0] - if first[0] == '-' { + if len(first) > 0 && first[0] == '-' { //--unknown --next-flag ... return args } //--unknown arg ... (args will be arg ...) - return args[1:] + if len(args) > 1 { + return args[1:] + } + return nil } func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []string, err error) { @@ -990,11 +993,12 @@ func (f *FlagSet) parseLongArg(s string, args []string, fn parseFunc) (a []strin } func (f *FlagSet) parseSingleShortArg(shorthands string, args []string, fn parseFunc) (outShorts string, outArgs []string, err error) { + outArgs = args + if strings.HasPrefix(shorthands, "test.") { return } - outArgs = args outShorts = shorthands[1:] c := shorthands[0] diff --git a/vendor/github.com/spf13/pflag/flag_test.go b/vendor/github.com/spf13/pflag/flag_test.go index f600f0aeb..7d02dbc8a 100644 --- a/vendor/github.com/spf13/pflag/flag_test.go +++ b/vendor/github.com/spf13/pflag/flag_test.go @@ -431,6 +431,11 @@ func testParseWithUnknownFlags(f *FlagSet, t *testing.T) { "--unknown8=unknown8value", "--boole", "--unknown6", + "", + "-uuuuu", + "", + "--unknown10", + "--unknown11", } want := []string{ "boola", "true", diff --git a/vendor/github.com/spf13/pflag/string_to_int.go b/vendor/github.com/spf13/pflag/string_to_int.go new file mode 100644 index 000000000..5ceda3965 --- /dev/null +++ b/vendor/github.com/spf13/pflag/string_to_int.go @@ -0,0 +1,149 @@ +package pflag + +import ( + "bytes" + "fmt" + "strconv" + "strings" +) + +// -- stringToInt Value +type stringToIntValue struct { + value *map[string]int + changed bool +} + +func newStringToIntValue(val map[string]int, p *map[string]int) *stringToIntValue { + ssv := new(stringToIntValue) + ssv.value = p + *ssv.value = val + return ssv +} + +// Format: a=1,b=2 +func (s *stringToIntValue) Set(val string) error { + ss := strings.Split(val, ",") + out := make(map[string]int, len(ss)) + for _, pair := range ss { + kv := strings.SplitN(pair, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("%s must be formatted as key=value", pair) + } + var err error + out[kv[0]], err = strconv.Atoi(kv[1]) + if err != nil { + return err + } + } + if !s.changed { + *s.value = out + } else { + for k, v := range out { + (*s.value)[k] = v + } + } + s.changed = true + return nil +} + +func (s *stringToIntValue) Type() string { + return "stringToInt" +} + +func (s *stringToIntValue) String() string { + var buf bytes.Buffer + i := 0 + for k, v := range *s.value { + if i > 0 { + buf.WriteRune(',') + } + buf.WriteString(k) + buf.WriteRune('=') + buf.WriteString(strconv.Itoa(v)) + i++ + } + return "[" + buf.String() + "]" +} + +func stringToIntConv(val string) (interface{}, error) { + val = strings.Trim(val, "[]") + // An empty string would cause an empty map + if len(val) == 0 { + return map[string]int{}, nil + } + ss := strings.Split(val, ",") + out := make(map[string]int, len(ss)) + for _, pair := range ss { + kv := strings.SplitN(pair, "=", 2) + if len(kv) != 2 { + return nil, fmt.Errorf("%s must be formatted as key=value", pair) + } + var err error + out[kv[0]], err = strconv.Atoi(kv[1]) + if err != nil { + return nil, err + } + } + return out, nil +} + +// GetStringToInt return the map[string]int value of a flag with the given name +func (f *FlagSet) GetStringToInt(name string) (map[string]int, error) { + val, err := f.getFlagType(name, "stringToInt", stringToIntConv) + if err != nil { + return map[string]int{}, err + } + return val.(map[string]int), nil +} + +// StringToIntVar defines a string flag with specified name, default value, and usage string. +// The argument p points to a map[string]int variable in which to store the values of the multiple flags. +// The value of each argument will not try to be separated by comma +func (f *FlagSet) StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) { + f.VarP(newStringToIntValue(value, p), name, "", usage) +} + +// StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) { + f.VarP(newStringToIntValue(value, p), name, shorthand, usage) +} + +// StringToIntVar defines a string flag with specified name, default value, and usage string. +// The argument p points to a map[string]int variable in which to store the value of the flag. +// The value of each argument will not try to be separated by comma +func StringToIntVar(p *map[string]int, name string, value map[string]int, usage string) { + CommandLine.VarP(newStringToIntValue(value, p), name, "", usage) +} + +// StringToIntVarP is like StringToIntVar, but accepts a shorthand letter that can be used after a single dash. +func StringToIntVarP(p *map[string]int, name, shorthand string, value map[string]int, usage string) { + CommandLine.VarP(newStringToIntValue(value, p), name, shorthand, usage) +} + +// StringToInt defines a string flag with specified name, default value, and usage string. +// The return value is the address of a map[string]int variable that stores the value of the flag. +// The value of each argument will not try to be separated by comma +func (f *FlagSet) StringToInt(name string, value map[string]int, usage string) *map[string]int { + p := map[string]int{} + f.StringToIntVarP(&p, name, "", value, usage) + return &p +} + +// StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int { + p := map[string]int{} + f.StringToIntVarP(&p, name, shorthand, value, usage) + return &p +} + +// StringToInt defines a string flag with specified name, default value, and usage string. +// The return value is the address of a map[string]int variable that stores the value of the flag. +// The value of each argument will not try to be separated by comma +func StringToInt(name string, value map[string]int, usage string) *map[string]int { + return CommandLine.StringToIntP(name, "", value, usage) +} + +// StringToIntP is like StringToInt, but accepts a shorthand letter that can be used after a single dash. +func StringToIntP(name, shorthand string, value map[string]int, usage string) *map[string]int { + return CommandLine.StringToIntP(name, shorthand, value, usage) +} diff --git a/vendor/github.com/spf13/pflag/string_to_int_test.go b/vendor/github.com/spf13/pflag/string_to_int_test.go new file mode 100644 index 000000000..b60bbafb4 --- /dev/null +++ b/vendor/github.com/spf13/pflag/string_to_int_test.go @@ -0,0 +1,156 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of ths2i source code s2i governed by a BSD-style +// license that can be found in the LICENSE file. + +package pflag + +import ( + "bytes" + "fmt" + "strconv" + "testing" +) + +func setUpS2IFlagSet(s2ip *map[string]int) *FlagSet { + f := NewFlagSet("test", ContinueOnError) + f.StringToIntVar(s2ip, "s2i", map[string]int{}, "Command separated ls2it!") + return f +} + +func setUpS2IFlagSetWithDefault(s2ip *map[string]int) *FlagSet { + f := NewFlagSet("test", ContinueOnError) + f.StringToIntVar(s2ip, "s2i", map[string]int{"a": 1, "b": 2}, "Command separated ls2it!") + return f +} + +func createS2IFlag(vals map[string]int) string { + var buf bytes.Buffer + i := 0 + for k, v := range vals { + if i > 0 { + buf.WriteRune(',') + } + buf.WriteString(k) + buf.WriteRune('=') + buf.WriteString(strconv.Itoa(v)) + i++ + } + return buf.String() +} + +func TestEmptyS2I(t *testing.T) { + var s2i map[string]int + f := setUpS2IFlagSet(&s2i) + err := f.Parse([]string{}) + if err != nil { + t.Fatal("expected no error; got", err) + } + + getS2I, err := f.GetStringToInt("s2i") + if err != nil { + t.Fatal("got an error from GetStringToInt():", err) + } + if len(getS2I) != 0 { + t.Fatalf("got s2i %v with len=%d but expected length=0", getS2I, len(getS2I)) + } +} + +func TestS2I(t *testing.T) { + var s2i map[string]int + f := setUpS2IFlagSet(&s2i) + + vals := map[string]int{"a": 1, "b": 2, "d": 4, "c": 3} + arg := fmt.Sprintf("--s2i=%s", createS2IFlag(vals)) + err := f.Parse([]string{arg}) + if err != nil { + t.Fatal("expected no error; got", err) + } + for k, v := range s2i { + if vals[k] != v { + t.Fatalf("expected s2i[%s] to be %d but got: %d", k, vals[k], v) + } + } + getS2I, err := f.GetStringToInt("s2i") + if err != nil { + t.Fatalf("got error: %v", err) + } + for k, v := range getS2I { + if vals[k] != v { + t.Fatalf("expected s2i[%s] to be %d but got: %d from GetStringToInt", k, vals[k], v) + } + } +} + +func TestS2IDefault(t *testing.T) { + var s2i map[string]int + f := setUpS2IFlagSetWithDefault(&s2i) + + vals := map[string]int{"a": 1, "b": 2} + + err := f.Parse([]string{}) + if err != nil { + t.Fatal("expected no error; got", err) + } + for k, v := range s2i { + if vals[k] != v { + t.Fatalf("expected s2i[%s] to be %d but got: %d", k, vals[k], v) + } + } + + getS2I, err := f.GetStringToInt("s2i") + if err != nil { + t.Fatal("got an error from GetStringToInt():", err) + } + for k, v := range getS2I { + if vals[k] != v { + t.Fatalf("expected s2i[%s] to be %d from GetStringToInt but got: %d", k, vals[k], v) + } + } +} + +func TestS2IWithDefault(t *testing.T) { + var s2i map[string]int + f := setUpS2IFlagSetWithDefault(&s2i) + + vals := map[string]int{"a": 1, "b": 2} + arg := fmt.Sprintf("--s2i=%s", createS2IFlag(vals)) + err := f.Parse([]string{arg}) + if err != nil { + t.Fatal("expected no error; got", err) + } + for k, v := range s2i { + if vals[k] != v { + t.Fatalf("expected s2i[%s] to be %d but got: %d", k, vals[k], v) + } + } + + getS2I, err := f.GetStringToInt("s2i") + if err != nil { + t.Fatal("got an error from GetStringToInt():", err) + } + for k, v := range getS2I { + if vals[k] != v { + t.Fatalf("expected s2i[%s] to be %d from GetStringToInt but got: %d", k, vals[k], v) + } + } +} + +func TestS2ICalledTwice(t *testing.T) { + var s2i map[string]int + f := setUpS2IFlagSet(&s2i) + + in := []string{"a=1,b=2", "b=3"} + expected := map[string]int{"a": 1, "b": 3} + argfmt := "--s2i=%s" + arg1 := fmt.Sprintf(argfmt, in[0]) + arg2 := fmt.Sprintf(argfmt, in[1]) + err := f.Parse([]string{arg1, arg2}) + if err != nil { + t.Fatal("expected no error; got", err) + } + for i, v := range s2i { + if expected[i] != v { + t.Fatalf("expected s2i[%s] to be %d but got: %d", i, expected[i], v) + } + } +} diff --git a/vendor/github.com/spf13/pflag/string_to_string.go b/vendor/github.com/spf13/pflag/string_to_string.go new file mode 100644 index 000000000..890a01afc --- /dev/null +++ b/vendor/github.com/spf13/pflag/string_to_string.go @@ -0,0 +1,160 @@ +package pflag + +import ( + "bytes" + "encoding/csv" + "fmt" + "strings" +) + +// -- stringToString Value +type stringToStringValue struct { + value *map[string]string + changed bool +} + +func newStringToStringValue(val map[string]string, p *map[string]string) *stringToStringValue { + ssv := new(stringToStringValue) + ssv.value = p + *ssv.value = val + return ssv +} + +// Format: a=1,b=2 +func (s *stringToStringValue) Set(val string) error { + var ss []string + n := strings.Count(val, "=") + switch n { + case 0: + return fmt.Errorf("%s must be formatted as key=value", val) + case 1: + ss = append(ss, strings.Trim(val, `"`)) + default: + r := csv.NewReader(strings.NewReader(val)) + var err error + ss, err = r.Read() + if err != nil { + return err + } + } + + out := make(map[string]string, len(ss)) + for _, pair := range ss { + kv := strings.SplitN(pair, "=", 2) + if len(kv) != 2 { + return fmt.Errorf("%s must be formatted as key=value", pair) + } + out[kv[0]] = kv[1] + } + if !s.changed { + *s.value = out + } else { + for k, v := range out { + (*s.value)[k] = v + } + } + s.changed = true + return nil +} + +func (s *stringToStringValue) Type() string { + return "stringToString" +} + +func (s *stringToStringValue) String() string { + records := make([]string, 0, len(*s.value)>>1) + for k, v := range *s.value { + records = append(records, k+"="+v) + } + + var buf bytes.Buffer + w := csv.NewWriter(&buf) + if err := w.Write(records); err != nil { + panic(err) + } + w.Flush() + return "[" + strings.TrimSpace(buf.String()) + "]" +} + +func stringToStringConv(val string) (interface{}, error) { + val = strings.Trim(val, "[]") + // An empty string would cause an empty map + if len(val) == 0 { + return map[string]string{}, nil + } + r := csv.NewReader(strings.NewReader(val)) + ss, err := r.Read() + if err != nil { + return nil, err + } + out := make(map[string]string, len(ss)) + for _, pair := range ss { + kv := strings.SplitN(pair, "=", 2) + if len(kv) != 2 { + return nil, fmt.Errorf("%s must be formatted as key=value", pair) + } + out[kv[0]] = kv[1] + } + return out, nil +} + +// GetStringToString return the map[string]string value of a flag with the given name +func (f *FlagSet) GetStringToString(name string) (map[string]string, error) { + val, err := f.getFlagType(name, "stringToString", stringToStringConv) + if err != nil { + return map[string]string{}, err + } + return val.(map[string]string), nil +} + +// StringToStringVar defines a string flag with specified name, default value, and usage string. +// The argument p points to a map[string]string variable in which to store the values of the multiple flags. +// The value of each argument will not try to be separated by comma +func (f *FlagSet) StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) { + f.VarP(newStringToStringValue(value, p), name, "", usage) +} + +// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) { + f.VarP(newStringToStringValue(value, p), name, shorthand, usage) +} + +// StringToStringVar defines a string flag with specified name, default value, and usage string. +// The argument p points to a map[string]string variable in which to store the value of the flag. +// The value of each argument will not try to be separated by comma +func StringToStringVar(p *map[string]string, name string, value map[string]string, usage string) { + CommandLine.VarP(newStringToStringValue(value, p), name, "", usage) +} + +// StringToStringVarP is like StringToStringVar, but accepts a shorthand letter that can be used after a single dash. +func StringToStringVarP(p *map[string]string, name, shorthand string, value map[string]string, usage string) { + CommandLine.VarP(newStringToStringValue(value, p), name, shorthand, usage) +} + +// StringToString defines a string flag with specified name, default value, and usage string. +// The return value is the address of a map[string]string variable that stores the value of the flag. +// The value of each argument will not try to be separated by comma +func (f *FlagSet) StringToString(name string, value map[string]string, usage string) *map[string]string { + p := map[string]string{} + f.StringToStringVarP(&p, name, "", value, usage) + return &p +} + +// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash. +func (f *FlagSet) StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string { + p := map[string]string{} + f.StringToStringVarP(&p, name, shorthand, value, usage) + return &p +} + +// StringToString defines a string flag with specified name, default value, and usage string. +// The return value is the address of a map[string]string variable that stores the value of the flag. +// The value of each argument will not try to be separated by comma +func StringToString(name string, value map[string]string, usage string) *map[string]string { + return CommandLine.StringToStringP(name, "", value, usage) +} + +// StringToStringP is like StringToString, but accepts a shorthand letter that can be used after a single dash. +func StringToStringP(name, shorthand string, value map[string]string, usage string) *map[string]string { + return CommandLine.StringToStringP(name, shorthand, value, usage) +} diff --git a/vendor/github.com/spf13/pflag/string_to_string_test.go b/vendor/github.com/spf13/pflag/string_to_string_test.go new file mode 100644 index 000000000..0777f03f9 --- /dev/null +++ b/vendor/github.com/spf13/pflag/string_to_string_test.go @@ -0,0 +1,162 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of ths2s source code s2s governed by a BSD-style +// license that can be found in the LICENSE file. + +package pflag + +import ( + "bytes" + "encoding/csv" + "fmt" + "strings" + "testing" +) + +func setUpS2SFlagSet(s2sp *map[string]string) *FlagSet { + f := NewFlagSet("test", ContinueOnError) + f.StringToStringVar(s2sp, "s2s", map[string]string{}, "Command separated ls2st!") + return f +} + +func setUpS2SFlagSetWithDefault(s2sp *map[string]string) *FlagSet { + f := NewFlagSet("test", ContinueOnError) + f.StringToStringVar(s2sp, "s2s", map[string]string{"da": "1", "db": "2", "de": "5,6"}, "Command separated ls2st!") + return f +} + +func createS2SFlag(vals map[string]string) string { + records := make([]string, 0, len(vals)>>1) + for k, v := range vals { + records = append(records, k+"="+v) + } + + var buf bytes.Buffer + w := csv.NewWriter(&buf) + if err := w.Write(records); err != nil { + panic(err) + } + w.Flush() + return strings.TrimSpace(buf.String()) +} + +func TestEmptyS2S(t *testing.T) { + var s2s map[string]string + f := setUpS2SFlagSet(&s2s) + err := f.Parse([]string{}) + if err != nil { + t.Fatal("expected no error; got", err) + } + + getS2S, err := f.GetStringToString("s2s") + if err != nil { + t.Fatal("got an error from GetStringToString():", err) + } + if len(getS2S) != 0 { + t.Fatalf("got s2s %v with len=%d but expected length=0", getS2S, len(getS2S)) + } +} + +func TestS2S(t *testing.T) { + var s2s map[string]string + f := setUpS2SFlagSet(&s2s) + + vals := map[string]string{"a": "1", "b": "2", "d": "4", "c": "3", "e": "5,6"} + arg := fmt.Sprintf("--s2s=%s", createS2SFlag(vals)) + err := f.Parse([]string{arg}) + if err != nil { + t.Fatal("expected no error; got", err) + } + for k, v := range s2s { + if vals[k] != v { + t.Fatalf("expected s2s[%s] to be %s but got: %s", k, vals[k], v) + } + } + getS2S, err := f.GetStringToString("s2s") + if err != nil { + t.Fatalf("got error: %v", err) + } + for k, v := range getS2S { + if vals[k] != v { + t.Fatalf("expected s2s[%s] to be %s but got: %s from GetStringToString", k, vals[k], v) + } + } +} + +func TestS2SDefault(t *testing.T) { + var s2s map[string]string + f := setUpS2SFlagSetWithDefault(&s2s) + + vals := map[string]string{"da": "1", "db": "2", "de": "5,6"} + + err := f.Parse([]string{}) + if err != nil { + t.Fatal("expected no error; got", err) + } + for k, v := range s2s { + if vals[k] != v { + t.Fatalf("expected s2s[%s] to be %s but got: %s", k, vals[k], v) + } + } + + getS2S, err := f.GetStringToString("s2s") + if err != nil { + t.Fatal("got an error from GetStringToString():", err) + } + for k, v := range getS2S { + if vals[k] != v { + t.Fatalf("expected s2s[%s] to be %s from GetStringToString but got: %s", k, vals[k], v) + } + } +} + +func TestS2SWithDefault(t *testing.T) { + var s2s map[string]string + f := setUpS2SFlagSetWithDefault(&s2s) + + vals := map[string]string{"a": "1", "b": "2", "e": "5,6"} + arg := fmt.Sprintf("--s2s=%s", createS2SFlag(vals)) + err := f.Parse([]string{arg}) + if err != nil { + t.Fatal("expected no error; got", err) + } + for k, v := range s2s { + if vals[k] != v { + t.Fatalf("expected s2s[%s] to be %s but got: %s", k, vals[k], v) + } + } + + getS2S, err := f.GetStringToString("s2s") + if err != nil { + t.Fatal("got an error from GetStringToString():", err) + } + for k, v := range getS2S { + if vals[k] != v { + t.Fatalf("expected s2s[%s] to be %s from GetStringToString but got: %s", k, vals[k], v) + } + } +} + +func TestS2SCalledTwice(t *testing.T) { + var s2s map[string]string + f := setUpS2SFlagSet(&s2s) + + in := []string{"a=1,b=2", "b=3", `"e=5,6"`, `f=7,8`} + expected := map[string]string{"a": "1", "b": "3", "e": "5,6", "f": "7,8"} + argfmt := "--s2s=%s" + arg0 := fmt.Sprintf(argfmt, in[0]) + arg1 := fmt.Sprintf(argfmt, in[1]) + arg2 := fmt.Sprintf(argfmt, in[2]) + arg3 := fmt.Sprintf(argfmt, in[3]) + err := f.Parse([]string{arg0, arg1, arg2, arg3}) + if err != nil { + t.Fatal("expected no error; got", err) + } + if len(s2s) != len(expected) { + t.Fatalf("expected %d flags; got %d flags", len(expected), len(s2s)) + } + for i, v := range s2s { + if expected[i] != v { + t.Fatalf("expected s2s[%s] to be %s but got: %s", i, expected[i], v) + } + } +} diff --git a/vendor/google.golang.org/appengine/README.md b/vendor/google.golang.org/appengine/README.md index 9fdbacd3c..d86768a2c 100644 --- a/vendor/google.golang.org/appengine/README.md +++ b/vendor/google.golang.org/appengine/README.md @@ -71,30 +71,3 @@ A few APIs were cleaned up, and there are some differences: [blobstore package](https://google.golang.org/appengine/blobstore). * `appengine/socket` is not required on App Engine flexible environment / Managed VMs. Use the standard `net` package instead. - -## Key Encode/Decode compatibiltiy to help with datastore library migrations - -Key compatibility updates have been added to help customers transition from google.golang.org/appengine/datastore to cloud.google.com/go/datastore. -The `EnableKeyConversion` enables automatic conversion from a key encoded with cloud.google.com/go/datastore to google.golang.org/appengine/datastore key type. - -### Enabling key conversion - -Enable key conversion by calling `EnableKeyConversion(ctx)` in the `/_ah/start` handler for basic and manual scaling or any handler in automatic scaling. - -#### 1. Basic or manual scaling - -This start handler will enable key conversion for all handlers in the service. - -``` -http.HandleFunc("/_ah/start", func(w http.ResponseWriter, r *http.Request) { - datastore.EnableKeyConversion(appengine.NewContext(r)) -}) -``` - -#### 2. Automatic scaling - -`/_ah/start` is not supported for automatic scaling and `/_ah/warmup` is not guaranteed to run, so you must call `datastore.EnableKeyConversion(appengine.NewContext(r))` -before you use code that needs key conversion. - -You may want to add this to each of your handlers, or introduce middleware where it's called. -`EnableKeyConversion` is safe for concurrent use. Any call to it after the first is ignored. \ No newline at end of file diff --git a/vendor/google.golang.org/appengine/capability/capability.go b/vendor/google.golang.org/appengine/capability/capability.go index 35604d4a4..3a60bd55f 100644 --- a/vendor/google.golang.org/appengine/capability/capability.go +++ b/vendor/google.golang.org/appengine/capability/capability.go @@ -29,11 +29,6 @@ import ( // If the underlying RPC fails (if the package is unknown, for example), // false is returned and information is written to the application log. func Enabled(ctx context.Context, api, capability string) bool { - // For non datastore*/write requests always return ENABLED - if !(api == "datastore_v3" && capability == "write") { - return true - } - req := &pb.IsEnabledRequest{ Package: &api, Capability: []string{capability}, @@ -43,5 +38,15 @@ func Enabled(ctx context.Context, api, capability string) bool { log.Warningf(ctx, "capability.Enabled: RPC failed: %v", err) return false } - return *res.SummaryStatus == pb.IsEnabledResponse_ENABLED + switch *res.SummaryStatus { + case pb.IsEnabledResponse_ENABLED, + pb.IsEnabledResponse_SCHEDULED_FUTURE, + pb.IsEnabledResponse_SCHEDULED_NOW: + return true + case pb.IsEnabledResponse_UNKNOWN: + log.Errorf(ctx, "capability.Enabled: unknown API capability %s/%s", api, capability) + return false + default: + return false + } } diff --git a/vendor/google.golang.org/appengine/datastore/internal/cloudkey/cloudkey.go b/vendor/google.golang.org/appengine/datastore/internal/cloudkey/cloudkey.go deleted file mode 100644 index 643d4049c..000000000 --- a/vendor/google.golang.org/appengine/datastore/internal/cloudkey/cloudkey.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2019 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -// Package cloudpb is a subset of types and functions, copied from cloud.google.com/go/datastore. -// -// They are copied here to provide compatibility to decode keys generated by the cloud.google.com/go/datastore package. -package cloudkey - -import ( - "encoding/base64" - "errors" - "strings" - - "github.com/golang/protobuf/proto" - cloudpb "google.golang.org/appengine/datastore/internal/cloudpb" -) - -///////////////////////////////////////////////////////////////////// -// Code below is copied from https://github.com/googleapis/google-cloud-go/blob/master/datastore/datastore.go -///////////////////////////////////////////////////////////////////// - -var ( - // ErrInvalidKey is returned when an invalid key is presented. - ErrInvalidKey = errors.New("datastore: invalid key") -) - -///////////////////////////////////////////////////////////////////// -// Code below is copied from https://github.com/googleapis/google-cloud-go/blob/master/datastore/key.go -///////////////////////////////////////////////////////////////////// - -// Key represents the datastore key for a stored entity. -type Key struct { - // Kind cannot be empty. - Kind string - // Either ID or Name must be zero for the Key to be valid. - // If both are zero, the Key is incomplete. - ID int64 - Name string - // Parent must either be a complete Key or nil. - Parent *Key - - // Namespace provides the ability to partition your data for multiple - // tenants. In most cases, it is not necessary to specify a namespace. - // See docs on datastore multitenancy for details: - // https://cloud.google.com/datastore/docs/concepts/multitenancy - Namespace string -} - -// DecodeKey decodes a key from the opaque representation returned by Encode. -func DecodeKey(encoded string) (*Key, error) { - // Re-add padding. - if m := len(encoded) % 4; m != 0 { - encoded += strings.Repeat("=", 4-m) - } - - b, err := base64.URLEncoding.DecodeString(encoded) - if err != nil { - return nil, err - } - - pKey := new(cloudpb.Key) - if err := proto.Unmarshal(b, pKey); err != nil { - return nil, err - } - return protoToKey(pKey) -} - -// valid returns whether the key is valid. -func (k *Key) valid() bool { - if k == nil { - return false - } - for ; k != nil; k = k.Parent { - if k.Kind == "" { - return false - } - if k.Name != "" && k.ID != 0 { - return false - } - if k.Parent != nil { - if k.Parent.Incomplete() { - return false - } - if k.Parent.Namespace != k.Namespace { - return false - } - } - } - return true -} - -// Incomplete reports whether the key does not refer to a stored entity. -func (k *Key) Incomplete() bool { - return k.Name == "" && k.ID == 0 -} - -// protoToKey decodes a protocol buffer representation of a key into an -// equivalent *Key object. If the key is invalid, protoToKey will return the -// invalid key along with ErrInvalidKey. -func protoToKey(p *cloudpb.Key) (*Key, error) { - var key *Key - var namespace string - if partition := p.PartitionId; partition != nil { - namespace = partition.NamespaceId - } - for _, el := range p.Path { - key = &Key{ - Namespace: namespace, - Kind: el.Kind, - ID: el.GetId(), - Name: el.GetName(), - Parent: key, - } - } - if !key.valid() { // Also detects key == nil. - return key, ErrInvalidKey - } - return key, nil -} diff --git a/vendor/google.golang.org/appengine/datastore/internal/cloudpb/entity.pb.go b/vendor/google.golang.org/appengine/datastore/internal/cloudpb/entity.pb.go deleted file mode 100644 index af8195f3f..000000000 --- a/vendor/google.golang.org/appengine/datastore/internal/cloudpb/entity.pb.go +++ /dev/null @@ -1,344 +0,0 @@ -// Copyright 2019 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -// Package cloudpb is a subset of protobufs, copied from google.golang.org/genproto/googleapis/datastore/v1. -// -// They are copied here to provide compatibility to decode keys generated by the cloud.google.com/go/datastore package. -package cloudpb - -import ( - "fmt" - - "github.com/golang/protobuf/proto" -) - -// A partition ID identifies a grouping of entities. The grouping is always -// by project and namespace, however the namespace ID may be empty. -// -// A partition ID contains several dimensions: -// project ID and namespace ID. -// -// Partition dimensions: -// -// - May be `""`. -// - Must be valid UTF-8 bytes. -// - Must have values that match regex `[A-Za-z\d\.\-_]{1,100}` -// If the value of any dimension matches regex `__.*__`, the partition is -// reserved/read-only. -// A reserved/read-only partition ID is forbidden in certain documented -// contexts. -// -// Foreign partition IDs (in which the project ID does -// not match the context project ID ) are discouraged. -// Reads and writes of foreign partition IDs may fail if the project is not in -// an active state. -type PartitionId struct { - // The ID of the project to which the entities belong. - ProjectId string `protobuf:"bytes,2,opt,name=project_id,json=projectId,proto3" json:"project_id,omitempty"` - // If not empty, the ID of the namespace to which the entities belong. - NamespaceId string `protobuf:"bytes,4,opt,name=namespace_id,json=namespaceId,proto3" json:"namespace_id,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *PartitionId) Reset() { *m = PartitionId{} } -func (m *PartitionId) String() string { return proto.CompactTextString(m) } -func (*PartitionId) ProtoMessage() {} -func (*PartitionId) Descriptor() ([]byte, []int) { - return fileDescriptor_entity_096a297364b049a5, []int{0} -} -func (m *PartitionId) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_PartitionId.Unmarshal(m, b) -} -func (m *PartitionId) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_PartitionId.Marshal(b, m, deterministic) -} -func (dst *PartitionId) XXX_Merge(src proto.Message) { - xxx_messageInfo_PartitionId.Merge(dst, src) -} -func (m *PartitionId) XXX_Size() int { - return xxx_messageInfo_PartitionId.Size(m) -} -func (m *PartitionId) XXX_DiscardUnknown() { - xxx_messageInfo_PartitionId.DiscardUnknown(m) -} - -var xxx_messageInfo_PartitionId proto.InternalMessageInfo - -func (m *PartitionId) GetProjectId() string { - if m != nil { - return m.ProjectId - } - return "" -} - -func (m *PartitionId) GetNamespaceId() string { - if m != nil { - return m.NamespaceId - } - return "" -} - -// A unique identifier for an entity. -// If a key's partition ID or any of its path kinds or names are -// reserved/read-only, the key is reserved/read-only. -// A reserved/read-only key is forbidden in certain documented contexts. -type Key struct { - // Entities are partitioned into subsets, currently identified by a project - // ID and namespace ID. - // Queries are scoped to a single partition. - PartitionId *PartitionId `protobuf:"bytes,1,opt,name=partition_id,json=partitionId,proto3" json:"partition_id,omitempty"` - // The entity path. - // An entity path consists of one or more elements composed of a kind and a - // string or numerical identifier, which identify entities. The first - // element identifies a _root entity_, the second element identifies - // a _child_ of the root entity, the third element identifies a child of the - // second entity, and so forth. The entities identified by all prefixes of - // the path are called the element's _ancestors_. - // - // An entity path is always fully complete: *all* of the entity's ancestors - // are required to be in the path along with the entity identifier itself. - // The only exception is that in some documented cases, the identifier in the - // last path element (for the entity) itself may be omitted. For example, - // the last path element of the key of `Mutation.insert` may have no - // identifier. - // - // A path can never be empty, and a path can have at most 100 elements. - Path []*Key_PathElement `protobuf:"bytes,2,rep,name=path,proto3" json:"path,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Key) Reset() { *m = Key{} } -func (m *Key) String() string { return proto.CompactTextString(m) } -func (*Key) ProtoMessage() {} -func (*Key) Descriptor() ([]byte, []int) { - return fileDescriptor_entity_096a297364b049a5, []int{1} -} -func (m *Key) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Key.Unmarshal(m, b) -} -func (m *Key) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Key.Marshal(b, m, deterministic) -} -func (dst *Key) XXX_Merge(src proto.Message) { - xxx_messageInfo_Key.Merge(dst, src) -} -func (m *Key) XXX_Size() int { - return xxx_messageInfo_Key.Size(m) -} -func (m *Key) XXX_DiscardUnknown() { - xxx_messageInfo_Key.DiscardUnknown(m) -} - -// A (kind, ID/name) pair used to construct a key path. -// -// If either name or ID is set, the element is complete. -// If neither is set, the element is incomplete. -type Key_PathElement struct { - // The kind of the entity. - // A kind matching regex `__.*__` is reserved/read-only. - // A kind must not contain more than 1500 bytes when UTF-8 encoded. - // Cannot be `""`. - Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` - // The type of ID. - // - // Types that are valid to be assigned to IdType: - // *Key_PathElement_Id - // *Key_PathElement_Name - IdType isKey_PathElement_IdType `protobuf_oneof:"id_type"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Key_PathElement) Reset() { *m = Key_PathElement{} } -func (m *Key_PathElement) String() string { return proto.CompactTextString(m) } -func (*Key_PathElement) ProtoMessage() {} -func (*Key_PathElement) Descriptor() ([]byte, []int) { - return fileDescriptor_entity_096a297364b049a5, []int{1, 0} -} -func (m *Key_PathElement) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Key_PathElement.Unmarshal(m, b) -} -func (m *Key_PathElement) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Key_PathElement.Marshal(b, m, deterministic) -} -func (dst *Key_PathElement) XXX_Merge(src proto.Message) { - xxx_messageInfo_Key_PathElement.Merge(dst, src) -} -func (m *Key_PathElement) XXX_Size() int { - return xxx_messageInfo_Key_PathElement.Size(m) -} -func (m *Key_PathElement) XXX_DiscardUnknown() { - xxx_messageInfo_Key_PathElement.DiscardUnknown(m) -} - -var xxx_messageInfo_Key_PathElement proto.InternalMessageInfo - -func (m *Key_PathElement) GetKind() string { - if m != nil { - return m.Kind - } - return "" -} - -type isKey_PathElement_IdType interface { - isKey_PathElement_IdType() -} - -type Key_PathElement_Id struct { - Id int64 `protobuf:"varint,2,opt,name=id,proto3,oneof"` -} - -type Key_PathElement_Name struct { - Name string `protobuf:"bytes,3,opt,name=name,proto3,oneof"` -} - -func (*Key_PathElement_Id) isKey_PathElement_IdType() {} - -func (*Key_PathElement_Name) isKey_PathElement_IdType() {} - -func (m *Key_PathElement) GetIdType() isKey_PathElement_IdType { - if m != nil { - return m.IdType - } - return nil -} - -func (m *Key_PathElement) GetId() int64 { - if x, ok := m.GetIdType().(*Key_PathElement_Id); ok { - return x.Id - } - return 0 -} - -func (m *Key_PathElement) GetName() string { - if x, ok := m.GetIdType().(*Key_PathElement_Name); ok { - return x.Name - } - return "" -} - -// XXX_OneofFuncs is for the internal use of the proto package. -func (*Key_PathElement) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) { - return _Key_PathElement_OneofMarshaler, _Key_PathElement_OneofUnmarshaler, _Key_PathElement_OneofSizer, []interface{}{ - (*Key_PathElement_Id)(nil), - (*Key_PathElement_Name)(nil), - } -} - -func _Key_PathElement_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { - m := msg.(*Key_PathElement) - // id_type - switch x := m.IdType.(type) { - case *Key_PathElement_Id: - b.EncodeVarint(2<<3 | proto.WireVarint) - b.EncodeVarint(uint64(x.Id)) - case *Key_PathElement_Name: - b.EncodeVarint(3<<3 | proto.WireBytes) - b.EncodeStringBytes(x.Name) - case nil: - default: - return fmt.Errorf("Key_PathElement.IdType has unexpected type %T", x) - } - return nil -} - -func _Key_PathElement_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) { - m := msg.(*Key_PathElement) - switch tag { - case 2: // id_type.id - if wire != proto.WireVarint { - return true, proto.ErrInternalBadWireType - } - x, err := b.DecodeVarint() - m.IdType = &Key_PathElement_Id{int64(x)} - return true, err - case 3: // id_type.name - if wire != proto.WireBytes { - return true, proto.ErrInternalBadWireType - } - x, err := b.DecodeStringBytes() - m.IdType = &Key_PathElement_Name{x} - return true, err - default: - return false, nil - } -} - -func _Key_PathElement_OneofSizer(msg proto.Message) (n int) { - m := msg.(*Key_PathElement) - // id_type - switch x := m.IdType.(type) { - case *Key_PathElement_Id: - n += 1 // tag and wire - n += proto.SizeVarint(uint64(x.Id)) - case *Key_PathElement_Name: - n += 1 // tag and wire - n += proto.SizeVarint(uint64(len(x.Name))) - n += len(x.Name) - case nil: - default: - panic(fmt.Sprintf("proto: unexpected type %T in oneof", x)) - } - return n -} - -var fileDescriptor_entity_096a297364b049a5 = []byte{ - // 780 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x94, 0xff, 0x6e, 0xdc, 0x44, - 0x10, 0xc7, 0xed, 0xbb, 0x5c, 0x1a, 0x8f, 0xdd, 0xa4, 0x6c, 0x2a, 0x61, 0x02, 0x28, 0x26, 0x80, - 0x74, 0x02, 0xc9, 0x6e, 0xc2, 0x1f, 0x54, 0x14, 0xa4, 0x72, 0x25, 0xe0, 0x28, 0x15, 0x9c, 0x56, - 0x55, 0x24, 0x50, 0xa4, 0xd3, 0xde, 0x79, 0xeb, 0x2e, 0x67, 0xef, 0x5a, 0xf6, 0x3a, 0xaa, 0xdf, - 0x05, 0xf1, 0x00, 0x3c, 0x0a, 0x8f, 0x80, 0x78, 0x18, 0xb4, 0x3f, 0xec, 0x0b, 0xed, 0x35, 0xff, - 0x79, 0x67, 0x3e, 0xdf, 0xd9, 0xef, 0xec, 0xce, 0x1a, 0xa2, 0x5c, 0x88, 0xbc, 0xa0, 0x49, 0x46, - 0x24, 0x69, 0xa4, 0xa8, 0x69, 0x72, 0x73, 0x9a, 0x50, 0x2e, 0x99, 0xec, 0xe2, 0xaa, 0x16, 0x52, - 0xa0, 0x43, 0x43, 0xc4, 0x03, 0x11, 0xdf, 0x9c, 0x1e, 0x7d, 0x64, 0x65, 0xa4, 0x62, 0x09, 0xe1, - 0x5c, 0x48, 0x22, 0x99, 0xe0, 0x8d, 0x91, 0x0c, 0x59, 0xbd, 0x5a, 0xb6, 0x2f, 0x93, 0x46, 0xd6, - 0xed, 0x4a, 0xda, 0xec, 0xf1, 0x9b, 0x59, 0xc9, 0x4a, 0xda, 0x48, 0x52, 0x56, 0x16, 0x08, 0x2d, - 0x20, 0xbb, 0x8a, 0x26, 0x05, 0x91, 0x05, 0xcf, 0x4d, 0xe6, 0xe4, 0x17, 0xf0, 0xe7, 0xa4, 0x96, - 0x4c, 0x6d, 0x76, 0x91, 0xa1, 0x8f, 0x01, 0xaa, 0x5a, 0xfc, 0x4e, 0x57, 0x72, 0xc1, 0xb2, 0x70, - 0x14, 0xb9, 0x53, 0x0f, 0x7b, 0x36, 0x72, 0x91, 0xa1, 0x4f, 0x20, 0xe0, 0xa4, 0xa4, 0x4d, 0x45, - 0x56, 0x54, 0x01, 0x3b, 0x1a, 0xf0, 0x87, 0xd8, 0x45, 0x76, 0xf2, 0x8f, 0x0b, 0xe3, 0x4b, 0xda, - 0xa1, 0x67, 0x10, 0x54, 0x7d, 0x61, 0x85, 0xba, 0x91, 0x3b, 0xf5, 0xcf, 0xa2, 0x78, 0x4b, 0xef, - 0xf1, 0x2d, 0x07, 0xd8, 0xaf, 0x6e, 0xd9, 0x79, 0x0c, 0x3b, 0x15, 0x91, 0xaf, 0xc2, 0x51, 0x34, - 0x9e, 0xfa, 0x67, 0x9f, 0x6d, 0x15, 0x5f, 0xd2, 0x2e, 0x9e, 0x13, 0xf9, 0xea, 0xbc, 0xa0, 0x25, - 0xe5, 0x12, 0x6b, 0xc5, 0xd1, 0x0b, 0xd5, 0xd7, 0x10, 0x44, 0x08, 0x76, 0xd6, 0x8c, 0x1b, 0x17, - 0x1e, 0xd6, 0xdf, 0xe8, 0x01, 0x8c, 0x6c, 0x8f, 0xe3, 0xd4, 0xc1, 0x23, 0x96, 0xa1, 0x87, 0xb0, - 0xa3, 0x5a, 0x09, 0xc7, 0x8a, 0x4a, 0x1d, 0xac, 0x57, 0x33, 0x0f, 0xee, 0xb1, 0x6c, 0xa1, 0x8e, - 0xee, 0xe4, 0x29, 0xc0, 0xf7, 0x75, 0x4d, 0xba, 0x2b, 0x52, 0xb4, 0x14, 0x9d, 0xc1, 0xee, 0x8d, - 0xfa, 0x68, 0x42, 0x57, 0xfb, 0x3b, 0xda, 0xea, 0x4f, 0xb3, 0xd8, 0x92, 0x27, 0x7f, 0x4c, 0x60, - 0x62, 0xd4, 0x4f, 0x00, 0x78, 0x5b, 0x14, 0x0b, 0x9d, 0x08, 0xfd, 0xc8, 0x9d, 0xee, 0x6f, 0x2a, - 0xf4, 0x37, 0x19, 0xff, 0xdc, 0x16, 0x85, 0xe6, 0x53, 0x07, 0x7b, 0xbc, 0x5f, 0xa0, 0xcf, 0xe1, - 0xfe, 0x52, 0x88, 0x82, 0x12, 0x6e, 0xf5, 0xaa, 0xb1, 0xbd, 0xd4, 0xc1, 0x81, 0x0d, 0x0f, 0x18, - 0xe3, 0x92, 0xe6, 0xb4, 0xb6, 0x58, 0xdf, 0x6d, 0x60, 0xc3, 0x06, 0xfb, 0x14, 0x82, 0x4c, 0xb4, - 0xcb, 0x82, 0x5a, 0x4a, 0xf5, 0xef, 0xa6, 0x0e, 0xf6, 0x4d, 0xd4, 0x40, 0xe7, 0x70, 0x30, 0x8c, - 0x95, 0xe5, 0x40, 0xdf, 0xe9, 0xdb, 0xa6, 0x5f, 0xf4, 0x5c, 0xea, 0xe0, 0xfd, 0x41, 0x64, 0xca, - 0x7c, 0x0d, 0xde, 0x9a, 0x76, 0xb6, 0xc0, 0x44, 0x17, 0x08, 0xdf, 0x75, 0xaf, 0xa9, 0x83, 0xf7, - 0xd6, 0xb4, 0x1b, 0x4c, 0x36, 0xb2, 0x66, 0x3c, 0xb7, 0xda, 0xf7, 0xec, 0x25, 0xf9, 0x26, 0x6a, - 0xa0, 0x63, 0x80, 0x65, 0x21, 0x96, 0x16, 0x41, 0x91, 0x3b, 0x0d, 0xd4, 0xc1, 0xa9, 0x98, 0x01, - 0xbe, 0x83, 0x83, 0x9c, 0x8a, 0x45, 0x25, 0x18, 0x97, 0x96, 0xda, 0xd3, 0x26, 0x0e, 0x7b, 0x13, - 0xea, 0xa2, 0xe3, 0xe7, 0x44, 0x3e, 0xe7, 0x79, 0xea, 0xe0, 0xfb, 0x39, 0x15, 0x73, 0x05, 0x1b, - 0xf9, 0x53, 0x08, 0xcc, 0x53, 0xb6, 0xda, 0x5d, 0xad, 0xfd, 0x70, 0x6b, 0x03, 0xe7, 0x1a, 0x54, - 0x0e, 0x8d, 0xc4, 0x54, 0x98, 0x81, 0x4f, 0xd4, 0x08, 0xd9, 0x02, 0x9e, 0x2e, 0x70, 0xbc, 0xb5, - 0xc0, 0x66, 0xd4, 0x52, 0x07, 0x03, 0xd9, 0x0c, 0x5e, 0x08, 0xf7, 0x4a, 0x4a, 0x38, 0xe3, 0x79, - 0xb8, 0x1f, 0xb9, 0xd3, 0x09, 0xee, 0x97, 0xe8, 0x11, 0x3c, 0xa4, 0xaf, 0x57, 0x45, 0x9b, 0xd1, - 0xc5, 0xcb, 0x5a, 0x94, 0x0b, 0xc6, 0x33, 0xfa, 0x9a, 0x36, 0xe1, 0xa1, 0x1a, 0x0f, 0x8c, 0x6c, - 0xee, 0xc7, 0x5a, 0x94, 0x17, 0x26, 0x33, 0x0b, 0x00, 0xb4, 0x13, 0x33, 0xe0, 0xff, 0xba, 0xb0, - 0x6b, 0x7c, 0xa3, 0x2f, 0x60, 0xbc, 0xa6, 0x9d, 0x7d, 0xb7, 0xef, 0xbc, 0x22, 0xac, 0x20, 0x74, - 0xa9, 0x7f, 0x1b, 0x15, 0xad, 0x25, 0xa3, 0x4d, 0x38, 0xd6, 0xaf, 0xe1, 0xcb, 0x3b, 0x0e, 0x25, - 0x9e, 0x0f, 0xf4, 0x39, 0x97, 0x75, 0x87, 0x6f, 0xc9, 0x8f, 0x7e, 0x85, 0x83, 0x37, 0xd2, 0xe8, - 0xc1, 0xc6, 0x8b, 0x67, 0x76, 0x7c, 0x04, 0x93, 0xcd, 0x44, 0xdf, 0xfd, 0xf4, 0x0c, 0xf8, 0xcd, - 0xe8, 0xb1, 0x3b, 0xfb, 0xd3, 0x85, 0xf7, 0x57, 0xa2, 0xdc, 0x06, 0xcf, 0x7c, 0x63, 0x6d, 0xae, - 0x86, 0x78, 0xee, 0xfe, 0xf6, 0xad, 0x65, 0x72, 0x51, 0x10, 0x9e, 0xc7, 0xa2, 0xce, 0x93, 0x9c, - 0x72, 0x3d, 0xe2, 0x89, 0x49, 0x91, 0x8a, 0x35, 0xff, 0xfb, 0xcb, 0x3f, 0x19, 0x16, 0x7f, 0x8d, - 0x3e, 0xf8, 0xc9, 0xc8, 0x9f, 0x15, 0xa2, 0xcd, 0xe2, 0x1f, 0x86, 0x8d, 0xae, 0x4e, 0xff, 0xee, - 0x73, 0xd7, 0x3a, 0x77, 0x3d, 0xe4, 0xae, 0xaf, 0x4e, 0x97, 0xbb, 0x7a, 0x83, 0xaf, 0xfe, 0x0b, - 0x00, 0x00, 0xff, 0xff, 0xf3, 0xdd, 0x11, 0x96, 0x45, 0x06, 0x00, 0x00, -} - -var xxx_messageInfo_Key proto.InternalMessageInfo diff --git a/vendor/google.golang.org/appengine/datastore/key.go b/vendor/google.golang.org/appengine/datastore/key.go index fd598dc96..6ab83eaf6 100644 --- a/vendor/google.golang.org/appengine/datastore/key.go +++ b/vendor/google.golang.org/appengine/datastore/key.go @@ -254,10 +254,6 @@ func DecodeKey(encoded string) (*Key, error) { ref := new(pb.Reference) if err := proto.Unmarshal(b, ref); err != nil { - // Couldn't decode it as an App Engine key, try decoding it as a key encoded by cloud.google.com/go/datastore. - if k := decodeCloudKey(encoded); k != nil { - return k, nil - } return nil, err } diff --git a/vendor/google.golang.org/appengine/datastore/keycompat.go b/vendor/google.golang.org/appengine/datastore/keycompat.go deleted file mode 100644 index 371a64eee..000000000 --- a/vendor/google.golang.org/appengine/datastore/keycompat.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2019 Google Inc. All rights reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package datastore - -import ( - "sync" - - "golang.org/x/net/context" - - "google.golang.org/appengine/datastore/internal/cloudkey" - "google.golang.org/appengine/internal" -) - -var keyConversion struct { - mu sync.RWMutex - appID string // read using getKeyConversionAppID -} - -// EnableKeyConversion enables encoded key compatibility with the Cloud -// Datastore client library (cloud.google.com/go/datastore). Encoded keys -// generated by the Cloud Datastore client library will be decoded into App -// Engine datastore keys. -// -// The context provided must be an App Engine context if running in App Engine -// first generation runtime. This can be called in the /_ah/start handler. It is -// safe to call multiple times, and is cheap to call, so can also be inserted as -// middleware. -// -// Enabling key compatibility does not affect the encoding format used by -// Key.Encode, it only expands the type of keys that are able to be decoded with -// DecodeKey. -func EnableKeyConversion(ctx context.Context) { - // Only attempt to set appID if it's unset. - // If already set, ignore. - if getKeyConversionAppID() != "" { - return - } - - keyConversion.mu.Lock() - // Check again to avoid race where another goroutine set appID between the call - // to getKeyConversionAppID above and taking the write lock. - if keyConversion.appID == "" { - keyConversion.appID = internal.FullyQualifiedAppID(ctx) - } - keyConversion.mu.Unlock() -} - -func getKeyConversionAppID() string { - keyConversion.mu.RLock() - appID := keyConversion.appID - keyConversion.mu.RUnlock() - return appID -} - -// decodeCloudKey attempts to decode the given encoded key generated by the -// Cloud Datastore client library (cloud.google.com/go/datastore), returning nil -// if the key couldn't be decoded. -func decodeCloudKey(encoded string) *Key { - appID := getKeyConversionAppID() - if appID == "" { - return nil - } - - k, err := cloudkey.DecodeKey(encoded) - if err != nil { - return nil - } - return convertCloudKey(k, appID) -} - -// convertCloudKey converts a Cloud Datastore key and converts it to an App -// Engine Datastore key. Cloud Datastore keys don't include the project/app ID, -// so we must add it back in. -func convertCloudKey(key *cloudkey.Key, appID string) *Key { - if key == nil { - return nil - } - k := &Key{ - intID: key.ID, - kind: key.Kind, - namespace: key.Namespace, - parent: convertCloudKey(key.Parent, appID), - stringID: key.Name, - appID: appID, - } - return k -} diff --git a/vendor/google.golang.org/appengine/datastore/keycompat_test.go b/vendor/google.golang.org/appengine/datastore/keycompat_test.go deleted file mode 100644 index 923fdac9a..000000000 --- a/vendor/google.golang.org/appengine/datastore/keycompat_test.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2019 Google Inc. All Rights Reserved. -// Use of this source code is governed by the Apache 2.0 -// license that can be found in the LICENSE file. - -package datastore - -import ( - "reflect" - "testing" -) - -func TestKeyConversion(t *testing.T) { - var tests = []struct { - desc string - key *Key - encodedKey string - }{ - { - desc: "A control test for legacy to legacy key conversion int as the key", - key: &Key{ - kind: "Person", - intID: 1, - appID: "glibrary", - }, - encodedKey: "aghnbGlicmFyeXIMCxIGUGVyc29uGAEM", - }, - { - desc: "A control test for legacy to legacy key conversion string as the key", - key: &Key{ - kind: "Graph", - stringID: "graph:7-day-active", - appID: "glibrary", - }, - encodedKey: "aghnbGlicmFyeXIdCxIFR3JhcGgiEmdyYXBoOjctZGF5LWFjdGl2ZQw", - }, - - // These are keys encoded with cloud.google.com/go/datastore - // Standard int as the key - { - desc: "Convert new key format to old key with int id", - key: &Key{ - kind: "WordIndex", - intID: 1033, - appID: "glibrary", - }, - encodedKey: "Eg4KCVdvcmRJbmRleBCJCA", - }, - // These are keys encoded with cloud.google.com/go/datastore - // Standard string - { - desc: "Convert new key format to old key with string id", - key: &Key{ - kind: "WordIndex", - stringID: "IAmAnID", - appID: "glibrary", - }, - encodedKey: "EhQKCVdvcmRJbmRleBoHSUFtQW5JRA", - }, - - // These are keys encoded with cloud.google.com/go/datastore - // ID String with parent as string - { - desc: "Convert new key format to old key with string id with a parent", - key: &Key{ - kind: "WordIndex", - stringID: "IAmAnID", - appID: "glibrary", - parent: &Key{ - kind: "LetterIndex", - stringID: "IAmAnotherID", - appID: "glibrary", - }, - }, - encodedKey: "EhsKC0xldHRlckluZGV4GgxJQW1Bbm90aGVySUQSFAoJV29yZEluZGV4GgdJQW1BbklE", - }, - } - - // Simulate the key converter enablement - keyConversion.appID = "glibrary" - for _, tc := range tests { - dk, err := DecodeKey(tc.encodedKey) - if err != nil { - t.Fatalf("DecodeKey: %v", err) - } - if !reflect.DeepEqual(dk, tc.key) { - t.Errorf("%s: got %+v, want %+v", tc.desc, dk, tc.key) - } - } -} diff --git a/vendor/google.golang.org/appengine/file/file.go b/vendor/google.golang.org/appengine/file/file.go index e63a4aca9..c3cd58baf 100644 --- a/vendor/google.golang.org/appengine/file/file.go +++ b/vendor/google.golang.org/appengine/file/file.go @@ -22,7 +22,7 @@ func DefaultBucketName(c context.Context) (string, error) { err := internal.Call(c, "app_identity_service", "GetDefaultGcsBucketName", req, res) if err != nil { - return "", fmt.Errorf("file: no default bucket name returned in RPC response: %v", err) + return "", fmt.Errorf("file: no default bucket name returned in RPC response: %v", res) } return res.GetDefaultGcsBucketName(), nil } diff --git a/vendor/google.golang.org/appengine/go.mod b/vendor/google.golang.org/appengine/go.mod index 451592798..f449359d2 100644 --- a/vendor/google.golang.org/appengine/go.mod +++ b/vendor/google.golang.org/appengine/go.mod @@ -1,10 +1,7 @@ module google.golang.org/appengine require ( - github.com/golang/protobuf v1.3.1 - golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5 // indirect - golang.org/x/net v0.0.0-20190603091049-60506f45cf65 - golang.org/x/sys v0.0.0-20190606165138-5da285871e9c // indirect - golang.org/x/text v0.3.2 - golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b // indirect + github.com/golang/protobuf v1.2.0 + golang.org/x/net v0.0.0-20180724234803-3673e40ba225 + golang.org/x/text v0.3.0 ) diff --git a/vendor/google.golang.org/appengine/go.sum b/vendor/google.golang.org/appengine/go.sum index cb3232556..1a221c089 100644 --- a/vendor/google.golang.org/appengine/go.sum +++ b/vendor/google.golang.org/appengine/go.sum @@ -1,22 +1,6 @@ github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225 h1:kNX+jCowfMYzvlSvJu5pQWEmyWFrBXJ3PBy10xKMXK8= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65 h1:+rhAzEzT3f4JtomfC371qB+0Ola2caSKcY69NUBZrRQ= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= diff --git a/vendor/k8s.io/component-base/Godeps/Godeps.json b/vendor/k8s.io/component-base/Godeps/Godeps.json index d6e0fdce2..dc8751c63 100644 --- a/vendor/k8s.io/component-base/Godeps/Godeps.json +++ b/vendor/k8s.io/component-base/Godeps/Godeps.json @@ -1,7 +1,7 @@ { "ImportPath": "k8s.io/component-base", "GoVersion": "go1.12", - "GodepVersion": "v80-k8s-r1", + "GodepVersion": "v80", "Packages": [ "./..." ], diff --git a/vendor/sigs.k8s.io/yaml/.travis.yml b/vendor/sigs.k8s.io/yaml/.travis.yml index e14abb965..03ddc7318 100644 --- a/vendor/sigs.k8s.io/yaml/.travis.yml +++ b/vendor/sigs.k8s.io/yaml/.travis.yml @@ -1,12 +1,14 @@ language: go dist: xenial go: - - 1.12.x + - 1.9.x + - 1.10.x + - 1.11.x script: - - diff -u <(echo -n) <(gofmt -d *.go) + - go get -t -v ./... + - diff -u <(echo -n) <(gofmt -d .) - diff -u <(echo -n) <(golint $(go list -e ./...) | grep -v YAMLToJSON) - - GO111MODULE=on go vet . - - GO111MODULE=on go test -v -race ./... - - git diff --exit-code + - go tool vet . + - go test -v -race ./... install: - go get golang.org/x/lint/golint diff --git a/vendor/sigs.k8s.io/yaml/OWNERS b/vendor/sigs.k8s.io/yaml/OWNERS index 325b40b07..11ad7ce1a 100644 --- a/vendor/sigs.k8s.io/yaml/OWNERS +++ b/vendor/sigs.k8s.io/yaml/OWNERS @@ -1,5 +1,3 @@ -# See the OWNERS docs at https://go.k8s.io/owners - approvers: - dims - lavalamp diff --git a/vendor/sigs.k8s.io/yaml/README.md b/vendor/sigs.k8s.io/yaml/README.md index 3735f25e3..0200f75b4 100644 --- a/vendor/sigs.k8s.io/yaml/README.md +++ b/vendor/sigs.k8s.io/yaml/README.md @@ -1,8 +1,6 @@ # YAML marshaling and unmarshaling support for Go -[![Build Status](https://travis-ci.org/kubernetes-sigs/yaml.svg)](https://travis-ci.org/kubernetes-sigs/yaml) - -kubernetes-sigs/yaml is a permanent fork of [ghodss/yaml](https://github.com/ghodss/yaml). +[![Build Status](https://travis-ci.org/ghodss/yaml.svg)](https://travis-ci.org/ghodss/yaml) ## Introduction @@ -34,13 +32,13 @@ GOOD: To install, run: ``` -$ go get sigs.k8s.io/yaml +$ go get github.com/ghodss/yaml ``` And import using: ``` -import "sigs.k8s.io/yaml" +import "github.com/ghodss/yaml" ``` Usage is very similar to the JSON library: @@ -51,7 +49,7 @@ package main import ( "fmt" - "sigs.k8s.io/yaml" + "github.com/ghodss/yaml" ) type Person struct { @@ -95,7 +93,7 @@ package main import ( "fmt" - "sigs.k8s.io/yaml" + "github.com/ghodss/yaml" ) func main() { diff --git a/vendor/sigs.k8s.io/yaml/go.mod b/vendor/sigs.k8s.io/yaml/go.mod deleted file mode 100644 index 4b9d63791..000000000 --- a/vendor/sigs.k8s.io/yaml/go.mod +++ /dev/null @@ -1,8 +0,0 @@ -module sigs.k8s.io/yaml - -go 1.12 - -require ( - github.com/davecgh/go-spew v1.1.1 - gopkg.in/yaml.v2 v2.2.2 -) diff --git a/vendor/sigs.k8s.io/yaml/go.sum b/vendor/sigs.k8s.io/yaml/go.sum deleted file mode 100644 index 22faccc9e..000000000 --- a/vendor/sigs.k8s.io/yaml/go.sum +++ /dev/null @@ -1,5 +0,0 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/sigs.k8s.io/yaml/yaml.go b/vendor/sigs.k8s.io/yaml/yaml.go index efbc535d4..024596112 100644 --- a/vendor/sigs.k8s.io/yaml/yaml.go +++ b/vendor/sigs.k8s.io/yaml/yaml.go @@ -317,64 +317,3 @@ func convertToJSONableObject(yamlObj interface{}, jsonTarget *reflect.Value) (in return yamlObj, nil } } - -// JSONObjectToYAMLObject converts an in-memory JSON object into a YAML in-memory MapSlice, -// without going through a byte representation. A nil or empty map[string]interface{} input is -// converted to an empty map, i.e. yaml.MapSlice(nil). -// -// interface{} slices stay interface{} slices. map[string]interface{} becomes yaml.MapSlice. -// -// int64 and float64 are down casted following the logic of github.com/go-yaml/yaml: -// - float64s are down-casted as far as possible without data-loss to int, int64, uint64. -// - int64s are down-casted to int if possible without data-loss. -// -// Big int/int64/uint64 do not lose precision as in the json-yaml roundtripping case. -// -// string, bool and any other types are unchanged. -func JSONObjectToYAMLObject(j map[string]interface{}) yaml.MapSlice { - if len(j) == 0 { - return nil - } - ret := make(yaml.MapSlice, 0, len(j)) - for k, v := range j { - ret = append(ret, yaml.MapItem{Key: k, Value: jsonToYAMLValue(v)}) - } - return ret -} - -func jsonToYAMLValue(j interface{}) interface{} { - switch j := j.(type) { - case map[string]interface{}: - if j == nil { - return interface{}(nil) - } - return JSONObjectToYAMLObject(j) - case []interface{}: - if j == nil { - return interface{}(nil) - } - ret := make([]interface{}, len(j)) - for i := range j { - ret[i] = jsonToYAMLValue(j[i]) - } - return ret - case float64: - // replicate the logic in https://github.com/go-yaml/yaml/blob/51d6538a90f86fe93ac480b35f37b2be17fef232/resolve.go#L151 - if i64 := int64(j); j == float64(i64) { - if i := int(i64); i64 == int64(i) { - return i - } - return i64 - } - if ui64 := uint64(j); j == float64(ui64) { - return ui64 - } - return j - case int64: - if i := int(j); j == int64(i) { - return i - } - return j - } - return j -} diff --git a/vendor/sigs.k8s.io/yaml/yaml_test.go b/vendor/sigs.k8s.io/yaml/yaml_test.go index a88cbf3b3..42a231567 100644 --- a/vendor/sigs.k8s.io/yaml/yaml_test.go +++ b/vendor/sigs.k8s.io/yaml/yaml_test.go @@ -1,16 +1,11 @@ package yaml import ( - "encoding/json" "fmt" "math" "reflect" - "sort" "strconv" "testing" - - "github.com/davecgh/go-spew/spew" - yaml "gopkg.in/yaml.v2" ) type MarshalTest struct { @@ -426,120 +421,3 @@ foo: baz t.Error("expected YAMLtoJSONStrict to fail on duplicate field names") } } - -func TestJSONObjectToYAMLObject(t *testing.T) { - intOrInt64 := func(i64 int64) interface{} { - if i := int(i64); i64 == int64(i) { - return i - } - return i64 - } - - tests := []struct { - name string - input map[string]interface{} - expected yaml.MapSlice - }{ - {name: "nil", expected: yaml.MapSlice(nil)}, - {name: "empty", input: map[string]interface{}{}, expected: yaml.MapSlice(nil)}, - { - name: "values", - input: map[string]interface{}{ - "nil slice": []interface{}(nil), - "nil map": map[string]interface{}(nil), - "empty slice": []interface{}{}, - "empty map": map[string]interface{}{}, - "bool": true, - "float64": float64(42.1), - "fractionless": float64(42), - "int": int(42), - "int64": int64(42), - "int64 big": float64(math.Pow(2, 62)), - "negative int64 big": -float64(math.Pow(2, 62)), - "map": map[string]interface{}{"foo": "bar"}, - "slice": []interface{}{"foo", "bar"}, - "string": string("foo"), - "uint64 big": float64(math.Pow(2, 63)), - }, - expected: yaml.MapSlice{ - {Key: "nil slice"}, - {Key: "nil map"}, - {Key: "empty slice", Value: []interface{}{}}, - {Key: "empty map", Value: yaml.MapSlice(nil)}, - {Key: "bool", Value: true}, - {Key: "float64", Value: float64(42.1)}, - {Key: "fractionless", Value: int(42)}, - {Key: "int", Value: int(42)}, - {Key: "int64", Value: int(42)}, - {Key: "int64 big", Value: intOrInt64(int64(1) << 62)}, - {Key: "negative int64 big", Value: intOrInt64(-(1 << 62))}, - {Key: "map", Value: yaml.MapSlice{{Key: "foo", Value: "bar"}}}, - {Key: "slice", Value: []interface{}{"foo", "bar"}}, - {Key: "string", Value: string("foo")}, - {Key: "uint64 big", Value: uint64(1) << 63}, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := JSONObjectToYAMLObject(tt.input) - sortMapSlicesInPlace(tt.expected) - sortMapSlicesInPlace(got) - if !reflect.DeepEqual(got, tt.expected) { - t.Errorf("jsonToYAML() = %v, want %v", spew.Sdump(got), spew.Sdump(tt.expected)) - } - - jsonBytes, err := json.Marshal(tt.input) - if err != nil { - t.Fatalf("unexpected json.Marshal error: %v", err) - } - var gotByRoundtrip yaml.MapSlice - if err := yaml.Unmarshal(jsonBytes, &gotByRoundtrip); err != nil { - t.Fatalf("unexpected yaml.Unmarshal error: %v", err) - } - - // yaml.Unmarshal loses precision, it's rounding to the 4th last digit. - // Replicate this here in the test, but don't change the type. - for i := range got { - switch got[i].Key { - case "int64 big", "uint64 big", "negative int64 big": - switch v := got[i].Value.(type) { - case int64: - d := int64(500) - if v < 0 { - d = -500 - } - got[i].Value = int64((v+d)/1000) * 1000 - case uint64: - got[i].Value = uint64((v+500)/1000) * 1000 - case int: - d := int(500) - if v < 0 { - d = -500 - } - got[i].Value = int((v+d)/1000) * 1000 - default: - t.Fatalf("unexpected type for key %s: %v:%T", got[i].Key, v, v) - } - } - } - - if !reflect.DeepEqual(got, gotByRoundtrip) { - t.Errorf("yaml.Unmarshal(json.Marshal(tt.input)) = %v, want %v\njson: %s", spew.Sdump(gotByRoundtrip), spew.Sdump(got), string(jsonBytes)) - } - }) - } -} - -func sortMapSlicesInPlace(x interface{}) { - switch x := x.(type) { - case []interface{}: - for i := range x { - sortMapSlicesInPlace(x[i]) - } - case yaml.MapSlice: - sort.Slice(x, func(a, b int) bool { - return x[a].Key.(string) < x[b].Key.(string) - }) - } -}