From 73decc2939865ff7d031186c6fe8ab946a19424a Mon Sep 17 00:00:00 2001 From: EItanya Date: Sat, 28 Dec 2019 09:50:23 -0500 Subject: [PATCH] initial commit --- .githooks/pre-commit | 30 +++ .gitignore | 20 ++ LICENSE | 201 +++++++++++++++++ Makefile | 51 +++++ README.md | 53 +++++ changelog/v0.0.1/api.yaml | 4 + ci/check-code-gen.sh | 34 +++ ci/tools.go | 22 ++ cloudbuild-cache.yaml | 34 +++ cloudbuild.yaml | 65 ++++++ go.mod | 11 + go.sum | 31 +++ pkg/modutils/mod.go | 75 +++++++ pkg/modutils/mod_test.go | 26 +++ pkg/modutils/modutils_suite_test.go | 13 ++ protodep/defaults.go | 11 + protodep/generate.sh | 44 ++++ protodep/protodep.pb.go | 252 +++++++++++++++++++++ protodep/protodep.pb.validate.go | 337 ++++++++++++++++++++++++++++ protodep/protodep.proto | 27 +++ 20 files changed, 1341 insertions(+) create mode 100755 .githooks/pre-commit create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 changelog/v0.0.1/api.yaml create mode 100755 ci/check-code-gen.sh create mode 100644 ci/tools.go create mode 100644 cloudbuild-cache.yaml create mode 100644 cloudbuild.yaml create mode 100644 go.mod create mode 100644 go.sum create mode 100644 pkg/modutils/mod.go create mode 100644 pkg/modutils/mod_test.go create mode 100644 pkg/modutils/modutils_suite_test.go create mode 100644 protodep/defaults.go create mode 100755 protodep/generate.sh create mode 100644 protodep/protodep.pb.go create mode 100644 protodep/protodep.pb.validate.go create mode 100644 protodep/protodep.proto diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..9cf40b7 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,30 @@ +#!/bin/sh +# Copyright 2012 The Go Authors. All rights reserved. +# Use of this source code is governed by a BSD-style +# license that can be found in the LICENSE file. + +# git gofmt pre-commit hook +# +# To use, store as .git/hooks/pre-commit inside your repository and make sure +# it has execute permissions. +# +# This script does not handle file names that contain spaces. + +gofiles=$(git diff --cached --name-only --diff-filter=ACM | grep '\.go$') +[ -z "$gofiles" ] && exit 0 + +unformatted=$(gofmt -l $gofiles) +badimports=$(goimports -l $gofiles) +[ -z "$unformatted" ] && [ -z "$badimports" ] && exit 0 + +# Some files are not gofmt'd or goimport'd. Print message and fail. + +echo >&2 "Go files must be formatted with gofmt and goimport. Please run:" +for fn in $unformatted; do +echo >&2 " gofmt -w $PWD/$fn" +done +for fn in $badimports; do +echo >&2 " goimports -w $PWD/$fn" +done + +exit 1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..47cb050 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# OSX Files +.DS_Store + +# Test binary, build with `go test -c` +*.test + +# IDEA files +*.idea/ + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out +vendor/ +_output/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f7b5e61 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2017 Solo.io, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c02082c --- /dev/null +++ b/Makefile @@ -0,0 +1,51 @@ +#---------------------------------------------------------------------------------- +# Base +#---------------------------------------------------------------------------------- + +ROOTDIR := $(shell pwd) +PACKAGE_PATH:=github.com/solo-io/protodep +OUTPUT_DIR ?= $(ROOTDIR)/_output +SOURCES := $(shell find . -name "*.go" | grep -v test.go) +VERSION ?= $(shell git describe --tags) + +#---------------------------------------------------------------------------------- +# Repo init +#---------------------------------------------------------------------------------- + +# https://www.viget.com/articles/two-ways-to-share-git-hooks-with-your-team/ +.PHONY: init +init: + git config core.hooksPath .githooks + +#---------------------------------------------------------------------------------- +# Protobufs +#---------------------------------------------------------------------------------- + +.PHONY: update-deps +update-deps: mod-download + $(shell cd vendor/github.com/solo-io/protoc-gen-ext; make install) + GO111MODULE=off go get -u golang.org/x/tools/cmd/goimports + GO111MODULE=off go get -u github.com/golang/protobuf/protoc-gen-go + GO111MODULE=off go get -u github.com/envoyproxy/protoc-gen-validate + GO111MODULE=off go get -u github.com/golang/mock/gomock + GO111MODULE=off go install github.com/golang/mock/mockgen + + +.PHONY: mod-download +mod-download: + go mod download + +#---------------------------------------------------------------------------------- +# Generated Code +#---------------------------------------------------------------------------------- + +.PHONY: generated-code +generated-code: $(OUTPUT_DIR)/.generated-code + +SUBDIRS:=pkg test +$(OUTPUT_DIR)/.generated-code: + mkdir -p ${OUTPUT_DIR} + $(GO_BUILD_FLAGS) go generate ./... + gofmt -w $(SUBDIRS) + goimports -w $(SUBDIRS) + touch $@ diff --git a/README.md b/README.md new file mode 100644 index 0000000..bf84ed3 --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# protodep + +protodep is an all purpose dependency management tool originally created to manage +vendoring protobuf files. However, it can also handle any non-language specific files +available through it's multiple gathering mechanisms. + +## configuration + +protodep is currently only available as a library, but the plan is to turn it into a standalone tool. + +To use protodep create a new protodep manager by calling `NewManager()` and supplying the working +directory of the project. protodep is meant to work at any level of a repo/project, so therefore +the working directory must be supplied. Then the `Ensure` function can be called to vendor in +all of the deps. The api for the `Ensure` function is reflected in the `protodep.proto` file in this +directory. + +Currently only gomod style dependencies are enabled, but git repo ones are coming soon. +### Examples + +* local + +```yaml +local: + patterns: + - **/*.proto +``` +a local config can be added to any config which will vendor files directly from the current directory +into the corresponding vendor directory + +* gomod + +```yaml +imports: + goMod: + package: github.com/solo-io/solo-kit + patterns: + - api/**/*.proto +``` +The package is the name of the gomod package which protodep will search for the files. It will call +`go list -m all` to find the correct version, and then search the local go mod cache for it. In order to +use a package which is not explicitly required by any go projects, it can be brought in using the `tools.go` +pattern. More information on tools in go mod can be found [here](https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module). + + +caveat: the gomod style dependency will only work if the package is specified in the list of required +packages for a given gomod package. + +* git repo: (coming soon) + + +## building + +Currently only involves regenerating the proto, which can be done with `go generate .` diff --git a/changelog/v0.0.1/api.yaml b/changelog/v0.0.1/api.yaml new file mode 100644 index 0000000..a6d26ee --- /dev/null +++ b/changelog/v0.0.1/api.yaml @@ -0,0 +1,4 @@ +changelog: +- type: NEW_FEATURE + description: Create API for protodep. + issueLink: https://github.com/solo-io/protodep/issues/1 \ No newline at end of file diff --git a/ci/check-code-gen.sh b/ci/check-code-gen.sh new file mode 100755 index 0000000..3a50992 --- /dev/null +++ b/ci/check-code-gen.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +set -ex + +protoc --version + +if [ ! -f .gitignore ]; then + echo "_output" > .gitignore +fi + + +git init +git config user.email "you@example.com" +git config --global user.name "Your Name" +git add . +git commit -m "set up dummy repo for diffing" -q + + +PATH=/workspace/gopath/bin:$PATH + +set +e + +make generated-code -B +if [[ $? -ne 0 ]]; then + echo "Code generation failed" + exit 1; +fi +if [[ $(git status --porcelain | wc -l) -ne 0 ]]; then + echo "Generating code produced a non-empty diff." + echo "Try running 'dep ensure && make install-codegen-deps generated-code -B' then re-pushing." + git status --porcelain + git diff | cat + exit 1; +fi diff --git a/ci/tools.go b/ci/tools.go new file mode 100644 index 0000000..fd048be --- /dev/null +++ b/ci/tools.go @@ -0,0 +1,22 @@ +// +build tools + +/* +Copyright 2019 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. +*/ + +// This package imports things required by build scripts, to force `go mod` to see them as dependencies +package tools + +import ( + _ "github.com/solo-io/protoc-gen-ext" + _ "github.com/envoyproxy/protoc-gen-validate" +) diff --git a/cloudbuild-cache.yaml b/cloudbuild-cache.yaml new file mode 100644 index 0000000..a572522 --- /dev/null +++ b/cloudbuild-cache.yaml @@ -0,0 +1,34 @@ +steps: +- name: gcr.io/cloud-builders/gsutil + entrypoint: 'bash' + args: ['-c', 'mkdir -p /go/pkg && cd /go/pkg && gsutil cat gs://$PROJECT_ID-cache/protodep/protodep-mod.tar.gz | tar -xzf -'] + env: + volumes: &vol + - name: 'gopath' + path: '/go/pkg' + id: 'untar-mod-cache' + +- name: 'golang:1.13' + args: ['go', 'mod', 'download'] + volumes: *vol + id: 'download' + +- name: 'golang:1.13' + args: ['go', 'mod', 'tidy'] + volumes: *vol + id: 'tidy' + +- name: 'golang:1.13' + entrypoint: 'bash' + volumes: *vol + args: ['-c', ' cd /go/pkg && tar -zvcf protodep-mod.tar.gz mod'] + id: 'tar-cache' + +- name: gcr.io/cloud-builders/gsutil + args: ['cp', '/go/pkg/protodep-mod.tar.gz', 'gs://$PROJECT_ID-cache/protodep/protodep-mod.tar.gz'] + volumes: *vol + id: 'upload-cache' + +options: + env: + - "GO111MODULE=on" \ No newline at end of file diff --git a/cloudbuild.yaml b/cloudbuild.yaml new file mode 100644 index 0000000..3517f8e --- /dev/null +++ b/cloudbuild.yaml @@ -0,0 +1,65 @@ +steps: + +- name: gcr.io/cloud-builders/gsutil + entrypoint: 'bash' + args: ['-c', 'mkdir -p /go/pkg && cd /go/pkg && gsutil cat gs://$PROJECT_ID-cache/protodep/protodep-mod.tar.gz | tar -xzf -'] + id: 'untar-mod-cache' + dir: &dir '/workspace/protodep' + +# prepare-workspace to set up the project so it can be built and tested +- name: 'gcr.io/$PROJECT_ID/prepare-go-workspace:0.2.2' + args: + - "--repo-owner" + - "solo-io" + - "--repo-name" + - protodep + - "--repo-sha" + - "$COMMIT_SHA" + - "--repo-output-dir" + - "." + env: + - 'GIT_SSH_CONFIG=FALSE' + id: 'prepare-workspace' + +# download massive container in parallel +- name: 'gcr.io/$PROJECT_ID/go-mod-ginkgo:0.2.1' + entrypoint: 'bash' + dir: *dir + args: ['-c', 'ls'] + waitFor: ['-'] + +# Installs go executables required by codegen tests +- name: 'gcr.io/$PROJECT_ID/go-mod-make:0.2.1' + args: ['update-deps'] + waitFor: ['prepare-workspace'] + id: 'update-deps' + dir: *dir + +# check code gen for kubernetes custom resources, should be no diff +- name: 'gcr.io/$PROJECT_ID/go-mod-make:0.2.1' + entrypoint: 'bash' + args: ['ci/check-code-gen.sh'] + env: + - 'PROJECT_ROOT=github.com/solo-io/protodep' + - 'TAGGED_VERSION=$TAG_NAME' + # waitFor: ['update-deps'] + dir: *dir + id: 'check-code-and-docs-gen' + + +# e2e-ginkgo is produced from https://github.com/solo-io/cloud-builders/e2e-ginkgo +# sets up redis, consul, kubectl, go with required environment variables +# need to use the provided entrypoint +- name: 'gcr.io/$PROJECT_ID/go-mod-ginkgo:0.2.1' + args: ['-r', '-v', '-race', '-p', '-compilers=2'] + dir: *dir + id: 'test' + + +timeout: 1500s +tags: ['protodep'] +options: + machineType: 'N1_HIGHCPU_32' + volumes: + - name: 'gopath' + path: '/go' \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..237f74d --- /dev/null +++ b/go.mod @@ -0,0 +1,11 @@ +module github.com/solo-io/protodep + +go 1.13 + +require ( + github.com/envoyproxy/protoc-gen-validate v0.1.0 + github.com/golang/protobuf v1.3.2 + github.com/onsi/ginkgo v1.11.0 + github.com/onsi/gomega v1.8.1 + github.com/rotisserie/eris v0.1.1 +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..3fcf4dc --- /dev/null +++ b/go.sum @@ -0,0 +1,31 @@ +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34= +github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/rotisserie/eris v0.1.1 h1:C0wEdnJ6+3jYx2r8RS4xBM+ZW+mVrXGocIaFbTdRYCA= +github.com/rotisserie/eris v0.1.1/go.mod h1:2ik3CyJrzlOjGyDGrKfqZivSfmkhCS3ktE+T1mNzzLk= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/pkg/modutils/mod.go b/pkg/modutils/mod.go new file mode 100644 index 0000000..75ca4ef --- /dev/null +++ b/pkg/modutils/mod.go @@ -0,0 +1,75 @@ +package modutils + +import ( + "bufio" + "bytes" + "os" + "os/exec" + "strings" + + "github.com/rotisserie/eris" +) + +var ( + ModPackageFileError = eris.New("could not find mod package file") + NonGoModPackageError = eris.New("path could not be found, as this function must be run from within a" + + "go.mod package") + + EmptyFileError = eris.New("empty file supplied, must be") + + UnableToListPackagesError = eris.New("unable to list dependencies for current go.mod packages") +) + +/* + Returns the current go mod package name from the go.mod file. + Use the function below to get the filename + Ex: github.com/solo-io/solo-kit +*/ +func GetCurrentModPackageName(module string) (string, error) { + f, err := os.Open(module) + if err != nil { + return "", eris.Wrap(ModPackageFileError, err.Error()) + } + defer f.Close() + scanner := bufio.NewScanner(f) + scanner.Split(bufio.ScanLines) + + if !scanner.Scan() { + return "", EmptyFileError + } + line := scanner.Text() + parts := strings.Split(line, " ") + + return parts[len(parts)-1], nil +} + +/* + Returns the current go mod package + Ex: /path/to/solo-kit/go.mod + + Will return /dev/null on unix if not in a go.mod package +*/ +func GetCurrentModPackageFile() (string, error) { + cmd := exec.Command("go", "env", "GOMOD") + modBytes, err := cmd.Output() + if err != nil { + return "", eris.Wrap(ModPackageFileError, err.Error()) + } + trimmedModFile := strings.TrimSpace(string(modBytes)) + if trimmedModFile == "/dev/null" || trimmedModFile == "" { + return "", NonGoModPackageError + } + return trimmedModFile, nil +} + +func GetCurrentPackageList() (*bytes.Buffer, error) { + modPackageReader := &bytes.Buffer{} + packageListCmd := exec.Command("go", "list", "-m", "all") + packageListCmd.Stdout = modPackageReader + packageListCmd.Stderr = modPackageReader + err := packageListCmd.Run() + if err != nil { + return nil, eris.Wrapf(UnableToListPackagesError, "filename: %s", modPackageReader.String()) + } + return modPackageReader, nil +} diff --git a/pkg/modutils/mod_test.go b/pkg/modutils/mod_test.go new file mode 100644 index 0000000..7b5be51 --- /dev/null +++ b/pkg/modutils/mod_test.go @@ -0,0 +1,26 @@ +package modutils + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "github.com/rotisserie/eris" +) + +var _ = Describe("modutils", func() { + It("will fail to get the package name if given the incorrect file", func() { + _, err := GetCurrentModPackageName("fake_file") + Expect(err).To(HaveOccurred()) + Expect(eris.Is(err, ModPackageFileError)).To(BeTrue()) + }) + It("will function correctly in conjuction with get mod file", func() { + name, err := GetCurrentModPackageFile() + Expect(err).NotTo(HaveOccurred()) + pacakgeName, err := GetCurrentModPackageName(name) + Expect(err).NotTo(HaveOccurred()) + Expect(pacakgeName).To(Equal("github.com/solo-io/protodep")) + }) + It("can list the packages used by this module", func() { + _, err := GetCurrentPackageList() + Expect(err).NotTo(HaveOccurred()) + }) +}) diff --git a/pkg/modutils/modutils_suite_test.go b/pkg/modutils/modutils_suite_test.go new file mode 100644 index 0000000..e5621c6 --- /dev/null +++ b/pkg/modutils/modutils_suite_test.go @@ -0,0 +1,13 @@ +package modutils_test + +import ( + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func TestModutils(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Modutils Suite") +} diff --git a/protodep/defaults.go b/protodep/defaults.go new file mode 100644 index 0000000..1c310f8 --- /dev/null +++ b/protodep/defaults.go @@ -0,0 +1,11 @@ +package protodep + +// need to reenable this once the functionality to vendor the protos is enabled +//-go:generate bash generate.sh + +const ( + // default directory into which proto, and other files will be vendored. + // Originally this was meant to be the vendor directory, but clashes with the go vendor directory + // meant it would be easier for this to inhabit it's own folder + DefaultDepDir = ".proto" +) diff --git a/protodep/generate.sh b/protodep/generate.sh new file mode 100755 index 0000000..6375a07 --- /dev/null +++ b/protodep/generate.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +set -e + +set -o errexit +set -o nounset +set -o pipefail + + +IN=$(dirname "${BASH_SOURCE[0]}") +ROOT=$(go env GOMOD | rev | cut -c8- | rev) +VALIDATE=${ROOT}/.proto/github.com/envoyprocy/protoc-gen-validate + +# code-generator does work with go.mod but makes assumptions about +# the project living in $GOPATH/src. To work around this and support +# any location; create a temporary directory, use this as an output +# base, and copy everything back once generated. +TEMP_DIR=$(mktemp -d) +cleanup() { + echo ">> Removing ${TEMP_DIR}" + rm -rf ${TEMP_DIR} +} +trap "cleanup" EXIT SIGINT + +echo ">> Temporary output directory ${TEMP_DIR}" + +IMPORTS="\ + -I=${IN} \ + -I=${VALIDATE}" + +INPUT_PROTOS="*.proto" + +GO_FLAG="--go_out=${TEMP_DIR}" +VALIDATE_FLAG="--validate_out=lang=go:${TEMP_DIR}" + + +protoc ${IMPORTS} \ + ${GO_FLAG} \ + ${VALIDATE_FLAG} \ + ${INPUT_PROTOS} + +cp -r ${TEMP_DIR}/github.com/solo-io/protodep/* ${ROOT} + +goimports -w . \ No newline at end of file diff --git a/protodep/protodep.pb.go b/protodep/protodep.pb.go new file mode 100644 index 0000000..c0104ee --- /dev/null +++ b/protodep/protodep.pb.go @@ -0,0 +1,252 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: protodep.proto + +package protodep + +import ( + fmt "fmt" + math "math" + + _ "github.com/envoyproxy/protoc-gen-validate/validate" + proto "github.com/golang/protobuf/proto" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package + +type Config struct { + Local *Local `protobuf:"bytes,1,opt,name=local,proto3" json:"local,omitempty"` + Imports []*Import `protobuf:"bytes,2,rep,name=imports,proto3" json:"imports,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Config) Reset() { *m = Config{} } +func (m *Config) String() string { return proto.CompactTextString(m) } +func (*Config) ProtoMessage() {} +func (*Config) Descriptor() ([]byte, []int) { + return fileDescriptor_7fec50c21b53b759, []int{0} +} + +func (m *Config) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Config.Unmarshal(m, b) +} +func (m *Config) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Config.Marshal(b, m, deterministic) +} +func (m *Config) XXX_Merge(src proto.Message) { + xxx_messageInfo_Config.Merge(m, src) +} +func (m *Config) XXX_Size() int { + return xxx_messageInfo_Config.Size(m) +} +func (m *Config) XXX_DiscardUnknown() { + xxx_messageInfo_Config.DiscardUnknown(m) +} + +var xxx_messageInfo_Config proto.InternalMessageInfo + +func (m *Config) GetLocal() *Local { + if m != nil { + return m.Local + } + return nil +} + +func (m *Config) GetImports() []*Import { + if m != nil { + return m.Imports + } + return nil +} + +type Import struct { + // Types that are valid to be assigned to ImportType: + // *Import_GoMod + ImportType isImport_ImportType `protobuf_oneof:"ImportType"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Import) Reset() { *m = Import{} } +func (m *Import) String() string { return proto.CompactTextString(m) } +func (*Import) ProtoMessage() {} +func (*Import) Descriptor() ([]byte, []int) { + return fileDescriptor_7fec50c21b53b759, []int{1} +} + +func (m *Import) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Import.Unmarshal(m, b) +} +func (m *Import) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Import.Marshal(b, m, deterministic) +} +func (m *Import) XXX_Merge(src proto.Message) { + xxx_messageInfo_Import.Merge(m, src) +} +func (m *Import) XXX_Size() int { + return xxx_messageInfo_Import.Size(m) +} +func (m *Import) XXX_DiscardUnknown() { + xxx_messageInfo_Import.DiscardUnknown(m) +} + +var xxx_messageInfo_Import proto.InternalMessageInfo + +type isImport_ImportType interface { + isImport_ImportType() +} + +type Import_GoMod struct { + GoMod *GoModImport `protobuf:"bytes,2,opt,name=go_mod,json=goMod,proto3,oneof"` +} + +func (*Import_GoMod) isImport_ImportType() {} + +func (m *Import) GetImportType() isImport_ImportType { + if m != nil { + return m.ImportType + } + return nil +} + +func (m *Import) GetGoMod() *GoModImport { + if x, ok := m.GetImportType().(*Import_GoMod); ok { + return x.GoMod + } + return nil +} + +// XXX_OneofWrappers is for the internal use of the proto package. +func (*Import) XXX_OneofWrappers() []interface{} { + return []interface{}{ + (*Import_GoMod)(nil), + } +} + +type Local struct { + Patterns []string `protobuf:"bytes,1,rep,name=patterns,proto3" json:"patterns,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Local) Reset() { *m = Local{} } +func (m *Local) String() string { return proto.CompactTextString(m) } +func (*Local) ProtoMessage() {} +func (*Local) Descriptor() ([]byte, []int) { + return fileDescriptor_7fec50c21b53b759, []int{2} +} + +func (m *Local) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Local.Unmarshal(m, b) +} +func (m *Local) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Local.Marshal(b, m, deterministic) +} +func (m *Local) XXX_Merge(src proto.Message) { + xxx_messageInfo_Local.Merge(m, src) +} +func (m *Local) XXX_Size() int { + return xxx_messageInfo_Local.Size(m) +} +func (m *Local) XXX_DiscardUnknown() { + xxx_messageInfo_Local.DiscardUnknown(m) +} + +var xxx_messageInfo_Local proto.InternalMessageInfo + +func (m *Local) GetPatterns() []string { + if m != nil { + return m.Patterns + } + return nil +} + +type GoModImport struct { + Patterns []string `protobuf:"bytes,1,rep,name=patterns,proto3" json:"patterns,omitempty"` + Package string `protobuf:"bytes,2,opt,name=package,proto3" json:"package,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *GoModImport) Reset() { *m = GoModImport{} } +func (m *GoModImport) String() string { return proto.CompactTextString(m) } +func (*GoModImport) ProtoMessage() {} +func (*GoModImport) Descriptor() ([]byte, []int) { + return fileDescriptor_7fec50c21b53b759, []int{3} +} + +func (m *GoModImport) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_GoModImport.Unmarshal(m, b) +} +func (m *GoModImport) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_GoModImport.Marshal(b, m, deterministic) +} +func (m *GoModImport) XXX_Merge(src proto.Message) { + xxx_messageInfo_GoModImport.Merge(m, src) +} +func (m *GoModImport) XXX_Size() int { + return xxx_messageInfo_GoModImport.Size(m) +} +func (m *GoModImport) XXX_DiscardUnknown() { + xxx_messageInfo_GoModImport.DiscardUnknown(m) +} + +var xxx_messageInfo_GoModImport proto.InternalMessageInfo + +func (m *GoModImport) GetPatterns() []string { + if m != nil { + return m.Patterns + } + return nil +} + +func (m *GoModImport) GetPackage() string { + if m != nil { + return m.Package + } + return "" +} + +func init() { + proto.RegisterType((*Config)(nil), "protodep.Config") + proto.RegisterType((*Import)(nil), "protodep.Import") + proto.RegisterType((*Local)(nil), "protodep.Local") + proto.RegisterType((*GoModImport)(nil), "protodep.GoModImport") +} + +func init() { proto.RegisterFile("protodep.proto", fileDescriptor_7fec50c21b53b759) } + +var fileDescriptor_7fec50c21b53b759 = []byte{ + // 286 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x5c, 0x8f, 0x41, 0x4a, 0xc3, 0x40, + 0x14, 0x86, 0x9d, 0xc4, 0xa4, 0xed, 0x2b, 0x68, 0x19, 0x11, 0x43, 0x57, 0x25, 0x45, 0x09, 0x05, + 0x13, 0xa8, 0x37, 0x88, 0x0b, 0x15, 0xec, 0x26, 0xb8, 0xaa, 0x0b, 0x99, 0x26, 0x71, 0x1c, 0x92, + 0xf4, 0x0d, 0xc9, 0x28, 0x78, 0x0d, 0x4f, 0x23, 0xae, 0x7a, 0x9d, 0xde, 0x42, 0x32, 0x43, 0x1a, + 0x71, 0x35, 0xef, 0xff, 0xff, 0xef, 0xfd, 0xbc, 0x81, 0x13, 0x59, 0xa3, 0xc2, 0x2c, 0x97, 0xa1, + 0x1e, 0xe8, 0xb0, 0xd3, 0xd3, 0x8b, 0x0f, 0x56, 0x8a, 0x8c, 0xa9, 0x3c, 0xea, 0x06, 0x83, 0xf8, + 0xcf, 0xe0, 0xde, 0xe2, 0xf6, 0x55, 0x70, 0x7a, 0x09, 0x4e, 0x89, 0x29, 0x2b, 0x3d, 0x32, 0x23, + 0xc1, 0x78, 0x79, 0x1a, 0x1e, 0xca, 0x1e, 0x5b, 0x3b, 0x31, 0x29, 0x5d, 0xc0, 0x40, 0x54, 0x12, + 0x6b, 0xd5, 0x78, 0xd6, 0xcc, 0x0e, 0xc6, 0xcb, 0x49, 0x0f, 0x3e, 0xe8, 0x20, 0xe9, 0x00, 0x7f, + 0x05, 0xae, 0xb1, 0x68, 0x08, 0x2e, 0xc7, 0x97, 0x0a, 0x33, 0xcf, 0xd2, 0xed, 0xe7, 0xfd, 0xd2, + 0x1d, 0xae, 0x30, 0x33, 0xd8, 0xfd, 0x51, 0xe2, 0xf0, 0x56, 0xc6, 0x67, 0x00, 0xc6, 0x7a, 0xfa, + 0x94, 0x39, 0x75, 0xbe, 0xf7, 0x3b, 0x9b, 0xf8, 0x73, 0x70, 0xf4, 0x29, 0x74, 0x0a, 0x43, 0xc9, + 0x94, 0xca, 0xeb, 0x6d, 0xe3, 0x91, 0x99, 0x1d, 0x8c, 0x92, 0x83, 0xf6, 0xd7, 0x30, 0xfe, 0xd3, + 0x48, 0xaf, 0xfe, 0xa3, 0x31, 0xfc, 0xec, 0x77, 0xb6, 0xf3, 0x45, 0xac, 0x21, 0xe9, 0xd7, 0xe8, + 0x1c, 0x06, 0x92, 0xa5, 0x05, 0xe3, 0xb9, 0xbe, 0x70, 0x14, 0x8f, 0x5a, 0xec, 0xb8, 0xb6, 0x26, + 0x24, 0xe9, 0x92, 0x78, 0xb1, 0x0e, 0xb8, 0x50, 0x6f, 0xef, 0x9b, 0x30, 0xc5, 0x2a, 0x6a, 0xb0, + 0xc4, 0x6b, 0x81, 0xe6, 0x2d, 0x84, 0x8a, 0x64, 0xc1, 0xa3, 0xee, 0x5b, 0x1b, 0x57, 0x4f, 0x37, + 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x7e, 0x21, 0x9f, 0xde, 0x94, 0x01, 0x00, 0x00, +} diff --git a/protodep/protodep.pb.validate.go b/protodep/protodep.pb.validate.go new file mode 100644 index 0000000..8500acf --- /dev/null +++ b/protodep/protodep.pb.validate.go @@ -0,0 +1,337 @@ +// Code generated by protoc-gen-validate. DO NOT EDIT. +// source: protodep.proto + +package protodep + +import ( + "bytes" + "errors" + "fmt" + "net" + "net/mail" + "net/url" + "regexp" + "strings" + "time" + "unicode/utf8" + + "github.com/golang/protobuf/ptypes" +) + +// ensure the imports are used +var ( + _ = bytes.MinRead + _ = errors.New("") + _ = fmt.Print + _ = utf8.UTFMax + _ = (*regexp.Regexp)(nil) + _ = (*strings.Reader)(nil) + _ = net.IPv4len + _ = time.Duration(0) + _ = (*url.URL)(nil) + _ = (*mail.Address)(nil) + _ = ptypes.DynamicAny{} +) + +// define the regex for a UUID once up-front +var _protodep_uuidPattern = regexp.MustCompile("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$") + +// Validate checks the field values on Config with the rules defined in the +// proto definition for this message. If any rules are violated, an error is returned. +func (m *Config) Validate() error { + if m == nil { + return nil + } + + if v, ok := interface{}(m.GetLocal()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ConfigValidationError{ + field: "Local", + reason: "embedded message failed validation", + cause: err, + } + } + } + + for idx, item := range m.GetImports() { + _, _ = idx, item + + if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ConfigValidationError{ + field: fmt.Sprintf("Imports[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + return nil +} + +// ConfigValidationError is the validation error returned by Config.Validate if +// the designated constraints aren't met. +type ConfigValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ConfigValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ConfigValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ConfigValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ConfigValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ConfigValidationError) ErrorName() string { return "ConfigValidationError" } + +// Error satisfies the builtin error interface +func (e ConfigValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sConfig.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ConfigValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ConfigValidationError{} + +// Validate checks the field values on Import with the rules defined in the +// proto definition for this message. If any rules are violated, an error is returned. +func (m *Import) Validate() error { + if m == nil { + return nil + } + + switch m.ImportType.(type) { + + case *Import_GoMod: + + if v, ok := interface{}(m.GetGoMod()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ImportValidationError{ + field: "GoMod", + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + return nil +} + +// ImportValidationError is the validation error returned by Import.Validate if +// the designated constraints aren't met. +type ImportValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ImportValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ImportValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ImportValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ImportValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ImportValidationError) ErrorName() string { return "ImportValidationError" } + +// Error satisfies the builtin error interface +func (e ImportValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sImport.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ImportValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ImportValidationError{} + +// Validate checks the field values on Local with the rules defined in the +// proto definition for this message. If any rules are violated, an error is returned. +func (m *Local) Validate() error { + if m == nil { + return nil + } + + return nil +} + +// LocalValidationError is the validation error returned by Local.Validate if +// the designated constraints aren't met. +type LocalValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e LocalValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e LocalValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e LocalValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e LocalValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e LocalValidationError) ErrorName() string { return "LocalValidationError" } + +// Error satisfies the builtin error interface +func (e LocalValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sLocal.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = LocalValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = LocalValidationError{} + +// Validate checks the field values on GoModImport with the rules defined in +// the proto definition for this message. If any rules are violated, an error +// is returned. +func (m *GoModImport) Validate() error { + if m == nil { + return nil + } + + // no validation rules for Package + + return nil +} + +// GoModImportValidationError is the validation error returned by +// GoModImport.Validate if the designated constraints aren't met. +type GoModImportValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e GoModImportValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e GoModImportValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e GoModImportValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e GoModImportValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e GoModImportValidationError) ErrorName() string { return "GoModImportValidationError" } + +// Error satisfies the builtin error interface +func (e GoModImportValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sGoModImport.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = GoModImportValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = GoModImportValidationError{} diff --git a/protodep/protodep.proto b/protodep/protodep.proto new file mode 100644 index 0000000..eb07ca8 --- /dev/null +++ b/protodep/protodep.proto @@ -0,0 +1,27 @@ +syntax = "proto3"; +package protodep; +option go_package = "github.com/solo-io/protodep/protodep"; + +import "validate/validate.proto"; + +message Config { + Local local = 1; + + repeated Import imports = 2; +} + +message Import { + oneof ImportType { + option (validate.required) = true; + GoModImport go_mod = 2; + } +} + +message Local { + repeated string patterns = 1; +} + +message GoModImport { + repeated string patterns = 1 [(validate.rules).repeated = { min_items: 1}]; + string package = 2 [(validate.rules).string = { min_len: 1}]; +}