From 9f1c31961f20c9d50768baf5725dfe49e186e3f7 Mon Sep 17 00:00:00 2001 From: Kazuki Suda Date: Fri, 27 Jul 2018 14:21:51 +0900 Subject: [PATCH] # This is a combination of 15 commits. # This is the 1st commit message: Document adding an external type # This is the commit message #2: Fix typo in book: flag is --owner, not --owners # This is the commit message #3: gitbook: fixed installation instructions # This is the commit message #4: Fix domain resource issues in controller - fix in controller-tools and vendor in kubebuilder - bind resource for controller based on whether resource is created. # This is the commit message #5: improve contributing guide # This is the commit message #6: Fix URL for the Gitbook The URL is .io, not .com # This is the commit message #7: Check go version Fixes #353 # This is the commit message #8: Validate create api flags Fixes #321 # This is the commit message #9: Update stable version in book Update newest stable version to "1.0.1". # This is the commit message #10: thirdparty tools: Dockerfile uses k8s 1.11 # This is the commit message #11: build: update cloudbuild config for building tools to use k8s 1.11 # This is the commit message #12: add document for connecting to existing kind # This is the commit message #13: add document for connecting to existing kind # This is the commit message #14: removed company from doc # This is the commit message #15: fixed typo --- CONTRIBUTING.md | 57 +- build/cloudbuild_tools.yaml | 2 +- build/thirdparty/darwin/Dockerfile | 16 +- build/thirdparty/linux/Dockerfile | 16 +- cmd/Gopkg.lock | 10 +- cmd/Gopkg.toml | 4 + cmd/kubebuilder/initproject/init.go | 53 +- cmd/kubebuilder/v1/api.go | 11 + .../github.com/Masterminds/semver/.travis.yml | 27 + .../Masterminds/semver/CHANGELOG.md | 86 +++ .../github.com/Masterminds/semver/LICENSE.txt | 20 + .../github.com/Masterminds/semver/Makefile | 36 ++ .../github.com/Masterminds/semver/README.md | 165 ++++++ .../Masterminds/semver/appveyor.yml | 44 ++ .../Masterminds/semver/benchmark_test.go | 157 ++++++ .../Masterminds/semver/collection.go | 24 + .../Masterminds/semver/collection_test.go | 46 ++ .../Masterminds/semver/constraints.go | 426 +++++++++++++++ .../Masterminds/semver/constraints_test.go | 465 +++++++++++++++++ .../github.com/Masterminds/semver/doc.go | 115 ++++ .../github.com/Masterminds/semver/version.go | 421 +++++++++++++++ .../Masterminds/semver/version_test.go | 490 ++++++++++++++++++ .../cmd/controller-gen/main.go | 7 +- .../pkg/scaffold/controller/controller.go | 31 +- .../pkg/scaffold/controller/controllertest.go | 8 +- .../pkg/apis/addtoscheme_policy_v1beta1.go | 26 + .../test/pkg/apis/creatures/v2alpha1/doc.go | 2 +- .../pkg/apis/creatures/v2alpha1/register.go | 4 +- .../test/pkg/apis/crew/v1/doc.go | 2 +- .../test/pkg/apis/crew/v1/register.go | 4 +- .../test/pkg/apis/policy/group.go | 18 + .../test/pkg/apis/policy/v1beta1/doc.go | 23 + .../policy/v1beta1/healthcheckpolicy_types.go | 64 +++ .../test/pkg/apis/policy/v1beta1/register.go | 38 ++ .../test/pkg/apis/ship/v1beta1/doc.go | 2 +- .../test/pkg/apis/ship/v1beta1/register.go | 4 +- .../pkg/controller/add_healthcheckpolicy.go | 26 + .../firstmate/firstmate_controller.go | 2 +- .../controller/frigate/frigate_controller.go | 2 +- .../healthcheckpolicy_controller.go | 106 ++++ .../controller/kraken/kraken_controller.go | 2 +- docs/README.md | 4 +- docs/book/README.md | 2 +- docs/book/SUMMARY.md | 2 +- .../basics/project_creation_and_structure.md | 2 +- .../getting_started/installation_and_setup.md | 28 +- docs/book/quick_start.md | 12 +- docs/connect_to_existing_kind.md | 65 +++ docs/using_an_external_type.md | 104 ++++ test/e2e/e2e_v0.go | 4 +- test/e2e/e2e_v1.go | 4 +- 51 files changed, 3165 insertions(+), 124 deletions(-) create mode 100644 cmd/vendor/github.com/Masterminds/semver/.travis.yml create mode 100644 cmd/vendor/github.com/Masterminds/semver/CHANGELOG.md create mode 100644 cmd/vendor/github.com/Masterminds/semver/LICENSE.txt create mode 100644 cmd/vendor/github.com/Masterminds/semver/Makefile create mode 100644 cmd/vendor/github.com/Masterminds/semver/README.md create mode 100644 cmd/vendor/github.com/Masterminds/semver/appveyor.yml create mode 100644 cmd/vendor/github.com/Masterminds/semver/benchmark_test.go create mode 100644 cmd/vendor/github.com/Masterminds/semver/collection.go create mode 100644 cmd/vendor/github.com/Masterminds/semver/collection_test.go create mode 100644 cmd/vendor/github.com/Masterminds/semver/constraints.go create mode 100644 cmd/vendor/github.com/Masterminds/semver/constraints_test.go create mode 100644 cmd/vendor/github.com/Masterminds/semver/doc.go create mode 100644 cmd/vendor/github.com/Masterminds/semver/version.go create mode 100644 cmd/vendor/github.com/Masterminds/semver/version_test.go create mode 100644 cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/addtoscheme_policy_v1beta1.go create mode 100644 cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/group.go create mode 100644 cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/doc.go create mode 100644 cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/healthcheckpolicy_types.go create mode 100644 cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/register.go create mode 100644 cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/add_healthcheckpolicy.go create mode 100644 cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/healthcheckpolicy/healthcheckpolicy_controller.go create mode 100644 docs/connect_to_existing_kind.md create mode 100644 docs/using_an_external_type.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7f2daf053f4..bae6f676fd6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,9 +3,10 @@ ## Sign the CLA Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests. -Please see https://git.k8s.io/community/CLA.md for more info -### Contributing A Patch +Please see https://git.k8s.io/community/CLA.md for more info. + +## Contributing steps 1. Submit an issue describing your proposed change to the repo in question. 1. The [repo owners](OWNERS) will respond to your issue promptly. @@ -15,31 +16,29 @@ Please see https://git.k8s.io/community/CLA.md for more info ## How to build kubebuilder locally -Setup: - -- Download [google container builder](https://cloud.google.com/container-builder/docs/build-debug-locally) -- Export `OUTPUT` to a location to write the directory containing the final build artifacts - -```sh -export OUTPUT=/tmp/kubebuilder -``` - -Run container-builder: - -```sh -container-builder-local --config=build/cloudbuild_local.yaml --dryrun=false \ - --write-workspace=$OUTPUT . -``` - -Extract `tar.gz` from $OUTPUT to /usr/local - -## Running kubebuilder tests - -```sh -go test ./pkg/... -``` - -## Community, discussion, contribution, and support +1. Setup tools + 1. Download and setup [gcloud](https://cloud.google.com/sdk/docs/downloads-interactive) + 1. Install `cloud-build-local` via `gcloud` + ```bash + $ gcloud install cloud-build-local + ``` +1. Build + 1. Export `OUTPUT` to a location to write the directory containing the final build artifacts + ```sh + $ export OUTPUT=/tmp/kubebuilder + ``` + 2. Run container-builder: + ```sh + $ cloud-build-local --config=build/cloudbuild_local.yaml --dryrun=false \ + --write-workspace=$OUTPUT . + ``` + 1. Extract `tar.gz` from $OUTPUT to /usr/local +1. Test + ```sh + go test ./pkg/... + ``` + +## Community, discussion and support Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/). @@ -48,8 +47,6 @@ You can reach the maintainers of this project at: - [Slack](http://slack.k8s.io/) - [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-kubebuilder) -### Code of conduct +## Code of conduct Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md). - -[google container builder]: https://github.com/kubernetes-sigs/container-builder-local diff --git a/build/cloudbuild_tools.yaml b/build/cloudbuild_tools.yaml index 09bd68492dc..008dde8afd8 100644 --- a/build/cloudbuild_tools.yaml +++ b/build/cloudbuild_tools.yaml @@ -13,7 +13,7 @@ # limitations under the License. steps: -- name: "gcr.io/kubebuilder/thirdparty-${_GOOS}:1.10.1" +- name: "gcr.io/kubebuilder/thirdparty-${_GOOS}:1.11.0" args: ["cp", "/kubebuilder_${_GOOS}_${_GOARCH}.tar.gz", "/workspace/kubebuilder-${TAG_NAME}-${_GOOS}-${_GOARCH}.tar.gz"] env: - 'GOOS=${_GOOS}' diff --git a/build/thirdparty/darwin/Dockerfile b/build/thirdparty/darwin/Dockerfile index 7cab9fb7d0d..a6844b3ad22 100644 --- a/build/thirdparty/darwin/Dockerfile +++ b/build/thirdparty/darwin/Dockerfile @@ -21,7 +21,7 @@ # - reference-docs # Build k8s.io/kubernetes binaries -FROM golang:1.10-stretch as kubernetes-darwin +FROM golang:1.10.2-stretch as kubernetes-darwin # Install tools RUN apt update RUN apt install rsync -y @@ -29,7 +29,7 @@ RUN go get github.com/jteeuwen/go-bindata/go-bindata ENV CGO 0 ENV DEST /usr/local/kubebuilder/bin/ RUN mkdir -p $DEST || echo "" -RUN git clone https://github.com/kubernetes/kubernetes $GOPATH/src/k8s.io/kubernetes --depth=1 -b release-1.10 +RUN git clone https://github.com/kubernetes/kubernetes $GOPATH/src/k8s.io/kubernetes --depth=1 -b release-1.11 WORKDIR /go/src/k8s.io/kubernetes # Build for linux first otherwise it won't work for darwin - :( @@ -52,7 +52,7 @@ RUN make WHAT=cmd/kubectl RUN cp _output/local/bin/$KUBE_BUILD_PLATFORMS/kubectl $DEST # Build coreos/etcd binaries -FROM golang:1.10-stretch as etcd-darwin +FROM golang:1.10.2-stretch as etcd-darwin ENV CGO 0 ENV GOOS darwin ENV GOARCH amd64 @@ -62,13 +62,13 @@ RUN git clone https://github.com/coreos/etcd $GOPATH/src/github.com/coreos/etcd RUN go build -o $DEST/etcd github.com/coreos/etcd # Build k8s.io/code-generator binaries -FROM golang:1.10-stretch as code-generator-darwin +FROM golang:1.10.2-stretch as code-generator-darwin ENV CGO 0 ENV GOOS darwin ENV GOARCH amd64 ENV DEST /usr/local/kubebuilder/bin/ RUN mkdir -p $DEST || echo "" -RUN git clone https://github.com/kubernetes/code-generator $GOPATH/src/k8s.io/code-generator --depth=1 -b release-1.10 +RUN git clone https://github.com/kubernetes/code-generator $GOPATH/src/k8s.io/code-generator --depth=1 -b release-1.11 RUN go build -o $DEST/client-gen k8s.io/code-generator/cmd/client-gen RUN go build -o $DEST/conversion-gen k8s.io/code-generator/cmd/conversion-gen RUN go build -o $DEST/deepcopy-gen k8s.io/code-generator/cmd/deepcopy-gen @@ -79,7 +79,7 @@ RUN go build -o $DEST/openapi-gen k8s.io/code-generator/cmd/openapi-gen # Build kubernetes-incubator/reference-docs binaries -FROM golang:1.10-stretch as reference-docs-darwin +FROM golang:1.10.2-stretch as reference-docs-darwin ENV CGO 0 ENV GOOS darwin ENV GOARCH amd64 @@ -89,7 +89,7 @@ RUN git clone https://github.com/kubernetes-incubator/reference-docs $GOPATH/src RUN go build -o $DEST/gen-apidocs github.com/kubernetes-incubator/reference-docs/gen-apidocs # Copy all binaries into a single tar.gz file -FROM golang:1.10-stretch as darwin +FROM golang:1.10.2-stretch as darwin RUN mkdir -p /usr/local/kubebuilder/bin/ COPY --from=etcd-darwin /usr/local/kubebuilder/bin/* /usr/local/kubebuilder/bin/ COPY --from=kubernetes-darwin /usr/local/kubebuilder/bin/* /usr/local/kubebuilder/bin/ @@ -100,4 +100,4 @@ RUN tar -czvf /kubebuilder_darwin_amd64.tar.gz kubebuilder/ # Host the tar.gz file in a thin image FROM alpine:3.7 -COPY --from=darwin /kubebuilder_darwin_amd64.tar.gz /kubebuilder_darwin_amd64.tar.gz \ No newline at end of file +COPY --from=darwin /kubebuilder_darwin_amd64.tar.gz /kubebuilder_darwin_amd64.tar.gz diff --git a/build/thirdparty/linux/Dockerfile b/build/thirdparty/linux/Dockerfile index c005ffbc639..789a9c36bb8 100644 --- a/build/thirdparty/linux/Dockerfile +++ b/build/thirdparty/linux/Dockerfile @@ -20,7 +20,7 @@ # - *-gen code generators # - reference-docs -FROM golang:1.10-stretch as kubernetes-linux +FROM golang:1.10.2-stretch as kubernetes-linux # Install tools RUN apt update RUN apt install rsync -y @@ -28,7 +28,7 @@ RUN go get github.com/jteeuwen/go-bindata/go-bindata ENV CGO 0 ENV DEST /usr/local/kubebuilder/bin/ RUN mkdir -p $DEST || echo "" -RUN git clone https://github.com/kubernetes/kubernetes $GOPATH/src/k8s.io/kubernetes --depth=1 -b release-1.10 +RUN git clone https://github.com/kubernetes/kubernetes $GOPATH/src/k8s.io/kubernetes --depth=1 -b release-1.11 WORKDIR /go/src/k8s.io/kubernetes ENV KUBE_BUILD_PLATFORMS linux/amd64 RUN make WHAT=cmd/kube-apiserver @@ -38,7 +38,7 @@ RUN cp _output/local/bin/$KUBE_BUILD_PLATFORMS/kube-apiserver $DEST RUN cp _output/local/bin/$KUBE_BUILD_PLATFORMS/kube-controller-manager $DEST RUN cp _output/local/bin/$KUBE_BUILD_PLATFORMS/kubectl $DEST -FROM golang:1.10-stretch as etcd-linux +FROM golang:1.10.2-stretch as etcd-linux ENV CGO 0 ENV GOOS linux ENV GOARCH amd64 @@ -47,13 +47,13 @@ RUN mkdir -p $DEST || echo "" RUN git clone https://github.com/coreos/etcd $GOPATH/src/github.com/coreos/etcd --depth=1 RUN go build -o $DEST/etcd github.com/coreos/etcd -FROM golang:1.10-stretch as code-generator-linux +FROM golang:1.10.2-stretch as code-generator-linux ENV CGO 0 ENV GOOS linux ENV GOARCH amd64 ENV DEST /usr/local/kubebuilder/bin/ RUN mkdir -p $DEST || echo "" -RUN git clone https://github.com/kubernetes/code-generator $GOPATH/src/k8s.io/code-generator --depth=1 -b release-1.10 +RUN git clone https://github.com/kubernetes/code-generator $GOPATH/src/k8s.io/code-generator --depth=1 -b release-1.11 RUN go build -o $DEST/client-gen k8s.io/code-generator/cmd/client-gen RUN go build -o $DEST/conversion-gen k8s.io/code-generator/cmd/conversion-gen RUN go build -o $DEST/deepcopy-gen k8s.io/code-generator/cmd/deepcopy-gen @@ -62,7 +62,7 @@ RUN go build -o $DEST/informer-gen k8s.io/code-generator/cmd/informer-gen RUN go build -o $DEST/lister-gen k8s.io/code-generator/cmd/lister-gen RUN go build -o $DEST/openapi-gen k8s.io/code-generator/cmd/openapi-gen -FROM golang:1.10-stretch as reference-docs-linux +FROM golang:1.10.2-stretch as reference-docs-linux ENV CGO 0 ENV GOOS linux ENV GOARCH amd64 @@ -71,7 +71,7 @@ RUN mkdir -p $DEST || echo "" RUN git clone https://github.com/kubernetes-incubator/reference-docs $GOPATH/src/github.com/kubernetes-incubator/reference-docs --branch kubebuilder --depth=1 RUN go build -o $DEST/gen-apidocs github.com/kubernetes-incubator/reference-docs/gen-apidocs -FROM golang:1.10-stretch as linux +FROM golang:1.10.2-stretch as linux RUN mkdir -p /usr/local/kubebuilder/bin/ COPY --from=etcd-linux /usr/local/kubebuilder/bin/* /usr/local/kubebuilder/bin/ COPY --from=kubernetes-linux /usr/local/kubebuilder/bin/* /usr/local/kubebuilder/bin/ @@ -81,4 +81,4 @@ WORKDIR /usr/local RUN tar -czvf /kubebuilder_linux_amd64.tar.gz kubebuilder/ FROM alpine:3.7 -COPY --from=linux /kubebuilder_linux_amd64.tar.gz /kubebuilder_linux_amd64.tar.gz \ No newline at end of file +COPY --from=linux /kubebuilder_linux_amd64.tar.gz /kubebuilder_linux_amd64.tar.gz diff --git a/cmd/Gopkg.lock b/cmd/Gopkg.lock index ecc5d336a6a..778ca5142e8 100644 --- a/cmd/Gopkg.lock +++ b/cmd/Gopkg.lock @@ -1,6 +1,12 @@ # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. +[[projects]] + name = "github.com/Masterminds/semver" + packages = ["."] + revision = "c7af12943936e8c39859482e61f0574c2fd7fc75" + version = "v1.4.2" + [[projects]] name = "github.com/ghodss/yaml" packages = ["."] @@ -204,11 +210,11 @@ "pkg/scaffold/resource", "pkg/util" ] - revision = "baf783301797f950d03f5e13933d1c8dbab7c090" + revision = "ade554d58413a7b2327cf38fde98484e23e66c82" [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "5f2f7c7d77ad09b2125ce55c6718ca5871a9fb30afa58a0bb1728a6185dd51b2" + inputs-digest = "475f5f0a899cbffb136a7173a0fcb0a18d13580717b537c7413264544542e3d1" solver-name = "gps-cdcl" solver-version = 1 diff --git a/cmd/Gopkg.toml b/cmd/Gopkg.toml index 88f3055eca1..0ed0e444913 100644 --- a/cmd/Gopkg.toml +++ b/cmd/Gopkg.toml @@ -47,3 +47,7 @@ [[constraint]] branch = "master" name = "sigs.k8s.io/controller-tools" + +[[constraint]] + name = "github.com/Masterminds/semver" + version = "1.4.2" diff --git a/cmd/kubebuilder/initproject/init.go b/cmd/kubebuilder/initproject/init.go index 62da93b6af5..5fb99fddd85 100644 --- a/cmd/kubebuilder/initproject/init.go +++ b/cmd/kubebuilder/initproject/init.go @@ -20,22 +20,22 @@ import ( "fmt" "log" "os" + "os/exec" "path/filepath" - "runtime" "strconv" "strings" + "github.com/Masterminds/semver" "github.com/kubernetes-sigs/kubebuilder/cmd/kubebuilder/util" "github.com/spf13/cobra" "sigs.k8s.io/controller-tools/pkg/scaffold/manager" "sigs.k8s.io/controller-tools/pkg/scaffold/project" ) - type initOptions struct { - domain string - copyright string - bazel bool + domain string + copyright string + bazel bool controllerOnly bool projectVersion string projectOptions @@ -52,20 +52,19 @@ func AddInit(cmd *cobra.Command) { kubebuilder init repo --domain mydomain `, Run: func(cmd *cobra.Command, args []string) { - o.runInitRepo() + o.runInitRepo() }, } v0comment := "Works only with project-version v0, " initCmd.Flags().StringVar(&o.domain, "domain", "", "domain for the API groups") - initCmd.Flags().StringVar(&o.copyright, "copyright", filepath.Join("hack", "boilerplate.go.txt"), v0comment + "Location of copyright boilerplate file.") - initCmd.Flags().BoolVar(&o.bazel, "bazel", false, v0comment + "if true, setup Bazel workspace artifacts") - initCmd.Flags().BoolVar(&o.controllerOnly, "controller-only", false, v0comment + "if true, setup controller only") + initCmd.Flags().StringVar(&o.copyright, "copyright", filepath.Join("hack", "boilerplate.go.txt"), v0comment+"Location of copyright boilerplate file.") + initCmd.Flags().BoolVar(&o.bazel, "bazel", false, v0comment+"if true, setup Bazel workspace artifacts") + initCmd.Flags().BoolVar(&o.controllerOnly, "controller-only", false, v0comment+"if true, setup controller only") initCmd.Flags().StringVar(&o.projectVersion, "project-version", "v1", "if set to v0, init project with kubebuilder legacy version") - initCmd.Flags().BoolVar( - &o.dep, "dep", true,"if specified, determines whether dep will be used.") + &o.dep, "dep", true, "if specified, determines whether dep will be used.") o.depFlag = initCmd.Flag("dep") o.prj = projectForFlags(initCmd.Flags()) @@ -78,10 +77,8 @@ kubebuilder init repo --domain mydomain } func (o *initOptions) runInitRepo() { - version := runtime.Version() - if versionCmp(version, "go1.10") < 0 { - log.Fatalf("The go version is %v, must be 1.10+", version) - } + checkGoVersion() + if !depExists() { log.Fatalf("Dep is not installed. Follow steps at: https://golang.github.io/dep/docs/installation.html") } @@ -129,6 +126,32 @@ func (o *initOptions) runInitRepo() { "$ kubebuilder create resource\n") } +func checkGoVersion() { + cmd := exec.Command("go", "version") + out, err := cmd.Output() + if err != nil { + log.Fatalf("Could not execute 'go version': %v", err) + } + + split := strings.Split(string(out), " ") + if len(split) < 3 { + log.Fatalf("Invalid go version: %q", string(out)) + } + goVersion := strings.TrimPrefix(split[2], "go") + if ver, err := semver.NewVersion(goVersion); err != nil { + if err != nil { + log.Fatalf("Invalid go version %q: %v", goVersion, err) + } + c, err := semver.NewConstraint(">= 1.10") + if err != nil { + log.Fatal("Invalid constraint: %v", err) + } + if !c.Check(ver) { + log.Fatalf("The go version is %v, must be 1.10+", goVersion) + } + } +} + func execute(path, templateName, templateValue string, data interface{}) { dir, err := os.Getwd() if err != nil { diff --git a/cmd/kubebuilder/v1/api.go b/cmd/kubebuilder/v1/api.go index f4936f0b9e3..38ddaa75daa 100644 --- a/cmd/kubebuilder/v1/api.go +++ b/cmd/kubebuilder/v1/api.go @@ -50,11 +50,22 @@ func (o *apiOptions) RunAddAPI() { fmt.Println("Create Resource under pkg/apis [y/n]?") o.doResource = util.Yesno(reader) } + if !o.controllerFlag.Changed { fmt.Println("Create Controller under pkg/controller [y/n]?") o.doController = util.Yesno(reader) } + if o.r.Group == "" { + log.Fatalf("Must specify --group") + } + if o.r.Version == "" { + log.Fatalf("Must specify --version") + } + if o.r.Kind == "" { + log.Fatalf("Must specify --kind") + } + fmt.Println("Writing scaffold for you to edit...") r := o.r diff --git a/cmd/vendor/github.com/Masterminds/semver/.travis.yml b/cmd/vendor/github.com/Masterminds/semver/.travis.yml new file mode 100644 index 00000000000..3d9ebadb933 --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/.travis.yml @@ -0,0 +1,27 @@ +language: go + +go: + - 1.6.x + - 1.7.x + - 1.8.x + - 1.9.x + - 1.10.x + - tip + +# Setting sudo access to false will let Travis CI use containers rather than +# VMs to run the tests. For more details see: +# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/ +# - http://docs.travis-ci.com/user/workers/standard-infrastructure/ +sudo: false + +script: + - make setup + - make test + +notifications: + webhooks: + urls: + - https://webhooks.gitter.im/e/06e3328629952dabe3e0 + on_success: change # options: [always|never|change] default: always + on_failure: always # options: [always|never|change] default: always + on_start: never # options: [always|never|change] default: always diff --git a/cmd/vendor/github.com/Masterminds/semver/CHANGELOG.md b/cmd/vendor/github.com/Masterminds/semver/CHANGELOG.md new file mode 100644 index 00000000000..b888e20abaa --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/CHANGELOG.md @@ -0,0 +1,86 @@ +# 1.4.2 (2018-04-10) + +## Changed +- #72: Updated the docs to point to vert for a console appliaction +- #71: Update the docs on pre-release comparator handling + +## Fixed +- #70: Fix the handling of pre-releases and the 0.0.0 release edge case + +# 1.4.1 (2018-04-02) + +## Fixed +- Fixed #64: Fix pre-release precedence issue (thanks @uudashr) + +# 1.4.0 (2017-10-04) + +## Changed +- #61: Update NewVersion to parse ints with a 64bit int size (thanks @zknill) + +# 1.3.1 (2017-07-10) + +## Fixed +- Fixed #57: number comparisons in prerelease sometimes inaccurate + +# 1.3.0 (2017-05-02) + +## Added +- #45: Added json (un)marshaling support (thanks @mh-cbon) +- Stability marker. See https://masterminds.github.io/stability/ + +## Fixed +- #51: Fix handling of single digit tilde constraint (thanks @dgodd) + +## Changed +- #55: The godoc icon moved from png to svg + +# 1.2.3 (2017-04-03) + +## Fixed +- #46: Fixed 0.x.x and 0.0.x in constraints being treated as * + +# Release 1.2.2 (2016-12-13) + +## Fixed +- #34: Fixed issue where hyphen range was not working with pre-release parsing. + +# Release 1.2.1 (2016-11-28) + +## Fixed +- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha" + properly. + +# Release 1.2.0 (2016-11-04) + +## Added +- #20: Added MustParse function for versions (thanks @adamreese) +- #15: Added increment methods on versions (thanks @mh-cbon) + +## Fixed +- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and + might not satisfy the intended compatibility. The change here ignores pre-releases + on constraint checks (e.g., ~ or ^) when a pre-release is not part of the + constraint. For example, `^1.2.3` will ignore pre-releases while + `^1.2.3-alpha` will include them. + +# Release 1.1.1 (2016-06-30) + +## Changed +- Issue #9: Speed up version comparison performance (thanks @sdboyer) +- Issue #8: Added benchmarks (thanks @sdboyer) +- Updated Go Report Card URL to new location +- Updated Readme to add code snippet formatting (thanks @mh-cbon) +- Updating tagging to v[SemVer] structure for compatibility with other tools. + +# Release 1.1.0 (2016-03-11) + +- Issue #2: Implemented validation to provide reasons a versions failed a + constraint. + +# Release 1.0.1 (2015-12-31) + +- Fixed #1: * constraint failing on valid versions. + +# Release 1.0.0 (2015-10-20) + +- Initial release diff --git a/cmd/vendor/github.com/Masterminds/semver/LICENSE.txt b/cmd/vendor/github.com/Masterminds/semver/LICENSE.txt new file mode 100644 index 00000000000..0da4aeadb09 --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/LICENSE.txt @@ -0,0 +1,20 @@ +The Masterminds +Copyright (C) 2014-2015, Matt Butcher and Matt Farina + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/cmd/vendor/github.com/Masterminds/semver/Makefile b/cmd/vendor/github.com/Masterminds/semver/Makefile new file mode 100644 index 00000000000..a7a1b4e36de --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/Makefile @@ -0,0 +1,36 @@ +.PHONY: setup +setup: + go get -u gopkg.in/alecthomas/gometalinter.v1 + gometalinter.v1 --install + +.PHONY: test +test: validate lint + @echo "==> Running tests" + go test -v + +.PHONY: validate +validate: + @echo "==> Running static validations" + @gometalinter.v1 \ + --disable-all \ + --enable deadcode \ + --severity deadcode:error \ + --enable gofmt \ + --enable gosimple \ + --enable ineffassign \ + --enable misspell \ + --enable vet \ + --tests \ + --vendor \ + --deadline 60s \ + ./... || exit_code=1 + +.PHONY: lint +lint: + @echo "==> Running linters" + @gometalinter.v1 \ + --disable-all \ + --enable golint \ + --vendor \ + --deadline 60s \ + ./... || : diff --git a/cmd/vendor/github.com/Masterminds/semver/README.md b/cmd/vendor/github.com/Masterminds/semver/README.md new file mode 100644 index 00000000000..3e934ed71ec --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/README.md @@ -0,0 +1,165 @@ +# SemVer + +The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to: + +* Parse semantic versions +* Sort semantic versions +* Check if a semantic version fits within a set of constraints +* Optionally work with a `v` prefix + +[![Stability: +Active](https://masterminds.github.io/stability/active.svg)](https://masterminds.github.io/stability/active.html) +[![Build Status](https://travis-ci.org/Masterminds/semver.svg)](https://travis-ci.org/Masterminds/semver) [![Build status](https://ci.appveyor.com/api/projects/status/jfk66lib7hb985k8/branch/master?svg=true&passingText=windows%20build%20passing&failingText=windows%20build%20failing)](https://ci.appveyor.com/project/mattfarina/semver/branch/master) [![GoDoc](https://godoc.org/github.com/Masterminds/semver?status.svg)](https://godoc.org/github.com/Masterminds/semver) [![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/semver)](https://goreportcard.com/report/github.com/Masterminds/semver) + +## Parsing Semantic Versions + +To parse a semantic version use the `NewVersion` function. For example, + +```go + v, err := semver.NewVersion("1.2.3-beta.1+build345") +``` + +If there is an error the version wasn't parseable. The version object has methods +to get the parts of the version, compare it to other versions, convert the +version back into a string, and get the original string. For more details +please see the [documentation](https://godoc.org/github.com/Masterminds/semver). + +## Sorting Semantic Versions + +A set of versions can be sorted using the [`sort`](https://golang.org/pkg/sort/) +package from the standard library. For example, + +```go + raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} + vs := make([]*semver.Version, len(raw)) + for i, r := range raw { + v, err := semver.NewVersion(r) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + vs[i] = v + } + + sort.Sort(semver.Collection(vs)) +``` + +## Checking Version Constraints + +Checking a version against version constraints is one of the most featureful +parts of the package. + +```go + c, err := semver.NewConstraint(">= 1.2.3") + if err != nil { + // Handle constraint not being parseable. + } + + v, _ := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parseable. + } + // Check if the version meets the constraints. The a variable will be true. + a := c.Check(v) +``` + +## Basic Comparisons + +There are two elements to the comparisons. First, a comparison string is a list +of comma separated and comparisons. These are then separated by || separated or +comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a +comparison that's greater than or equal to 1.2 and less than 3.0.0 or is +greater than or equal to 4.2.3. + +The basic comparisons are: + +* `=`: equal (aliased to no operator) +* `!=`: not equal +* `>`: greater than +* `<`: less than +* `>=`: greater than or equal to +* `<=`: less than or equal to + +_Note, according to the Semantic Version specification pre-releases may not be +API compliant with their release counterpart. It says,_ + +> _A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version._ + +_SemVer comparisons without a pre-release value will skip pre-release versions. +For example, `>1.2.3` will skip pre-releases when looking at a list of values +while `>1.2.3-alpha.1` will evaluate pre-releases._ + +## Hyphen Range Comparisons + +There are multiple methods to handle ranges and the first is hyphens ranges. +These look like: + +* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` +* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5` + +## Wildcards In Comparisons + +The `x`, `X`, and `*` characters can be used as a wildcard character. This works +for all comparison operators. When used on the `=` operator it falls +back to the pack level comparison (see tilde below). For example, + +* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` +* `>= 1.2.x` is equivalent to `>= 1.2.0` +* `<= 2.x` is equivalent to `<= 3` +* `*` is equivalent to `>= 0.0.0` + +## Tilde Range Comparisons (Patch) + +The tilde (`~`) comparison operator is for patch level ranges when a minor +version is specified and major level changes when the minor number is missing. +For example, + +* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` +* `~1` is equivalent to `>= 1, < 2` +* `~2.3` is equivalent to `>= 2.3, < 2.4` +* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` +* `~1.x` is equivalent to `>= 1, < 2` + +## Caret Range Comparisons (Major) + +The caret (`^`) comparison operator is for major level changes. This is useful +when comparisons of API versions as a major change is API breaking. For example, + +* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` +* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` +* `^2.3` is equivalent to `>= 2.3, < 3` +* `^2.x` is equivalent to `>= 2.0.0, < 3` + +# Validation + +In addition to testing a version against a constraint, a version can be validated +against a constraint. When validation fails a slice of errors containing why a +version didn't meet the constraint is returned. For example, + +```go + c, err := semver.NewConstraint("<= 1.2.3, >= 1.4") + if err != nil { + // Handle constraint not being parseable. + } + + v, _ := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parseable. + } + + // Validate a version against a constraint. + a, msgs := c.Validate(v) + // a is false + for _, m := range msgs { + fmt.Println(m) + + // Loops over the errors which would read + // "1.3 is greater than 1.2.3" + // "1.3 is less than 1.4" + } +``` + +# Contribute + +If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues) +or [create a pull request](https://github.com/Masterminds/semver/pulls). diff --git a/cmd/vendor/github.com/Masterminds/semver/appveyor.yml b/cmd/vendor/github.com/Masterminds/semver/appveyor.yml new file mode 100644 index 00000000000..b2778df15a4 --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/appveyor.yml @@ -0,0 +1,44 @@ +version: build-{build}.{branch} + +clone_folder: C:\gopath\src\github.com\Masterminds\semver +shallow_clone: true + +environment: + GOPATH: C:\gopath + +platform: + - x64 + +install: + - go version + - go env + - go get -u gopkg.in/alecthomas/gometalinter.v1 + - set PATH=%PATH%;%GOPATH%\bin + - gometalinter.v1.exe --install + +build_script: + - go install -v ./... + +test_script: + - "gometalinter.v1 \ + --disable-all \ + --enable deadcode \ + --severity deadcode:error \ + --enable gofmt \ + --enable gosimple \ + --enable ineffassign \ + --enable misspell \ + --enable vet \ + --tests \ + --vendor \ + --deadline 60s \ + ./... || exit_code=1" + - "gometalinter.v1 \ + --disable-all \ + --enable golint \ + --vendor \ + --deadline 60s \ + ./... || :" + - go test -v + +deploy: off diff --git a/cmd/vendor/github.com/Masterminds/semver/benchmark_test.go b/cmd/vendor/github.com/Masterminds/semver/benchmark_test.go new file mode 100644 index 00000000000..58a5c289f40 --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/benchmark_test.go @@ -0,0 +1,157 @@ +package semver_test + +import ( + "testing" + + "github.com/Masterminds/semver" +) + +/* Constraint creation benchmarks */ + +func benchNewConstraint(c string, b *testing.B) { + for i := 0; i < b.N; i++ { + semver.NewConstraint(c) + } +} + +func BenchmarkNewConstraintUnary(b *testing.B) { + benchNewConstraint("=2.0", b) +} + +func BenchmarkNewConstraintTilde(b *testing.B) { + benchNewConstraint("~2.0.0", b) +} + +func BenchmarkNewConstraintCaret(b *testing.B) { + benchNewConstraint("^2.0.0", b) +} + +func BenchmarkNewConstraintWildcard(b *testing.B) { + benchNewConstraint("1.x", b) +} + +func BenchmarkNewConstraintRange(b *testing.B) { + benchNewConstraint(">=2.1.x, <3.1.0", b) +} + +func BenchmarkNewConstraintUnion(b *testing.B) { + benchNewConstraint("~2.0.0 || =3.1.0", b) +} + +/* Check benchmarks */ + +func benchCheckVersion(c, v string, b *testing.B) { + version, _ := semver.NewVersion(v) + constraint, _ := semver.NewConstraint(c) + + for i := 0; i < b.N; i++ { + constraint.Check(version) + } +} + +func BenchmarkCheckVersionUnary(b *testing.B) { + benchCheckVersion("=2.0", "2.0.0", b) +} + +func BenchmarkCheckVersionTilde(b *testing.B) { + benchCheckVersion("~2.0.0", "2.0.5", b) +} + +func BenchmarkCheckVersionCaret(b *testing.B) { + benchCheckVersion("^2.0.0", "2.1.0", b) +} + +func BenchmarkCheckVersionWildcard(b *testing.B) { + benchCheckVersion("1.x", "1.4.0", b) +} + +func BenchmarkCheckVersionRange(b *testing.B) { + benchCheckVersion(">=2.1.x, <3.1.0", "2.4.5", b) +} + +func BenchmarkCheckVersionUnion(b *testing.B) { + benchCheckVersion("~2.0.0 || =3.1.0", "3.1.0", b) +} + +func benchValidateVersion(c, v string, b *testing.B) { + version, _ := semver.NewVersion(v) + constraint, _ := semver.NewConstraint(c) + + for i := 0; i < b.N; i++ { + constraint.Validate(version) + } +} + +/* Validate benchmarks, including fails */ + +func BenchmarkValidateVersionUnary(b *testing.B) { + benchValidateVersion("=2.0", "2.0.0", b) +} + +func BenchmarkValidateVersionUnaryFail(b *testing.B) { + benchValidateVersion("=2.0", "2.0.1", b) +} + +func BenchmarkValidateVersionTilde(b *testing.B) { + benchValidateVersion("~2.0.0", "2.0.5", b) +} + +func BenchmarkValidateVersionTildeFail(b *testing.B) { + benchValidateVersion("~2.0.0", "1.0.5", b) +} + +func BenchmarkValidateVersionCaret(b *testing.B) { + benchValidateVersion("^2.0.0", "2.1.0", b) +} + +func BenchmarkValidateVersionCaretFail(b *testing.B) { + benchValidateVersion("^2.0.0", "4.1.0", b) +} + +func BenchmarkValidateVersionWildcard(b *testing.B) { + benchValidateVersion("1.x", "1.4.0", b) +} + +func BenchmarkValidateVersionWildcardFail(b *testing.B) { + benchValidateVersion("1.x", "2.4.0", b) +} + +func BenchmarkValidateVersionRange(b *testing.B) { + benchValidateVersion(">=2.1.x, <3.1.0", "2.4.5", b) +} + +func BenchmarkValidateVersionRangeFail(b *testing.B) { + benchValidateVersion(">=2.1.x, <3.1.0", "1.4.5", b) +} + +func BenchmarkValidateVersionUnion(b *testing.B) { + benchValidateVersion("~2.0.0 || =3.1.0", "3.1.0", b) +} + +func BenchmarkValidateVersionUnionFail(b *testing.B) { + benchValidateVersion("~2.0.0 || =3.1.0", "3.1.1", b) +} + +/* Version creation benchmarks */ + +func benchNewVersion(v string, b *testing.B) { + for i := 0; i < b.N; i++ { + semver.NewVersion(v) + } +} + +func BenchmarkNewVersionSimple(b *testing.B) { + benchNewVersion("1.0.0", b) +} + +func BenchmarkNewVersionPre(b *testing.B) { + benchNewVersion("1.0.0-alpha", b) +} + +func BenchmarkNewVersionMeta(b *testing.B) { + benchNewVersion("1.0.0+metadata", b) +} + +func BenchmarkNewVersionMetaDash(b *testing.B) { + benchNewVersion("1.0.0+metadata-dash", b) +} diff --git a/cmd/vendor/github.com/Masterminds/semver/collection.go b/cmd/vendor/github.com/Masterminds/semver/collection.go new file mode 100644 index 00000000000..a78235895fd --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/collection.go @@ -0,0 +1,24 @@ +package semver + +// Collection is a collection of Version instances and implements the sort +// interface. See the sort package for more details. +// https://golang.org/pkg/sort/ +type Collection []*Version + +// Len returns the length of a collection. The number of Version instances +// on the slice. +func (c Collection) Len() int { + return len(c) +} + +// Less is needed for the sort interface to compare two Version objects on the +// slice. If checks if one is less than the other. +func (c Collection) Less(i, j int) bool { + return c[i].LessThan(c[j]) +} + +// Swap is needed for the sort interface to replace the Version objects +// at two different positions in the slice. +func (c Collection) Swap(i, j int) { + c[i], c[j] = c[j], c[i] +} diff --git a/cmd/vendor/github.com/Masterminds/semver/collection_test.go b/cmd/vendor/github.com/Masterminds/semver/collection_test.go new file mode 100644 index 00000000000..71b909c4e02 --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/collection_test.go @@ -0,0 +1,46 @@ +package semver + +import ( + "reflect" + "sort" + "testing" +) + +func TestCollection(t *testing.T) { + raw := []string{ + "1.2.3", + "1.0", + "1.3", + "2", + "0.4.2", + } + + vs := make([]*Version, len(raw)) + for i, r := range raw { + v, err := NewVersion(r) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + vs[i] = v + } + + sort.Sort(Collection(vs)) + + e := []string{ + "0.4.2", + "1.0.0", + "1.2.3", + "1.3.0", + "2.0.0", + } + + a := make([]string, len(vs)) + for i, v := range vs { + a[i] = v.String() + } + + if !reflect.DeepEqual(a, e) { + t.Error("Sorting Collection failed") + } +} diff --git a/cmd/vendor/github.com/Masterminds/semver/constraints.go b/cmd/vendor/github.com/Masterminds/semver/constraints.go new file mode 100644 index 00000000000..a41a6a7a4a8 --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/constraints.go @@ -0,0 +1,426 @@ +package semver + +import ( + "errors" + "fmt" + "regexp" + "strings" +) + +// Constraints is one or more constraint that a semantic version can be +// checked against. +type Constraints struct { + constraints [][]*constraint +} + +// NewConstraint returns a Constraints instance that a Version instance can +// be checked against. If there is a parse error it will be returned. +func NewConstraint(c string) (*Constraints, error) { + + // Rewrite - ranges into a comparison operation. + c = rewriteRange(c) + + ors := strings.Split(c, "||") + or := make([][]*constraint, len(ors)) + for k, v := range ors { + cs := strings.Split(v, ",") + result := make([]*constraint, len(cs)) + for i, s := range cs { + pc, err := parseConstraint(s) + if err != nil { + return nil, err + } + + result[i] = pc + } + or[k] = result + } + + o := &Constraints{constraints: or} + return o, nil +} + +// Check tests if a version satisfies the constraints. +func (cs Constraints) Check(v *Version) bool { + // loop over the ORs and check the inner ANDs + for _, o := range cs.constraints { + joy := true + for _, c := range o { + if !c.check(v) { + joy = false + break + } + } + + if joy { + return true + } + } + + return false +} + +// Validate checks if a version satisfies a constraint. If not a slice of +// reasons for the failure are returned in addition to a bool. +func (cs Constraints) Validate(v *Version) (bool, []error) { + // loop over the ORs and check the inner ANDs + var e []error + for _, o := range cs.constraints { + joy := true + for _, c := range o { + if !c.check(v) { + em := fmt.Errorf(c.msg, v, c.orig) + e = append(e, em) + joy = false + } + } + + if joy { + return true, []error{} + } + } + + return false, e +} + +var constraintOps map[string]cfunc +var constraintMsg map[string]string +var constraintRegex *regexp.Regexp + +func init() { + constraintOps = map[string]cfunc{ + "": constraintTildeOrEqual, + "=": constraintTildeOrEqual, + "!=": constraintNotEqual, + ">": constraintGreaterThan, + "<": constraintLessThan, + ">=": constraintGreaterThanEqual, + "=>": constraintGreaterThanEqual, + "<=": constraintLessThanEqual, + "=<": constraintLessThanEqual, + "~": constraintTilde, + "~>": constraintTilde, + "^": constraintCaret, + } + + constraintMsg = map[string]string{ + "": "%s is not equal to %s", + "=": "%s is not equal to %s", + "!=": "%s is equal to %s", + ">": "%s is less than or equal to %s", + "<": "%s is greater than or equal to %s", + ">=": "%s is less than %s", + "=>": "%s is less than %s", + "<=": "%s is greater than %s", + "=<": "%s is greater than %s", + "~": "%s does not have same major and minor version as %s", + "~>": "%s does not have same major and minor version as %s", + "^": "%s does not have same major version as %s", + } + + ops := make([]string, 0, len(constraintOps)) + for k := range constraintOps { + ops = append(ops, regexp.QuoteMeta(k)) + } + + constraintRegex = regexp.MustCompile(fmt.Sprintf( + `^\s*(%s)\s*(%s)\s*$`, + strings.Join(ops, "|"), + cvRegex)) + + constraintRangeRegex = regexp.MustCompile(fmt.Sprintf( + `\s*(%s)\s+-\s+(%s)\s*`, + cvRegex, cvRegex)) +} + +// An individual constraint +type constraint struct { + // The callback function for the restraint. It performs the logic for + // the constraint. + function cfunc + + msg string + + // The version used in the constraint check. For example, if a constraint + // is '<= 2.0.0' the con a version instance representing 2.0.0. + con *Version + + // The original parsed version (e.g., 4.x from != 4.x) + orig string + + // When an x is used as part of the version (e.g., 1.x) + minorDirty bool + dirty bool + patchDirty bool +} + +// Check if a version meets the constraint +func (c *constraint) check(v *Version) bool { + return c.function(v, c) +} + +type cfunc func(v *Version, c *constraint) bool + +func parseConstraint(c string) (*constraint, error) { + m := constraintRegex.FindStringSubmatch(c) + if m == nil { + return nil, fmt.Errorf("improper constraint: %s", c) + } + + ver := m[2] + orig := ver + minorDirty := false + patchDirty := false + dirty := false + if isX(m[3]) { + ver = "0.0.0" + dirty = true + } else if isX(strings.TrimPrefix(m[4], ".")) || m[4] == "" { + minorDirty = true + dirty = true + ver = fmt.Sprintf("%s.0.0%s", m[3], m[6]) + } else if isX(strings.TrimPrefix(m[5], ".")) { + dirty = true + patchDirty = true + ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6]) + } + + con, err := NewVersion(ver) + if err != nil { + + // The constraintRegex should catch any regex parsing errors. So, + // we should never get here. + return nil, errors.New("constraint Parser Error") + } + + cs := &constraint{ + function: constraintOps[m[1]], + msg: constraintMsg[m[1]], + con: con, + orig: orig, + minorDirty: minorDirty, + patchDirty: patchDirty, + dirty: dirty, + } + return cs, nil +} + +// Constraint functions +func constraintNotEqual(v *Version, c *constraint) bool { + if c.dirty { + + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false + } + + if c.con.Major() != v.Major() { + return true + } + if c.con.Minor() != v.Minor() && !c.minorDirty { + return true + } else if c.minorDirty { + return false + } + + return false + } + + return !v.Equal(c.con) +} + +func constraintGreaterThan(v *Version, c *constraint) bool { + + // An edge case the constraint is 0.0.0 and the version is 0.0.0-someprerelease + // exists. This that case. + if !isNonZero(c.con) && isNonZero(v) { + return true + } + + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false + } + + return v.Compare(c.con) == 1 +} + +func constraintLessThan(v *Version, c *constraint) bool { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false + } + + if !c.dirty { + return v.Compare(c.con) < 0 + } + + if v.Major() > c.con.Major() { + return false + } else if v.Minor() > c.con.Minor() && !c.minorDirty { + return false + } + + return true +} + +func constraintGreaterThanEqual(v *Version, c *constraint) bool { + // An edge case the constraint is 0.0.0 and the version is 0.0.0-someprerelease + // exists. This that case. + if !isNonZero(c.con) && isNonZero(v) { + return true + } + + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false + } + + return v.Compare(c.con) >= 0 +} + +func constraintLessThanEqual(v *Version, c *constraint) bool { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false + } + + if !c.dirty { + return v.Compare(c.con) <= 0 + } + + if v.Major() > c.con.Major() { + return false + } else if v.Minor() > c.con.Minor() && !c.minorDirty { + return false + } + + return true +} + +// ~*, ~>* --> >= 0.0.0 (any) +// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0 +// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0 +// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0 +// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0 +// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0 +func constraintTilde(v *Version, c *constraint) bool { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false + } + + if v.LessThan(c.con) { + return false + } + + // ~0.0.0 is a special case where all constraints are accepted. It's + // equivalent to >= 0.0.0. + if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 && + !c.minorDirty && !c.patchDirty { + return true + } + + if v.Major() != c.con.Major() { + return false + } + + if v.Minor() != c.con.Minor() && !c.minorDirty { + return false + } + + return true +} + +// When there is a .x (dirty) status it automatically opts in to ~. Otherwise +// it's a straight = +func constraintTildeOrEqual(v *Version, c *constraint) bool { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false + } + + if c.dirty { + c.msg = constraintMsg["~"] + return constraintTilde(v, c) + } + + return v.Equal(c.con) +} + +// ^* --> (any) +// ^2, ^2.x, ^2.x.x --> >=2.0.0, <3.0.0 +// ^2.0, ^2.0.x --> >=2.0.0, <3.0.0 +// ^1.2, ^1.2.x --> >=1.2.0, <2.0.0 +// ^1.2.3 --> >=1.2.3, <2.0.0 +// ^1.2.0 --> >=1.2.0, <2.0.0 +func constraintCaret(v *Version, c *constraint) bool { + // If there is a pre-release on the version but the constraint isn't looking + // for them assume that pre-releases are not compatible. See issue 21 for + // more details. + if v.Prerelease() != "" && c.con.Prerelease() == "" { + return false + } + + if v.LessThan(c.con) { + return false + } + + if v.Major() != c.con.Major() { + return false + } + + return true +} + +var constraintRangeRegex *regexp.Regexp + +const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` + + `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + + `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + +func isX(x string) bool { + switch x { + case "x", "*", "X": + return true + default: + return false + } +} + +func rewriteRange(i string) string { + m := constraintRangeRegex.FindAllStringSubmatch(i, -1) + if m == nil { + return i + } + o := i + for _, v := range m { + t := fmt.Sprintf(">= %s, <= %s", v[1], v[11]) + o = strings.Replace(o, v[0], t, 1) + } + + return o +} + +// Detect if a version is not zero (0.0.0) +func isNonZero(v *Version) bool { + if v.Major() != 0 || v.Minor() != 0 || v.Patch() != 0 || v.Prerelease() != "" { + return true + } + + return false +} diff --git a/cmd/vendor/github.com/Masterminds/semver/constraints_test.go b/cmd/vendor/github.com/Masterminds/semver/constraints_test.go new file mode 100644 index 00000000000..bf52c90bd26 --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/constraints_test.go @@ -0,0 +1,465 @@ +package semver + +import ( + "reflect" + "testing" +) + +func TestParseConstraint(t *testing.T) { + tests := []struct { + in string + f cfunc + v string + err bool + }{ + {">= 1.2", constraintGreaterThanEqual, "1.2.0", false}, + {"1.0", constraintTildeOrEqual, "1.0.0", false}, + {"foo", nil, "", true}, + {"<= 1.2", constraintLessThanEqual, "1.2.0", false}, + {"=< 1.2", constraintLessThanEqual, "1.2.0", false}, + {"=> 1.2", constraintGreaterThanEqual, "1.2.0", false}, + {"v1.2", constraintTildeOrEqual, "1.2.0", false}, + {"=1.5", constraintTildeOrEqual, "1.5.0", false}, + {"> 1.3", constraintGreaterThan, "1.3.0", false}, + {"< 1.4.1", constraintLessThan, "1.4.1", false}, + } + + for _, tc := range tests { + c, err := parseConstraint(tc.in) + if tc.err && err == nil { + t.Errorf("Expected error for %s didn't occur", tc.in) + } else if !tc.err && err != nil { + t.Errorf("Unexpected error for %s", tc.in) + } + + // If an error was expected continue the loop and don't try the other + // tests as they will cause errors. + if tc.err { + continue + } + + if tc.v != c.con.String() { + t.Errorf("Incorrect version found on %s", tc.in) + } + + f1 := reflect.ValueOf(tc.f) + f2 := reflect.ValueOf(c.function) + if f1 != f2 { + t.Errorf("Wrong constraint found for %s", tc.in) + } + } +} + +func TestConstraintCheck(t *testing.T) { + tests := []struct { + constraint string + version string + check bool + }{ + {"= 2.0", "1.2.3", false}, + {"= 2.0", "2.0.0", true}, + {"4.1", "4.1.0", true}, + {"!=4.1", "4.1.0", false}, + {"!=4.1", "5.1.0", true}, + {">1.1", "4.1.0", true}, + {">1.1", "1.1.0", false}, + {"<1.1", "0.1.0", true}, + {"<1.1", "1.1.0", false}, + {"<1.1", "1.1.1", false}, + {">=1.1", "4.1.0", true}, + {">=1.1", "1.1.0", true}, + {">=1.1", "0.0.9", false}, + {"<=1.1", "0.1.0", true}, + {"<=1.1", "1.1.0", true}, + {"<=1.1", "1.1.1", false}, + {">0", "0.0.1-alpha", true}, + {">=0", "0.0.1-alpha", true}, + {">0", "0", false}, + {">=0", "0", true}, + {"=0", "1", false}, + } + + for _, tc := range tests { + c, err := parseConstraint(tc.constraint) + if err != nil { + t.Errorf("err: %s", err) + continue + } + + v, err := NewVersion(tc.version) + if err != nil { + t.Errorf("err: %s", err) + continue + } + + a := c.check(v) + if a != tc.check { + t.Errorf("Constraint %q failing with %q", tc.constraint, tc.version) + } + } +} + +func TestNewConstraint(t *testing.T) { + tests := []struct { + input string + ors int + count int + err bool + }{ + {">= 1.1", 1, 1, false}, + {"2.0", 1, 1, false}, + {"v2.3.5-20161202202307-sha.e8fc5e5", 1, 1, false}, + {">= bar", 0, 0, true}, + {">= 1.2.3, < 2.0", 1, 2, false}, + {">= 1.2.3, < 2.0 || => 3.0, < 4", 2, 2, false}, + + // The 3 - 4 should be broken into 2 by the range rewriting + {"3 - 4 || => 3.0, < 4", 2, 2, false}, + } + + for _, tc := range tests { + v, err := NewConstraint(tc.input) + if tc.err && err == nil { + t.Errorf("expected but did not get error for: %s", tc.input) + continue + } else if !tc.err && err != nil { + t.Errorf("unexpectederror for input %s: %s", tc.input, err) + continue + } + if tc.err { + continue + } + + l := len(v.constraints) + if tc.ors != l { + t.Errorf("Expected %s to have %d ORs but got %d", + tc.input, tc.ors, l) + } + + l = len(v.constraints[0]) + if tc.count != l { + t.Errorf("Expected %s to have %d constraints but got %d", + tc.input, tc.count, l) + } + } +} + +func TestConstraintsCheck(t *testing.T) { + tests := []struct { + constraint string + version string + check bool + }{ + {"*", "1.2.3", true}, + {"~0.0.0", "1.2.3", true}, + {"0.x.x", "1.2.3", false}, + {"0.0.x", "1.2.3", false}, + {"0.0.0", "1.2.3", false}, + {"*", "1.2.3", true}, + {"^0.0.0", "1.2.3", false}, + {"= 2.0", "1.2.3", false}, + {"= 2.0", "2.0.0", true}, + {"4.1", "4.1.0", true}, + {"4.1.x", "4.1.3", true}, + {"1.x", "1.4", true}, + {"!=4.1", "4.1.0", false}, + {"!=4.1-alpha", "4.1.0-alpha", false}, + {"!=4.1-alpha", "4.1.0", true}, + {"!=4.1", "5.1.0", true}, + {"!=4.x", "5.1.0", true}, + {"!=4.x", "4.1.0", false}, + {"!=4.1.x", "4.2.0", true}, + {"!=4.2.x", "4.2.3", false}, + {">1.1", "4.1.0", true}, + {">1.1", "1.1.0", false}, + {"<1.1", "0.1.0", true}, + {"<1.1", "1.1.0", false}, + {"<1.1", "1.1.1", false}, + {"<1.x", "1.1.1", true}, + {"<1.x", "2.1.1", false}, + {"<1.1.x", "1.2.1", false}, + {"<1.1.x", "1.1.500", true}, + {"<1.2.x", "1.1.1", true}, + {">=1.1", "4.1.0", true}, + {">=1.1", "4.1.0-beta", false}, + {">=1.1", "1.1.0", true}, + {">=1.1", "0.0.9", false}, + {"<=1.1", "0.1.0", true}, + {"<=1.1", "0.1.0-alpha", false}, + {"<=1.1-a", "0.1.0-alpha", true}, + {"<=1.1", "1.1.0", true}, + {"<=1.x", "1.1.0", true}, + {"<=2.x", "3.1.0", false}, + {"<=1.1", "1.1.1", false}, + {"<=1.1.x", "1.2.500", false}, + {">1.1, <2", "1.1.1", true}, + {">1.1, <3", "4.3.2", false}, + {">=1.1, <2, !=1.2.3", "1.2.3", false}, + {">=1.1, <2, !=1.2.3 || > 3", "3.1.2", true}, + {">=1.1, <2, !=1.2.3 || >= 3", "3.0.0", true}, + {">=1.1, <2, !=1.2.3 || > 3", "3.0.0", false}, + {">=1.1, <2, !=1.2.3 || > 3", "1.2.3", false}, + {"1.1 - 2", "1.1.1", true}, + {"1.1-3", "4.3.2", false}, + {"^1.1", "1.1.1", true}, + {"^1.1", "4.3.2", false}, + {"^1.x", "1.1.1", true}, + {"^2.x", "1.1.1", false}, + {"^1.x", "2.1.1", false}, + {"^1.x", "1.1.1-beta1", false}, + {"^1.1.2-alpha", "1.2.1-beta1", true}, + {"^1.2.x-alpha", "1.1.1-beta1", false}, + {"~*", "2.1.1", true}, + {"~1", "2.1.1", false}, + {"~1", "1.3.5", true}, + {"~1", "1.4", true}, + {"~1.x", "2.1.1", false}, + {"~1.x", "1.3.5", true}, + {"~1.x", "1.4", true}, + {"~1.1", "1.1.1", true}, + {"~1.1", "1.1.1-alpha", false}, + {"~1.1-alpha", "1.1.1-beta", true}, + {"~1.1.1-beta", "1.1.1-alpha", false}, + {"~1.1.1-beta", "1.1.1", true}, + {"~1.2.3", "1.2.5", true}, + {"~1.2.3", "1.2.2", false}, + {"~1.2.3", "1.3.2", false}, + {"~1.1", "1.2.3", false}, + {"~1.3", "2.4.5", false}, + } + + for _, tc := range tests { + c, err := NewConstraint(tc.constraint) + if err != nil { + t.Errorf("err: %s", err) + continue + } + + v, err := NewVersion(tc.version) + if err != nil { + t.Errorf("err: %s", err) + continue + } + + a := c.Check(v) + if a != tc.check { + t.Errorf("Constraint '%s' failing with '%s'", tc.constraint, tc.version) + } + } +} + +func TestRewriteRange(t *testing.T) { + tests := []struct { + c string + nc string + }{ + {"2 - 3", ">= 2, <= 3"}, + {"2 - 3, 2 - 3", ">= 2, <= 3,>= 2, <= 3"}, + {"2 - 3, 4.0.0 - 5.1", ">= 2, <= 3,>= 4.0.0, <= 5.1"}, + } + + for _, tc := range tests { + o := rewriteRange(tc.c) + + if o != tc.nc { + t.Errorf("Range %s rewritten incorrectly as '%s'", tc.c, o) + } + } +} + +func TestIsX(t *testing.T) { + tests := []struct { + t string + c bool + }{ + {"A", false}, + {"%", false}, + {"X", true}, + {"x", true}, + {"*", true}, + } + + for _, tc := range tests { + a := isX(tc.t) + if a != tc.c { + t.Errorf("Function isX error on %s", tc.t) + } + } +} + +func TestConstraintsValidate(t *testing.T) { + tests := []struct { + constraint string + version string + check bool + }{ + {"*", "1.2.3", true}, + {"~0.0.0", "1.2.3", true}, + {"= 2.0", "1.2.3", false}, + {"= 2.0", "2.0.0", true}, + {"4.1", "4.1.0", true}, + {"4.1.x", "4.1.3", true}, + {"1.x", "1.4", true}, + {"!=4.1", "4.1.0", false}, + {"!=4.1", "5.1.0", true}, + {"!=4.x", "5.1.0", true}, + {"!=4.x", "4.1.0", false}, + {"!=4.1.x", "4.2.0", true}, + {"!=4.2.x", "4.2.3", false}, + {">1.1", "4.1.0", true}, + {">1.1", "1.1.0", false}, + {"<1.1", "0.1.0", true}, + {"<1.1", "1.1.0", false}, + {"<1.1", "1.1.1", false}, + {"<1.x", "1.1.1", true}, + {"<1.x", "2.1.1", false}, + {"<1.1.x", "1.2.1", false}, + {"<1.1.x", "1.1.500", true}, + {"<1.2.x", "1.1.1", true}, + {">=1.1", "4.1.0", true}, + {">=1.1", "1.1.0", true}, + {">=1.1", "0.0.9", false}, + {"<=1.1", "0.1.0", true}, + {"<=1.1", "1.1.0", true}, + {"<=1.x", "1.1.0", true}, + {"<=2.x", "3.1.0", false}, + {"<=1.1", "1.1.1", false}, + {"<=1.1.x", "1.2.500", false}, + {">1.1, <2", "1.1.1", true}, + {">1.1, <3", "4.3.2", false}, + {">=1.1, <2, !=1.2.3", "1.2.3", false}, + {">=1.1, <2, !=1.2.3 || > 3", "3.1.2", true}, + {">=1.1, <2, !=1.2.3 || >= 3", "3.0.0", true}, + {">=1.1, <2, !=1.2.3 || > 3", "3.0.0", false}, + {">=1.1, <2, !=1.2.3 || > 3", "1.2.3", false}, + {"1.1 - 2", "1.1.1", true}, + {"1.1-3", "4.3.2", false}, + {"^1.1", "1.1.1", true}, + {"^1.1", "1.1.1-alpha", false}, + {"^1.1.1-alpha", "1.1.1-beta", true}, + {"^1.1.1-beta", "1.1.1-alpha", false}, + {"^1.1", "4.3.2", false}, + {"^1.x", "1.1.1", true}, + {"^2.x", "1.1.1", false}, + {"^1.x", "2.1.1", false}, + {"~*", "2.1.1", true}, + {"~1", "2.1.1", false}, + {"~1", "1.3.5", true}, + {"~1", "1.3.5-beta", false}, + {"~1.x", "2.1.1", false}, + {"~1.x", "1.3.5", true}, + {"~1.x", "1.3.5-beta", false}, + {"~1.3.6-alpha", "1.3.5-beta", false}, + {"~1.3.5-alpha", "1.3.5-beta", true}, + {"~1.3.5-beta", "1.3.5-alpha", false}, + {"~1.x", "1.4", true}, + {"~1.1", "1.1.1", true}, + {"~1.2.3", "1.2.5", true}, + {"~1.2.3", "1.2.2", false}, + {"~1.2.3", "1.3.2", false}, + {"~1.1", "1.2.3", false}, + {"~1.3", "2.4.5", false}, + } + + for _, tc := range tests { + c, err := NewConstraint(tc.constraint) + if err != nil { + t.Errorf("err: %s", err) + continue + } + + v, err := NewVersion(tc.version) + if err != nil { + t.Errorf("err: %s", err) + continue + } + + a, msgs := c.Validate(v) + if a != tc.check { + t.Errorf("Constraint '%s' failing with '%s'", tc.constraint, tc.version) + } else if !a && len(msgs) == 0 { + t.Errorf("%q failed with %q but no errors returned", tc.constraint, tc.version) + } + + // if a == false { + // for _, m := range msgs { + // t.Errorf("%s", m) + // } + // } + } + + v, err := NewVersion("1.2.3") + if err != nil { + t.Errorf("err: %s", err) + } + + c, err := NewConstraint("!= 1.2.5, ^2, <= 1.1.x") + if err != nil { + t.Errorf("err: %s", err) + } + + _, msgs := c.Validate(v) + if len(msgs) != 2 { + t.Error("Invalid number of validations found") + } + e := msgs[0].Error() + if e != "1.2.3 does not have same major version as 2" { + t.Error("Did not get expected message: 1.2.3 does not have same major version as 2") + } + e = msgs[1].Error() + if e != "1.2.3 is greater than 1.1.x" { + t.Error("Did not get expected message: 1.2.3 is greater than 1.1.x") + } + + tests2 := []struct { + constraint, version, msg string + }{ + {"= 2.0", "1.2.3", "1.2.3 is not equal to 2.0"}, + {"!=4.1", "4.1.0", "4.1.0 is equal to 4.1"}, + {"!=4.x", "4.1.0", "4.1.0 is equal to 4.x"}, + {"!=4.2.x", "4.2.3", "4.2.3 is equal to 4.2.x"}, + {">1.1", "1.1.0", "1.1.0 is less than or equal to 1.1"}, + {"<1.1", "1.1.0", "1.1.0 is greater than or equal to 1.1"}, + {"<1.1", "1.1.1", "1.1.1 is greater than or equal to 1.1"}, + {"<1.x", "2.1.1", "2.1.1 is greater than or equal to 1.x"}, + {"<1.1.x", "1.2.1", "1.2.1 is greater than or equal to 1.1.x"}, + {">=1.1", "0.0.9", "0.0.9 is less than 1.1"}, + {"<=2.x", "3.1.0", "3.1.0 is greater than 2.x"}, + {"<=1.1", "1.1.1", "1.1.1 is greater than 1.1"}, + {"<=1.1.x", "1.2.500", "1.2.500 is greater than 1.1.x"}, + {">1.1, <3", "4.3.2", "4.3.2 is greater than or equal to 3"}, + {">=1.1, <2, !=1.2.3", "1.2.3", "1.2.3 is equal to 1.2.3"}, + {">=1.1, <2, !=1.2.3 || > 3", "3.0.0", "3.0.0 is greater than or equal to 2"}, + {">=1.1, <2, !=1.2.3 || > 3", "1.2.3", "1.2.3 is equal to 1.2.3"}, + {"1.1 - 3", "4.3.2", "4.3.2 is greater than 3"}, + {"^1.1", "4.3.2", "4.3.2 does not have same major version as 1.1"}, + {"^2.x", "1.1.1", "1.1.1 does not have same major version as 2.x"}, + {"^1.x", "2.1.1", "2.1.1 does not have same major version as 1.x"}, + {"~1", "2.1.2", "2.1.2 does not have same major and minor version as 1"}, + {"~1.x", "2.1.1", "2.1.1 does not have same major and minor version as 1.x"}, + {"~1.2.3", "1.2.2", "1.2.2 does not have same major and minor version as 1.2.3"}, + {"~1.2.3", "1.3.2", "1.3.2 does not have same major and minor version as 1.2.3"}, + {"~1.1", "1.2.3", "1.2.3 does not have same major and minor version as 1.1"}, + {"~1.3", "2.4.5", "2.4.5 does not have same major and minor version as 1.3"}, + } + + for _, tc := range tests2 { + c, err := NewConstraint(tc.constraint) + if err != nil { + t.Errorf("err: %s", err) + continue + } + + v, err := NewVersion(tc.version) + if err != nil { + t.Errorf("err: %s", err) + continue + } + + _, msgs := c.Validate(v) + e := msgs[0].Error() + if e != tc.msg { + t.Errorf("Did not get expected message %q: %s", tc.msg, e) + } + } +} diff --git a/cmd/vendor/github.com/Masterminds/semver/doc.go b/cmd/vendor/github.com/Masterminds/semver/doc.go new file mode 100644 index 00000000000..e00f65eb73c --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/doc.go @@ -0,0 +1,115 @@ +/* +Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go. + +Specifically it provides the ability to: + + * Parse semantic versions + * Sort semantic versions + * Check if a semantic version fits within a set of constraints + * Optionally work with a `v` prefix + +Parsing Semantic Versions + +To parse a semantic version use the `NewVersion` function. For example, + + v, err := semver.NewVersion("1.2.3-beta.1+build345") + +If there is an error the version wasn't parseable. The version object has methods +to get the parts of the version, compare it to other versions, convert the +version back into a string, and get the original string. For more details +please see the documentation at https://godoc.org/github.com/Masterminds/semver. + +Sorting Semantic Versions + +A set of versions can be sorted using the `sort` package from the standard library. +For example, + + raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",} + vs := make([]*semver.Version, len(raw)) + for i, r := range raw { + v, err := semver.NewVersion(r) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + vs[i] = v + } + + sort.Sort(semver.Collection(vs)) + +Checking Version Constraints + +Checking a version against version constraints is one of the most featureful +parts of the package. + + c, err := semver.NewConstraint(">= 1.2.3") + if err != nil { + // Handle constraint not being parseable. + } + + v, _ := semver.NewVersion("1.3") + if err != nil { + // Handle version not being parseable. + } + // Check if the version meets the constraints. The a variable will be true. + a := c.Check(v) + +Basic Comparisons + +There are two elements to the comparisons. First, a comparison string is a list +of comma separated and comparisons. These are then separated by || separated or +comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a +comparison that's greater than or equal to 1.2 and less than 3.0.0 or is +greater than or equal to 4.2.3. + +The basic comparisons are: + + * `=`: equal (aliased to no operator) + * `!=`: not equal + * `>`: greater than + * `<`: less than + * `>=`: greater than or equal to + * `<=`: less than or equal to + +Hyphen Range Comparisons + +There are multiple methods to handle ranges and the first is hyphens ranges. +These look like: + + * `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5` + * `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5` + +Wildcards In Comparisons + +The `x`, `X`, and `*` characters can be used as a wildcard character. This works +for all comparison operators. When used on the `=` operator it falls +back to the pack level comparison (see tilde below). For example, + + * `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` + * `>= 1.2.x` is equivalent to `>= 1.2.0` + * `<= 2.x` is equivalent to `<= 3` + * `*` is equivalent to `>= 0.0.0` + +Tilde Range Comparisons (Patch) + +The tilde (`~`) comparison operator is for patch level ranges when a minor +version is specified and major level changes when the minor number is missing. +For example, + + * `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0` + * `~1` is equivalent to `>= 1, < 2` + * `~2.3` is equivalent to `>= 2.3, < 2.4` + * `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0` + * `~1.x` is equivalent to `>= 1, < 2` + +Caret Range Comparisons (Major) + +The caret (`^`) comparison operator is for major level changes. This is useful +when comparisons of API versions as a major change is API breaking. For example, + + * `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0` + * `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0` + * `^2.3` is equivalent to `>= 2.3, < 3` + * `^2.x` is equivalent to `>= 2.0.0, < 3` +*/ +package semver diff --git a/cmd/vendor/github.com/Masterminds/semver/version.go b/cmd/vendor/github.com/Masterminds/semver/version.go new file mode 100644 index 00000000000..9d22ea6308d --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/version.go @@ -0,0 +1,421 @@ +package semver + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "regexp" + "strconv" + "strings" +) + +// The compiled version of the regex created at init() is cached here so it +// only needs to be created once. +var versionRegex *regexp.Regexp +var validPrereleaseRegex *regexp.Regexp + +var ( + // ErrInvalidSemVer is returned a version is found to be invalid when + // being parsed. + ErrInvalidSemVer = errors.New("Invalid Semantic Version") + + // ErrInvalidMetadata is returned when the metadata is an invalid format + ErrInvalidMetadata = errors.New("Invalid Metadata string") + + // ErrInvalidPrerelease is returned when the pre-release is an invalid format + ErrInvalidPrerelease = errors.New("Invalid Prerelease string") +) + +// SemVerRegex is the regular expression used to parse a semantic version. +const SemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` + + `(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + + `(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` + +// ValidPrerelease is the regular expression which validates +// both prerelease and metadata values. +const ValidPrerelease string = `^([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*)` + +// Version represents a single semantic version. +type Version struct { + major, minor, patch int64 + pre string + metadata string + original string +} + +func init() { + versionRegex = regexp.MustCompile("^" + SemVerRegex + "$") + validPrereleaseRegex = regexp.MustCompile(ValidPrerelease) +} + +// NewVersion parses a given version and returns an instance of Version or +// an error if unable to parse the version. +func NewVersion(v string) (*Version, error) { + m := versionRegex.FindStringSubmatch(v) + if m == nil { + return nil, ErrInvalidSemVer + } + + sv := &Version{ + metadata: m[8], + pre: m[5], + original: v, + } + + var temp int64 + temp, err := strconv.ParseInt(m[1], 10, 64) + if err != nil { + return nil, fmt.Errorf("Error parsing version segment: %s", err) + } + sv.major = temp + + if m[2] != "" { + temp, err = strconv.ParseInt(strings.TrimPrefix(m[2], "."), 10, 64) + if err != nil { + return nil, fmt.Errorf("Error parsing version segment: %s", err) + } + sv.minor = temp + } else { + sv.minor = 0 + } + + if m[3] != "" { + temp, err = strconv.ParseInt(strings.TrimPrefix(m[3], "."), 10, 64) + if err != nil { + return nil, fmt.Errorf("Error parsing version segment: %s", err) + } + sv.patch = temp + } else { + sv.patch = 0 + } + + return sv, nil +} + +// MustParse parses a given version and panics on error. +func MustParse(v string) *Version { + sv, err := NewVersion(v) + if err != nil { + panic(err) + } + return sv +} + +// String converts a Version object to a string. +// Note, if the original version contained a leading v this version will not. +// See the Original() method to retrieve the original value. Semantic Versions +// don't contain a leading v per the spec. Instead it's optional on +// impelementation. +func (v *Version) String() string { + var buf bytes.Buffer + + fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch) + if v.pre != "" { + fmt.Fprintf(&buf, "-%s", v.pre) + } + if v.metadata != "" { + fmt.Fprintf(&buf, "+%s", v.metadata) + } + + return buf.String() +} + +// Original returns the original value passed in to be parsed. +func (v *Version) Original() string { + return v.original +} + +// Major returns the major version. +func (v *Version) Major() int64 { + return v.major +} + +// Minor returns the minor version. +func (v *Version) Minor() int64 { + return v.minor +} + +// Patch returns the patch version. +func (v *Version) Patch() int64 { + return v.patch +} + +// Prerelease returns the pre-release version. +func (v *Version) Prerelease() string { + return v.pre +} + +// Metadata returns the metadata on the version. +func (v *Version) Metadata() string { + return v.metadata +} + +// originalVPrefix returns the original 'v' prefix if any. +func (v *Version) originalVPrefix() string { + + // Note, only lowercase v is supported as a prefix by the parser. + if v.original != "" && v.original[:1] == "v" { + return v.original[:1] + } + return "" +} + +// IncPatch produces the next patch version. +// If the current version does not have prerelease/metadata information, +// it unsets metadata and prerelease values, increments patch number. +// If the current version has any of prerelease or metadata information, +// it unsets both values and keeps curent patch value +func (v Version) IncPatch() Version { + vNext := v + // according to http://semver.org/#spec-item-9 + // Pre-release versions have a lower precedence than the associated normal version. + // according to http://semver.org/#spec-item-10 + // Build metadata SHOULD be ignored when determining version precedence. + if v.pre != "" { + vNext.metadata = "" + vNext.pre = "" + } else { + vNext.metadata = "" + vNext.pre = "" + vNext.patch = v.patch + 1 + } + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext +} + +// IncMinor produces the next minor version. +// Sets patch to 0. +// Increments minor number. +// Unsets metadata. +// Unsets prerelease status. +func (v Version) IncMinor() Version { + vNext := v + vNext.metadata = "" + vNext.pre = "" + vNext.patch = 0 + vNext.minor = v.minor + 1 + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext +} + +// IncMajor produces the next major version. +// Sets patch to 0. +// Sets minor to 0. +// Increments major number. +// Unsets metadata. +// Unsets prerelease status. +func (v Version) IncMajor() Version { + vNext := v + vNext.metadata = "" + vNext.pre = "" + vNext.patch = 0 + vNext.minor = 0 + vNext.major = v.major + 1 + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext +} + +// SetPrerelease defines the prerelease value. +// Value must not include the required 'hypen' prefix. +func (v Version) SetPrerelease(prerelease string) (Version, error) { + vNext := v + if len(prerelease) > 0 && !validPrereleaseRegex.MatchString(prerelease) { + return vNext, ErrInvalidPrerelease + } + vNext.pre = prerelease + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext, nil +} + +// SetMetadata defines metadata value. +// Value must not include the required 'plus' prefix. +func (v Version) SetMetadata(metadata string) (Version, error) { + vNext := v + if len(metadata) > 0 && !validPrereleaseRegex.MatchString(metadata) { + return vNext, ErrInvalidMetadata + } + vNext.metadata = metadata + vNext.original = v.originalVPrefix() + "" + vNext.String() + return vNext, nil +} + +// LessThan tests if one version is less than another one. +func (v *Version) LessThan(o *Version) bool { + return v.Compare(o) < 0 +} + +// GreaterThan tests if one version is greater than another one. +func (v *Version) GreaterThan(o *Version) bool { + return v.Compare(o) > 0 +} + +// Equal tests if two versions are equal to each other. +// Note, versions can be equal with different metadata since metadata +// is not considered part of the comparable version. +func (v *Version) Equal(o *Version) bool { + return v.Compare(o) == 0 +} + +// Compare compares this version to another one. It returns -1, 0, or 1 if +// the version smaller, equal, or larger than the other version. +// +// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is +// lower than the version without a prerelease. +func (v *Version) Compare(o *Version) int { + // Compare the major, minor, and patch version for differences. If a + // difference is found return the comparison. + if d := compareSegment(v.Major(), o.Major()); d != 0 { + return d + } + if d := compareSegment(v.Minor(), o.Minor()); d != 0 { + return d + } + if d := compareSegment(v.Patch(), o.Patch()); d != 0 { + return d + } + + // At this point the major, minor, and patch versions are the same. + ps := v.pre + po := o.Prerelease() + + if ps == "" && po == "" { + return 0 + } + if ps == "" { + return 1 + } + if po == "" { + return -1 + } + + return comparePrerelease(ps, po) +} + +// UnmarshalJSON implements JSON.Unmarshaler interface. +func (v *Version) UnmarshalJSON(b []byte) error { + var s string + if err := json.Unmarshal(b, &s); err != nil { + return err + } + temp, err := NewVersion(s) + if err != nil { + return err + } + v.major = temp.major + v.minor = temp.minor + v.patch = temp.patch + v.pre = temp.pre + v.metadata = temp.metadata + v.original = temp.original + temp = nil + return nil +} + +// MarshalJSON implements JSON.Marshaler interface. +func (v *Version) MarshalJSON() ([]byte, error) { + return json.Marshal(v.String()) +} + +func compareSegment(v, o int64) int { + if v < o { + return -1 + } + if v > o { + return 1 + } + + return 0 +} + +func comparePrerelease(v, o string) int { + + // split the prelease versions by their part. The separator, per the spec, + // is a . + sparts := strings.Split(v, ".") + oparts := strings.Split(o, ".") + + // Find the longer length of the parts to know how many loop iterations to + // go through. + slen := len(sparts) + olen := len(oparts) + + l := slen + if olen > slen { + l = olen + } + + // Iterate over each part of the prereleases to compare the differences. + for i := 0; i < l; i++ { + // Since the lentgh of the parts can be different we need to create + // a placeholder. This is to avoid out of bounds issues. + stemp := "" + if i < slen { + stemp = sparts[i] + } + + otemp := "" + if i < olen { + otemp = oparts[i] + } + + d := comparePrePart(stemp, otemp) + if d != 0 { + return d + } + } + + // Reaching here means two versions are of equal value but have different + // metadata (the part following a +). They are not identical in string form + // but the version comparison finds them to be equal. + return 0 +} + +func comparePrePart(s, o string) int { + // Fastpath if they are equal + if s == o { + return 0 + } + + // When s or o are empty we can use the other in an attempt to determine + // the response. + if s == "" { + if o != "" { + return -1 + } + return 1 + } + + if o == "" { + if s != "" { + return 1 + } + return -1 + } + + // When comparing strings "99" is greater than "103". To handle + // cases like this we need to detect numbers and compare them. + + oi, n1 := strconv.ParseInt(o, 10, 64) + si, n2 := strconv.ParseInt(s, 10, 64) + + // The case where both are strings compare the strings + if n1 != nil && n2 != nil { + if s > o { + return 1 + } + return -1 + } else if n1 != nil { + // o is a string and s is a number + return -1 + } else if n2 != nil { + // s is a string and o is a number + return 1 + } + // Both are numbers + if si > oi { + return 1 + } + return -1 + +} diff --git a/cmd/vendor/github.com/Masterminds/semver/version_test.go b/cmd/vendor/github.com/Masterminds/semver/version_test.go new file mode 100644 index 00000000000..ff5d644a74b --- /dev/null +++ b/cmd/vendor/github.com/Masterminds/semver/version_test.go @@ -0,0 +1,490 @@ +package semver + +import ( + "encoding/json" + "fmt" + "testing" +) + +func TestNewVersion(t *testing.T) { + tests := []struct { + version string + err bool + }{ + {"1.2.3", false}, + {"v1.2.3", false}, + {"1.0", false}, + {"v1.0", false}, + {"1", false}, + {"v1", false}, + {"1.2.beta", true}, + {"v1.2.beta", true}, + {"foo", true}, + {"1.2-5", false}, + {"v1.2-5", false}, + {"1.2-beta.5", false}, + {"v1.2-beta.5", false}, + {"\n1.2", true}, + {"\nv1.2", true}, + {"1.2.0-x.Y.0+metadata", false}, + {"v1.2.0-x.Y.0+metadata", false}, + {"1.2.0-x.Y.0+metadata-width-hypen", false}, + {"v1.2.0-x.Y.0+metadata-width-hypen", false}, + {"1.2.3-rc1-with-hypen", false}, + {"v1.2.3-rc1-with-hypen", false}, + {"1.2.3.4", true}, + {"v1.2.3.4", true}, + {"1.2.2147483648", false}, + {"1.2147483648.3", false}, + {"2147483648.3.0", false}, + } + + for _, tc := range tests { + _, err := NewVersion(tc.version) + if tc.err && err == nil { + t.Fatalf("expected error for version: %s", tc.version) + } else if !tc.err && err != nil { + t.Fatalf("error for version %s: %s", tc.version, err) + } + } +} + +func TestOriginal(t *testing.T) { + tests := []string{ + "1.2.3", + "v1.2.3", + "1.0", + "v1.0", + "1", + "v1", + "1.2-5", + "v1.2-5", + "1.2-beta.5", + "v1.2-beta.5", + "1.2.0-x.Y.0+metadata", + "v1.2.0-x.Y.0+metadata", + "1.2.0-x.Y.0+metadata-width-hypen", + "v1.2.0-x.Y.0+metadata-width-hypen", + "1.2.3-rc1-with-hypen", + "v1.2.3-rc1-with-hypen", + } + + for _, tc := range tests { + v, err := NewVersion(tc) + if err != nil { + t.Errorf("Error parsing version %s", tc) + } + + o := v.Original() + if o != tc { + t.Errorf("Error retrieving originl. Expected '%s' but got '%s'", tc, v) + } + } +} + +func TestParts(t *testing.T) { + v, err := NewVersion("1.2.3-beta.1+build.123") + if err != nil { + t.Error("Error parsing version 1.2.3-beta.1+build.123") + } + + if v.Major() != 1 { + t.Error("Major() returning wrong value") + } + if v.Minor() != 2 { + t.Error("Minor() returning wrong value") + } + if v.Patch() != 3 { + t.Error("Patch() returning wrong value") + } + if v.Prerelease() != "beta.1" { + t.Error("Prerelease() returning wrong value") + } + if v.Metadata() != "build.123" { + t.Error("Metadata() returning wrong value") + } +} + +func TestString(t *testing.T) { + tests := []struct { + version string + expected string + }{ + {"1.2.3", "1.2.3"}, + {"v1.2.3", "1.2.3"}, + {"1.0", "1.0.0"}, + {"v1.0", "1.0.0"}, + {"1", "1.0.0"}, + {"v1", "1.0.0"}, + {"1.2-5", "1.2.0-5"}, + {"v1.2-5", "1.2.0-5"}, + {"1.2-beta.5", "1.2.0-beta.5"}, + {"v1.2-beta.5", "1.2.0-beta.5"}, + {"1.2.0-x.Y.0+metadata", "1.2.0-x.Y.0+metadata"}, + {"v1.2.0-x.Y.0+metadata", "1.2.0-x.Y.0+metadata"}, + {"1.2.0-x.Y.0+metadata-width-hypen", "1.2.0-x.Y.0+metadata-width-hypen"}, + {"v1.2.0-x.Y.0+metadata-width-hypen", "1.2.0-x.Y.0+metadata-width-hypen"}, + {"1.2.3-rc1-with-hypen", "1.2.3-rc1-with-hypen"}, + {"v1.2.3-rc1-with-hypen", "1.2.3-rc1-with-hypen"}, + } + + for _, tc := range tests { + v, err := NewVersion(tc.version) + if err != nil { + t.Errorf("Error parsing version %s", tc) + } + + s := v.String() + if s != tc.expected { + t.Errorf("Error generating string. Expected '%s' but got '%s'", tc.expected, s) + } + } +} + +func TestCompare(t *testing.T) { + tests := []struct { + v1 string + v2 string + expected int + }{ + {"1.2.3", "1.5.1", -1}, + {"2.2.3", "1.5.1", 1}, + {"2.2.3", "2.2.2", 1}, + {"3.2-beta", "3.2-beta", 0}, + {"1.3", "1.1.4", 1}, + {"4.2", "4.2-beta", 1}, + {"4.2-beta", "4.2", -1}, + {"4.2-alpha", "4.2-beta", -1}, + {"4.2-alpha", "4.2-alpha", 0}, + {"4.2-beta.2", "4.2-beta.1", 1}, + {"4.2-beta2", "4.2-beta1", 1}, + {"4.2-beta", "4.2-beta.2", -1}, + {"4.2-beta", "4.2-beta.foo", -1}, + {"4.2-beta.2", "4.2-beta", 1}, + {"4.2-beta.foo", "4.2-beta", 1}, + {"1.2+bar", "1.2+baz", 0}, + } + + for _, tc := range tests { + v1, err := NewVersion(tc.v1) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + v2, err := NewVersion(tc.v2) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + a := v1.Compare(v2) + e := tc.expected + if a != e { + t.Errorf( + "Comparison of '%s' and '%s' failed. Expected '%d', got '%d'", + tc.v1, tc.v2, e, a, + ) + } + } +} + +func TestLessThan(t *testing.T) { + tests := []struct { + v1 string + v2 string + expected bool + }{ + {"1.2.3", "1.5.1", true}, + {"2.2.3", "1.5.1", false}, + {"3.2-beta", "3.2-beta", false}, + } + + for _, tc := range tests { + v1, err := NewVersion(tc.v1) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + v2, err := NewVersion(tc.v2) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + a := v1.LessThan(v2) + e := tc.expected + if a != e { + t.Errorf( + "Comparison of '%s' and '%s' failed. Expected '%t', got '%t'", + tc.v1, tc.v2, e, a, + ) + } + } +} + +func TestGreaterThan(t *testing.T) { + tests := []struct { + v1 string + v2 string + expected bool + }{ + {"1.2.3", "1.5.1", false}, + {"2.2.3", "1.5.1", true}, + {"3.2-beta", "3.2-beta", false}, + {"3.2.0-beta.1", "3.2.0-beta.5", false}, + {"3.2-beta.4", "3.2-beta.2", true}, + {"7.43.0-SNAPSHOT.99", "7.43.0-SNAPSHOT.103", false}, + {"7.43.0-SNAPSHOT.FOO", "7.43.0-SNAPSHOT.103", true}, + {"7.43.0-SNAPSHOT.99", "7.43.0-SNAPSHOT.BAR", false}, + } + + for _, tc := range tests { + v1, err := NewVersion(tc.v1) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + v2, err := NewVersion(tc.v2) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + a := v1.GreaterThan(v2) + e := tc.expected + if a != e { + t.Errorf( + "Comparison of '%s' and '%s' failed. Expected '%t', got '%t'", + tc.v1, tc.v2, e, a, + ) + } + } +} + +func TestEqual(t *testing.T) { + tests := []struct { + v1 string + v2 string + expected bool + }{ + {"1.2.3", "1.5.1", false}, + {"2.2.3", "1.5.1", false}, + {"3.2-beta", "3.2-beta", true}, + {"3.2-beta+foo", "3.2-beta+bar", true}, + } + + for _, tc := range tests { + v1, err := NewVersion(tc.v1) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + v2, err := NewVersion(tc.v2) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + a := v1.Equal(v2) + e := tc.expected + if a != e { + t.Errorf( + "Comparison of '%s' and '%s' failed. Expected '%t', got '%t'", + tc.v1, tc.v2, e, a, + ) + } + } +} + +func TestInc(t *testing.T) { + tests := []struct { + v1 string + expected string + how string + expectedOriginal string + }{ + {"1.2.3", "1.2.4", "patch", "1.2.4"}, + {"v1.2.4", "1.2.5", "patch", "v1.2.5"}, + {"1.2.3", "1.3.0", "minor", "1.3.0"}, + {"v1.2.4", "1.3.0", "minor", "v1.3.0"}, + {"1.2.3", "2.0.0", "major", "2.0.0"}, + {"v1.2.4", "2.0.0", "major", "v2.0.0"}, + {"1.2.3+meta", "1.2.4", "patch", "1.2.4"}, + {"1.2.3-beta+meta", "1.2.3", "patch", "1.2.3"}, + {"v1.2.4-beta+meta", "1.2.4", "patch", "v1.2.4"}, + {"1.2.3-beta+meta", "1.3.0", "minor", "1.3.0"}, + {"v1.2.4-beta+meta", "1.3.0", "minor", "v1.3.0"}, + {"1.2.3-beta+meta", "2.0.0", "major", "2.0.0"}, + {"v1.2.4-beta+meta", "2.0.0", "major", "v2.0.0"}, + } + + for _, tc := range tests { + v1, err := NewVersion(tc.v1) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + var v2 Version + switch tc.how { + case "patch": + v2 = v1.IncPatch() + case "minor": + v2 = v1.IncMinor() + case "major": + v2 = v1.IncMajor() + } + + a := v2.String() + e := tc.expected + if a != e { + t.Errorf( + "Inc %q failed. Expected %q got %q", + tc.how, e, a, + ) + } + + a = v2.Original() + e = tc.expectedOriginal + if a != e { + t.Errorf( + "Inc %q failed. Expected original %q got %q", + tc.how, e, a, + ) + } + } +} + +func TestSetPrerelease(t *testing.T) { + tests := []struct { + v1 string + prerelease string + expectedVersion string + expectedPrerelease string + expectedOriginal string + expectedErr error + }{ + {"1.2.3", "**", "1.2.3", "", "1.2.3", ErrInvalidPrerelease}, + {"1.2.3", "beta", "1.2.3-beta", "beta", "1.2.3-beta", nil}, + {"v1.2.4", "beta", "1.2.4-beta", "beta", "v1.2.4-beta", nil}, + } + + for _, tc := range tests { + v1, err := NewVersion(tc.v1) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + v2, err := v1.SetPrerelease(tc.prerelease) + if err != tc.expectedErr { + t.Errorf("Expected to get err=%s, but got err=%s", tc.expectedErr, err) + } + + a := v2.Prerelease() + e := tc.expectedPrerelease + if a != e { + t.Errorf("Expected prerelease value=%q, but got %q", e, a) + } + + a = v2.String() + e = tc.expectedVersion + if a != e { + t.Errorf("Expected version string=%q, but got %q", e, a) + } + + a = v2.Original() + e = tc.expectedOriginal + if a != e { + t.Errorf("Expected version original=%q, but got %q", e, a) + } + } +} + +func TestSetMetadata(t *testing.T) { + tests := []struct { + v1 string + metadata string + expectedVersion string + expectedMetadata string + expectedOriginal string + expectedErr error + }{ + {"1.2.3", "**", "1.2.3", "", "1.2.3", ErrInvalidMetadata}, + {"1.2.3", "meta", "1.2.3+meta", "meta", "1.2.3+meta", nil}, + {"v1.2.4", "meta", "1.2.4+meta", "meta", "v1.2.4+meta", nil}, + } + + for _, tc := range tests { + v1, err := NewVersion(tc.v1) + if err != nil { + t.Errorf("Error parsing version: %s", err) + } + + v2, err := v1.SetMetadata(tc.metadata) + if err != tc.expectedErr { + t.Errorf("Expected to get err=%s, but got err=%s", tc.expectedErr, err) + } + + a := v2.Metadata() + e := tc.expectedMetadata + if a != e { + t.Errorf("Expected metadata value=%q, but got %q", e, a) + } + + a = v2.String() + e = tc.expectedVersion + if e != a { + t.Errorf("Expected version string=%q, but got %q", e, a) + } + + a = v2.Original() + e = tc.expectedOriginal + if a != e { + t.Errorf("Expected version original=%q, but got %q", e, a) + } + } +} + +func TestOriginalVPrefix(t *testing.T) { + tests := []struct { + version string + vprefix string + }{ + {"1.2.3", ""}, + {"v1.2.4", "v"}, + } + + for _, tc := range tests { + v1, _ := NewVersion(tc.version) + a := v1.originalVPrefix() + e := tc.vprefix + if a != e { + t.Errorf("Expected vprefix=%q, but got %q", e, a) + } + } +} + +func TestJsonMarshal(t *testing.T) { + sVer := "1.1.1" + x, err := NewVersion(sVer) + if err != nil { + t.Errorf("Error creating version: %s", err) + } + out, err2 := json.Marshal(x) + if err2 != nil { + t.Errorf("Error marshaling version: %s", err2) + } + got := string(out) + want := fmt.Sprintf("%q", sVer) + if got != want { + t.Errorf("Error marshaling unexpected marshaled content: got=%q want=%q", got, want) + } +} + +func TestJsonUnmarshal(t *testing.T) { + sVer := "1.1.1" + ver := &Version{} + err := json.Unmarshal([]byte(fmt.Sprintf("%q", sVer)), ver) + if err != nil { + t.Errorf("Error unmarshaling version: %s", err) + } + got := ver.String() + want := sVer + if got != want { + t.Errorf("Error unmarshaling unexpected object content: got=%q want=%q", got, want) + } +} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go b/cmd/vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go index 08fb3d6ba88..5fb09e55eee 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go @@ -133,9 +133,10 @@ Usage: projectDir = currDir } crdGen := &crdgenerator.Generator{ - RootPath: projectDir, - OutputDir: filepath.Join(projectDir, "config", "crds"), - Namespace: namespace, + RootPath: projectDir, + OutputDir: filepath.Join(projectDir, "config", "crds"), + Namespace: namespace, + SkipMapValidation: true, } if err := crdGen.ValidateAndInitFields(); err != nil { log.Fatal(err) diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/pkg/scaffold/controller/controller.go b/cmd/vendor/sigs.k8s.io/controller-tools/pkg/scaffold/controller/controller.go index a97bf370d09..de7e4fce423 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/pkg/scaffold/controller/controller.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/pkg/scaffold/controller/controller.go @@ -17,6 +17,8 @@ limitations under the License. package controller import ( + "fmt" + "os" "path" "path/filepath" "strings" @@ -61,16 +63,8 @@ func (a *Controller) GetInput() (input.Input, error) { "rbac.authorization": "k8s.io", "storage": "k8s.io", } - if domain, found := coreGroups[a.Resource.Group]; found { - a.ResourcePackage = path.Join("k8s.io", "api") - a.GroupDomain = a.Resource.Group - if domain != "" { - a.GroupDomain = a.Resource.Group + "." + domain - } - } else { - a.ResourcePackage = path.Join(a.Repo, "pkg", "apis") - a.GroupDomain = a.Resource.Group + "." + a.Domain - } + + a.ResourcePackage, a.GroupDomain = getResourceInfo(coreGroups, a.Resource, a.Input) if a.Plural == "" { rs := inflect.NewDefaultRuleset() @@ -87,6 +81,23 @@ func (a *Controller) GetInput() (input.Input, error) { return a.Input, nil } +func getResourceInfo(coreGroups map[string]string, r *resource.Resource, in input.Input) (resourcePackage, groupDomain string) { + resourcePath := filepath.Join("pkg", "apis", r.Group, r.Version, + fmt.Sprintf("%s_types.go", strings.ToLower(r.Kind))) + if _, err := os.Stat(resourcePath); os.IsNotExist(err) { + if domain, found := coreGroups[r.Group]; found { + resourcePackage := path.Join("k8s.io", "api") + groupDomain = r.Group + if domain != "" { + groupDomain = r.Group + "." + domain + } + return resourcePackage, groupDomain + } + // TODO: need to support '--resource-pkg-path' flag for specifying resourcePath + } + return path.Join(in.Repo, "pkg", "apis"), r.Group + "." + in.Domain +} + var controllerTemplate = `{{ .Boilerplate }} package {{ lower .Resource.Kind }} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/pkg/scaffold/controller/controllertest.go b/cmd/vendor/sigs.k8s.io/controller-tools/pkg/scaffold/controller/controllertest.go index 4b421b04f99..c01446f805b 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/pkg/scaffold/controller/controllertest.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/pkg/scaffold/controller/controllertest.go @@ -17,7 +17,6 @@ limitations under the License. package controller import ( - "path" "path/filepath" "strings" @@ -59,11 +58,8 @@ func (a *Test) GetInput() (input.Input, error) { "rbac.authorization": "k8s.io", "storage": "k8s.io", } - if _, found := coreGroups[a.Resource.Group]; found { - a.ResourcePackage = path.Join("k8s.io", "api") - } else { - a.ResourcePackage = path.Join(a.Repo, "pkg", "apis") - } + + a.ResourcePackage, _ = getResourceInfo(coreGroups, a.Resource, a.Input) a.TemplateBody = controllerTestTemplate a.Input.IfExistsAction = input.Error diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/addtoscheme_policy_v1beta1.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/addtoscheme_policy_v1beta1.go new file mode 100644 index 00000000000..ae7ce242f9c --- /dev/null +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/addtoscheme_policy_v1beta1.go @@ -0,0 +1,26 @@ +/* +Copyright 2018 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package apis + +import ( + "sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1" +) + +func init() { + // Register the types with the Scheme so the components can map objects to GroupVersionKinds and back + AddToSchemes = append(AddToSchemes, v1beta1.SchemeBuilder.AddToScheme) +} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/creatures/v2alpha1/doc.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/creatures/v2alpha1/doc.go index 1bb98d32b7d..73fa73a37c2 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/creatures/v2alpha1/doc.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/creatures/v2alpha1/doc.go @@ -19,5 +19,5 @@ limitations under the License. // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=sigs.k8s.io/controller-tools/test/pkg/apis/creatures // +k8s:defaulter-gen=TypeMeta -// +groupName=creatures.k8s.io +// +groupName=creatures.testproject.org package v2alpha1 diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/creatures/v2alpha1/register.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/creatures/v2alpha1/register.go index ae0dde124f4..3807d89883d 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/creatures/v2alpha1/register.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/creatures/v2alpha1/register.go @@ -21,7 +21,7 @@ limitations under the License. // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=sigs.k8s.io/controller-tools/test/pkg/apis/creatures // +k8s:defaulter-gen=TypeMeta -// +groupName=creatures.k8s.io +// +groupName=creatures.testproject.org package v2alpha1 import ( @@ -31,7 +31,7 @@ import ( var ( // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: "creatures.k8s.io", Version: "v2alpha1"} + SchemeGroupVersion = schema.GroupVersion{Group: "creatures.testproject.org", Version: "v2alpha1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/crew/v1/doc.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/crew/v1/doc.go index c3a5aaffa9a..15287c8d066 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/crew/v1/doc.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/crew/v1/doc.go @@ -19,5 +19,5 @@ limitations under the License. // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=sigs.k8s.io/controller-tools/test/pkg/apis/crew // +k8s:defaulter-gen=TypeMeta -// +groupName=crew.k8s.io +// +groupName=crew.testproject.org package v1 diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/crew/v1/register.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/crew/v1/register.go index dca99b02ffe..c70b2202fe3 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/crew/v1/register.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/crew/v1/register.go @@ -21,7 +21,7 @@ limitations under the License. // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=sigs.k8s.io/controller-tools/test/pkg/apis/crew // +k8s:defaulter-gen=TypeMeta -// +groupName=crew.k8s.io +// +groupName=crew.testproject.org package v1 import ( @@ -31,7 +31,7 @@ import ( var ( // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: "crew.k8s.io", Version: "v1"} + SchemeGroupVersion = schema.GroupVersion{Group: "crew.testproject.org", Version: "v1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/group.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/group.go new file mode 100644 index 00000000000..38489bbdb98 --- /dev/null +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/group.go @@ -0,0 +1,18 @@ +/* +Copyright 2018 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package policy contains policy API versions +package policy diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/doc.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/doc.go new file mode 100644 index 00000000000..de9987bbf83 --- /dev/null +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2018 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1beta1 contains API Schema definitions for the policy v1beta1 API group +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=sigs.k8s.io/controller-tools/test/pkg/apis/policy +// +k8s:defaulter-gen=TypeMeta +// +groupName=policy.testproject.org +package v1beta1 diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/healthcheckpolicy_types.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/healthcheckpolicy_types.go new file mode 100644 index 00000000000..23cd7ba7d3e --- /dev/null +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/healthcheckpolicy_types.go @@ -0,0 +1,64 @@ +/* +Copyright 2018 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// HealthCheckPolicySpec defines the desired state of HealthCheckPolicy +type HealthCheckPolicySpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// HealthCheckPolicyStatus defines the observed state of HealthCheckPolicy +type HealthCheckPolicyStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +genclient:nonNamespaced + +// HealthCheckPolicy is the Schema for the healthcheckpolicies API +// +k8s:openapi-gen=true +type HealthCheckPolicy struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec HealthCheckPolicySpec `json:"spec,omitempty"` + Status HealthCheckPolicyStatus `json:"status,omitempty"` +} + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +// +genclient:nonNamespaced + +// HealthCheckPolicyList contains a list of HealthCheckPolicy +type HealthCheckPolicyList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []HealthCheckPolicy `json:"items"` +} + +func init() { + SchemeBuilder.Register(&HealthCheckPolicy{}, &HealthCheckPolicyList{}) +} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/register.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/register.go new file mode 100644 index 00000000000..97aed5549db --- /dev/null +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1/register.go @@ -0,0 +1,38 @@ +/* +Copyright 2018 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// NOTE: Boilerplate only. Ignore this file. + +// Package v1beta1 contains API Schema definitions for the policy v1beta1 API group +// +k8s:openapi-gen=true +// +k8s:deepcopy-gen=package,register +// +k8s:conversion-gen=sigs.k8s.io/controller-tools/test/pkg/apis/policy +// +k8s:defaulter-gen=TypeMeta +// +groupName=policy.testproject.org +package v1beta1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/runtime/scheme" +) + +var ( + // SchemeGroupVersion is group version used to register these objects + SchemeGroupVersion = schema.GroupVersion{Group: "policy.testproject.org", Version: "v1beta1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} +) diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/ship/v1beta1/doc.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/ship/v1beta1/doc.go index 8a42f5698d7..a4f24d0706b 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/ship/v1beta1/doc.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/ship/v1beta1/doc.go @@ -19,5 +19,5 @@ limitations under the License. // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=sigs.k8s.io/controller-tools/test/pkg/apis/ship // +k8s:defaulter-gen=TypeMeta -// +groupName=ship.k8s.io +// +groupName=ship.testproject.org package v1beta1 diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/ship/v1beta1/register.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/ship/v1beta1/register.go index c8d5eb64ca5..7a487bd2e4d 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/ship/v1beta1/register.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/apis/ship/v1beta1/register.go @@ -21,7 +21,7 @@ limitations under the License. // +k8s:deepcopy-gen=package,register // +k8s:conversion-gen=sigs.k8s.io/controller-tools/test/pkg/apis/ship // +k8s:defaulter-gen=TypeMeta -// +groupName=ship.k8s.io +// +groupName=ship.testproject.org package v1beta1 import ( @@ -31,7 +31,7 @@ import ( var ( // SchemeGroupVersion is group version used to register these objects - SchemeGroupVersion = schema.GroupVersion{Group: "ship.k8s.io", Version: "v1beta1"} + SchemeGroupVersion = schema.GroupVersion{Group: "ship.testproject.org", Version: "v1beta1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/add_healthcheckpolicy.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/add_healthcheckpolicy.go new file mode 100644 index 00000000000..4b80ba5d4e0 --- /dev/null +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/add_healthcheckpolicy.go @@ -0,0 +1,26 @@ +/* +Copyright 2018 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controller + +import ( + "sigs.k8s.io/controller-tools/test/pkg/controller/healthcheckpolicy" +) + +func init() { + // AddToManagerFuncs is a list of functions to create controllers and add them to a manager. + AddToManagerFuncs = append(AddToManagerFuncs, healthcheckpolicy.Add) +} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/firstmate/firstmate_controller.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/firstmate/firstmate_controller.go index 288e9ccc8a4..606d3bb554b 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/firstmate/firstmate_controller.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/firstmate/firstmate_controller.go @@ -95,7 +95,7 @@ type ReconcileFirstMate struct { // a Deployment as an example // Automatically generate RBAC rules to allow the Controller to read and write Deployments // +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=crew.k8s.io,resources=firstmates,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=crew.testproject.org,resources=firstmates,verbs=get;list;watch;create;update;patch;delete func (r *ReconcileFirstMate) Reconcile(request reconcile.Request) (reconcile.Result, error) { // Fetch the FirstMate instance instance := &crewv1.FirstMate{} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/frigate/frigate_controller.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/frigate/frigate_controller.go index 5dcdf563e60..c360f64a9cf 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/frigate/frigate_controller.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/frigate/frigate_controller.go @@ -87,7 +87,7 @@ type ReconcileFrigate struct { // and what is in the Frigate.Spec // TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes // a Deployment as an example -// +kubebuilder:rbac:groups=ship.k8s.io,resources=frigates,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=ship.testproject.org,resources=frigates,verbs=get;list;watch;create;update;patch;delete func (r *ReconcileFrigate) Reconcile(request reconcile.Request) (reconcile.Result, error) { // Fetch the Frigate instance instance := &shipv1beta1.Frigate{} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/healthcheckpolicy/healthcheckpolicy_controller.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/healthcheckpolicy/healthcheckpolicy_controller.go new file mode 100644 index 00000000000..c310f620af3 --- /dev/null +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/healthcheckpolicy/healthcheckpolicy_controller.go @@ -0,0 +1,106 @@ +/* +Copyright 2018 The Kubernetes authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package healthcheckpolicy + +import ( + "context" + + appsv1 "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/manager" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "sigs.k8s.io/controller-runtime/pkg/source" + policyv1beta1 "sigs.k8s.io/controller-tools/test/pkg/apis/policy/v1beta1" +) + +/** +* USER ACTION REQUIRED: This is a scaffold file intended for the user to modify with their own Controller +* business logic. Delete these comments after modifying this file.* + */ + +// Add creates a new HealthCheckPolicy Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller +// and Start it when the Manager is Started. +// USER ACTION REQUIRED: update cmd/manager/main.go to call this policy.Add(mgr) to install this Controller +func Add(mgr manager.Manager) error { + return add(mgr, newReconciler(mgr)) +} + +// newReconciler returns a new reconcile.Reconciler +func newReconciler(mgr manager.Manager) reconcile.Reconciler { + return &ReconcileHealthCheckPolicy{Client: mgr.GetClient(), scheme: mgr.GetScheme()} +} + +// add adds a new Controller to mgr with r as the reconcile.Reconciler +func add(mgr manager.Manager, r reconcile.Reconciler) error { + // Create a new controller + c, err := controller.New("healthcheckpolicy-controller", mgr, controller.Options{Reconciler: r}) + if err != nil { + return err + } + + // Watch for changes to HealthCheckPolicy + err = c.Watch(&source.Kind{Type: &policyv1beta1.HealthCheckPolicy{}}, &handler.EnqueueRequestForObject{}) + if err != nil { + return err + } + + // TODO(user): Modify this to be the types you create + // Uncomment watch a Deployment created by HealthCheckPolicy - change this for objects you create + err = c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{ + IsController: true, + OwnerType: &policyv1beta1.HealthCheckPolicy{}, + }) + if err != nil { + return err + } + + return nil +} + +var _ reconcile.Reconciler = &ReconcileHealthCheckPolicy{} + +// ReconcileHealthCheckPolicy reconciles a HealthCheckPolicy object +type ReconcileHealthCheckPolicy struct { + client.Client + scheme *runtime.Scheme +} + +// Reconcile reads that state of the cluster for a HealthCheckPolicy object and makes changes based on the state read +// and what is in the HealthCheckPolicy.Spec +// TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes +// a Deployment as an example +// +kubebuilder:rbac:groups=policy.testproject.org,resources=healthcheckpolicies,verbs=get;list;watch;create;update;patch;delete +func (r *ReconcileHealthCheckPolicy) Reconcile(request reconcile.Request) (reconcile.Result, error) { + // Fetch the HealthCheckPolicy instance + instance := &policyv1beta1.HealthCheckPolicy{} + err := r.Get(context.TODO(), request.NamespacedName, instance) + if err != nil { + if errors.IsNotFound(err) { + // Object not found, return. Created objects are automatically garbage collected. + // For additional cleanup logic use finalizers. + return reconcile.Result{}, nil + } + // Error reading the object - requeue the request. + return reconcile.Result{}, err + } + + return reconcile.Result{}, nil +} diff --git a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/kraken/kraken_controller.go b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/kraken/kraken_controller.go index e913e66d044..d9e23993abd 100644 --- a/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/kraken/kraken_controller.go +++ b/cmd/vendor/sigs.k8s.io/controller-tools/test/pkg/controller/kraken/kraken_controller.go @@ -87,7 +87,7 @@ type ReconcileKraken struct { // and what is in the Kraken.Spec // TODO(user): Modify this Reconcile function to implement your Controller logic. The scaffolding writes // a Deployment as an example -// +kubebuilder:rbac:groups=creatures.k8s.io,resources=krakens,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=creatures.testproject.org,resources=krakens,verbs=get;list;watch;create;update;patch;delete func (r *ReconcileKraken) Reconcile(request reconcile.Request) (reconcile.Result, error) { // Fetch the Kraken instance instance := &creaturesv2alpha1.Kraken{} diff --git a/docs/README.md b/docs/README.md index 649ac2c02d7..b10c7a23a3a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -4,5 +4,5 @@ 1. Follow the instructions at [https://toolchain.gitbook.com/](https://toolchain.gitbook.com/) to install gitbook. 2. cd into the `docs/book` directory -3. Run `gitbook server` -4. Visit `localhost:4000` \ No newline at end of file +3. Run `gitbook serve` +4. Visit `localhost:4000` diff --git a/docs/book/README.md b/docs/book/README.md index 52005e98c4d..bbfb59131ec 100644 --- a/docs/book/README.md +++ b/docs/book/README.md @@ -39,7 +39,7 @@ Including: ## Resources -GitBook: [book.kubebuilder.com](http://book.kubebuilder.com) +GitBook: [book.kubebuilder.io](http://book.kubebuilder.io) GitHub Repo: [kubernetes-sigs/kubebuilder](https://github.com/kubernetes-sigs/kubebuilder) Slack channel: [#kubeuilder](http://slack.k8s.io/#kubebuilder) Google Group: [kubebuilder@googlegroups.com](https://groups.google.com/forum/#!forum/kubebuilder) diff --git a/docs/book/SUMMARY.md b/docs/book/SUMMARY.md index b6fc2312c5d..afce76be84c 100644 --- a/docs/book/SUMMARY.md +++ b/docs/book/SUMMARY.md @@ -18,7 +18,7 @@ * [What is a Resource](basics/what_is_a_resource.md) * [Resource Example](basics/simple_resource.md) * Controllers - * [What is a Contoller](basics/what_is_a_controller.md) + * [What is a Controller](basics/what_is_a_controller.md) * [Controller Example](basics/simple_controller.md) * Managers * [What is the Manager](basics/what_is_the_controller_manager.md) diff --git a/docs/book/basics/project_creation_and_structure.md b/docs/book/basics/project_creation_and_structure.md index d6befdac5e4..6cd02a00813 100644 --- a/docs/book/basics/project_creation_and_structure.md +++ b/docs/book/basics/project_creation_and_structure.md @@ -68,7 +68,7 @@ that will be required to build your project. {% sample lang="bash" %} ```bash -$ kubebuilder init --domain k8s.io --license apache2 --owners "The Kubernetes Authors" +$ kubebuilder init --domain k8s.io --license apache2 --owner "The Kubernetes Authors" ``` {% endmethod %} diff --git a/docs/book/getting_started/installation_and_setup.md b/docs/book/getting_started/installation_and_setup.md index 80c4f80d7d5..fd5cc15c67a 100644 --- a/docs/book/getting_started/installation_and_setup.md +++ b/docs/book/getting_started/installation_and_setup.md @@ -11,15 +11,15 @@ Install kubebuilder by downloading the latest stable release from the {% sample lang="mac" %} ```bash -version=1.0.0 # latest stable version +version=1.0.1 # latest stable version arch=amd64 # download the release -curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v$version/kubebuilder_$version_darwin_$arch.tar.gz +curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v${version}/kubebuilder_${version}_darwin_${arch}.tar.gz # extract the archive -tar -zxvf kubebuilder_$version_darwin_$arch.tar.gz -sudo mv kubebuilder_$version_darwin_$arch /usr/local/kubebuilder +tar -zxvf kubebuilder_${version}_darwin_${arch}.tar.gz +sudo mv kubebuilder_${version}_darwin_${arch} /usr/local/kubebuilder # update your PATH to include /usr/local/kubebuilder/bin export PATH=$PATH:/usr/local/kubebuilder/bin @@ -27,15 +27,15 @@ export PATH=$PATH:/usr/local/kubebuilder/bin {% sample lang="linux" %} ```bash -version=1.0.0 # latest stable version +version=1.0.1 # latest stable version arch=amd64 # download the release -curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v$version/kubebuilder_$version_linux_$arch.tar.gz +curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v${version}/kubebuilder_${version}_linux_${arch}.tar.gz # extract the archive -tar -zxvf kubebuilder_$version_linux_$arch.tar.gz -sudo mv kubebuilder_$version_linux_$arch /usr/local/kubebuilder +tar -zxvf kubebuilder_${version}_linux_${arch}.tar.gz +sudo mv kubebuilder_${version}_linux_${arch} /usr/local/kubebuilder # update your PATH to include /usr/local/kubebuilder/bin export PATH=$PATH:/usr/local/kubebuilder/bin @@ -55,11 +55,11 @@ this release is not well tested, so you might encounter some bugs. arch=amd64 # download the release -curl -L -O https://storage.googleapis.com/kubebuilder-release/kubebuilder_master_darwin_$arch.tar.gz +curl -L -O https://storage.googleapis.com/kubebuilder-release/kubebuilder_master_darwin_${arch}.tar.gz # extract the archive -tar -zxvf kubebuilder_master_darwin_$arch.tar.gz -sudo mv kubebuilder_master_darwin_$arch /usr/local/kubebuilder +tar -zxvf kubebuilder_master_darwin_${arch}.tar.gz +sudo mv kubebuilder_master_darwin_${arch} /usr/local/kubebuilder # update your PATH to include /usr/local/kubebuilder/bin export PATH=$PATH:/usr/local/kubebuilder/bin @@ -69,11 +69,11 @@ export PATH=$PATH:/usr/local/kubebuilder/bin arch=amd64 # download the release -curl -L -O https://storage.googleapis.com/kubebuilder-release/kubebuilder_master_linux_$arch.tar.gz +curl -L -O https://storage.googleapis.com/kubebuilder-release/kubebuilder_master_linux_${arch}.tar.gz # extract the archive -tar -zxvf kubebuilder_master_linux_$arch.tar.gz -sudo mv kubebuilder_master_linux_$arch /usr/local/kubebuilder +tar -zxvf kubebuilder_master_linux_${arch}.tar.gz +sudo mv kubebuilder_master_linux_${arch} /usr/local/kubebuilder # update your PATH to include /usr/local/kubebuilder/bin export PATH=$PATH:/usr/local/kubebuilder/bin diff --git a/docs/book/quick_start.md b/docs/book/quick_start.md index 9b37665b4e7..a96e32e7845 100644 --- a/docs/book/quick_start.md +++ b/docs/book/quick_start.md @@ -21,11 +21,11 @@ version=1.0.0 # latest stable version arch=amd64 # download the release -curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v$version/kubebuilder_$version_darwin_$arch.tar.gz +curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v${version}/kubebuilder_${version}_darwin_${arch}.tar.gz # extract the archive -tar -zxvf kubebuilder_$version_darwin_$arch.tar.gz -sudo mv kubebuilder_$version_darwin_$arch /usr/local/kubebuilder +tar -zxvf kubebuilder_${version}_darwin_${arch}.tar.gz +sudo mv kubebuilder_${version}_darwin_${arch} /usr/local/kubebuilder # update your PATH to include /usr/local/kubebuilder/bin export PATH=$PATH:/usr/local/kubebuilder/bin @@ -37,11 +37,11 @@ version=1.0.0 # latest stable version arch=amd64 # download the release -curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v$version/kubebuilder_$version_linux_$arch.tar.gz +curl -L -O https://github.com/kubernetes-sigs/kubebuilder/releases/download/v${version}/kubebuilder_${version}_linux_${arch}.tar.gz # extract the archive -tar -zxvf kubebuilder_$version_linux_$arch.tar.gz -sudo mv kubebuilder_$version_linux_$arch /usr/local/kubebuilder +tar -zxvf kubebuilder_${version}_linux_${arch}.tar.gz +sudo mv kubebuilder_${version}_linux_${arch} /usr/local/kubebuilder # update your PATH to include /usr/local/kubebuilder/bin export PATH=$PATH:/usr/local/kubebuilder/bin diff --git a/docs/connect_to_existing_kind.md b/docs/connect_to_existing_kind.md new file mode 100644 index 00000000000..bcee0e8fc7c --- /dev/null +++ b/docs/connect_to_existing_kind.md @@ -0,0 +1,65 @@ +# Connect to an Existing Kind + +### Locate your domain and group variables + +The following kubectl commands may be useful + +``` +kubectl api-resources --verbs=list -o name + +kubectl api-resources --verbs=list -o name | grep mydomain.com +``` + +### Create a project + +``` +kubebuilder init --domain $APIDOMAIN --owner "MyCompany" +``` + +### Add a controller + +be sure to answer no when it asks if you would like to crate an api? [Y/n] +``` +kubebuilder create api --group $APIGROUP --version $APIVERSION --kind MyKind + +``` + +### Register your Types + +Add the following file to the pkg/apis directory + +file: pkg/apis/mytype_type.go +``` +package apis + +import ( + "github.com/username/myapirepo/apis/mygroup/v1alpha1" + "k8s.io/apimachinery/pkg/runtime/schema" + "log" + "sigs.k8s.io/controller-runtime/pkg/runtime/scheme" +) + +func init() { + // schemeGroupVersion is group version used to register these objects + schemeGroupVersion := schema.GroupVersion{Group: "mygroup.mydomain.com", Version: "v1alpha1"} + + // schemeBuilder is used to add go types to the GroupVersionKind scheme + schemeBuilder := &scheme.Builder{GroupVersion: schemeGroupVersion} + schemeBuilder.Register(&v1alpha1.MyKind{}, + &v1alpha1.MyKindList{}) + + // Register the types with the Scheme so the components can map objects + // to GroupVersionKinds and back + AddToSchemes = append(AddToSchemes, schemeBuilder.AddToScheme) +} + +``` + +### Use the correct import for your api + +``` +import ( +mygroupv1alpha1 "mydomain.com/myapiproject/apis/mygroup/v1alpha1" + +... +``` diff --git a/docs/using_an_external_type.md b/docs/using_an_external_type.md new file mode 100644 index 00000000000..187c6fb95fc --- /dev/null +++ b/docs/using_an_external_type.md @@ -0,0 +1,104 @@ +# Using an external Type + + +# Introduction + +There are several different external types that may be referenced when writing a controller. +* A Custom Resource Definition (CRD) that is defined in the current project `kubebuilder create api`. +* A Core Kubernetes Resources eg. `kubebuilder create api --group apps --version v1 --kind Deployment`. +* A CRD that is created and installed in another project. +* A CR defined via an API Aggregation (AA). Aggregated APIs are subordinate APIServers that sit behind the primary API server, which acts as a proxy. + +Currrently Kubebuilder handles the first two, CRDs and Core Resources, seamlessly. External CRDs and CRs created via Aggregation must be scaffolded manually. + +In order to use a Kubernetes Custom Resource that has been defined in another project +you will need to have several items of information. +* The Domain of the CR +* The Group under the Domain +* The Go import path of the CR Type definition. + +The Domain and Group variables have been discussed in other parts of the documentation. The import path would be located in the project that installs the CR. + +Example API Aggregation directory structure +``` +github.com + ├── example + ├── myproject + ├── apis + ├── mygroup + ├── doc.go + ├── install + │   ├── install.go + ├── v1alpha1 + │   ├── doc.go + │   ├── register.go + │   ├── types.go + │   ├── zz_generated.deepcopy.go +``` + +In the case above the import path would be `github.com/example/myproject/apis/mygroup/v1alpha1` + +### Create a project + +``` +kubebuilder init --domain $APIDOMAIN --owner "MyCompany" +``` + +### Add a controller + +be sure to answer no when it asks if you would like to create an api? [Y/n] +``` +kubebuilder create api --group $APIGROUP --version $APIVERSION --kind MyKind + +``` + +## Edit the Api files. + +### Register your Types + +Add the following file to the pkg/apis directory + +file: pkg/apis/mytype_addtoscheme.go +``` +package apis + +import ( + mygroupv1alpha1 "github.com/username/myapirepo/apis/mygroup/v1alpha1" +) + +func init() { + // Register the types with the Scheme so the components can map objects + // to GroupVersionKinds and back + AddToSchemes = append(AddToSchemes, mygroupv1alpha1.AddToScheme) +} + +``` + +## Edit the Controller files + +### Use the correct import for your api + +file: pkg/controllers/mytype_controller.go +``` +import mygroupv1alpha1 "github.com/example/myproject/apis/mygroup/v1alpha1" + +``` + +### Update dependencies + +``` +dep ensure --add +``` + +## Helpful Tips + +### Locate your domain and group variables + +The following kubectl commands may be useful + +``` +kubectl api-resources --verbs=list -o name + +kubectl api-resources --verbs=list -o name | grep mydomain.com +``` + diff --git a/test/e2e/e2e_v0.go b/test/e2e/e2e_v0.go index 50c2959a71e..8bacd3f8a77 100644 --- a/test/e2e/e2e_v0.go +++ b/test/e2e/e2e_v0.go @@ -80,7 +80,7 @@ var _ = Describe("v0 main workflow", func() { Expect(err).NotTo(HaveOccurred()) By("validate the controller-manager pod running as expected") - verifyContollerUp := func() error { + verifyControllerUp := func() error { // Get pod name // TODO: Use kubectl to format the output with a go-template getOptions := []string{"get", "pods", "-n", c.namespace, "-l", "control-plane=controller-manager", "-o", "go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}{{ \"\\n\" }}{{ end }}{{ end }}"} @@ -104,7 +104,7 @@ var _ = Describe("v0 main workflow", func() { return nil } - Eventually(verifyContollerUp, 1*time.Minute, 500*time.Millisecond).Should(BeNil()) + Eventually(verifyControllerUp, 1*time.Minute, 500*time.Millisecond).Should(BeNil()) By("creating resource object") inputFile = filepath.Join(kubebuilderTest.Dir, "hack", "sample", strings.ToLower(c.kind)+".yaml") diff --git a/test/e2e/e2e_v1.go b/test/e2e/e2e_v1.go index 6d463d7893f..c5592c2a8f0 100644 --- a/test/e2e/e2e_v1.go +++ b/test/e2e/e2e_v1.go @@ -97,7 +97,7 @@ var _ = Describe("v1 main workflow", func() { err = kubebuilderTest.Make(makeDeployOptions) By("validate the controller-manager pod running as expected") - verifyContollerUp := func() error { + verifyControllerUp := func() error { // Get pod name getOptions := []string{"get", "pods", "-l", "control-plane=controller-manager", "-n", fmt.Sprintf("e2e-%s-system", testSuffix), "-o", "go-template={{ range .items }}{{ if not .metadata.deletionTimestamp }}{{ .metadata.name }}{{ \"\\n\" }}{{ end }}{{ end }}"} podOutput, err := kubebuilderTest.RunKubectlCommand(framework.GetKubectlArgs(getOptions)) @@ -119,7 +119,7 @@ var _ = Describe("v1 main workflow", func() { return nil } - Eventually(verifyContollerUp, 5*time.Minute, time.Second).Should(BeNil()) + Eventually(verifyControllerUp, 5*time.Minute, time.Second).Should(BeNil()) By("creating an instance of CR") inputFile := filepath.Join("config", "samples", fmt.Sprintf("%s_%s_%s.yaml", c.group, c.version, strings.ToLower(c.kind)))