107 Commits

Author SHA1 Message Date
Manfred Touron
7b16849798 feat: update protoc 2020-07-08 23:31:19 +02:00
moul-bot
014a8d4143 chore: repo maintenance 🤖
more details: https://github.com/moul/repoman

Signed-off-by: moul-bot <bot@moul.io>
2020-07-08 23:20:56 +02:00
Manfred Touron
57c04e0d2a Merge pull request #155 from moul/dev/moul/update-web-editor 2020-05-20 13:50:16 +02:00
Manfred Touron
1c966f6e9f feat: update web-editor 2020-05-20 13:46:11 +02:00
Manfred Touron
a0668cce22 New Project Layout (#152)
New Project Layout
2020-01-15 18:08:30 +01:00
Manfred Touron
dfcdc3b99e chore: get rid of travis 2020-01-15 18:06:01 +01:00
Manfred Touron
b659c9914b feat: add circle config 2020-01-15 18:04:17 +01:00
Manfred Touron
d284f78f18 chore: bump deps 2020-01-15 18:01:54 +01:00
Manfred Touron
cae6348e1a feat: new project layout 2020-01-15 18:00:59 +01:00
moul-bot
d6e112de34 feat: semantic release (#151)
feat: semantic release
2020-01-15 17:40:37 +01:00
Manfred Touron
f3d1bfdee9 feat: semantic release 2020-01-15 17:36:50 +01:00
Manfred Touron
066f210f39 Merge pull request #148 from batazor/fix
Fix index helpers
2019-12-04 11:52:42 +01:00
Victor Login
b244c9cc31 Fix index helpers 2019-11-27 19:30:42 +03:00
Manfred Touron
3a6b47dc92 add parameter file-mode for template at file level (#143)
add parameter file-mode for template at file level
2019-05-30 20:12:52 +02:00
Manfred Touron
5b5d8bf81e Add stringFileOptionsExtension (#144)
Add stringFileOptionsExtension
2019-05-30 20:12:25 +02:00
Manfred Touron
42f1289ddc Update README.md 2019-05-03 13:58:23 +02:00
Gero
2d28c0f341 Add stringFileOptionsExtension 2019-04-26 15:34:25 -03:00
Mike Lee
e4d1fef8fe fmt 2019-03-29 19:24:47 -04:00
Mike Lee
1d71729a7c add parameter file-mode for templates that wish to parse at a file level instead of each service 2019-03-29 13:35:55 -04:00
Manfred Touron
c6eca2356c Merge pull request #142 from moul/dev/moul/rebase-85
Introducing two new helpers, one for returning in templates go_packag…
2019-02-10 22:00:41 +01:00
Manfred Touron
3576fd314a Merge pull request #141 from moul/dev/moul/fix-int64-extension
fix: fix 'int64*Extension' helpers
2019-02-10 21:41:51 +01:00
webii
f43d2a2ac8 Introducing two new helpers, one for returning in templates go_package path, and second one giving only last element of go_package namespace 2019-02-10 21:41:03 +01:00
Manfred Touron
baffaa4b6a Merge pull request #127 from piotrekmonko/fix_intermittent_errors
fixes intermittent error reporting
2019-02-10 21:37:31 +01:00
Manfred Touron
db5e9b7f99 fix: fix 'int64*Extension' helpers 2019-02-10 19:55:05 +01:00
Manfred Touron
be3a88a34a Merge pull request #140 from moul/dev/moul/message-options
feat: add message option helpers
2019-02-08 19:12:27 +01:00
Manfred Touron
bd48cf6168 feat: add message option helpers 2019-02-08 19:07:56 +01:00
Manfred Touron
7110803a05 Merge pull request #139 from moul/dev/moul/int64FieldExtension
feat: add int64FieldExtension helper
2019-01-20 07:21:16 +01:00
Manfred Touron
c41132a4f6 chore: switch to golangci-lint 2019-01-20 07:18:16 +01:00
Manfred Touron
36f4177b68 chore: lint 2019-01-19 20:01:03 +01:00
Manfred Touron
1ff20846eb feat: add int64FieldExtension helper 2019-01-18 19:41:46 +01:00
Manfred Touron
5202ea7a53 chore: group renovate bump PRs into one 2019-01-09 16:37:05 +01:00
Peter Monko
6949b76e12 fixes intermittent error reporting 2018-10-03 13:31:08 +02:00
Manfred Touron
0a47157c26 Merge pull request #109 from moul/dev/moul/escaped-paths
feat: support escaped paths (#107)
2018-09-13 17:57:54 +02:00
Manfred Touron
48265e1947 feat: support escaped paths (#107) 2018-09-13 17:52:52 +02:00
Manfred Touron
5ab09755c8 Merge pull request #108 from moul/dev/moul/canonical-url
configure modules + switch to canonical URL
2018-09-13 16:52:01 +02:00
Manfred Touron
8b191e85f2 chore: switch to go modules 2018-09-13 16:47:21 +02:00
Manfred Touron
c015ff9539 chore: switch to moul.io/protoc-gen-gotemplate 2018-09-13 16:38:39 +02:00
Manfred Touron
ac2e25e74f Merge pull request #105 from moul/fix/gfanton/store-concurrency
fix(store): Fix store concurrency
2018-09-12 20:13:57 +02:00
Manfred Touron
7d8c6c4b19 Merge pull request #103 from moul/renovate/configure
Configure Renovate
2018-09-12 20:13:39 +02:00
Renovate Bot
8ec535ac58 Add renovate.json 2018-08-28 16:31:46 +00:00
Manfred Touron
ca3f353d44 Merge pull request #106 from sfroment/dev/sfroment/update-protoc
Update the znly/protoc image
2018-08-28 18:26:05 +02:00
Sacha Froment
9b14e8fb8a fix: update to the latest image
Signed-off-by: Sacha Froment <sfroment42@gmail.com>
2018-08-28 17:11:38 +02:00
Guilhem Fanton
5b8733f8ec fix(store): Fix store concurrency 2018-08-23 18:49:20 +02:00
Manfred Touron
90a63053d4 Merge pull request #104 from moul/dev/gfanton/add-bool-method-option
feat(options): Add bool method option
2018-08-20 17:55:15 +02:00
Guilhem Fanton
8a8c54b5b4 chore(store): Dont panic on get store 2018-08-20 17:41:58 +02:00
Guilhem Fanton
9938cbdf5a feat(option): Add bool method option 2018-08-20 17:41:36 +02:00
Manfred Touron
0fe0e49401 chore: set git remote to GitHub https URL 2018-08-14 00:56:16 +02:00
Julien Hayotte
5b056b2579 Merge pull request #102 from jhayotte/MessageEmbedded
feat: add goTypeWithGoPackage
2018-08-09 10:40:48 +02:00
jhayotte
4b9116a5dd feat: add goTypeWithGoPackage
This function allows you to prefix your field of type message with what
you defined in the option go_package.

Moreover it handles message embedded.

In this commit, I rename gometalinter gas option in gosec.
2018-08-09 10:28:26 +02:00
Manfred Touron
6abbdf4cfb Merge pull request #96 from moul/helpers/gfanton/add-store-helper
Add Concat/Join/Store helpers
2018-04-07 19:42:21 +02:00
Guilhem Fanton
adb58bd940 Add concat & Join helper methods 2018-04-06 17:18:38 +02:00
Julien Hayotte
283713bd93 Merge pull request #95 from Tommy-42/master
Add arithmetics helpers - fix #94
2018-03-21 17:29:47 +01:00
Tommy PAGEARD
19fb3c8da9 Add arithmetics helpers - fix #94 2018-03-21 15:03:26 +01:00
Manfred Touron
77a820ea6f Merge pull request #93 from sumup/feature/stringMethodOptionsExtension
Add stringMethodOptionsExtension
2018-02-27 11:02:53 +01:00
Jan Weitz
6765ff04eb Add stringMethodOptionsExtension
This helper function can be used on service methods
to read options, which extend method options by a string.

e.g.

It is possible to read "Some string" for a custom

`my_method_option.bar` message option extension.

See:

https://developers.google.com/protocol-buffers/docs/proto#customoptions

on how to define a custom extension and referencing is by a fieldID.

```
service MyService {

  rpc MyMethod(RequestType) returns(ResponseType) {
    option (my_method_option.bar) = "Some string";
  }
}
```

If `my_method_option.bar` was defined for `fieldID: 50000`
one can reference it using protoc-gen-template like:

```
{{- stringMethodOptionsExtension 50000 .method }}
```
2018-02-23 16:55:45 +01:00
Alexandre Beslic
bb3105a862 Merge pull request #91 from tkerambloch/dev/tkerambloch/getHttpPathInAdditionalBindings
Helper: add helper like httpPath for get path in additional bindings options
2018-02-13 17:34:22 +01:00
Thomas KERAMBLOCH
0c29a9922f add helper like httpPath for get path in additional bindings options 2018-02-13 16:00:04 +01:00
Alexandre Beslic
aff21c1e7c Merge pull request #90 from tkerambloch/dev/tkerambloch/helperGetIndexArray
fix type int32 in index helper
2018-02-12 17:03:31 +01:00
Thomas KERAMBLOCH
15ac366c8d fix type int32 in index helper 2018-02-12 16:48:36 +01:00
Alexandre Beslic
5a9555bcf5 Merge pull request #89 from tkerambloch/dev/tkerambloch/helperGetIndexArray
Add Helper 'index': get elem of array with the index
2018-02-10 18:43:45 +01:00
Thomas KERAMBLOCH
3f1d5001d9 Add Helper 'index': get elem of array with the index 2018-02-10 18:00:39 +01:00
Manfred Touron
be5f14041f Merge pull request #83 from pmoroney/new-helpers
add new helpers
2018-01-12 23:25:50 +01:00
Pat Moroney
100279cd16 add comment about tree traversal 2018-01-12 11:36:29 -07:00
Pat Moroney
4f138c4f92 remove duplicated line 2018-01-12 11:23:17 -07:00
Pat Moroney
78cb5588b1 make nilString constant 2018-01-12 11:12:15 -07:00
Pat Moroney
0b600dd93f rename fieldId to fieldID 2018-01-12 10:56:25 -07:00
Pat Moroney
decb64ccd8 add new helpers 2018-01-12 10:38:10 -07:00
Manfred Touron
7e17e4319f Merge pull request #82 from moul/dev/moul/lint
Setup gometalinter + fix lint
2017-12-28 15:38:19 +01:00
Manfred Touron
c64e1d8ed6 Setup gometalinter + fix lint 2017-12-28 15:34:09 +01:00
Manfred Touron
f84ba571b5 Merge pull request #81 from moul/dev/moul/bump-deps
Bump deps + add helpers examples
2017-12-19 17:42:54 +01:00
Manfred Touron
5da3d00df2 Add a new 'helpers' example 2017-12-19 15:55:33 +01:00
Manfred Touron
9f831eb4de Bump sprig@v2.14.1 2017-12-19 14:00:29 +01:00
Manfred Touron
230480afd1 Switch from glide to govendor 2017-12-19 13:55:52 +01:00
Manfred Touron
ccffd8bfe2 Merge pull request #78 from shiwano/split-array
Fix error on use pipeline after splitArray result
2017-12-19 08:57:29 +01:00
Alexandre Beslic
bd68210bc3 Merge pull request #77 from abronan/func_map_additions
Additional sprig rule to handle Go convention
2017-12-01 10:53:35 +01:00
Shogo Iwano
c833301bd5 Fix error on use pipeline after splitArray result 2017-12-01 01:43:18 +09:00
Alexandre Beslic
3dbba43e5f func map additions to handle golang convention while executing templates with id fields
Signed-off-by: Alexandre Beslic <abeslic@abronan.com>
2017-11-29 15:46:48 +01:00
Manfred Touron
055b1a5a86 Add fork-me ribbon 2017-10-26 23:04:12 +02:00
Manfred Touron
6db1457a28 Update README.md 2017-10-26 22:59:32 +02:00
Manfred Touron
6ceb257a3b Add web-editor.jpg 2017-10-26 22:58:10 +02:00
Manfred Touron
fc09c682e3 Merge pull request #76 from moul/dev/moul/web-editor
Initial version of the web-editor
2017-10-26 22:54:41 +02:00
Manfred Touron
22c3e39e89 Update vendors 2017-10-26 19:13:44 +02:00
Manfred Touron
64c92d0c8d Initial version of the web-editor 2017-10-26 19:13:44 +02:00
Manfred Touron
ba84ae0c01 Merge pull request #75 from moul/dev/moul/fix-docker-build
Fix Docker build
2017-10-10 11:48:00 +02:00
Manfred Touron
8caafb8ec4 Refactor Dockerfile 2017-10-10 10:59:53 +02:00
Manfred Touron
fe71150b76 Merge pull request #74 from pmoroney/master
Add httpBody helper function
2017-09-19 21:29:51 +00:00
Pat Moroney
7172d5b49d Add httpBody helper function 2017-09-19 14:53:57 -06:00
jhayotte
a0e68f8a2b enhance isFieldMessageTimeStamp 2017-09-18 18:56:37 +02:00
Julien Hayotte
1dc5500690 Merge pull request #73 from moul/dev/jhayotte/time
Add helper isFieldMessageTimeStamp
2017-09-18 16:22:28 +02:00
jhayotte
dab343fc15 Add helper isFieldMessageTimeStamp 2017-09-18 15:04:39 +02:00
Julien Hayotte
a921a29c7e Merge pull request #72 from moul/dev/jhayotte/deps
fixes: upgrade huandu/xtrings to handle capital word with func ToCamelCase
2017-09-08 09:52:43 +02:00
jhayotte
6db729b136 fix: upgrade huandu/xtrings to handle capital word with func ToCamelCase 2017-09-08 09:10:17 +02:00
Anastasia DERUELLE
ee845f3ed6 fix (helper): fix goTypeWithPackage enum case 2017-08-30 15:33:35 +02:00
Manfred Touron
19fd9d7959 Merge pull request #69 from moul/dev/proullon/helpers
feat (helpers): add strings helper
2017-06-26 17:34:13 +02:00
Pierre Roullon
07992907fd feat (helpers): add strings helper 2017-06-26 11:34:02 +02:00
Pierre Roullon
c52b282d96 fix (helper): fix goType enum case 2017-06-23 07:49:29 +00:00
Pierre Roullon
d454efa152 feat (helper): add haskellType helper 2017-06-23 07:49:29 +00:00
Pierre Roullon
80a62f29d8 fix (helper): splitArray helper does not return emtpy string 2017-06-23 07:49:29 +00:00
Valerio Gheri
8a25e9ba06 Merge pull request #67 from moul/vgheri/int32-fix
Fixes #5
2017-06-09 11:59:07 +02:00
Valerio Gheri
37fe30907a Fixes #5 2017-06-09 11:53:33 +02:00
Manfred Touron
fd268a723e Merge pull request #65 from moul/dev/jhayotte/timestamp
handle google.protobuf.timestamp
2017-06-08 17:02:19 +02:00
jhayotte
d0c5bb5a97 handle google.protobuf.timestamp 2017-06-08 16:40:52 +02:00
Manfred Touron
098b247649 Merge pull request #64 from moul/dev/moul/fix-urls-vars-from-message
Make urlHasVarsFromMessage consistent with getMessageType
2017-05-19 20:13:42 +02:00
Manfred Touron
09adcbdcd9 Make urlHasVarsFromMessage consistent with getMessageType 2017-05-19 20:10:20 +02:00
Manfred Touron
31a84ee58f Isolate helpers in their own package (#63) 2017-05-19 10:02:40 +02:00
Manfred Touron
62b7b2227e Add Docker usage (fix #8) 2017-05-19 09:56:47 +02:00
Manfred Touron
0f43ead321 Add $GOPATH/bin in /usr/local/bin:/usr/local/sbin::/Users/moul/mbin:/Users/moul/mbin2:/Users/moul/node_modules/.bin:/usr/local/share/npm/bin:/bin:/sbin:/usr/bin:/usr/sbin:/Users/moul/go/bin env var 2017-05-19 09:49:03 +02:00
2159 changed files with 7021 additions and 848824 deletions

17
.circleci/config.yml Normal file
View File

@@ -0,0 +1,17 @@
version: 2.1
orbs:
moul: moul/build@1.14.0 # https://github.com/moul/build
workflows:
main:
jobs:
- moul/golang-build:
gopkg: moul.io/protoc-gen-gotemplate
- moul/golang-build:
gopkg: moul.io/protoc-gen-gotemplate
tag: '1.12'
- moul/golang-build:
gopkg: moul.io/protoc-gen-gotemplate
tag: '1.11'
- moul/docker-build

3
.dockerignore Normal file
View File

@@ -0,0 +1,3 @@
Dockerfile
*~
.git/

15
.gitattributes vendored Normal file
View File

@@ -0,0 +1,15 @@
# Auto detect text files and perform LF normalization
* text=auto
# Collapse vendored and generated files on GitHub
vendor/* linguist-vendored
rules.mk linguist-vendored
*/vendor/* linguist-vendored
*.gen.* linguist-generated
*.pb.go linguist-generated
go.sum linguist-generated
go.mod linguist-generated
gen.sum linguist-generated
# Reduce conflicts on markdown files
*.md merge=union

1
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1 @@
* @moul

6
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
#github: ["moul"]
patreon: moul
open_collective: moul
custom:
- "https://www.buymeacoffee.com/moul"
- "https://manfred.life/donate"

31
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,31 @@
---
name: Bug report
about: Create a report to help us improve
title: "[BUG] "
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Type '....'
3. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots / Logs**
If applicable, add screenshots or logs to help explain your problem.
**Versions (please complete the following information, if relevant):**
- Software version: [e.g. v1.2.3, latest, building from sources]
- OS: [e.g. Ubuntu, Mac, iOS, ...]
- Golang version [e.g. 1.13]
**Additional context**
Add any other context about the problem here.

8
.github/ISSUE_TEMPLATE/custom.md vendored Normal file
View File

@@ -0,0 +1,8 @@
---
name: Custom
about: 'Anything else: questions, discussions, thanks, ascii-arts, ...'
title: ''
labels: discussion
assignees: moul
---

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[IDEA] "
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

9
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,9 @@
<!--
Thank you for your contribution to this repo!
Before submitting a pull request, please check the following:
- reference any related issue, PR, link
- use the "WIP" title prefix if you need help or more time to finish your PR
you can remove this markdown comment
-->

7
.github/renovate.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"extends": [
"config:base"
],
"groupName": "all",
"gomodTidy": true
}

13
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,13 @@
name: Semantic Release
on: push
jobs:
semantic-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- uses: codfish/semantic-release-action@v1
if: github.ref == 'refs/heads/master'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

43
.gitignore vendored
View File

@@ -1,26 +1,25 @@
/protoc-gen-gotemplate # Temporary files
*~
*#
.#*
coverage.txt
# Compiled Object files, Static and Dynamic libs (Shared Objects) # Vendors
*.o package-lock.json
*.a node_modules/
*.so vendor/
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
# Binaries for programs and plugins
dist/
gin-bin
*.exe *.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test *.test
*.prof
# Output of the go coverage tool, specifically when used with LiteIDE
*.out

36
.golangci.yml Normal file
View File

@@ -0,0 +1,36 @@
run:
deadline: 1m
tests: false
skip-files:
- ".*\\.gen\\.go"
skip-dirs:
- "examples"
linters-settings:
golint:
min-confidence: 0
maligned:
suggest-new: true
goconst:
min-len: 5
min-occurrences: 4
misspell:
locale: US
linters:
disable-all: true
enable:
- goconst
- misspell
- deadcode
- misspell
- structcheck
- errcheck
- unused
- varcheck
- staticcheck
- unconvert
- gofmt
- goimports
- golint
- ineffassign

8
.releaserc.js Normal file
View File

@@ -0,0 +1,8 @@
module.exports = {
branch: 'master',
plugins: [
'@semantic-release/commit-analyzer',
'@semantic-release/release-notes-generator',
'@semantic-release/github',
],
};

View File

@@ -1,15 +0,0 @@
language: go
go: 1.8.x
install:
- go get github.com/Masterminds/glide
- wget https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/master/.travis/install-protoc.sh && chmod +x install-protoc.sh && ./install-protoc.sh 3.2.0
- go get -u github.com/golang/protobuf/protoc-gen-go
script:
- make install
- make test
cache:
directories:
- $HOME/local
env:
global:
- "PATH=$PATH:$HOME/local/bin"

30
AUTHORS Normal file
View File

@@ -0,0 +1,30 @@
# This file lists all individuals having contributed content to the repository.
# For how it is generated, see 'https://github.com/moul/rules.mk'
Alexandre Beslic <abeslic@abronan.com>
Anastasia DERUELLE <anastasia.deruelle@gmail.com>
Gero <geronimo@eclypsium.com>
gfanton <guilhem.fanton@gmail.com>
Guilhem Fanton <guilhem.fanton@gmail.com>
Jan Weitz <jan@iosphere.de>
jhayotte <julien.hayotte@gmail.com>
Julien Hayotte <julien.hayotte@gmail.com>
Manfred Touron <94029+moul@users.noreply.github.com>
Manfred Touron <m@42.am>
Mathieu Acthernoene <zoontek@gmail.com>
Mike Lee <mike.lee@safeguardproperties.com>
moul-bot <41326314+moul-bot@users.noreply.github.com>
moul-bot <bot@moul.io>
Pat Moroney <pat@pat.email>
Pat Moroney <pmoroney@name.com>
Peter Monko <piotrek.monko@gmail.com>
Pierre Roullon <pierre.roullon@gmail.com>
Quentin Perez <qperez@ocs.online.net>
Renovate Bot <bot@renovateapp.com>
Sacha Froment <sfroment42@gmail.com>
Shogo Iwano <shiwano@gmail.com>
Thomas KERAMBLOCH <tkerambloch@vente-privee.com>
Tommy PAGEARD <tpageard@vente-privee.com>
Valerio Gheri <valerio.gheri@gmail.com>
Victor Login <batazor111@gmail.com>
webii <michal.jaglewicz@gmail.com>

View File

@@ -1,5 +1,18 @@
FROM znly/protoc # builder
RUN apk --update add make git go rsync FROM golang:1.14-alpine as builder
COPY . /go/src/github.com/moul/protoc-gen-gotemplate RUN apk --no-cache add make git go rsync libc-dev
WORKDIR /go/src/github.com/moul/protoc-gen-gotemplate RUN go get -u golang.org/x/tools/cmd/goimports
RUN go install . RUN go get -u github.com/gobuffalo/packr/v2/packr2
COPY . /go/src/moul.io/protoc-gen-gotemplate
WORKDIR /go/src/moul.io/protoc-gen-gotemplate
RUN packr2
RUN go install -a -tags netgo -ldflags '-w -extldflags "-static"' . ./cmd/web-editor
RUN ls -la /go/bin
# runtime
FROM znly/protoc:0.3.0
COPY --from=builder /go/bin/web-editor /go/bin/
COPY --from=builder /go/bin/protoc-gen-gotemplate /go/bin/
ENV PATH=$PATH:/go/bin
EXPOSE 8080
ENTRYPOINT []

View File

@@ -1,13 +1,15 @@
.PHONY: build GOPKG ?= moul.io/protoc-gen-gotemplate
build: DOCKER_IMAGE ?= moul/protoc-gen-gotemplate
go build -v -i -o protoc-gen-gotemplate . GOBINS ?= . ./cmd/web-editor
GOLIBS ?= .
.PHONY: install all: test install
install:
go install .
.PHONY: test include rules.mk
test: install
.PHONY: examples
examples: install
cd examples/time && make
cd examples/enum && make cd examples/enum && make
cd examples/import && make cd examples/import && make
cd examples/dummy && make cd examples/dummy && make
@@ -16,13 +18,7 @@ test: install
cd examples/flow && make cd examples/flow && make
cd examples/sitemap && make cd examples/sitemap && make
cd examples/go-generate && make cd examples/go-generate && make
cd examples/single-package-mode && make #cd examples/single-package-mode && make
# cd examples/go-kit && make cd examples/helpers && make
cd examples/arithmetics && make
.PHONY: docker.build #cd examples/go-kit && make
docker.build:
docker build --pull -t moul/protoc-gen-gotemplate .
.PHONY: docker.push
docker.push: docker.build
docker push moul/protoc-gen-gotemplate

View File

@@ -22,6 +22,12 @@ The plugin parses **protobuf** files, generates an **ast**, and walks a local **
3. the `ast` is given to [Golang's `text/template` engine](https://golang.org/pkg/text/template/) for each *user* template files 3. the `ast` is given to [Golang's `text/template` engine](https://golang.org/pkg/text/template/) for each *user* template files
4. the *funcmap* enriching the template engine is based on [Masterminds/sprig](https://github.com/Masterminds/sprig), and contains type-manipulation, iteration and language-specific helpers 4. the *funcmap* enriching the template engine is based on [Masterminds/sprig](https://github.com/Masterminds/sprig), and contains type-manipulation, iteration and language-specific helpers
## Web editor
![Web editor screenshot](https://github.com/moul/protoc-gen-gotemplate/raw/master/assets/web-editor.jpg)
[Demo server](http://protoc-gen-gotemplate.m.42.am/)
## Usage ## Usage
`protoc-gen-gotemplate` requires a **template_dir** directory *(by default `./templates`)*. `protoc-gen-gotemplate` requires a **template_dir** directory *(by default `./templates`)*.
@@ -67,33 +73,59 @@ See [examples](./examples).
This project uses [Masterminds/sprig](https://github.com/Masterminds/sprig) library and additional functions to extend the builtin [text/template](https://golang.org/pkg/text/template) helpers. This project uses [Masterminds/sprig](https://github.com/Masterminds/sprig) library and additional functions to extend the builtin [text/template](https://golang.org/pkg/text/template) helpers.
Non-exhaustive list of new helpers:s Non-exhaustive list of new helpers:
* **all the functions from [sprig](https://github.com/Masterminds/sprig)** * **all the functions from [sprig](https://github.com/Masterminds/sprig)**
* `json` * `add`
* `prettyjson` * `boolFieldExtension`
* `first`
* `last`
* `splitArray`
* `upperFirst`
* `lowerFirst`
* `camelCase` * `camelCase`
* `lowerCamelCase` * `contains`
* `kebabCase` * `divide`
* `snakeCase` * `fieldMapKeyType`
* `getProtoFile` * `fieldMapValueType`
* `getMessageType` * `first`
* `getEnumValue` * `getEnumValue`
* `getMessageType`
* `getProtoFile`
* `goNormalize`
* `goTypeWithPackage`
* `goType`
* `goZeroValue`
* `haskellType`
* `httpBody`
* `httpPath`
* `httpPathsAdditionalBindings`
* `httpVerb`
* `index`
* `int64FieldExtension`
* `isFieldMap`
* `isFieldMessageTimeStamp`
* `isFieldMessage` * `isFieldMessage`
* `isFieldRepeated` * `isFieldRepeated`
* `goType`
* `goTypeWithPackage`
* `jsType`
* `jsSuffixReserved` * `jsSuffixReserved`
* `jsType`
* `json`
* `kebabCase`
* `last`
* `leadingComment`
* `leadingDetachedComments`
* `lowerCamelCase`
* `lowerFirst`
* `lowerGoNormalize`
* `multiply`
* `namespacedFlowType` * `namespacedFlowType`
* `httpVerb` * `prettyjson`
* `httpPath` * `replaceDict`
* `shortType` * `shortType`
* `snakeCase`
* `splitArray`
* `stringFieldExtension`
* `stringMethodOptionsExtension`
* `string`
* `subtract`
* `trailingComment`
* `trimstr`
* `upperFirst`
* `urlHasVarsFromMessage` * `urlHasVarsFromMessage`
See the project helpers for the complete list. See the project helpers for the complete list.
@@ -102,7 +134,18 @@ See the project helpers for the complete list.
* Install the **Go** compiler and tools from https://golang.org/doc/install * Install the **Go** compiler and tools from https://golang.org/doc/install
* Install **protobuf**: `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}` * Install **protobuf**: `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`
* Install **protoc-gen-gotemplate**: `go get -u github.com/moul/protoc-gen-gotemplate` * Install **protoc-gen-gotemplate**: `go get -u moul.io/protoc-gen-gotemplate`
## Docker
* automated docker hub build: [https://hub.docker.com/r/moul/protoc-gen-gotemplate/](https://hub.docker.com/r/moul/protoc-gen-gotemplate/)
* Based on [http://github.com/znly/protoc](http://github.com/znly/protoc)
Usage:
```console
$> docker run --rm -v "$(pwd):$(pwd)" -w "$(pwd)" moul/protoc-gen-gotemplate -I. --gotemplate_out=./output/ ./*.proto
```
## Projects using `protoc-gen-gotemplate` ## Projects using `protoc-gen-gotemplate`
@@ -110,6 +153,10 @@ See the project helpers for the complete list.
* [translator](https://github.com/moul/translator): Translator Micro-service using Gettext and Go-Kit * [translator](https://github.com/moul/translator): Translator Micro-service using Gettext and Go-Kit
* [acl](https://github.com/moul/acl): ACL micro-service (gRPC/protobuf + http/json) * [acl](https://github.com/moul/acl): ACL micro-service (gRPC/protobuf + http/json)
## See also
* [pbhbs](https://github.com/gponsinet/pbhbs): protobuf gen based on handlebarjs template
## License ## License
MIT MIT

6
assets/assets Normal file
View File

@@ -0,0 +1,6 @@
/Users/moul/go/src/moul.io/protoc-gen-gotemplate/assets:
total used in directory 552 available 9223372036849978910
drwxr-xr-x 4 moul staff 128 Dec 9 11:31 .
lrwxr-xr-x 1 moul staff 33 Dec 9 11:31 .#web-editor.jpg -> moul@manfred-spacegray.local.9471
drwxr-xr-x 21 moul staff 672 Sep 13 18:05 ..
-rw-r--r--@ 1 moul staff 280357 Oct 26 2017 web-editor.jpg

BIN
assets/web-editor.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

121
cmd/web-editor/main.go Normal file
View File

@@ -0,0 +1,121 @@
package main
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
packr "github.com/gobuffalo/packr/v2"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
)
func generate(w http.ResponseWriter, r *http.Request) {
// read input
decoder := json.NewDecoder(r.Body)
type Input struct {
Protobuf string `json:"protobuf"`
Template string `json:"template"`
}
var input Input
if err := decoder.Decode(&input); err != nil {
returnError(w, err)
return
}
// create workspace
dir, err := ioutil.TempDir("", "pggt")
if err != nil {
returnError(w, err)
}
// clean up
defer func() {
if err = os.RemoveAll(dir); err != nil {
log.Printf("error: failed to remove temporary directory: %v", err)
}
}()
if err = ioutil.WriteFile(filepath.Join(dir, "example.proto"), []byte(input.Protobuf), 0644); err != nil {
returnError(w, err)
return
}
if err = ioutil.WriteFile(filepath.Join(dir, "example.output.tmpl"), []byte(input.Template), 0644); err != nil {
returnError(w, err)
return
}
// generate
cmd := exec.Command("protoc", "-I"+dir, "--gotemplate_out=template_dir="+dir+",debug=true:"+dir, filepath.Join(dir, "example.proto")) // #nosec
out, err := cmd.CombinedOutput()
if err != nil {
returnError(w, errors.New(string(out)))
return
}
// read output
content, err := ioutil.ReadFile(filepath.Join(dir, "example.output")) // #nosec
if err != nil {
returnError(w, err)
return
}
returnContent(w, content)
}
func returnContent(w http.ResponseWriter, output interface{}) {
payload := map[string]interface{}{
"output": fmt.Sprintf("%s", output),
}
response, err := json.Marshal(payload)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
if _, err := w.Write(response); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func returnError(w http.ResponseWriter, err error) {
payload := map[string]interface{}{
"error": fmt.Sprintf("%v", err),
}
response, err := json.Marshal(payload)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusInternalServerError)
if _, err := w.Write(response); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
func main() {
r := mux.NewRouter()
box := packr.New("static", "./static")
r.Handle("/", http.FileServer(box))
r.HandleFunc("/generate", generate)
addr := fmt.Sprintf(":%s", os.Getenv("PORT"))
if addr == ":" {
addr = ":8080"
}
fmt.Printf("Listening on %s...\n", addr)
h := handlers.LoggingHandler(os.Stderr, r)
h = handlers.CompressHandler(h)
h = handlers.RecoveryHandler()(h)
if err := http.ListenAndServe(addr, h); err != nil {
panic(err)
}
}

View File

@@ -0,0 +1,138 @@
<html>
<head>
<title>protoc-gen-gotemplate web editor</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.3/angular-animate.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.3.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.3/ui-bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-protobuf.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/mode-golang.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/theme-cobalt.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/worker-javascript.js"></script>
<script src="//angular-ui.github.io/ui-ace/dist/ui-ace.min.js"></script>
<script type="text/javascript">
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9+/=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/rn/g,"n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}}
angular.module("pggt", ['pggt.controllers','ngAnimate','ui.bootstrap', 'ui.ace']);
angular.module("pggt.controllers", [])
.controller('PggtCtrl', ['$scope', '$http', '$interval', function($scope, $http, $interval) {
$scope.requestType = 'post';
$scope.url = '/generate';
$scope.response = null;
$scope.errors = null;
$scope.inputHasChanged = false;
$scope.checkModel = {
optimize: false,
disableNetwork: false,
toArm: false,
};
$scope.$watchCollection('checkModel', function() {
$scope.sendRequest();
});
var cron = $interval(function() {
if ($scope.inputHasChanged) {
$scope.sendRequest();
}
}, 2000);
// b64encoded version of https://github.com/grpc/grpc-go/blob/master/examples/route_guide/routeguide/route_guide.proto
$scope.protobuf = Base64.decode("Ly8gQ29weXJpZ2h0IDIwMTUgZ1JQQyBhdXRob3JzLg0KLy8NCi8vIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOw0KLy8geW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLg0KLy8gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0DQovLw0KLy8gICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMA0KLy8NCi8vIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUNCi8vIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuICJBUyBJUyIgQkFTSVMsDQovLyBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4NCi8vIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQNCi8vIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLg0KDQpzeW50YXggPSAicHJvdG8zIjsNCg0Kb3B0aW9uIGphdmFfbXVsdGlwbGVfZmlsZXMgPSB0cnVlOw0Kb3B0aW9uIGphdmFfcGFja2FnZSA9ICJpby5ncnBjLmV4YW1wbGVzLnJvdXRlZ3VpZGUiOw0Kb3B0aW9uIGphdmFfb3V0ZXJfY2xhc3NuYW1lID0gIlJvdXRlR3VpZGVQcm90byI7DQoNCnBhY2thZ2Ugcm91dGVndWlkZTsNCg0KLy8gSW50ZXJmYWNlIGV4cG9ydGVkIGJ5IHRoZSBzZXJ2ZXIuDQpzZXJ2aWNlIFJvdXRlR3VpZGUgew0KICAvLyBBIHNpbXBsZSBSUEMuDQogIC8vDQogIC8vIE9idGFpbnMgdGhlIGZlYXR1cmUgYXQgYSBnaXZlbiBwb3NpdGlvbi4NCiAgLy8NCiAgLy8gQSBmZWF0dXJlIHdpdGggYW4gZW1wdHkgbmFtZSBpcyByZXR1cm5lZCBpZiB0aGVyZSdzIG5vIGZlYXR1cmUgYXQgdGhlIGdpdmVuDQogIC8vIHBvc2l0aW9uLg0KICBycGMgR2V0RmVhdHVyZShQb2ludCkgcmV0dXJucyAoRmVhdHVyZSkge30NCg0KICAvLyBBIHNlcnZlci10by1jbGllbnQgc3RyZWFtaW5nIFJQQy4NCiAgLy8NCiAgLy8gT2J0YWlucyB0aGUgRmVhdHVyZXMgYXZhaWxhYmxlIHdpdGhpbiB0aGUgZ2l2ZW4gUmVjdGFuZ2xlLiAgUmVzdWx0cyBhcmUNCiAgLy8gc3RyZWFtZWQgcmF0aGVyIHRoYW4gcmV0dXJuZWQgYXQgb25jZSAoZS5nLiBpbiBhIHJlc3BvbnNlIG1lc3NhZ2Ugd2l0aCBhDQogIC8vIHJlcGVhdGVkIGZpZWxkKSwgYXMgdGhlIHJlY3RhbmdsZSBtYXkgY292ZXIgYSBsYXJnZSBhcmVhIGFuZCBjb250YWluIGENCiAgLy8gaHVnZSBudW1iZXIgb2YgZmVhdHVyZXMuDQogIHJwYyBMaXN0RmVhdHVyZXMoUmVjdGFuZ2xlKSByZXR1cm5zIChzdHJlYW0gRmVhdHVyZSkge30NCg0KICAvLyBBIGNsaWVudC10by1zZXJ2ZXIgc3RyZWFtaW5nIFJQQy4NCiAgLy8NCiAgLy8gQWNjZXB0cyBhIHN0cmVhbSBvZiBQb2ludHMgb24gYSByb3V0ZSBiZWluZyB0cmF2ZXJzZWQsIHJldHVybmluZyBhDQogIC8vIFJvdXRlU3VtbWFyeSB3aGVuIHRyYXZlcnNhbCBpcyBjb21wbGV0ZWQuDQogIHJwYyBSZWNvcmRSb3V0ZShzdHJlYW0gUG9pbnQpIHJldHVybnMgKFJvdXRlU3VtbWFyeSkge30NCg0KICAvLyBBIEJpZGlyZWN0aW9uYWwgc3RyZWFtaW5nIFJQQy4NCiAgLy8NCiAgLy8gQWNjZXB0cyBhIHN0cmVhbSBvZiBSb3V0ZU5vdGVzIHNlbnQgd2hpbGUgYSByb3V0ZSBpcyBiZWluZyB0cmF2ZXJzZWQsDQogIC8vIHdoaWxlIHJlY2VpdmluZyBvdGhlciBSb3V0ZU5vdGVzIChlLmcuIGZyb20gb3RoZXIgdXNlcnMpLg0KICBycGMgUm91dGVDaGF0KHN0cmVhbSBSb3V0ZU5vdGUpIHJldHVybnMgKHN0cmVhbSBSb3V0ZU5vdGUpIHt9DQp9DQoNCi8vIFBvaW50cyBhcmUgcmVwcmVzZW50ZWQgYXMgbGF0aXR1ZGUtbG9uZ2l0dWRlIHBhaXJzIGluIHRoZSBFNyByZXByZXNlbnRhdGlvbg0KLy8gKGRlZ3JlZXMgbXVsdGlwbGllZCBieSAxMCoqNyBhbmQgcm91bmRlZCB0byB0aGUgbmVhcmVzdCBpbnRlZ2VyKS4NCi8vIExhdGl0dWRlcyBzaG91bGQgYmUgaW4gdGhlIHJhbmdlICsvLSA5MCBkZWdyZWVzIGFuZCBsb25naXR1ZGUgc2hvdWxkIGJlIGluDQovLyB0aGUgcmFuZ2UgKy8tIDE4MCBkZWdyZWVzIChpbmNsdXNpdmUpLg0KbWVzc2FnZSBQb2ludCB7DQogIGludDMyIGxhdGl0dWRlID0gMTsNCiAgaW50MzIgbG9uZ2l0dWRlID0gMjsNCn0NCg0KLy8gQSBsYXRpdHVkZS1sb25naXR1ZGUgcmVjdGFuZ2xlLCByZXByZXNlbnRlZCBhcyB0d28gZGlhZ29uYWxseSBvcHBvc2l0ZQ0KLy8gcG9pbnRzICJsbyIgYW5kICJoaSIuDQptZXNzYWdlIFJlY3RhbmdsZSB7DQogIC8vIE9uZSBjb3JuZXIgb2YgdGhlIHJlY3RhbmdsZS4NCiAgUG9pbnQgbG8gPSAxOw0KDQogIC8vIFRoZSBvdGhlciBjb3JuZXIgb2YgdGhlIHJlY3RhbmdsZS4NCiAgUG9pbnQgaGkgPSAyOw0KfQ0KDQovLyBBIGZlYXR1cmUgbmFtZXMgc29tZXRoaW5nIGF0IGEgZ2l2ZW4gcG9pbnQuDQovLw0KLy8gSWYgYSBmZWF0dXJlIGNvdWxkIG5vdCBiZSBuYW1lZCwgdGhlIG5hbWUgaXMgZW1wdHkuDQptZXNzYWdlIEZlYXR1cmUgew0KICAvLyBUaGUgbmFtZSBvZiB0aGUgZmVhdHVyZS4NCiAgc3RyaW5nIG5hbWUgPSAxOw0KDQogIC8vIFRoZSBwb2ludCB3aGVyZSB0aGUgZmVhdHVyZSBpcyBkZXRlY3RlZC4NCiAgUG9pbnQgbG9jYXRpb24gPSAyOw0KfQ0KDQovLyBBIFJvdXRlTm90ZSBpcyBhIG1lc3NhZ2Ugc2VudCB3aGlsZSBhdCBhIGdpdmVuIHBvaW50Lg0KbWVzc2FnZSBSb3V0ZU5vdGUgew0KICAvLyBUaGUgbG9jYXRpb24gZnJvbSB3aGljaCB0aGUgbWVzc2FnZSBpcyBzZW50Lg0KICBQb2ludCBsb2NhdGlvbiA9IDE7DQoNCiAgLy8gVGhlIG1lc3NhZ2UgdG8gYmUgc2VudC4NCiAgc3RyaW5nIG1lc3NhZ2UgPSAyOw0KfQ0KDQovLyBBIFJvdXRlU3VtbWFyeSBpcyByZWNlaXZlZCBpbiByZXNwb25zZSB0byBhIFJlY29yZFJvdXRlIHJwYy4NCi8vDQovLyBJdCBjb250YWlucyB0aGUgbnVtYmVyIG9mIGluZGl2aWR1YWwgcG9pbnRzIHJlY2VpdmVkLCB0aGUgbnVtYmVyIG9mDQovLyBkZXRlY3RlZCBmZWF0dXJlcywgYW5kIHRoZSB0b3RhbCBkaXN0YW5jZSBjb3ZlcmVkIGFzIHRoZSBjdW11bGF0aXZlIHN1bSBvZg0KLy8gdGhlIGRpc3RhbmNlIGJldHdlZW4gZWFjaCBwb2ludC4NCm1lc3NhZ2UgUm91dGVTdW1tYXJ5IHsNCiAgLy8gVGhlIG51bWJlciBvZiBwb2ludHMgcmVjZWl2ZWQuDQogIGludDMyIHBvaW50X2NvdW50ID0gMTsNCg0KICAvLyBUaGUgbnVtYmVyIG9mIGtub3duIGZlYXR1cmVzIHBhc3NlZCB3aGlsZSB0cmF2ZXJzaW5nIHRoZSByb3V0ZS4NCiAgaW50MzIgZmVhdHVyZV9jb3VudCA9IDI7DQoNCiAgLy8gVGhlIGRpc3RhbmNlIGNvdmVyZWQgaW4gbWV0cmVzLg0KICBpbnQzMiBkaXN0YW5jZSA9IDM7DQoNCiAgLy8gVGhlIGR1cmF0aW9uIG9mIHRoZSB0cmF2ZXJzYWwgaW4gc2Vjb25kcy4NCiAgaW50MzIgZWxhcHNlZF90aW1lID0gNDsNCn0=");
$scope.template = Base64.decode("Ly8gQ29kZSBnZW5lcmF0ZWQgYnkgcHJvdG9jLWdlbi1nb3RlbXBsYXRlDQpwYWNrYWdlIHt7LlNlcnZpY2UuTmFtZX19cGINCg0KaW1wb3J0ICgNCiAgImdvbGFuZy5vcmcveC9uZXQvY29udGV4dCINCikNCg0KdHlwZSBTZXJ2aWNlIGludGVyZmFjZSB7DQp7ey0gcmFuZ2UgLlNlcnZpY2UuTWV0aG9kfX0NCnt7LSBpZiBhbmQgKG5vdCAuU2VydmVyU3RyZWFtaW5nKSAobm90IC5DbGllbnRTdHJlYW1pbmcpfX0NCiAge3suTmFtZX19KGNvbnRleHQuQ29udGV4dCwgKnt7Lk5hbWV9fVJlcXVlc3QpICgqe3suTmFtZX19UmVzcG9uc2UsIGVycm9yKQ0Ke3stIGVsc2UgaWYgYW5kIC5TZXJ2ZXJTdHJlYW1pbmcgKG5vdCAuQ2xpZW50U3RyZWFtaW5nKX19DQoge3suTmFtZX19KGNvbnRleHQuQ29udGV4dCwgKnt7Lk5hbWV9fVJlcXVlc3QsIGNoYW4gc3RydWN0e30pIChjaGFuICp7ey5OYW1lfX1SZXNwb25zZSwgZXJyb3IpDQp7ey0gZWxzZSBpZiBhbmQgKG5vdCAuU2VydmVyU3RyZWFtaW5nKSAuQ2xpZW50U3RyZWFtaW5nfX0NCiAge3suTmFtZX19KGNvbnRleHQuQ29udGV4dCwgY2hhbiAqe3suTmFtZX19UmVxdWVzdCkgKCp7ey5OYW1lfX1SZXNwb25zZSwgZXJyb3IpDQp7ey0gZWxzZSBpZiBhbmQgKC5TZXJ2ZXJTdHJlYW1pbmcpICguQ2xpZW50U3RyZWFtaW5nKX19DQogIHt7Lk5hbWV9fShjb250ZXh0LkNvbnRleHQsIGNoYW4gKnt7Lk5hbWV9fVJlcXVlc3QpIChjaGFuICp7ey5OYW1lfX1SZXNwb25zZSwgZXJyb3IpDQp7ey0gZW5kfX0ge3svKiBzdHJlYW1pbmcgaWZzKi99fQ0Ke3stIGVuZH19IHt7LypyYW5nZSBNZXRob2QqL319DQp9DQoNCi8vIE1ldGhvZHMNCi8vIC0tLS0tLS0NCnt7LSByYW5nZSAuU2VydmljZS5NZXRob2R9fQ0KLy8gKiB7ey5OYW1lfX0NCnt7LSBlbmR9fQ0KLy8NCi8vIE1lc3NhZ2UgdHlwZXMNCi8vIC0tLS0tLS0tLS0tLS0NCnt7LSByYW5nZSAuRmlsZS5NZXNzYWdlVHlwZX19DQovLyAqIHt7Lk5hbWV9fQ0Ke3stIGVuZH19");
$scope.inputLoaded = function(_editor) {
$scope.inputEditor = _editor;
};
$scope.outputLoaded = function(_editor) {
$scope.outputEditor = _editor;
};
$scope.inputChanged = function(e) {
$scope.inputHasChanged = true;
};
$scope.sendRequest = function(){
$scope.inputHasChanged = false;
var data = {
protobuf: $scope.protobuf,
template: $scope.template,
};
$http.post($scope.url, data)
.success(function(data,status,headers,config) {
$scope.errors = {};
$scope.response = {};
$scope.response.data = data;
$scope.response.status = status;
$scope.response.headers = headers;
$scope.response.config = config;
$scope.outputEditor.setValue(data['output'], 1);
})
.error(function(data,status,headers,config) {
$scope.errors = {};
$scope.response = {};
$scope.errors.data = data;
$scope.errors.status = status;
$scope.errors.headers = headers;
$scope.errors.config = config;
$scope.outputEditor.setValue(data['error'], 1);
});
};
}]);
</script>
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/8.3/styles/github.min.css">
<style>.ace_editor { height: 80%; min-height: 500px; }</style>
</head>
<body ng-app="pggt">
<div class="container-fluid" ng-controller="PggtCtrl">
<div class="row">
<div class="col-md-8">
<form name="dpform" ng-submit="sendRequest()" class="well">
<fieldset>
<legend>`protoc-gen-gotemplate`: input</legend>
<div class="row">
<div class="col-md-6">
<label for="protobuf">./example.proto</label>
<div ng-model="protobuf" name="protobuf" id="protobuf" language="protobuf"
ui-ace="{mode:'protobuf',theme:'cobalt',onChange:inputChanged,onLoad:inputLoaded,useWrapMode:true}">
</div>
</div>
<div class="col-md-6">
<label for="template">./example.txt.tmpl</label>
<div ng-model="template" name="template" id="template" language="text"
ui-ace="{mode:'text',theme:'cobalt',onChange:inputChanged,onLoad:inputLoaded,useWrapMode:true}">
</div>
</div>
</div>
</fieldset>
</form>
</div>
<div class="col-md-4">
<div class="well">
<fieldset>
<legend>Output</legend>
<label>./example.txt</label>
<div ui-ace="{mode:'text',theme:'cobalt',onLoad:outputLoaded,useWrapMode:true}" readonly></div>
</fieldset>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div>Command: <code>protoc --gotemplate_out=template_dir=.:. example.proto</code></div>
<div>Powered by <a href="https://moul.io/protoc-gen-gotemplate">protoc-gen-gotemplate</a></div>
</div>
</div>
</div>
<a href="https://moul.io/protoc-gen-gotemplate"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/365986a132ccd6a44c23a9169022c0b5c890c387/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png"></a>
</body>
</html>

View File

@@ -3,6 +3,7 @@ package main
import ( import (
"bytes" "bytes"
"log" "log"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
@@ -10,7 +11,9 @@ import (
"time" "time"
"github.com/golang/protobuf/protoc-gen-go/descriptor" "github.com/golang/protobuf/protoc-gen-go/descriptor"
"github.com/golang/protobuf/protoc-gen-go/plugin" plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
pgghelpers "moul.io/protoc-gen-gotemplate/helpers"
) )
type GenericTemplateBasedEncoder struct { type GenericTemplateBasedEncoder struct {
@@ -50,6 +53,7 @@ func NewGenericServiceTemplateBasedEncoder(templateDir string, service *descript
if debug { if debug {
log.Printf("new encoder: file=%q service=%q template-dir=%q", file.GetName(), service.GetName(), templateDir) log.Printf("new encoder: file=%q service=%q template-dir=%q", file.GetName(), service.GetName(), templateDir)
} }
pgghelpers.InitPathMap(file)
return return
} }
@@ -66,6 +70,7 @@ func NewGenericTemplateBasedEncoder(templateDir string, file *descriptor.FileDes
if debug { if debug {
log.Printf("new encoder: file=%q template-dir=%q", file.GetName(), templateDir) log.Printf("new encoder: file=%q template-dir=%q", file.GetName(), templateDir)
} }
pgghelpers.InitPathMap(file)
return return
} }
@@ -90,6 +95,7 @@ func (e *GenericTemplateBasedEncoder) templates() ([]string, error) {
if e.debug { if e.debug {
log.Printf("new template: %q", rel) log.Printf("new template: %q", rel)
} }
filenames = append(filenames, rel) filenames = append(filenames, rel)
return nil return nil
}) })
@@ -98,11 +104,20 @@ func (e *GenericTemplateBasedEncoder) templates() ([]string, error) {
func (e *GenericTemplateBasedEncoder) genAst(templateFilename string) (*Ast, error) { func (e *GenericTemplateBasedEncoder) genAst(templateFilename string) (*Ast, error) {
// prepare the ast passed to the template engine // prepare the ast passed to the template engine
hostname, _ := os.Hostname() hostname, err := os.Hostname()
pwd, _ := os.Getwd() if err != nil {
return nil, err
}
pwd, err := os.Getwd()
if err != nil {
return nil, err
}
goPwd := "" goPwd := ""
if os.Getenv("GOPATH") != "" { if os.Getenv("GOPATH") != "" {
goPwd, _ = filepath.Rel(os.Getenv("GOPATH")+"/src", pwd) goPwd, err = filepath.Rel(os.Getenv("GOPATH")+"/src", pwd)
if err != nil {
return nil, err
}
if strings.Contains(goPwd, "../") { if strings.Contains(goPwd, "../") {
goPwd = "" goPwd = ""
} }
@@ -122,7 +137,15 @@ func (e *GenericTemplateBasedEncoder) genAst(templateFilename string) (*Ast, err
Enum: e.enum, Enum: e.enum,
} }
buffer := new(bytes.Buffer) buffer := new(bytes.Buffer)
tmpl, err := template.New("").Funcs(ProtoHelpersFuncMap).Parse(templateFilename)
unescaped, err := url.QueryUnescape(templateFilename)
if err != nil {
log.Printf("failed to unescape filepath %q: %v", templateFilename, err)
} else {
templateFilename = unescaped
}
tmpl, err := template.New("").Funcs(pgghelpers.ProtoHelpersFuncMap).Parse(templateFilename)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -137,7 +160,7 @@ func (e *GenericTemplateBasedEncoder) buildContent(templateFilename string) (str
// initialize template engine // initialize template engine
fullPath := filepath.Join(e.templateDir, templateFilename) fullPath := filepath.Join(e.templateDir, templateFilename)
templateName := filepath.Base(fullPath) templateName := filepath.Base(fullPath)
tmpl, err := template.New(templateName).Funcs(ProtoHelpersFuncMap).ParseFiles(fullPath) tmpl, err := template.New(templateName).Funcs(pgghelpers.ProtoHelpersFuncMap).ParseFiles(fullPath)
if err != nil { if err != nil {
return "", "", err return "", "", err
} }
@@ -168,7 +191,8 @@ func (e *GenericTemplateBasedEncoder) Files() []*plugin_go.CodeGeneratorResponse
resultChan := make(chan *plugin_go.CodeGeneratorResponse_File, length) resultChan := make(chan *plugin_go.CodeGeneratorResponse_File, length)
for _, templateFilename := range templates { for _, templateFilename := range templates {
go func(tmpl string) { go func(tmpl string) {
content, translatedFilename, err := e.buildContent(tmpl) var translatedFilename, content string
content, translatedFilename, err = e.buildContent(tmpl)
if err != nil { if err != nil {
errChan <- err errChan <- err
return return
@@ -186,10 +210,8 @@ func (e *GenericTemplateBasedEncoder) Files() []*plugin_go.CodeGeneratorResponse
case f := <-resultChan: case f := <-resultChan:
files = append(files, f) files = append(files, f)
case err = <-errChan: case err = <-errChan:
panic(err)
} }
} }
if err != nil {
panic(err)
}
return files return files
} }

View File

@@ -0,0 +1,13 @@
.PHONY: build
build:
mkdir -p output
protoc -I. --gotemplate_out=template_dir=templates,debug=true,all=true:output proto/*.proto
.PHONY: re
re: clean build
.PHONY: clean
clean:
rm -rf output

View File

@@ -0,0 +1,5 @@
add(1,2) = 3
subtract(1,2) = -1
multiply(1,2) = 2
divide(2,1) = 2

View File

@@ -0,0 +1,2 @@
syntax = "proto3";
package Arithmetics;

View File

@@ -0,0 +1,6 @@
{{with $a := 1}}{{with $b := 2}}
add(1,2) = {{add $a $b}}
subtract(1,2) = {{subtract $a $b}}
multiply(1,2) = {{multiply $a $b}}
divide(2,1) = {{divide $b $a}}
{{end}}{{end}}

View File

@@ -1,6 +1,6 @@
{ {
"build-date": "2017-05-02T11:50:25.063291628+02:00", "build-date": "2017-05-19T20:09:45.954357761+02:00",
"build-hostname": "manfred-spacegray.local", "build-hostname": "manfred-spacegray.aircard",
"build-user": "moul", "build-user": "moul",
"pwd": "/Users/moul/Git/moul/protoc-gen-gotemplate/examples/dummy", "pwd": "/Users/moul/Git/moul/protoc-gen-gotemplate/examples/dummy",
"debug": false, "debug": false,
@@ -839,5 +839,6 @@
"options": {} "options": {}
} }
] ]
} },
"enum": null
} }

View File

@@ -1,4 +1,4 @@
package: github.com/moul/protoc-gen-gotemplate/examples/go-kit package: moul.io/protoc-gen-gotemplate/examples/go-kit
import: import:
- package: github.com/go-kit/kit - package: github.com/go-kit/kit
subpackages: subpackages:

View File

@@ -12,23 +12,23 @@ import (
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
"google.golang.org/grpc" "google.golang.org/grpc"
session_svc "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session" session_svc "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session"
session_endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints" session_endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints"
session_pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb" session_pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
session_grpctransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/transports/grpc" session_grpctransport "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/transports/grpc"
session_httptransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/transports/http" session_httptransport "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/transports/http"
sprint_svc "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint" sprint_svc "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint"
sprint_endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints" sprint_endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints"
sprint_pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb" sprint_pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
sprint_grpctransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/transports/grpc" sprint_grpctransport "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/transports/grpc"
sprint_httptransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/transports/http" sprint_httptransport "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/transports/http"
user_svc "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user" user_svc "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user"
user_endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints" user_endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"
user_pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb" user_pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
user_grpctransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/transports/grpc" user_grpctransport "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/transports/grpc"
user_httptransport "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/transports/http" user_httptransport "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/transports/http"
) )
func main() { func main() {

View File

@@ -9,8 +9,8 @@ import (
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
"google.golang.org/grpc" "google.golang.org/grpc"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
) )
func New(conn *grpc.ClientConn, logger log.Logger) pb.SessionServiceServer { func New(conn *grpc.ClientConn, logger log.Logger) pb.SessionServiceServer {

View File

@@ -5,8 +5,8 @@ import (
"fmt" "fmt"
"github.com/go-kit/kit/endpoint" "github.com/go-kit/kit/endpoint"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
oldcontext "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
) )
var _ = endpoint.Chain var _ = endpoint.Chain

View File

@@ -7,8 +7,8 @@ import (
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
oldcontext "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
) )
// avoid import errors // avoid import errors

View File

@@ -8,8 +8,8 @@ import (
gokit_endpoint "github.com/go-kit/kit/endpoint" gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http" httptransport "github.com/go-kit/kit/transport/http"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
) )
var _ = log.Printf var _ = log.Printf

View File

@@ -5,7 +5,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
) )
type Service struct{} type Service struct{}

View File

@@ -9,8 +9,8 @@ import (
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
"google.golang.org/grpc" "google.golang.org/grpc"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
) )
func New(conn *grpc.ClientConn, logger log.Logger) pb.SprintServiceServer { func New(conn *grpc.ClientConn, logger log.Logger) pb.SprintServiceServer {

View File

@@ -5,8 +5,8 @@ import (
"fmt" "fmt"
"github.com/go-kit/kit/endpoint" "github.com/go-kit/kit/endpoint"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
oldcontext "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
) )
var _ = endpoint.Chain var _ = endpoint.Chain

View File

@@ -7,8 +7,8 @@ import (
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
oldcontext "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
) )
// avoid import errors // avoid import errors

View File

@@ -8,8 +8,8 @@ import (
gokit_endpoint "github.com/go-kit/kit/endpoint" gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http" httptransport "github.com/go-kit/kit/transport/http"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
) )
var _ = log.Printf var _ = log.Printf

View File

@@ -5,7 +5,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
) )
type Service struct{} type Service struct{}

View File

@@ -9,8 +9,8 @@ import (
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
"google.golang.org/grpc" "google.golang.org/grpc"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
) )
func New(conn *grpc.ClientConn, logger log.Logger) pb.UserServiceServer { func New(conn *grpc.ClientConn, logger log.Logger) pb.UserServiceServer {

View File

@@ -5,8 +5,8 @@ import (
"fmt" "fmt"
"github.com/go-kit/kit/endpoint" "github.com/go-kit/kit/endpoint"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
oldcontext "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
) )
var _ = endpoint.Chain var _ = endpoint.Chain

View File

@@ -7,8 +7,8 @@ import (
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
oldcontext "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
) )
// avoid import errors // avoid import errors

View File

@@ -8,8 +8,8 @@ import (
gokit_endpoint "github.com/go-kit/kit/endpoint" gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http" httptransport "github.com/go-kit/kit/transport/http"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
) )
var _ = log.Printf var _ = log.Printf

View File

@@ -5,7 +5,7 @@ import (
"golang.org/x/net/context" "golang.org/x/net/context"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
) )
type Service struct{} type Service struct{}

View File

@@ -27,7 +27,7 @@ func New(conn *grpc.ClientConn, logger log.Logger) pb.{{.File.Package | title}}S
Encode{{.Name}}Request, Encode{{.Name}}Request,
Decode{{.Name}}Response, Decode{{.Name}}Response,
pb.{{.Name}}Response{}, pb.{{.Name}}Response{},
append([]grpctransport.ClientOption{}, grpctransport.ClientBefore(jwt.FromGRPCContext()))..., append([]grpctransport.ClientOption{}, grpctransport.ClientBefore(jwt.ContextToGRPC()))...,
).Endpoint() ).Endpoint()
} }
{{end}} {{end}}

11
examples/go.mod generated Normal file
View File

@@ -0,0 +1,11 @@
module moul.io/protoc-gen-gotemplate/examples
go 1.14
require (
github.com/go-kit/kit v0.10.0
github.com/golang/protobuf v1.4.2
github.com/gorilla/handlers v1.4.2
golang.org/x/net v0.0.0-20200707034311-ab3426394381
google.golang.org/grpc v1.30.0
)

385
examples/go.sum generated Normal file
View File

@@ -0,0 +1,385 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI=
github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A=
github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU=
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo=
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE=
github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU=
github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k=
github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w=
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA=
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.30.0 h1:M5a8xTlYTxwMn5ZFkwhRabsygDY5G8TYLyQDBxJNAxE=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=

13
examples/helpers/Makefile Normal file
View File

@@ -0,0 +1,13 @@
.PHONY: build
build:
mkdir -p output
protoc -I. --gotemplate_out=template_dir=.,debug=true:. *.proto
.PHONY: re
re: clean build
.PHONY: clean
clean:
rm -rf output

View File

@@ -0,0 +1,58 @@
# Common variables
{{.File.Name}}: helpers.proto
{{.File.Name | upper}}: HELPERS.PROTO
{{.File.Package | base | replace "." "-"}} dummy
{{$packageDir := .File.Name | dir}}{{$packageDir}} .
{{$packageName := .File.Name | base | replace ".proto" ""}}{{$packageName}} helpers
{{$packageImport := .File.Package | replace "." "_"}}{{$packageImport}} dummy
{{$namespacedPackage := .File.Package}}{{$namespacedPackage}} dummy
{{$currentFile := .File.Name | getProtoFile}}{{$currentFile}} <nil>
{{- /*{{- $currentPackageName := $currentFile.GoPkg.Name}}{{$currentPackageName}}*/}}
# TODO: more variables
# Sprig: strings
{{trim " hello "}}: hello
{{trimAll "$" "$5.00"}}: 5.00
{{trimSuffix "-" "hello-"}}: hello
{{upper "hello"}}: HELLO
{{lower "HELLO"}}: hello
{{title "hello world"}}: Hello World
{{untitle "Hello World"}}: hello world
{{repeat 3 "hello"}}: hellohellohello
{{substr 0 5 "hello world"}}: hello
{{nospace "hello w o r l d"}}: helloworld
{{trunc 5 "hello world"}}: hello
{{abbrev 5 "hello world"}}: he...
{{abbrevboth 5 10 "1234 5678 9123"}}: ...5678...
{{initials "First Try"}}: FT
{{randNumeric 3}}: 528
{{- /*{{wrap 80 $someText}}*/}}:
{{wrapWith 5 "\t" "Hello World"}}: Hello World
{{contains "cat" "catch"}}: true
{{hasPrefix "cat" "catch"}}: true
{{cat "hello" "beautiful" "world"}}: hello beautiful world
{{- /*{{indent 4 $lots_of_text}}*/}}:
{{- /*{{indent 4 $lots_of_text}}*/}}:
{{"I Am Henry VIII" | replace " " "-"}}: I-Am-Henry-VIII
{{len .Service.Method | plural "one anchovy" "many anchovies"}}: many anchovies
{{snakecase "FirstName"}}: first_name
{{camelcase "http_server"}}: HttpServer
{{shuffle "hello"}}: holle
{{regexMatch "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" "test@acme.com"}}: true
{{- /*{{regexFindAll "[2,4,6,8]" "123456789"}}*/}}:
{{regexFind "[a-zA-Z][1-9]" "abcd1234"}}: d1
{{regexReplaceAll "a(x*)b" "-ab-axxb-" "${1}W"}}: -W-xxW-
{{regexReplaceAllLiteral "a(x*)b" "-ab-axxb-" "${1}"}}: -${1}-${1}-
{{regexSplit "z+" "pizza" -1}}: [pi a]
# Get one specific method on array method using index
{{ index .Service.Method 1 }}: name:"Iii" input_type:".dummy.Dummy2" output_type:".dummy.Dummy1" options:<>
# Sprig: advanced
{{if contains "cat" "catch"}}yes{{else}}no{{end}}: yes
{{1 | plural "one anchovy" "many anchovies"}}: one anchovy
{{2 | plural "one anchovy" "many anchovies"}}: many anchovies
{{3 | plural "one anchovy" "many anchovies"}}: many anchovies
# TODO: more sprig examples
# TODO: all built-in examples

View File

@@ -0,0 +1,59 @@
# Common variables
{{`{{.File.Name}}`}}: {{.File.Name}}
{{`{{.File.Name | upper}}`}}: {{.File.Name | upper}}
{{`{{.File.Package | base | replace "." "-"}}`}} {{.File.Package | base | replace "." "-"}}
{{- /*{{`{{$file := .File}}{{$file}}`}} {{$file := .File}}{{$file}}*/}}
{{`{{$packageDir := .File.Name | dir}}{{$packageDir}}`}} {{$packageDir := .File.Name | dir}}{{$packageDir}}
{{`{{$packageName := .File.Name | base | replace ".proto" ""}}{{$packageName}}`}} {{$packageName := .File.Name | base | replace ".proto" ""}}{{$packageName}}
{{`{{$packageImport := .File.Package | replace "." "_"}}{{$packageImport}}`}} {{$packageImport := .File.Package | replace "." "_"}}{{$packageImport}}
{{`{{$namespacedPackage := .File.Package}}{{$namespacedPackage}}`}} {{$namespacedPackage := .File.Package}}{{$namespacedPackage}}
{{`{{$currentFile := .File.Name | getProtoFile}}{{$currentFile}}`}} {{$currentFile := .File.Name | getProtoFile}}{{$currentFile}}
{{`{{- /*{{- $currentPackageName := $currentFile.GoPkg.Name}}{{$currentPackageName}}*/}}`}} {{- /*{{- $currentPackageName := $currentFile.GoPkg.Name}}{{$currentPackageName}}*/}}
# TODO: more variables
# Sprig: strings
{{`{{trim " hello "}}`}}: {{trim " hello "}}
{{`{{trimAll "$" "$5.00"}}`}}: {{trimAll "$" "$5.00"}}
{{`{{trimSuffix "-" "hello-"}}`}}: {{trimSuffix "-" "hello-"}}
{{`{{upper "hello"}}`}}: {{upper "hello"}}
{{`{{lower "HELLO"}}`}}: {{lower "HELLO"}}
{{`{{title "hello world"}}`}}: {{title "hello world"}}
{{`{{untitle "Hello World"}}`}}: {{untitle "Hello World"}}
{{`{{repeat 3 "hello"}}`}}: {{repeat 3 "hello"}}
{{`{{substr 0 5 "hello world"}}`}}: {{substr 0 5 "hello world"}}
{{`{{nospace "hello w o r l d"}}`}}: {{nospace "hello w o r l d"}}
{{`{{trunc 5 "hello world"}}`}}: {{trunc 5 "hello world"}}
{{`{{abbrev 5 "hello world"}}`}}: {{abbrev 5 "hello world"}}
{{`{{abbrevboth 5 10 "1234 5678 9123"}}`}}: {{abbrevboth 5 10 "1234 5678 9123"}}
{{`{{initials "First Try"}}`}}: {{initials "First Try"}}
{{`{{randNumeric 3}}`}}: {{randNumeric 3}}
{{`{{- /*{{wrap 80 $someText}}*/}}`}}: {{- /*{{wrap 80 $someText}}*/}}
{{`{{wrapWith 5 "\t" "Hello World"}}`}}: {{wrapWith 5 "\t" "Hello World"}}
{{`{{contains "cat" "catch"}}`}}: {{contains "cat" "catch"}}
{{`{{hasPrefix "cat" "catch"}}`}}: {{hasPrefix "cat" "catch"}}
{{`{{cat "hello" "beautiful" "world"}}`}}: {{cat "hello" "beautiful" "world"}}
{{`{{- /*{{indent 4 $lots_of_text}}*/}}`}}: {{- /*{{indent 4 $lots_of_text}}*/}}
{{`{{- /*{{indent 4 $lots_of_text}}*/}}`}}: {{- /*{{indent 4 $lots_of_text}}*/}}
{{`{{"I Am Henry VIII" | replace " " "-"}}`}}: {{"I Am Henry VIII" | replace " " "-"}}
{{`{{len .Service.Method | plural "one anchovy" "many anchovies"}}`}}: {{len .Service.Method | plural "one anchovy" "many anchovies"}}
{{`{{snakecase "FirstName"}}`}}: {{snakecase "FirstName"}}
{{`{{camelcase "http_server"}}`}}: {{camelcase "http_server"}}
{{`{{shuffle "hello"}}`}}: {{shuffle "hello"}}
{{`{{regexMatch "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" "test@acme.com"}}`}}: {{regexMatch "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}" "test@acme.com"}}
{{`{{- /*{{regexFindAll "[2,4,6,8]" "123456789"}}*/}}`}}: {{- /*{{regexFindAll "[2,4,6,8]" "123456789"}}*/}}
{{`{{regexFind "[a-zA-Z][1-9]" "abcd1234"}}`}}: {{regexFind "[a-zA-Z][1-9]" "abcd1234"}}
{{`{{regexReplaceAll "a(x*)b" "-ab-axxb-" "${1}W"}}`}}: {{regexReplaceAll "a(x*)b" "-ab-axxb-" "${1}W"}}
{{`{{regexReplaceAllLiteral "a(x*)b" "-ab-axxb-" "${1}"}}`}}: {{regexReplaceAllLiteral "a(x*)b" "-ab-axxb-" "${1}"}}
{{`{{regexSplit "z+" "pizza" -1}}`}}: {{regexSplit "z+" "pizza" -1}}
# Get one specific method on array method using index
{{`{{ index .Service.Method 1 }}`}}: {{ index .Service.Method 1 }}
# Sprig: advanced
{{`{{if contains "cat" "catch"}}yes{{else}}no{{end}}`}}: {{if contains "cat" "catch"}}yes{{else}}no{{end}}
{{`{{1 | plural "one anchovy" "many anchovies"}}`}}: {{1 | plural "one anchovy" "many anchovies"}}
{{`{{2 | plural "one anchovy" "many anchovies"}}`}}: {{2 | plural "one anchovy" "many anchovies"}}
{{`{{3 | plural "one anchovy" "many anchovies"}}`}}: {{3 | plural "one anchovy" "many anchovies"}}
# TODO: more sprig examples
# TODO: all built-in examples

View File

@@ -0,0 +1,25 @@
syntax = "proto3";
package dummy;
option go_package = "moul.io/protoc-gen-gotemplate/examples/helpers";
message Dummy1 {
float aaa = 1;
string bbb = 2;
int32 ccc = 3;
int64 ddd = 4;
repeated string eee = 5;
}
message Dummy2 {
float fff = 1;
Dummy1 ggg = 2;
}
message Dummy3 {}
service DummyService {
rpc Hhh(Dummy1) returns (Dummy2) {}
rpc Iii(Dummy2) returns (Dummy1) {}
}

View File

@@ -3,7 +3,7 @@ build:
mkdir -p output mkdir -p output
# generate pb.go inluding imported proto # generate pb.go inluding imported proto
protoc --go_out=Mproto/common.proto=github.com/moul/protoc-gen-gotemplate/examples/import/output/models/common:./output proto/article.proto protoc --go_out=Mproto/common.proto=moul.io/protoc-gen-gotemplate/examples/import/output/models/common:./output proto/article.proto
protoc --go_out=,plugins=grpc:./output proto/common.proto protoc --go_out=,plugins=grpc:./output proto/common.proto
# build our go file based on our template # build our go file based on our template

View File

@@ -1,113 +1,374 @@
// Code generated by protoc-gen-go. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.25.0
// protoc v3.12.3
// source: proto/article.proto // source: proto/article.proto
// DO NOT EDIT!
/*
Package article is a generated protocol buffer package.
It is generated from these files:
proto/article.proto
It has these top-level messages:
GetArticleRequest
GetArticleResponse
Article
*/
package article package article
import proto "github.com/golang/protobuf/proto" import (
import fmt "fmt" proto "github.com/golang/protobuf/proto"
import math "math" protoreflect "google.golang.org/protobuf/reflect/protoreflect"
import common "github.com/moul/protoc-gen-gotemplate/examples/import/output/models/common" protoimpl "google.golang.org/protobuf/runtime/protoimpl"
common "moul.io/protoc-gen-gotemplate/examples/import/output/models/common"
reflect "reflect"
sync "sync"
)
// Reference imports to suppress errors if they are not otherwise used. const (
var _ = proto.Marshal // Verify that this generated code is sufficiently up-to-date.
var _ = fmt.Errorf _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
var _ = math.Inf // Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// This is a compile-time assertion to ensure that this generated file // This is a compile-time assertion that a sufficiently up-to-date version
// is compatible with the proto package it is being compiled against. // of the legacy proto package is being used.
// A compilation error at this line likely means your copy of the const _ = proto.ProtoPackageIsVersion4
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type GetArticleRequest struct { type GetArticleRequest struct {
Getarticle *common.GetArticle `protobuf:"bytes,1,opt,name=getarticle" json:"getarticle,omitempty"` state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Getarticle *common.GetArticle `protobuf:"bytes,1,opt,name=getarticle,proto3" json:"getarticle,omitempty"`
} }
func (m *GetArticleRequest) Reset() { *m = GetArticleRequest{} } func (x *GetArticleRequest) Reset() {
func (m *GetArticleRequest) String() string { return proto.CompactTextString(m) } *x = GetArticleRequest{}
func (*GetArticleRequest) ProtoMessage() {} if protoimpl.UnsafeEnabled {
func (*GetArticleRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } mi := &file_proto_article_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (m *GetArticleRequest) GetGetarticle() *common.GetArticle { func (x *GetArticleRequest) String() string {
if m != nil { return protoimpl.X.MessageStringOf(x)
return m.Getarticle }
func (*GetArticleRequest) ProtoMessage() {}
func (x *GetArticleRequest) ProtoReflect() protoreflect.Message {
mi := &file_proto_article_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetArticleRequest.ProtoReflect.Descriptor instead.
func (*GetArticleRequest) Descriptor() ([]byte, []int) {
return file_proto_article_proto_rawDescGZIP(), []int{0}
}
func (x *GetArticleRequest) GetGetarticle() *common.GetArticle {
if x != nil {
return x.Getarticle
} }
return nil return nil
} }
type GetArticleResponse struct { type GetArticleResponse struct {
Article *Article `protobuf:"bytes,1,opt,name=article" json:"article,omitempty"` state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Article *Article `protobuf:"bytes,1,opt,name=article,proto3" json:"article,omitempty"`
// The generated output should write []*GetArticleResponse_Storage.Storage for this field.
Storages []*GetArticleResponse_Storage `protobuf:"bytes,2,rep,name=storages,proto3" json:"storages,omitempty"`
} }
func (m *GetArticleResponse) Reset() { *m = GetArticleResponse{} } func (x *GetArticleResponse) Reset() {
func (m *GetArticleResponse) String() string { return proto.CompactTextString(m) } *x = GetArticleResponse{}
func (*GetArticleResponse) ProtoMessage() {} if protoimpl.UnsafeEnabled {
func (*GetArticleResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } mi := &file_proto_article_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (m *GetArticleResponse) GetArticle() *Article { func (x *GetArticleResponse) String() string {
if m != nil { return protoimpl.X.MessageStringOf(x)
return m.Article }
func (*GetArticleResponse) ProtoMessage() {}
func (x *GetArticleResponse) ProtoReflect() protoreflect.Message {
mi := &file_proto_article_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetArticleResponse.ProtoReflect.Descriptor instead.
func (*GetArticleResponse) Descriptor() ([]byte, []int) {
return file_proto_article_proto_rawDescGZIP(), []int{1}
}
func (x *GetArticleResponse) GetArticle() *Article {
if x != nil {
return x.Article
}
return nil
}
func (x *GetArticleResponse) GetStorages() []*GetArticleResponse_Storage {
if x != nil {
return x.Storages
} }
return nil return nil
} }
type Article struct { type Article struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` state protoimpl.MessageState
Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
} }
func (m *Article) Reset() { *m = Article{} } func (x *Article) Reset() {
func (m *Article) String() string { return proto.CompactTextString(m) } *x = Article{}
func (*Article) ProtoMessage() {} if protoimpl.UnsafeEnabled {
func (*Article) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } mi := &file_proto_article_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (m *Article) GetId() string { func (x *Article) String() string {
if m != nil { return protoimpl.X.MessageStringOf(x)
return m.Id }
func (*Article) ProtoMessage() {}
func (x *Article) ProtoReflect() protoreflect.Message {
mi := &file_proto_article_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Article.ProtoReflect.Descriptor instead.
func (*Article) Descriptor() ([]byte, []int) {
return file_proto_article_proto_rawDescGZIP(), []int{2}
}
func (x *Article) GetId() string {
if x != nil {
return x.Id
} }
return "" return ""
} }
func (m *Article) GetName() string { func (x *Article) GetName() string {
if m != nil { if x != nil {
return m.Name return x.Name
} }
return "" return ""
} }
func init() { type GetArticleResponse_Storage struct {
proto.RegisterType((*GetArticleRequest)(nil), "article.GetArticleRequest") state protoimpl.MessageState
proto.RegisterType((*GetArticleResponse)(nil), "article.GetArticleResponse") sizeCache protoimpl.SizeCache
proto.RegisterType((*Article)(nil), "article.Article") unknownFields protoimpl.UnknownFields
Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"`
} }
func init() { proto.RegisterFile("proto/article.proto", fileDescriptor0) } func (x *GetArticleResponse_Storage) Reset() {
*x = GetArticleResponse_Storage{}
var fileDescriptor0 = []byte{ if protoimpl.UnsafeEnabled {
// 208 bytes of a gzipped FileDescriptorProto mi := &file_proto_article_proto_msgTypes[3]
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2e, 0x28, 0xca, 0x2f, ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
0xc9, 0xd7, 0x4f, 0x2c, 0x2a, 0xc9, 0x4c, 0xce, 0x49, 0xd5, 0x03, 0xf3, 0x84, 0xd8, 0xa1, 0x5c, ms.StoreMessageInfo(mi)
0x29, 0x21, 0x88, 0x6c, 0x72, 0x7e, 0x6e, 0x6e, 0x7e, 0x1e, 0x44, 0x52, 0xc9, 0x9d, 0x4b, 0xd0, }
0x3d, 0xb5, 0xc4, 0x11, 0xa2, 0x22, 0x28, 0xb5, 0xb0, 0x34, 0xb5, 0xb8, 0x44, 0xc8, 0x88, 0x8b, }
0x2b, 0x3d, 0xb5, 0x04, 0xaa, 0x4d, 0x82, 0x51, 0x81, 0x51, 0x83, 0xdb, 0x48, 0x48, 0x0f, 0xaa,
0x0f, 0x49, 0x39, 0x92, 0x2a, 0x25, 0x07, 0x2e, 0x21, 0x64, 0x83, 0x8a, 0x0b, 0xf2, 0xf3, 0x8a, func (x *GetArticleResponse_Storage) String() string {
0x53, 0x85, 0xb4, 0xb8, 0xd8, 0x51, 0x8d, 0x11, 0xd0, 0x83, 0x39, 0x0e, 0xa6, 0x14, 0xa6, 0x40, return protoimpl.X.MessageStringOf(x)
0x49, 0x97, 0x8b, 0x1d, 0x2a, 0x26, 0xc4, 0xc7, 0xc5, 0x94, 0x99, 0x02, 0xd6, 0xc1, 0x19, 0xc4, }
0x94, 0x99, 0x22, 0x24, 0xc4, 0xc5, 0x92, 0x97, 0x98, 0x9b, 0x2a, 0xc1, 0x04, 0x16, 0x01, 0xb3,
0x8d, 0x42, 0xb9, 0xb8, 0xa0, 0x3a, 0x8b, 0xcb, 0x92, 0x85, 0xdc, 0xb9, 0xb8, 0x10, 0xd6, 0x0b, func (*GetArticleResponse_Storage) ProtoMessage() {}
0x49, 0xc1, 0x6d, 0xc1, 0xf0, 0x9c, 0x94, 0x34, 0x56, 0x39, 0x88, 0x7b, 0x95, 0x18, 0x9c, 0x24,
0xa2, 0xc4, 0x72, 0xf3, 0x53, 0x52, 0x73, 0x8a, 0x61, 0xa1, 0x68, 0x0d, 0xa5, 0x93, 0xd8, 0xc0, func (x *GetArticleResponse_Storage) ProtoReflect() protoreflect.Message {
0x21, 0x66, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x16, 0x18, 0x87, 0xc4, 0x65, 0x01, 0x00, 0x00, mi := &file_proto_article_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use GetArticleResponse_Storage.ProtoReflect.Descriptor instead.
func (*GetArticleResponse_Storage) Descriptor() ([]byte, []int) {
return file_proto_article_proto_rawDescGZIP(), []int{1, 0}
}
func (x *GetArticleResponse_Storage) GetCode() string {
if x != nil {
return x.Code
}
return ""
}
var File_proto_article_proto protoreflect.FileDescriptor
var file_proto_article_proto_rawDesc = []byte{
0x0a, 0x13, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x1a, 0x12,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x22, 0x47, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x0a, 0x67, 0x65, 0x74, 0x61, 0x72,
0x74, 0x69, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x6f,
0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52,
0x0a, 0x67, 0x65, 0x74, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x22, 0xa0, 0x01, 0x0a, 0x12,
0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x41, 0x72,
0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x07, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x3f,
0x0a, 0x08, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x23, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72,
0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x74,
0x6f, 0x72, 0x61, 0x67, 0x65, 0x52, 0x08, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x73, 0x1a,
0x1d, 0x0a, 0x07, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f,
0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x2d,
0x0a, 0x07, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x32, 0x55, 0x0a,
0x0a, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x73, 0x76, 0x63, 0x12, 0x47, 0x0a, 0x0a, 0x47,
0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x12, 0x1a, 0x2e, 0x63, 0x6f, 0x6d, 0x70,
0x61, 0x6e, 0x79, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x2e,
0x47, 0x65, 0x74, 0x41, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x42, 0x18, 0x5a, 0x16, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x73, 0x2f, 0x61,
0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x3b, 0x61, 0x72, 0x74, 0x69, 0x63, 0x6c, 0x65, 0x62, 0x06,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_proto_article_proto_rawDescOnce sync.Once
file_proto_article_proto_rawDescData = file_proto_article_proto_rawDesc
)
func file_proto_article_proto_rawDescGZIP() []byte {
file_proto_article_proto_rawDescOnce.Do(func() {
file_proto_article_proto_rawDescData = protoimpl.X.CompressGZIP(file_proto_article_proto_rawDescData)
})
return file_proto_article_proto_rawDescData
}
var file_proto_article_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_proto_article_proto_goTypes = []interface{}{
(*GetArticleRequest)(nil), // 0: company.GetArticleRequest
(*GetArticleResponse)(nil), // 1: company.GetArticleResponse
(*Article)(nil), // 2: company.Article
(*GetArticleResponse_Storage)(nil), // 3: company.GetArticleResponse.Storage
(*common.GetArticle)(nil), // 4: common.GetArticle
}
var file_proto_article_proto_depIdxs = []int32{
4, // 0: company.GetArticleRequest.getarticle:type_name -> common.GetArticle
2, // 1: company.GetArticleResponse.article:type_name -> company.Article
3, // 2: company.GetArticleResponse.storages:type_name -> company.GetArticleResponse.Storage
0, // 3: company.articlesvc.GetArticle:input_type -> company.GetArticleRequest
1, // 4: company.articlesvc.GetArticle:output_type -> company.GetArticleResponse
4, // [4:5] is the sub-list for method output_type
3, // [3:4] is the sub-list for method input_type
3, // [3:3] is the sub-list for extension type_name
3, // [3:3] is the sub-list for extension extendee
0, // [0:3] is the sub-list for field type_name
}
func init() { file_proto_article_proto_init() }
func file_proto_article_proto_init() {
if File_proto_article_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_proto_article_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetArticleRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_article_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetArticleResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_article_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Article); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_proto_article_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*GetArticleResponse_Storage); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_proto_article_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_proto_article_proto_goTypes,
DependencyIndexes: file_proto_article_proto_depIdxs,
MessageInfos: file_proto_article_proto_msgTypes,
}.Build()
File_proto_article_proto = out.File
file_proto_article_proto_rawDesc = nil
file_proto_article_proto_goTypes = nil
file_proto_article_proto_depIdxs = nil
} }

View File

@@ -1,6 +1,5 @@
// Code generated by protoc-gen-go. // Code generated by protoc-gen-go. DO NOT EDIT.
// source: proto/common.proto // source: proto/common.proto
// DO NOT EDIT!
/* /*
Package common is a generated protocol buffer package. Package common is a generated protocol buffer package.

View File

@@ -1,11 +1,26 @@
// Code generated by protoc-gen-gotemplate // Code generated by protoc-gen-gotemplate
package article package company
import ( import (
"github.com/moul/protoc-gen-gotemplate/examples/import/output/models/article" "context"
"github.com/moul/protoc-gen-gotemplate/examples/import/output/models/common"
"moul.io/protoc-gen-gotemplate/examples/import/output/models/article"
"moul.io/protoc-gen-gotemplate/examples/import/output/models/common"
) )
type Repository interface { type Repository interface {
GetArticle(getarticle *common.GetArticle ) (*article.Article, error) GetArticle(getarticle *common.GetArticle) (*company.Article, []*company.Storage, error)
}
// ------------------------- Public SDK -----------------------------
// GetArticle : proto: missing extension proto: missing extension
func (sdk *Sdk) GetArticle(ctx context.Context,
getarticle *article.GetArticle, token, requestID string) (article *article.Article, storages []*article.GetArticleResponse_Storage, err error) {
out := &pb.GetArticleResponse{}
_ = out
return out.Article, out.Storages, nil
} }

View File

@@ -1,13 +1,25 @@
syntax = "proto3"; syntax = "proto3";
package article; package company;
option go_package = "models/article;article"; option go_package = "models/article;article";
import "proto/common.proto"; import "proto/common.proto";
message GetArticleRequest { common.GetArticle getarticle = 1;} message GetArticleRequest {
message GetArticleResponse { Article article = 1;} common.GetArticle getarticle = 1;
}
message GetArticleResponse {
Article article = 1;
message Storage {
string code = 1;
}
// The generated output should write []*GetArticleResponse_Storage.Storage for this field.
repeated Storage storages = 2;
}
message Article{ message Article{
string id = 1; string id = 1;

View File

@@ -1,11 +1,41 @@
// Code generated by protoc-gen-gotemplate // Code generated by protoc-gen-gotemplate
{{- $file := .File}}
package {{.File.Package}} package {{.File.Package}}
import ( import (
"github.com/moul/protoc-gen-gotemplate/examples/import/output/models/article" "moul.io/protoc-gen-gotemplate/examples/import/output/models/article"
"github.com/moul/protoc-gen-gotemplate/examples/import/output/models/common" "moul.io/protoc-gen-gotemplate/examples/import/output/models/common"
) )
type Repository interface { type Repository interface {
{{range $m := .Service.Method}}{{with $t := $m.InputType | getMessageType $.File}} {{$m.Name}}({{range $f := $t.Field}}{{$f.Name|lowerCamelCase}} {{$f| goTypeWithPackage }} {{end}}) ({{with $out := $m.OutputType | getMessageType $.File}}{{range $f := $out.Field}}{{$f | goTypeWithPackage}}, {{end}}{{end}} error){{end}}{{end}} {{range $m := .Service.Method}}{{with $t := $m.InputType | getMessageType $.File}} {{$m.Name}}({{range $f := $t.Field}}{{$f.Name|lowerCamelCase}} {{$f| goTypeWithPackage }} {{end}}) ({{with $out := $m.OutputType | getMessageType $.File}}{{range $f := $out.Field}}{{$f | goTypeWithPackage}}, {{end}}{{end}} error){{end}}{{end}}
} }
// ------------------------- Public SDK -----------------------------
{{$pkg := "pb"}}
{{range $m := .Service.Method}}
{{with $t := $m.InputType | getMessageType $.File}}
{{if and (not $m.ServerStreaming) (not $m.ClientStreaming)}}
{{/* ----------------------------- nominal case ---------------------------- */}}
// {{$m.Name}} : {{$m | httpVerb}} {{$m | httpPath}}
func (sdk *Sdk) {{$m.Name}}(ctx context.Context, {{if $t.OneofDecl}} req *{{$pkg}}.{{$m.Name}}Request,{{else}}{{range $f := $t.Field}}
{{$f.Name|lowerCamelCase}} {{$f| goTypeWithGoPackage $.File}},{{end}}{{end}} token, requestID string)({{with $out := $m.OutputType | getMessageType $.File}}{{range $f := $out.Field}}{{$f.Name|lowerCamelCase}} {{$f | goTypeWithGoPackage $.File}}, {{end}}{{end}}err error) {
out := &{{$pkg}}.{{$m.Name}}Response{}
_ = out
{{with $out := $m.OutputType | getMessageType $.File}}
return {{range $f := $out.Field}}out.{{$f.Name|camelCase}}, {{end}}nil
{{end}} {{/* with */}}
}
{{end}} {{/* streaming ifs */}}
{{end}}{{end}} {{/* range with */}}

View File

@@ -9,7 +9,7 @@ build:
protoc -I./proto --go_out=plugins=grpc:output proto/aaa/aaa.proto protoc -I./proto --go_out=plugins=grpc:output proto/aaa/aaa.proto
protoc -I./proto --go_out=plugins=grpc:output proto/bbb/bbb.proto protoc -I./proto --go_out=plugins=grpc:output proto/bbb/bbb.proto
@rm -rf output/aaa output/bbb @rm -rf output/aaa output/bbb
@mv output/github.com/moul/protoc-gen-gotemplate/examples/single-package-mode/output/* output/ @mv output/moul.io/protoc-gen-gotemplate/examples/single-package-mode/output/* output/
@rm -rf output/github.com @rm -rf output/github.com
@# protoc-gen-gotemplate @# protoc-gen-gotemplate

View File

@@ -17,7 +17,7 @@ package bbb
import proto "github.com/golang/protobuf/proto" import proto "github.com/golang/protobuf/proto"
import fmt "fmt" import fmt "fmt"
import math "math" import math "math"
import the_aaa_package "github.com/moul/protoc-gen-gotemplate/examples/single-package-mode/output/aaa" import the_aaa_package "moul.io/protoc-gen-gotemplate/examples/single-package-mode/output/aaa"
import ( import (
context "golang.org/x/net/context" context "golang.org/x/net/context"

View File

@@ -4,8 +4,8 @@ package bbb
import ( import (
"fmt" "fmt"
"github.com/moul/protoc-gen-gotemplate/examples/single-package-mode/output/aaa"
"golang.org/x/net/context" "golang.org/x/net/context"
"moul.io/protoc-gen-gotemplate/examples/single-package-mode/output/aaa"
) )
type Service struct{} type Service struct{}

View File

@@ -1,6 +1,6 @@
syntax = "proto3"; syntax = "proto3";
option go_package = "github.com/moul/protoc-gen-gotemplate/examples/single-package-mode/output/aaa"; option go_package = "moul.io/protoc-gen-gotemplate/examples/single-package-mode/output/aaa";
package the.aaa.package; package the.aaa.package;

View File

@@ -2,7 +2,7 @@ syntax = "proto3";
package the.bbb.package; package the.bbb.package;
option go_package = "github.com/moul/protoc-gen-gotemplate/examples/single-package-mode/output/bbb"; option go_package = "moul.io/protoc-gen-gotemplate/examples/single-package-mode/output/bbb";
import "aaa/aaa.proto"; import "aaa/aaa.proto";

View File

@@ -4,18 +4,18 @@
<loc>/posts</loc> <loc>/posts</loc>
<priority>0.5</priority> <priority>0.5</priority>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<lastmod>2017-03-31</lastmod> <lastmod>2017-05-19</lastmod>
</url> </url>
<url> <url>
<loc>/authors</loc> <loc>/authors</loc>
<priority>0.5</priority> <priority>0.5</priority>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<lastmod>2017-03-31</lastmod> <lastmod>2017-05-19</lastmod>
</url> </url>
<url> <url>
<loc>/comments</loc> <loc>/comments</loc>
<priority>0.5</priority> <priority>0.5</priority>
<changefreq>monthly</changefreq> <changefreq>monthly</changefreq>
<lastmod>2017-03-31</lastmod> <lastmod>2017-05-19</lastmod>
</url> </url>
</urlset> </urlset>

13
examples/time/Makefile Normal file
View File

@@ -0,0 +1,13 @@
.PHONY: build
build:
mkdir -p output
protoc -I. --gotemplate_out=template_dir=templates,debug=true:output proto/*.proto
.PHONY: re
re: clean build
.PHONY: clean
clean:
rm -rf output

View File

@@ -0,0 +1,10 @@
// Code generated by protoc-gen-gotemplate
package foo
import (
"github.com/golang/protobuf/ptypes/timestamp"
)
type Repository interface {
GetFoo(timestamp *timestamp.Timestamp ) (string, error)
}

View File

@@ -0,0 +1,12 @@
syntax = "proto3";
package foo;
import "google/protobuf/timestamp.proto";
message GetFooRequest { google.protobuf.Timestamp timestamp = 1;}
message GetFooResponse { string result = 1;}
service foosvc {
rpc GetFoo (GetFooRequest) returns (GetFooResponse){}
}

View File

@@ -0,0 +1,10 @@
// Code generated by protoc-gen-gotemplate
package {{.File.Package}}
import (
"github.com/golang/protobuf/ptypes/timestamp"
)
type Repository interface {
{{range $m := .Service.Method}}{{with $t := $m.InputType | getMessageType $.File}} {{$m.Name}}({{range $f := $t.Field}}{{$f.Name|lowerCamelCase}} {{$f| goTypeWithPackage }} {{end}}) ({{with $out := $m.OutputType | getMessageType $.File}}{{range $f := $out.Field}}{{$f | goTypeWithPackage}}, {{end}}{{end}} error){{end}}{{end}}
}

89
glide.lock generated
View File

@@ -1,89 +0,0 @@
hash: 1944ae13e983e8da7b26c697fc40d79d34326b8c7f56c8939fb16f1ff8caca5b
updated: 2017-05-18T19:20:01.855895064+02:00
imports:
- name: github.com/aokoli/goutils
version: e57d01ace047c1a43e6a49ecf3ecc50ed2be81d1
- name: github.com/dgrijalva/jwt-go
version: c9eaceb2896dbb515dae7ec352b377a226a52721
- name: github.com/go-kit/kit
version: 9f5c614cd1e70102f80b644edbc760805ebf16d5
subpackages:
- auth/jwt
- endpoint
- log
- transport/grpc
- transport/http
- name: github.com/go-logfmt/logfmt
version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5
- name: github.com/go-stack/stack
version: 7a2f19628aabfe68f0766b59e74d6315f8347d22
- name: github.com/golang/glog
version: 23def4e6c14b4da8ac2ed8007337bc5eb5007998
- name: github.com/golang/protobuf
version: 8ee79997227bf9b34611aee7946ae64735e6fd93
subpackages:
- proto
- protoc-gen-go/descriptor
- protoc-gen-go/generator
- protoc-gen-go/plugin
- name: github.com/gorilla/handlers
version: e1b2144f2167de0e1042d1d35e5cba5119d4fb5d
- name: github.com/grpc-ecosystem/grpc-gateway
version: 589b126116b5fc961939b3e156c29e4d9d58222f
subpackages:
- protoc-gen-grpc-gateway/descriptor
- protoc-gen-grpc-gateway/httprule
- utilities
- name: github.com/huandu/xstrings
version: 3959339b333561bf62a38b424fd41517c2c90f40
- name: github.com/imdario/mergo
version: 3e95a51e0639b4cf372f2ccf74c86749d747fbdc
- name: github.com/kr/fs
version: 2788f0dbd16903de03cb8186e5c7d97b69ad387b
- name: github.com/kr/logfmt
version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0
- name: github.com/Masterminds/semver
version: 59c29afe1a994eacb71c833025ca7acf874bb1da
- name: github.com/Masterminds/sprig
version: 2f4371ac162f912989f01cc2b6af4ba6660e6a30
- name: github.com/satori/go.uuid
version: 879c5887cd475cd7864858769793b2ceb0d44feb
- name: golang.org/x/crypto
version: 0fe963104e9d1877082f8fb38f816fcd97eb1d10
subpackages:
- pbkdf2
- scrypt
- name: golang.org/x/net
version: da2b4fa28524a3baf148c1b94df4440267063c88
subpackages:
- context
- context/ctxhttp
- http2
- http2/hpack
- idna
- internal/timeseries
- lex/httplex
- trace
- name: golang.org/x/text
version: a49bea13b776691cb1b49873e5d8df96ec74831a
subpackages:
- secure/bidirule
- transform
- unicode/bidi
- unicode/norm
- name: google.golang.org/genproto
version: bb3573be0c484136831138976d444b8754777aff
subpackages:
- googleapis/api/annotations
- name: google.golang.org/grpc
version: 777daa17ff9b5daef1cfdf915088a2ada3332bf0
subpackages:
- codes
- credentials
- grpclog
- internal
- metadata
- naming
- peer
- transport
testImports: []

View File

@@ -1,16 +0,0 @@
package: github.com/moul/protoc-gen-gotemplate
import:
- package: github.com/golang/protobuf
subpackages:
- proto
- protoc-gen-go/descriptor
- protoc-gen-go/generator
- protoc-gen-go/plugin
- package: github.com/kr/fs
- package: github.com/Masterminds/sprig
- package: github.com/huandu/xstrings
- package: google.golang.org/genproto
subpackages:
- googleapis/api/annotations
- package: github.com/grpc-ecosystem/grpc-gateway
version: 1.2.2

22
go.mod generated Normal file
View File

@@ -0,0 +1,22 @@
module moul.io/protoc-gen-gotemplate
require (
github.com/Masterminds/goutils v1.1.0 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible
github.com/gobuffalo/packr/v2 v2.8.0
github.com/golang/protobuf v1.3.2
github.com/google/uuid v1.1.1 // indirect
github.com/gorilla/handlers v1.4.2
github.com/gorilla/mux v1.7.3
github.com/grpc-ecosystem/grpc-gateway v1.12.1
github.com/huandu/xstrings v1.3.0
github.com/imdario/mergo v0.3.8 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/reflectwalk v1.0.1 // indirect
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d // indirect
google.golang.org/genproto v0.0.0-20200113173426-e1de0a7b01eb
gopkg.in/yaml.v2 v2.2.7 // indirect
)
go 1.13

227
go.sum generated Normal file
View File

@@ -0,0 +1,227 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gqc=
github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=
github.com/gobuffalo/packd v1.0.0 h1:6ERZvJHfe24rfFmA9OaoKBdC7+c9sydrytMg8SdFGBM=
github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI=
github.com/gobuffalo/packr/v2 v2.8.0 h1:IULGd15bQL59ijXLxEvA5wlMxsmx/ZkQv9T282zNVIY=
github.com/gobuffalo/packr/v2 v2.8.0/go.mod h1:PDk2k3vGevNE3SwVyVRgQCCXETC9SaONCNSXT1Q8M1g=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/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/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/handlers v1.4.2 h1:0QniY0USkHQ1RGCLfKxeNHK9bkDHGRYGNDFBCS+YARg=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.12.1 h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4=
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/huandu/xstrings v1.3.0 h1:gvV6jG9dTgFEncxo+AF7PH6MZXi/vZl25owA/8Dg8Wo=
github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karrick/godirwalk v1.15.3 h1:0a2pXOgtB16CqIqXTiT7+K9L73f74n/aNQUnH6Ortew=
github.com/karrick/godirwalk v1.15.3/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=
github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=
github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.5.2 h1:qLvObTrvO/XRCqmkKxUlOBc48bI3efyDuAZe25QiF0w=
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d h1:2+ZP7EfsZV7Vvmx3TIqSlSzATMkTAKqM14YGFPoSKjI=
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20200113173426-e1de0a7b01eb h1:EsMpWw4S8DM2QYm5idfmmWsv2N57GWi2tx3p96Gpja4=
google.golang.org/genproto v0.0.0-20200113173426-e1de0a7b01eb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View File

@@ -1,343 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"regexp"
"strings"
"text/template"
"github.com/Masterminds/sprig"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/descriptor"
ggdescriptor "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
"github.com/huandu/xstrings"
options "google.golang.org/genproto/googleapis/api/annotations"
)
var jsReservedRe *regexp.Regexp = regexp.MustCompile(`(^|[^A-Za-z])(do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)($|[^A-Za-z])`)
var ProtoHelpersFuncMap = template.FuncMap{
"string": func(i interface {
String() string
}) string {
return i.String()
},
"json": func(v interface{}) string {
a, _ := json.Marshal(v)
return string(a)
},
"prettyjson": func(v interface{}) string {
a, _ := json.MarshalIndent(v, "", " ")
return string(a)
},
"splitArray": func(sep string, s string) []string {
return strings.Split(s, sep)
},
"first": func(a []string) string {
return a[0]
},
"last": func(a []string) string {
return a[len(a)-1]
},
"upperFirst": func(s string) string {
return strings.ToUpper(s[:1]) + s[1:]
},
"lowerFirst": func(s string) string {
return strings.ToLower(s[:1]) + s[1:]
},
"camelCase": func(s string) string {
if len(s) > 1 {
return xstrings.ToCamelCase(s)
}
return strings.ToUpper(s[:1])
},
"lowerCamelCase": func(s string) string {
if len(s) > 1 {
s = xstrings.ToCamelCase(s)
}
return strings.ToLower(s[:1]) + s[1:]
},
"kebabCase": func(s string) string {
return strings.Replace(xstrings.ToSnakeCase(s), "_", "-", -1)
},
"snakeCase": xstrings.ToSnakeCase,
"getProtoFile": getProtoFile,
"getMessageType": getMessageType,
"getEnumValue": getEnumValue,
"isFieldMessage": isFieldMessage,
"isFieldRepeated": isFieldRepeated,
"goType": goType,
"goTypeWithPackage": goTypeWithPackage,
"jsType": jsType,
"jsSuffixReserved": jsSuffixReservedKeyword,
"namespacedFlowType": namespacedFlowType,
"httpVerb": httpVerb,
"httpPath": httpPath,
"shortType": shortType,
"urlHasVarsFromMessage": urlHasVarsFromMessage,
}
func init() {
for k, v := range sprig.TxtFuncMap() {
ProtoHelpersFuncMap[k] = v
}
}
func getProtoFile(name string) *ggdescriptor.File {
if registry == nil {
return nil
}
file, err := registry.LookupFile(name)
if err != nil {
panic(err)
}
return file
}
func getMessageType(f *descriptor.FileDescriptorProto, name string) *ggdescriptor.Message {
if registry != nil {
msg, err := registry.LookupMsg(".", name)
if err != nil {
panic(err)
}
return msg
}
// name is in the form .packageName.MessageTypeName.InnerMessageTypeName...
// e.g. .article.ProductTag
splits := strings.Split(name, ".")
target := splits[len(splits)-1]
for _, m := range f.MessageType {
if target == *m.Name {
return &ggdescriptor.Message{
DescriptorProto: m,
}
}
}
return nil
}
func getEnumValue(f []*descriptor.EnumDescriptorProto, name string) []*descriptor.EnumValueDescriptorProto {
for _, item := range f {
if strings.EqualFold(*item.Name, name) {
return item.GetValue()
}
}
return nil
}
func isFieldMessage(f *descriptor.FieldDescriptorProto) bool {
if f.Type != nil && *f.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE {
return true
}
return false
}
func isFieldRepeated(f *descriptor.FieldDescriptorProto) bool {
if f.Type != nil && f.Label != nil && *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return true
}
return false
}
func goTypeWithPackage(f *descriptor.FieldDescriptorProto) string {
pkg := ""
if *f.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE {
pkg = getPackageTypeName(*f.TypeName)
}
return goType(pkg, f)
}
func goType(pkg string, f *descriptor.FieldDescriptorProto) string {
switch *f.Type {
case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[]float64"
}
return "float64"
case descriptor.FieldDescriptorProto_TYPE_FLOAT:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[]float32"
}
return "float32"
case descriptor.FieldDescriptorProto_TYPE_INT64:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[]int64"
}
return "int64"
case descriptor.FieldDescriptorProto_TYPE_UINT64:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[]uint64"
}
return "uint64"
case descriptor.FieldDescriptorProto_TYPE_INT32:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[]uint32"
}
return "uint32"
case descriptor.FieldDescriptorProto_TYPE_BOOL:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[]bool"
}
return "bool"
case descriptor.FieldDescriptorProto_TYPE_STRING:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[]string"
}
return "string"
case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
if pkg != "" {
pkg = pkg + "."
}
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return fmt.Sprintf("[]*%s%s", pkg, shortType(*f.TypeName))
}
return fmt.Sprintf("*%s%s", pkg, shortType(*f.TypeName))
case descriptor.FieldDescriptorProto_TYPE_BYTES:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[]byte"
}
return "byte"
case descriptor.FieldDescriptorProto_TYPE_UINT32:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[]uint32"
}
return "uint32"
case descriptor.FieldDescriptorProto_TYPE_ENUM:
return fmt.Sprintf("*%s.%s", pkg, shortType(*f.TypeName))
default:
return "interface{}"
}
}
func jsType(f *descriptor.FieldDescriptorProto) string {
template := "%s"
if isFieldRepeated(f) == true {
template = "Array<%s>"
}
switch *f.Type {
case descriptor.FieldDescriptorProto_TYPE_MESSAGE,
descriptor.FieldDescriptorProto_TYPE_ENUM:
return fmt.Sprintf(template, namespacedFlowType(*f.TypeName))
case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
descriptor.FieldDescriptorProto_TYPE_FLOAT,
descriptor.FieldDescriptorProto_TYPE_INT64,
descriptor.FieldDescriptorProto_TYPE_UINT64,
descriptor.FieldDescriptorProto_TYPE_INT32,
descriptor.FieldDescriptorProto_TYPE_FIXED64,
descriptor.FieldDescriptorProto_TYPE_FIXED32,
descriptor.FieldDescriptorProto_TYPE_UINT32,
descriptor.FieldDescriptorProto_TYPE_SFIXED32,
descriptor.FieldDescriptorProto_TYPE_SFIXED64,
descriptor.FieldDescriptorProto_TYPE_SINT32,
descriptor.FieldDescriptorProto_TYPE_SINT64:
return fmt.Sprintf(template, "number")
case descriptor.FieldDescriptorProto_TYPE_BOOL:
return fmt.Sprintf(template, "boolean")
case descriptor.FieldDescriptorProto_TYPE_BYTES:
return fmt.Sprintf(template, "Uint8Array")
case descriptor.FieldDescriptorProto_TYPE_STRING:
return fmt.Sprintf(template, "string")
default:
return fmt.Sprintf(template, "any")
}
}
func jsSuffixReservedKeyword(s string) string {
return jsReservedRe.ReplaceAllString(s, "${1}${2}_${3}")
}
func getPackageTypeName(s string) string {
if strings.Contains(s, ".") {
return strings.Split(s, ".")[1]
}
return ""
}
func shortType(s string) string {
t := strings.Split(s, ".")
return t[len(t)-1]
}
func namespacedFlowType(s string) string {
trimmed := strings.TrimLeft(s, ".")
splitted := strings.Split(trimmed, ".")
return strings.Join(splitted, "$")
}
func httpPath(m *descriptor.MethodDescriptorProto) string {
ext, err := proto.GetExtension(m.Options, options.E_Http)
if err != nil {
return err.Error()
}
opts, ok := ext.(*options.HttpRule)
if !ok {
return fmt.Sprintf("extension is %T; want an HttpRule", ext)
}
switch t := opts.Pattern.(type) {
default:
return ""
case *options.HttpRule_Get:
return t.Get
case *options.HttpRule_Post:
return t.Post
case *options.HttpRule_Put:
return t.Put
case *options.HttpRule_Delete:
return t.Delete
case *options.HttpRule_Patch:
return t.Patch
case *options.HttpRule_Custom:
return t.Custom.Path
}
}
func httpVerb(m *descriptor.MethodDescriptorProto) string {
ext, err := proto.GetExtension(m.Options, options.E_Http)
if err != nil {
return err.Error()
}
opts, ok := ext.(*options.HttpRule)
if !ok {
return fmt.Sprintf("extension is %T; want an HttpRule", ext)
}
switch t := opts.Pattern.(type) {
default:
return ""
case *options.HttpRule_Get:
return "GET"
case *options.HttpRule_Post:
return "POST"
case *options.HttpRule_Put:
return "PUT"
case *options.HttpRule_Delete:
return "DELETE"
case *options.HttpRule_Patch:
return "PATCH"
case *options.HttpRule_Custom:
return t.Custom.Kind
}
}
func urlHasVarsFromMessage(path string, d *descriptor.DescriptorProto) bool {
for _, field := range d.Field {
if !isFieldMessage(field) {
if strings.Contains(path, fmt.Sprintf("{%s}", *field.Name)) {
return true
}
}
}
return false
}

1327
helpers/helpers.go Normal file

File diff suppressed because it is too large Load Diff

55
main.go
View File

@@ -1,4 +1,4 @@
package main package main // import "moul.io/protoc-gen-gotemplate"
import ( import (
"io/ioutil" "io/ioutil"
@@ -8,14 +8,21 @@ import (
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/generator" "github.com/golang/protobuf/protoc-gen-go/generator"
"github.com/golang/protobuf/protoc-gen-go/plugin" plugin_go "github.com/golang/protobuf/protoc-gen-go/plugin"
ggdescriptor "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor" ggdescriptor "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
pgghelpers "moul.io/protoc-gen-gotemplate/helpers"
) )
var ( var (
registry *ggdescriptor.Registry // some helpers need access to registry registry *ggdescriptor.Registry // some helpers need access to registry
) )
const (
boolTrue = "true"
boolFalse = "false"
)
func main() { func main() {
g := generator.New() g := generator.New()
@@ -24,7 +31,7 @@ func main() {
g.Error(err, "reading input") g.Error(err, "reading input")
} }
if err := proto.Unmarshal(data, g.Request); err != nil { if err = proto.Unmarshal(data, g.Request); err != nil {
g.Error(err, "parsing input proto") g.Error(err, "parsing input proto")
} }
@@ -41,6 +48,7 @@ func main() {
debug = false debug = false
all = false all = false
singlePackageMode = false singlePackageMode = false
fileMode = false
) )
if parameter := g.Request.GetParameter(); parameter != "" { if parameter := g.Request.GetParameter(); parameter != "" {
for _, param := range strings.Split(parameter, ",") { for _, param := range strings.Split(parameter, ",") {
@@ -52,37 +60,40 @@ func main() {
switch parts[0] { switch parts[0] {
case "template_dir": case "template_dir":
templateDir = parts[1] templateDir = parts[1]
break
case "destination_dir": case "destination_dir":
destinationDir = parts[1] destinationDir = parts[1]
break
case "single-package-mode": case "single-package-mode":
switch strings.ToLower(parts[1]) { switch strings.ToLower(parts[1]) {
case "true", "t": case boolTrue, "t":
singlePackageMode = true singlePackageMode = true
case "false", "f": case boolFalse, "f":
default: default:
log.Printf("Err: invalid value for single-package-mode: %q", parts[1]) log.Printf("Err: invalid value for single-package-mode: %q", parts[1])
} }
break
case "debug": case "debug":
switch strings.ToLower(parts[1]) { switch strings.ToLower(parts[1]) {
case "true", "t": case boolTrue, "t":
debug = true debug = true
case "false", "f": case boolFalse, "f":
default: default:
log.Printf("Err: invalid value for debug: %q", parts[1]) log.Printf("Err: invalid value for debug: %q", parts[1])
} }
break
case "all": case "all":
switch strings.ToLower(parts[1]) { switch strings.ToLower(parts[1]) {
case "true", "t": case boolTrue, "t":
all = true all = true
case "false", "f": case boolFalse, "f":
default: default:
log.Printf("Err: invalid value for debug: %q", parts[1]) log.Printf("Err: invalid value for debug: %q", parts[1])
} }
break case "file-mode":
switch strings.ToLower(parts[1]) {
case boolTrue, "t":
fileMode = true
case boolFalse, "f":
default:
log.Printf("Err: invalid value for file-mode: %q", parts[1])
}
default: default:
log.Printf("Err: unknown parameter: %q", param) log.Printf("Err: unknown parameter: %q", param)
} }
@@ -101,7 +112,8 @@ func main() {
if singlePackageMode { if singlePackageMode {
registry = ggdescriptor.NewRegistry() registry = ggdescriptor.NewRegistry()
if err := registry.Load(g.Request); err != nil { pgghelpers.SetRegistry(registry)
if err = registry.Load(g.Request); err != nil {
g.Error(err, "registry: failed to load the request") g.Error(err, "registry: failed to load the request")
} }
} }
@@ -110,7 +122,7 @@ func main() {
for _, file := range g.Request.GetProtoFile() { for _, file := range g.Request.GetProtoFile() {
if all { if all {
if singlePackageMode { if singlePackageMode {
if _, err := registry.LookupFile(file.GetName()); err != nil { if _, err = registry.LookupFile(file.GetName()); err != nil {
g.Error(err, "registry: failed to lookup file %q", file.GetName()) g.Error(err, "registry: failed to lookup file %q", file.GetName())
} }
} }
@@ -122,6 +134,17 @@ func main() {
continue continue
} }
if fileMode {
if s := file.GetService(); s != nil && len(s) > 0 {
encoder := NewGenericTemplateBasedEncoder(templateDir, file, debug, destinationDir)
for _, tmpl := range encoder.Files() {
concatOrAppend(tmpl)
}
}
continue
}
for _, service := range file.GetService() { for _, service := range file.GetService() {
encoder := NewGenericServiceTemplateBasedEncoder(templateDir, service, file, debug, destinationDir) encoder := NewGenericServiceTemplateBasedEncoder(templateDir, service, file, debug, destinationDir)
for _, tmpl := range encoder.Files() { for _, tmpl := range encoder.Files() {

321
rules.mk vendored Normal file
View File

@@ -0,0 +1,321 @@
# +--------------------------------------------------------------+
# | * * * moul.io/rules.mk |
# +--------------------------------------------------------------+
# | |
# | ++ ______________________________________ |
# | ++++ / \ |
# | ++++ | | |
# | ++++++++++ | https://moul.io/rules.mk is a set | |
# | +++ | | of common Makefile rules that can | |
# | ++ | | be configured from the Makefile | |
# | + -== ==| | or with environment variables. | |
# | ( <*> <*> | | |
# | | | /| Manfred Touron | |
# | | _) / | manfred.life | |
# | | +++ / \______________________________________/ |
# | \ =+ / |
# | \ + |
# | |\++++++ |
# | | ++++ ||// |
# | ___| |___ _||/__ __|
# | / --- \ \| ||| __ _ ___ __ __/ /|
# |/ | | \ \ / / ' \/ _ \/ // / / |
# || | | | | | /_/_/_/\___/\_,_/_/ |
# +--------------------------------------------------------------+
all: help
##
## Common helpers
##
rwildcard = $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
check-program = $(foreach exec,$(1),$(if $(shell PATH="$(PATH)" which $(exec)),,$(error "No $(exec) in PATH")))
##
## rules.mk
##
ifneq ($(wildcard rules.mk),)
.PHONY: rulesmk.bumpdeps
rulesmk.bumpdeps:
wget -O rules.mk https://raw.githubusercontent.com/moul/rules.mk/master/rules.mk
BUMPDEPS_STEPS += rulesmk.bumpdeps
endif
##
## Maintainer
##
ifneq ($(wildcard .git/HEAD),)
.PHONY: generate.authors
generate.authors: AUTHORS
AUTHORS: .git/
echo "# This file lists all individuals having contributed content to the repository." > AUTHORS
echo "# For how it is generated, see 'https://github.com/moul/rules.mk'" >> AUTHORS
echo >> AUTHORS
git log --format='%aN <%aE>' | LC_ALL=C.UTF-8 sort -uf >> AUTHORS
GENERATE_STEPS += generate.authors
endif
##
## Golang
##
ifndef GOPKG
ifneq ($(wildcard go.mod),)
GOPKG = $(shell sed '/module/!d;s/^omdule\ //' go.mod)
endif
endif
ifdef GOPKG
GO ?= go
GOPATH ?= $(HOME)/go
GO_INSTALL_OPTS ?=
GO_TEST_OPTS ?= -test.timeout=30s
GOMOD_DIR ?= .
GOCOVERAGE_FILE ?= ./coverage.txt
GOTESTJSON_FILE ?= ./go-test.json
GOBUILDLOG_FILE ?= ./go-build.log
GOINSTALLLOG_FILE ?= ./go-install.log
ifdef GOBINS
.PHONY: go.install
go.install:
ifeq ($(CI),true)
@rm -f /tmp/goinstall.log
@set -e; for dir in $(GOBINS); do ( set -xe; \
cd $$dir; \
$(GO) install -v $(GO_INSTALL_OPTS) .; \
); done 2>&1 | tee $(GOINSTALLLOG_FILE)
else
@set -e; for dir in $(GOBINS); do ( set -xe; \
cd $$dir; \
$(GO) install $(GO_INSTALL_OPTS) .; \
); done
endif
INSTALL_STEPS += go.install
.PHONY: go.release
go.release:
$(call check-program, goreleaser)
goreleaser --snapshot --skip-publish --rm-dist
@echo -n "Do you want to release? [y/N] " && read ans && \
if [ $${ans:-N} = y ]; then set -xe; goreleaser --rm-dist; fi
RELEASE_STEPS += go.release
endif
.PHONY: go.unittest
go.unittest:
ifeq ($(CI),true)
@echo "mode: atomic" > /tmp/gocoverage
@rm -f $(GOTESTJSON_FILE)
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do (set -e; (set -euf pipefail; \
cd $$dir; \
($(GO) test ./... $(GO_TEST_OPTS) -cover -coverprofile=/tmp/profile.out -covermode=atomic -race -json | tee -a $(GOTESTJSON_FILE) 3>&1 1>&2 2>&3 | tee -a $(GOBUILDLOG_FILE); \
); \
if [ -f /tmp/profile.out ]; then \
cat /tmp/profile.out | sed "/mode: atomic/d" >> /tmp/gocoverage; \
rm -f /tmp/profile.out; \
fi)); done
@mv /tmp/gocoverage $(GOCOVERAGE_FILE)
else
@echo "mode: atomic" > /tmp/gocoverage
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do (set -e; (set -xe; \
cd $$dir; \
$(GO) test ./... $(GO_TEST_OPTS) -cover -coverprofile=/tmp/profile.out -covermode=atomic -race); \
if [ -f /tmp/profile.out ]; then \
cat /tmp/profile.out | sed "/mode: atomic/d" >> /tmp/gocoverage; \
rm -f /tmp/profile.out; \
fi); done
@mv /tmp/gocoverage $(GOCOVERAGE_FILE)
endif
.PHONY: go.checkdoc
go.checkdoc:
go doc $(GOMOD_DIR)
.PHONY: go.coverfunc
go.coverfunc: go.unittest
go tool cover -func=$(GOCOVERAGE_FILE) | grep -v .pb.go: | grep -v .pb.gw.go:
.PHONY: go.lint
go.lint:
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do ( set -xe; \
cd $$dir; \
golangci-lint run --verbose ./...; \
); done
.PHONY: go.tidy
go.tidy:
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do ( set -xe; \
cd $$dir; \
$(GO) mod tidy; \
); done
.PHONY: go.build
go.build:
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do ( set -xe; \
cd $$dir; \
$(GO) build ./...; \
); done
.PHONY: go.bump-deps
go.bumpdeps:
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do ( set -xe; \
cd $$dir; \
$(GO) get -u ./...; \
); done
.PHONY: go.bump-deps
go.fmt:
if ! command -v goimports &>/dev/null; then GO111MODULE=off go get golang.org/x/tools/cmd/goimports; fi
@set -e; for dir in `find $(GOMOD_DIR) -type f -name "go.mod" | grep -v /vendor/ | sed 's@/[^/]*$$@@' | sort | uniq`; do ( set -xe; \
cd $$dir; \
goimports -w `go list -f '{{.Dir}}' ./...)` \
); done
BUILD_STEPS += go.build
BUMPDEPS_STEPS += go.bumpdeps
TIDY_STEPS += go.tidy
LINT_STEPS += go.lint
UNITTEST_STEPS += go.unittest
FMT_STEPS += go.fmt
endif
##
## Gitattributes
##
ifneq ($(wildcard .gitattributes),)
.PHONY: _linguist-ignored
_linguist-kept:
@git check-attr linguist-vendored $(shell git check-attr linguist-generated $(shell find . -type f | grep -v .git/) | grep unspecified | cut -d: -f1) | grep unspecified | cut -d: -f1 | sort
.PHONY: _linguist-kept
_linguist-ignored:
@git check-attr linguist-vendored linguist-ignored `find . -not -path './.git/*' -type f` | grep '\ set$$' | cut -d: -f1 | sort -u
endif
##
## Node
##
ifndef NPM_PACKAGES
ifneq ($(wildcard package.json),)
NPM_PACKAGES = .
endif
endif
ifdef NPM_PACKAGES
.PHONY: npm.publish
npm.publish:
@echo -n "Do you want to npm publish? [y/N] " && read ans && \
@if [ $${ans:-N} = y ]; then \
set -e; for dir in $(NPM_PACKAGES); do ( set -xe; \
cd $$dir; \
npm publish --access=public; \
); done; \
fi
RELEASE_STEPS += npm.publish
endif
##
## Docker
##
docker_build = docker build \
--build-arg VCS_REF=`git rev-parse --short HEAD` \
--build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \
--build-arg VERSION=`git describe --tags --always` \
-t "$2" -f "$1" "$(dir $1)"
ifndef DOCKERFILE_PATH
DOCKERFILE_PATH = ./Dockerfile
endif
ifndef DOCKER_IMAGE
ifneq ($(wildcard Dockerfile),)
DOCKER_IMAGE = $(notdir $(PWD))
endif
endif
ifdef DOCKER_IMAGE
ifneq ($(DOCKER_IMAGE),none)
.PHONY: docker.build
docker.build:
$(call check-program, docker)
$(call docker_build,$(DOCKERFILE_PATH),$(DOCKER_IMAGE))
BUILD_STEPS += docker.build
endif
endif
##
## Common
##
TEST_STEPS += $(UNITTEST_STEPS)
TEST_STEPS += $(LINT_STEPS)
TEST_STEPS += $(TIDY_STEPS)
ifneq ($(strip $(TEST_STEPS)),)
.PHONY: test
test: $(PRE_TEST_STEPS) $(TEST_STEPS)
endif
ifdef INSTALL_STEPS
.PHONY: install
install: $(PRE_INSTALL_STEPS) $(INSTALL_STEPS)
endif
ifdef UNITTEST_STEPS
.PHONY: unittest
unittest: $(PRE_UNITTEST_STEPS) $(UNITTEST_STEPS)
endif
ifdef LINT_STEPS
.PHONY: lint
lint: $(PRE_LINT_STEPS) $(FMT_STEPS) $(LINT_STEPS)
endif
ifdef TIDY_STEPS
.PHONY: tidy
tidy: $(PRE_TIDY_STEPS) $(TIDY_STEPS)
endif
ifdef BUILD_STEPS
.PHONY: build
build: $(PRE_BUILD_STEPS) $(BUILD_STEPS)
endif
ifdef RELEASE_STEPS
.PHONY: release
release: $(PRE_RELEASE_STEPS) $(RELEASE_STEPS)
endif
ifdef BUMPDEPS_STEPS
.PHONY: bumpdeps
bumpdeps: $(PRE_BUMDEPS_STEPS) $(BUMPDEPS_STEPS)
endif
ifdef FMT_STEPS
.PHONY: fmt
fmt: $(PRE_FMT_STEPS) $(FMT_STEPS)
endif
ifdef GENERATE_STEPS
.PHONY: generate
generate: $(PRE_GENERATE_STEPS) $(GENERATE_STEPS)
endif
.PHONY: help
help::
@echo "General commands:"
@[ "$(BUILD_STEPS)" != "" ] && echo " build" || true
@[ "$(BUMPDEPS_STEPS)" != "" ] && echo " bumpdeps" || true
@[ "$(FMT_STEPS)" != "" ] && echo " fmt" || true
@[ "$(GENERATE_STEPS)" != "" ] && echo " generate" || true
@[ "$(INSTALL_STEPS)" != "" ] && echo " install" || true
@[ "$(LINT_STEPS)" != "" ] && echo " lint" || true
@[ "$(RELEASE_STEPS)" != "" ] && echo " release" || true
@[ "$(TEST_STEPS)" != "" ] && echo " test" || true
@[ "$(TIDY_STEPS)" != "" ] && echo " tidy" || true
@[ "$(UNITTEST_STEPS)" != "" ] && echo " unittest" || true
@# FIXME: list other commands

View File

@@ -26,7 +26,7 @@
* the good old ./generate.sh bash script * the good old ./generate.sh bash script
* go:generate * go:generate
* make * make
* protobuf + [protoc-gen-gotemplate](https://github.com/moul/protoc-gen-gotemplate) * protobuf + [protoc-gen-gotemplate](https://moul.io/protoc-gen-gotemplate)
--- ---
@@ -69,7 +69,7 @@ package sessionsvc
import ( import (
"fmt" "fmt"
"golang.org/x/net/context" "golang.org/x/net/context"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
) )
type Service struct{} type Service struct{}
@@ -94,8 +94,8 @@ package {{.File.Package}}_httptransport
import ( import (
gokit_endpoint "github.com/go-kit/kit/endpoint" gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http" httptransport "github.com/go-kit/kit/transport/http"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/{{.File.Package}}/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/{{.File.Package}}/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/{{.File.Package}}/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/{{.File.Package}}/gen/pb"
) )
``` ```
@@ -105,8 +105,8 @@ package user_httptransport
import ( import (
gokit_endpoint "github.com/go-kit/kit/endpoint" gokit_endpoint "github.com/go-kit/kit/endpoint"
httptransport "github.com/go-kit/kit/transport/http" httptransport "github.com/go-kit/kit/transport/http"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints" endpoints "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb" pb "moul.io/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
) )
``` ```
@@ -197,7 +197,7 @@ func RegisterHandlers(ctx context.Context, svc pb.UserServiceServer, mux *http.S
# generation usages # generation usages
* go-kit boilerplate (see [examples/go-kit](https://github.com/moul/protoc-gen-gotemplate/tree/master/examples/go-kit)) * go-kit boilerplate (see [examples/go-kit](https://moul.io/protoc-gen-gotemplate/tree/master/examples/go-kit))
* k8s configuration * k8s configuration
* Dockerfile * Dockerfile
* documentation * documentation
@@ -243,5 +243,5 @@ func RegisterHandlers(ctx context.Context, svc pb.UserServiceServer, mux *http.S
# questions? # questions?
### github.com/moul/protoc-gen-gotemplate ### moul.io/protoc-gen-gotemplate
### @moul ### @moul

View File

@@ -1,25 +0,0 @@
language: go
go:
- 1.5
- 1.6
- 1.7
- 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:
- GO15VENDOREXPERIMENT=1 make setup
- GO15VENDOREXPERIMENT=1 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

View File

@@ -1,157 +0,0 @@
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)
}

View File

@@ -1,46 +0,0 @@
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")
}
}

View File

@@ -1,452 +0,0 @@
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},
}
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},
{"= 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.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.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.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)
}
}
}

View File

@@ -1,450 +0,0 @@
package semver
import (
"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},
}
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},
}
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)
}
}
}

View File

@@ -1,24 +0,0 @@
language: go
go:
- 1.6
- 1.7
- 1.8
- 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 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

View File

@@ -1,16 +1,131 @@
# Release 1.2.0 (2016-02-01) # Changelog
## Release 2.14.1 (2017-12-01)
### Fixed
- #60: Fix typo in function name documentation (thanks @neil-ca-moore)
- #61: Removing line with {{ due to blocking github pages genertion
- #64: Update the list functions to handle int, string, and other slices for compatibility
## Release 2.14.0 (2017-10-06)
This new version of Sprig adds a set of functions for generating and working with SSL certificates.
- `genCA` generates an SSL Certificate Authority
- `genSelfSignedCert` generates an SSL self-signed certificate
- `genSignedCert` generates an SSL certificate and key based on a given CA
## Release 2.13.0 (2017-09-18)
This release adds new functions, including:
- `regexMatch`, `regexFindAll`, `regexFind`, `regexReplaceAll`, `regexReplaceAllLiteral`, and `regexSplit` to work with regular expressions
- `floor`, `ceil`, and `round` math functions
- `toDate` converts a string to a date
- `nindent` is just like `indent` but also prepends a new line
- `ago` returns the time from `time.Now`
### Added
- #40: Added basic regex functionality (thanks @alanquillin)
- #41: Added ceil floor and round functions (thanks @alanquillin)
- #48: Added toDate function (thanks @andreynering)
- #50: Added nindent function (thanks @binoculars)
- #46: Added ago function (thanks @slayer)
### Changed
- #51: Updated godocs to include new string functions (thanks @curtisallen)
- #49: Added ability to merge multiple dicts (thanks @binoculars)
## Release 2.12.0 (2017-05-17)
- `snakecase`, `camelcase`, and `shuffle` are three new string functions
- `fail` allows you to bail out of a template render when conditions are not met
## Release 2.11.0 (2017-05-02)
- Added `toJson` and `toPrettyJson`
- Added `merge`
- Refactored documentation
## Release 2.10.0 (2017-03-15)
- Added `semver` and `semverCompare` for Semantic Versions
- `list` replaces `tuple`
- Fixed issue with `join`
- Added `first`, `last`, `intial`, `rest`, `prepend`, `append`, `toString`, `toStrings`, `sortAlpha`, `reverse`, `coalesce`, `pluck`, `pick`, `compact`, `keys`, `omit`, `uniq`, `has`, `without`
## Release 2.9.0 (2017-02-23)
- Added `splitList` to split a list
- Added crypto functions of `genPrivateKey` and `derivePassword`
## Release 2.8.0 (2016-12-21)
- Added access to several path functions (`base`, `dir`, `clean`, `ext`, and `abs`)
- Added functions for _mutating_ dictionaries (`set`, `unset`, `hasKey`)
## Release 2.7.0 (2016-12-01)
- Added `sha256sum` to generate a hash of an input
- Added functions to convert a numeric or string to `int`, `int64`, `float64`
## Release 2.6.0 (2016-10-03)
- Added a `uuidv4` template function for generating UUIDs inside of a template.
## Release 2.5.0 (2016-08-19)
- New `trimSuffix`, `trimPrefix`, `hasSuffix`, and `hasPrefix` functions
- New aliases have been added for a few functions that didn't follow the naming conventions (`trimAll` and `abbrevBoth`)
- `trimall` and `abbrevboth` (notice the case) are deprecated and will be removed in 3.0.0
## Release 2.4.0 (2016-08-16)
- Adds two functions: `until` and `untilStep`
## Release 2.3.0 (2016-06-21)
- cat: Concatenate strings with whitespace separators.
- replace: Replace parts of a string: `replace " " "-" "Me First"` renders "Me-First"
- plural: Format plurals: `len "foo" | plural "one foo" "many foos"` renders "many foos"
- indent: Indent blocks of text in a way that is sensitive to "\n" characters.
## Release 2.2.0 (2016-04-21)
- Added a `genPrivateKey` function (Thanks @bacongobbler)
## Release 2.1.0 (2016-03-30)
- `default` now prints the default value when it does not receive a value down the pipeline. It is much safer now to do `{{.Foo | default "bar"}}`.
- Added accessors for "hermetic" functions. These return only functions that, when given the same input, produce the same output.
## Release 2.0.0 (2016-03-29)
Because we switched from `int` to `int64` as the return value for all integer math functions, the library's major version number has been incremented.
- `min` complements `max` (formerly `biggest`)
- `empty` indicates that a value is the empty value for its type
- `tuple` creates a tuple inside of a template: `{{$t := tuple "a", "b" "c"}}`
- `dict` creates a dictionary inside of a template `{{$d := dict "key1" "val1" "key2" "val2"}}`
- Date formatters have been added for HTML dates (as used in `date` input fields)
- Integer math functions can convert from a number of types, including `string` (via `strconv.ParseInt`).
## Release 1.2.0 (2016-02-01)
- Added quote and squote - Added quote and squote
- Added b32enc and b32dec - Added b32enc and b32dec
- add now takes varargs - add now takes varargs
- biggest now takes varargs - biggest now takes varargs
# Release 1.1.0 (2015-12-29) ## Release 1.1.0 (2015-12-29)
- Added #4: Added contains function. strings.Contains, but with the arguments - Added #4: Added contains function. strings.Contains, but with the arguments
switched to simplify common pipelines. (thanks krancour) switched to simplify common pipelines. (thanks krancour)
- Added Travis-CI testing support - Added Travis-CI testing support
# Release 1.0.0 (2015-12-23) ## Release 1.0.0 (2015-12-23)
- Initial release - Initial release

View File

@@ -10,12 +10,16 @@ import (
"crypto/rsa" "crypto/rsa"
"crypto/sha256" "crypto/sha256"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix"
"encoding/asn1" "encoding/asn1"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"encoding/pem" "encoding/pem"
"errors"
"fmt" "fmt"
"math/big" "math/big"
"net"
"time"
uuid "github.com/satori/go.uuid" uuid "github.com/satori/go.uuid"
"golang.org/x/crypto/scrypt" "golang.org/x/crypto/scrypt"
@@ -146,3 +150,231 @@ func pemBlockForKey(priv interface{}) *pem.Block {
return nil return nil
} }
} }
type certificate struct {
Cert string
Key string
}
func generateCertificateAuthority(
cn string,
daysValid int,
) (certificate, error) {
ca := certificate{}
template, err := getBaseCertTemplate(cn, nil, nil, daysValid)
if err != nil {
return ca, err
}
// Override KeyUsage and IsCA
template.KeyUsage = x509.KeyUsageKeyEncipherment |
x509.KeyUsageDigitalSignature |
x509.KeyUsageCertSign
template.IsCA = true
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return ca, fmt.Errorf("error generating rsa key: %s", err)
}
ca.Cert, ca.Key, err = getCertAndKey(template, priv, template, priv)
if err != nil {
return ca, err
}
return ca, nil
}
func generateSelfSignedCertificate(
cn string,
ips []interface{},
alternateDNS []interface{},
daysValid int,
) (certificate, error) {
cert := certificate{}
template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
if err != nil {
return cert, err
}
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return cert, fmt.Errorf("error generating rsa key: %s", err)
}
cert.Cert, cert.Key, err = getCertAndKey(template, priv, template, priv)
if err != nil {
return cert, err
}
return cert, nil
}
func generateSignedCertificate(
cn string,
ips []interface{},
alternateDNS []interface{},
daysValid int,
ca certificate,
) (certificate, error) {
cert := certificate{}
decodedSignerCert, _ := pem.Decode([]byte(ca.Cert))
if decodedSignerCert == nil {
return cert, errors.New("unable to decode certificate")
}
signerCert, err := x509.ParseCertificate(decodedSignerCert.Bytes)
if err != nil {
return cert, fmt.Errorf(
"error parsing certificate: decodedSignerCert.Bytes: %s",
err,
)
}
decodedSignerKey, _ := pem.Decode([]byte(ca.Key))
if decodedSignerKey == nil {
return cert, errors.New("unable to decode key")
}
signerKey, err := x509.ParsePKCS1PrivateKey(decodedSignerKey.Bytes)
if err != nil {
return cert, fmt.Errorf(
"error parsing prive key: decodedSignerKey.Bytes: %s",
err,
)
}
template, err := getBaseCertTemplate(cn, ips, alternateDNS, daysValid)
if err != nil {
return cert, err
}
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return cert, fmt.Errorf("error generating rsa key: %s", err)
}
cert.Cert, cert.Key, err = getCertAndKey(
template,
priv,
signerCert,
signerKey,
)
if err != nil {
return cert, err
}
return cert, nil
}
func getCertAndKey(
template *x509.Certificate,
signeeKey *rsa.PrivateKey,
parent *x509.Certificate,
signingKey *rsa.PrivateKey,
) (string, string, error) {
derBytes, err := x509.CreateCertificate(
rand.Reader,
template,
parent,
&signeeKey.PublicKey,
signingKey,
)
if err != nil {
return "", "", fmt.Errorf("error creating certificate: %s", err)
}
certBuffer := bytes.Buffer{}
if err := pem.Encode(
&certBuffer,
&pem.Block{Type: "CERTIFICATE", Bytes: derBytes},
); err != nil {
return "", "", fmt.Errorf("error pem-encoding certificate: %s", err)
}
keyBuffer := bytes.Buffer{}
if err := pem.Encode(
&keyBuffer,
&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(signeeKey),
},
); err != nil {
return "", "", fmt.Errorf("error pem-encoding key: %s", err)
}
return string(certBuffer.Bytes()), string(keyBuffer.Bytes()), nil
}
func getBaseCertTemplate(
cn string,
ips []interface{},
alternateDNS []interface{},
daysValid int,
) (*x509.Certificate, error) {
ipAddresses, err := getNetIPs(ips)
if err != nil {
return nil, err
}
dnsNames, err := getAlternateDNSStrs(alternateDNS)
if err != nil {
return nil, err
}
return &x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
CommonName: cn,
},
IPAddresses: ipAddresses,
DNSNames: dnsNames,
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour * 24 * time.Duration(daysValid)),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{
x509.ExtKeyUsageServerAuth,
x509.ExtKeyUsageClientAuth,
},
BasicConstraintsValid: true,
}, nil
}
func getNetIPs(ips []interface{}) ([]net.IP, error) {
if ips == nil {
return []net.IP{}, nil
}
var ipStr string
var ok bool
var netIP net.IP
netIPs := make([]net.IP, len(ips))
for i, ip := range ips {
ipStr, ok = ip.(string)
if !ok {
return nil, fmt.Errorf("error parsing ip: %v is not a string", ip)
}
netIP = net.ParseIP(ipStr)
if netIP == nil {
return nil, fmt.Errorf("error parsing ip: %s", ipStr)
}
netIPs[i] = netIP
}
return netIPs, nil
}
func getAlternateDNSStrs(alternateDNS []interface{}) ([]string, error) {
if alternateDNS == nil {
return []string{}, nil
}
var dnsStr string
var ok bool
alternateDNSStrs := make([]string, len(alternateDNS))
for i, dns := range alternateDNS {
dnsStr, ok = dns.(string)
if !ok {
return nil, fmt.Errorf(
"error processing alternate dns name: %v is not a string",
dns,
)
}
alternateDNSStrs[i] = dnsStr
}
return alternateDNSStrs, nil
}

View File

@@ -1,110 +0,0 @@
package sprig
import (
"strings"
"testing"
)
func TestSha256Sum(t *testing.T) {
tpl := `{{"abc" | sha256sum}}`
if err := runt(tpl, "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); err != nil {
t.Error(err)
}
}
func TestDerivePassword(t *testing.T) {
expectations := map[string]string{
`{{derivePassword 1 "long" "password" "user" "example.com"}}`: "ZedaFaxcZaso9*",
`{{derivePassword 2 "long" "password" "user" "example.com"}}`: "Fovi2@JifpTupx",
`{{derivePassword 1 "maximum" "password" "user" "example.com"}}`: "pf4zS1LjCg&LjhsZ7T2~",
`{{derivePassword 1 "medium" "password" "user" "example.com"}}`: "ZedJuz8$",
`{{derivePassword 1 "basic" "password" "user" "example.com"}}`: "pIS54PLs",
`{{derivePassword 1 "short" "password" "user" "example.com"}}`: "Zed5",
`{{derivePassword 1 "pin" "password" "user" "example.com"}}`: "6685",
}
for tpl, result := range expectations {
out, err := runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if 0 != strings.Compare(out, result) {
t.Error("Generated password does not match for", tpl)
}
}
}
// NOTE(bacongobbler): this test is really _slow_ because of how long it takes to compute
// and generate a new crypto key.
func TestGenPrivateKey(t *testing.T) {
// test that calling by default generates an RSA private key
tpl := `{{genPrivateKey ""}}`
out, err := runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if !strings.Contains(out, "RSA PRIVATE KEY") {
t.Error("Expected RSA PRIVATE KEY")
}
// test all acceptable arguments
tpl = `{{genPrivateKey "rsa"}}`
out, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if !strings.Contains(out, "RSA PRIVATE KEY") {
t.Error("Expected RSA PRIVATE KEY")
}
tpl = `{{genPrivateKey "dsa"}}`
out, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if !strings.Contains(out, "DSA PRIVATE KEY") {
t.Error("Expected DSA PRIVATE KEY")
}
tpl = `{{genPrivateKey "ecdsa"}}`
out, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if !strings.Contains(out, "EC PRIVATE KEY") {
t.Error("Expected EC PRIVATE KEY")
}
// test bad
tpl = `{{genPrivateKey "bad"}}`
out, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if out != "Unknown type bad" {
t.Error("Expected type 'bad' to be an unknown crypto algorithm")
}
// ensure that we can base64 encode the string
tpl = `{{genPrivateKey "rsa" | b64enc}}`
out, err = runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
}
func TestUUIDGeneration(t *testing.T) {
tpl := `{{uuidv4}}`
out, err := runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if len(out) != 36 {
t.Error("Expected UUID of length 36")
}
out2, err := runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if out == out2 {
t.Error("Expected subsequent UUID generations to be different")
}
}

View File

@@ -51,3 +51,26 @@ func dateModify(fmt string, date time.Time) time.Time {
} }
return date.Add(d) return date.Add(d)
} }
func dateAgo(date interface{}) string {
var t time.Time
switch date := date.(type) {
default:
t = time.Now()
case time.Time:
t = date
case int64:
t = time.Unix(date, 0)
case int:
t = time.Unix(int64(date), 0)
}
// Drop resolution to seconds
duration := time.Since(t) / time.Second * time.Second
return duration.String()
}
func toDate(fmt, str string) time.Time {
t, _ := time.ParseInLocation(fmt, str, time.Local)
return t
}

View File

@@ -1,13 +0,0 @@
package sprig
import (
"testing"
)
func TestHtmlDate(t *testing.T) {
t.Skip()
tpl := `{{ htmlDate 0}}`
if err := runt(tpl, "1970-01-01"); err != nil {
t.Error(err)
}
}

View File

@@ -1,107 +0,0 @@
package sprig
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestDefault(t *testing.T) {
tpl := `{{"" | default "foo"}}`
if err := runt(tpl, "foo"); err != nil {
t.Error(err)
}
tpl = `{{default "foo" 234}}`
if err := runt(tpl, "234"); err != nil {
t.Error(err)
}
tpl = `{{default "foo" 2.34}}`
if err := runt(tpl, "2.34"); err != nil {
t.Error(err)
}
tpl = `{{ .Nothing | default "123" }}`
if err := runt(tpl, "123"); err != nil {
t.Error(err)
}
tpl = `{{ default "123" }}`
if err := runt(tpl, "123"); err != nil {
t.Error(err)
}
}
func TestEmpty(t *testing.T) {
tpl := `{{if empty 1}}1{{else}}0{{end}}`
if err := runt(tpl, "0"); err != nil {
t.Error(err)
}
tpl = `{{if empty 0}}1{{else}}0{{end}}`
if err := runt(tpl, "1"); err != nil {
t.Error(err)
}
tpl = `{{if empty ""}}1{{else}}0{{end}}`
if err := runt(tpl, "1"); err != nil {
t.Error(err)
}
tpl = `{{if empty 0.0}}1{{else}}0{{end}}`
if err := runt(tpl, "1"); err != nil {
t.Error(err)
}
tpl = `{{if empty false}}1{{else}}0{{end}}`
if err := runt(tpl, "1"); err != nil {
t.Error(err)
}
dict := map[string]interface{}{"top": map[string]interface{}{}}
tpl = `{{if empty .top.NoSuchThing}}1{{else}}0{{end}}`
if err := runtv(tpl, "1", dict); err != nil {
t.Error(err)
}
tpl = `{{if empty .bottom.NoSuchThing}}1{{else}}0{{end}}`
if err := runtv(tpl, "1", dict); err != nil {
t.Error(err)
}
}
func TestCoalesce(t *testing.T) {
tests := map[string]string{
`{{ coalesce 1 }}`: "1",
`{{ coalesce "" 0 nil 2 }}`: "2",
`{{ $two := 2 }}{{ coalesce "" 0 nil $two }}`: "2",
`{{ $two := 2 }}{{ coalesce "" $two 0 0 0 }}`: "2",
`{{ $two := 2 }}{{ coalesce "" $two 3 4 5 }}`: "2",
`{{ coalesce }}`: "<no value>",
}
for tpl, expect := range tests {
assert.NoError(t, runt(tpl, expect))
}
dict := map[string]interface{}{"top": map[string]interface{}{}}
tpl := `{{ coalesce .top.NoSuchThing .bottom .bottom.dollar "airplane"}}`
if err := runtv(tpl, "airplane", dict); err != nil {
t.Error(err)
}
}
func TestToJson(t *testing.T) {
dict := map[string]interface{}{"Top": map[string]interface{}{"bool": true, "string": "test", "number": 42}}
tpl := `{{.Top | toJson}}`
expected := `{"bool":true,"number":42,"string":"test"}`
if err := runtv(tpl, expected, dict); err != nil {
t.Error(err)
}
}
func TestToPrettyJson(t *testing.T) {
dict := map[string]interface{}{"Top": map[string]interface{}{"bool": true, "string": "test", "number": 42}}
tpl := `{{.Top | toPrettyJson}}`
expected := `{
"bool": true,
"number": 42,
"string": "test"
}`
if err := runtv(tpl, expected, dict); err != nil {
t.Error(err)
}
}

View File

@@ -75,10 +75,12 @@ func dict(v ...interface{}) map[string]interface{} {
return dict return dict
} }
func merge(dst map[string]interface{}, src map[string]interface{}) interface{} { func merge(dst map[string]interface{}, srcs ...map[string]interface{}) interface{} {
if err := mergo.Merge(&dst, src); err != nil { for _, src := range srcs {
// Swallow errors inside of a template. if err := mergo.Merge(&dst, src); err != nil {
return "" // Swallow errors inside of a template.
return ""
}
} }
return dst return dst
} }

View File

@@ -1,174 +0,0 @@
package sprig
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestDict(t *testing.T) {
tpl := `{{$d := dict 1 2 "three" "four" 5}}{{range $k, $v := $d}}{{$k}}{{$v}}{{end}}`
out, err := runRaw(tpl, nil)
if err != nil {
t.Error(err)
}
if len(out) != 12 {
t.Errorf("Expected length 12, got %d", len(out))
}
// dict does not guarantee ordering because it is backed by a map.
if !strings.Contains(out, "12") {
t.Error("Expected grouping 12")
}
if !strings.Contains(out, "threefour") {
t.Error("Expected grouping threefour")
}
if !strings.Contains(out, "5") {
t.Error("Expected 5")
}
tpl = `{{$t := dict "I" "shot" "the" "albatross"}}{{$t.the}} {{$t.I}}`
if err := runt(tpl, "albatross shot"); err != nil {
t.Error(err)
}
}
func TestUnset(t *testing.T) {
tpl := `{{- $d := dict "one" 1 "two" 222222 -}}
{{- $_ := unset $d "two" -}}
{{- range $k, $v := $d}}{{$k}}{{$v}}{{- end -}}
`
expect := "one1"
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
func TestHasKey(t *testing.T) {
tpl := `{{- $d := dict "one" 1 "two" 222222 -}}
{{- if hasKey $d "one" -}}1{{- end -}}
`
expect := "1"
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
func TestPluck(t *testing.T) {
tpl := `
{{- $d := dict "one" 1 "two" 222222 -}}
{{- $d2 := dict "one" 1 "two" 33333 -}}
{{- $d3 := dict "one" 1 -}}
{{- $d4 := dict "one" 1 "two" 4444 -}}
{{- pluck "two" $d $d2 $d3 $d4 -}}
`
expect := "[222222 33333 4444]"
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
func TestKeys(t *testing.T) {
tests := map[string]string{
`{{ dict "foo" 1 "bar" 2 | keys | sortAlpha }}`: "[bar foo]",
`{{ dict | keys }}`: "[]",
}
for tpl, expect := range tests {
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
}
func TestPick(t *testing.T) {
tests := map[string]string{
`{{- $d := dict "one" 1 "two" 222222 }}{{ pick $d "two" | len -}}`: "1",
`{{- $d := dict "one" 1 "two" 222222 }}{{ pick $d "two" -}}`: "map[two:222222]",
`{{- $d := dict "one" 1 "two" 222222 }}{{ pick $d "one" "two" | len -}}`: "2",
`{{- $d := dict "one" 1 "two" 222222 }}{{ pick $d "one" "two" "three" | len -}}`: "2",
`{{- $d := dict }}{{ pick $d "two" | len -}}`: "0",
}
for tpl, expect := range tests {
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
}
func TestOmit(t *testing.T) {
tests := map[string]string{
`{{- $d := dict "one" 1 "two" 222222 }}{{ omit $d "one" | len -}}`: "1",
`{{- $d := dict "one" 1 "two" 222222 }}{{ omit $d "one" -}}`: "map[two:222222]",
`{{- $d := dict "one" 1 "two" 222222 }}{{ omit $d "one" "two" | len -}}`: "0",
`{{- $d := dict "one" 1 "two" 222222 }}{{ omit $d "two" "three" | len -}}`: "1",
`{{- $d := dict }}{{ omit $d "two" | len -}}`: "0",
}
for tpl, expect := range tests {
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
}
func TestSet(t *testing.T) {
tpl := `{{- $d := dict "one" 1 "two" 222222 -}}
{{- $_ := set $d "two" 2 -}}
{{- $_ := set $d "three" 3 -}}
{{- if hasKey $d "one" -}}{{$d.one}}{{- end -}}
{{- if hasKey $d "two" -}}{{$d.two}}{{- end -}}
{{- if hasKey $d "three" -}}{{$d.three}}{{- end -}}
`
expect := "123"
if err := runt(tpl, expect); err != nil {
t.Error(err)
}
}
func TestCompact(t *testing.T) {
tests := map[string]string{
`{{ list 1 0 "" "hello" | compact }}`: `[1 hello]`,
`{{ list "" "" | compact }}`: `[]`,
`{{ list | compact }}`: `[]`,
}
for tpl, expect := range tests {
assert.NoError(t, runt(tpl, expect))
}
}
func TestMerge(t *testing.T) {
dict := map[string]interface{}{
"src": map[string]interface{}{
"a": 1,
"b": 2,
"d": map[string]interface{}{
"e": "four",
},
"g": []int{6, 7},
},
"dst": map[string]interface{}{
"a": "one",
"c": 3,
"d": map[string]interface{}{
"f": 5,
},
"g": []int{8, 9},
},
}
tpl := `{{merge .dst .src}}`
_, err := runRaw(tpl, dict)
if err != nil {
t.Error(err)
}
expected := map[string]interface{}{
"a": "one", // key overridden
"b": 2, // merged from src
"c": 3, // merged from dst
"d": map[string]interface{}{ // deep merge
"e": "four",
"f": 5,
},
"g": []int{8, 9}, // overridden - arrays are not merged
}
assert.Equal(t, expected, dict["dst"])
}

View File

@@ -48,6 +48,10 @@ String Functions
- randAlpha: Given a length, generate an alphabetic string - randAlpha: Given a length, generate an alphabetic string
- randAscii: Given a length, generate a random ASCII string (symbols included) - randAscii: Given a length, generate a random ASCII string (symbols included)
- randNumeric: Given a length, generate a string of digits. - randNumeric: Given a length, generate a string of digits.
- swapcase: SwapCase swaps the case of a string using a word based algorithm. see https://godoc.org/github.com/Masterminds/goutils#SwapCase
- shuffle: Shuffle randomizes runes in a string and returns the result. It uses default random source in `math/rand`
- snakecase: convert all upper case characters in a string to underscore format.
- camelcase: convert all lower case characters behind underscores to upper case character
- wrap: Force a line wrap at the given width. `wrap 80 "imagine a longer string"` - wrap: Force a line wrap at the given width. `wrap 80 "imagine a longer string"`
- wrapWith: Wrap a line at the given length, but using 'sep' instead of a newline. `wrapWith 50, "<br>", $html` - wrapWith: Wrap a line at the given length, but using 'sep' instead of a newline. `wrapWith 50, "<br>", $html`
- contains: strings.Contains, but with the arguments switched: `contains substr str`. (This simplifies common pipelines) - contains: strings.Contains, but with the arguments switched: `contains substr str`. (This simplifies common pipelines)
@@ -57,6 +61,7 @@ String Functions
- squote: Wrap string(s) in double quotation marks, does not escape content. - squote: Wrap string(s) in double quotation marks, does not escape content.
- cat: Concatenate strings, separating them by spaces. `cat $a $b $c`. - cat: Concatenate strings, separating them by spaces. `cat $a $b $c`.
- indent: Indent a string using space characters. `indent 4 "foo\nbar"` produces " foo\n bar" - indent: Indent a string using space characters. `indent 4 "foo\nbar"` produces " foo\n bar"
- nindent: Indent a string using space characters and prepend a new line. `indent 4 "foo\nbar"` produces "\n foo\n bar"
- replace: Replace an old with a new in a string: `$name | replace " " "-"` - replace: Replace an old with a new in a string: `$name | replace " " "-"`
- plural: Choose singular or plural based on length: `len $fish | plural "one anchovy" "many anchovies"` - plural: Choose singular or plural based on length: `len $fish | plural "one anchovy" "many anchovies"`
- sha256sum: Generate a hex encoded sha256 hash of the input - sha256sum: Generate a hex encoded sha256 hash of the input
@@ -84,7 +89,7 @@ Integer Slice Functions:
Conversions: Conversions:
- atoi: Convert a string to an integer. 0 if the integer could not be parsed. - atoi: Convert a string to an integer. 0 if the integer could not be parsed.
- in64: Convert a string or another numeric type to an int64. - int64: Convert a string or another numeric type to an int64.
- int: Convert a string or another numeric type to an int. - int: Convert a string or another numeric type to an int.
- float64: Convert a string or another numeric type to a float64. - float64: Convert a string or another numeric type to a float64.

View File

@@ -1 +0,0 @@
theme: jekyll-theme-slate

View File

@@ -1,25 +0,0 @@
# Type Conversion Functions
The following type conversion functions are provided by Sprig:
- `atoi`: Convert a string to an integer
- `float64`: Convert to a float64
- `int`: Convert to an `int` at the system's width.
- `int64`: Convert to an `int64`
- `toString`: Convert to a string
- `toStrings`: Convert a list, slice, or array to a list of strings.
Only `atoi` requires that the input be a specific type. The others will attempt
to convert from any type to the destination type. For example, `int64` can convert
floats to ints, and it can also convert strings to ints.
## toStrings
Given a list-like collection, produce a slice of strings.
```
list 1 2 3 | toStrings
```
The above converts `1` to `"1"`, `2` to `"2"`, and so on, and then returns
them as a list.

View File

@@ -1,37 +0,0 @@
# Cryptographic and Security Functions
Sprig provides a couple of advanced cryptographic functions.
## sha256sum
The `sha256sum` function receives a string, and computes it's SHA256 digest.
```
sha256sum "Hello world!"
```
The above will compute the SHA 256 sum in an "ASCII armored" format that is
safe to print.
## derivePassword
The `derivePassword` function can be used to derive a specific password based on
some shared "master password" constraints. The algorithm for this is
[well specified](http://masterpasswordapp.com/algorithm.html).
```
derivePassword 1 "long" "password" "user" "example.com"
```
Note that it is considered insecure to store the parts directly in the template.
## generatePrivateKey
The `generatePrivateKey` function generates a new private key encoded into a PEM
block.
It takes one of the values for its first param:
- `ecdsa`: Generate an elyptical curve DSA key (P256)
- `dsa`: Generate a DSA key (L2048N256)
- `rsa`: Generate an RSA 4096 key

View File

@@ -1,62 +0,0 @@
# Date Functions
## now
The current date/time. Use this in conjunction with other date functions.
## date
The `date` function formats a date.
Format the date to YEAR-MONTH-DAY:
```
now | date "2006-01-02"
```
Date formatting in Go is a [little bit different](https://pauladamsmith.com/blog/2011/05/go_time.html).
In short, take this as the base date:
```
Mon Jan 2 15:04:05 MST 2006
```
Write it in the format you want. Above, `2006-01-02` is the same date, but
in the format we want.
## dateInZone
Same as `date`, but with a timezone.
```
date "2006-01-02" (now) "UTC"
```
## dateModify
The `dateModify` takes a modification and a date and returns the timestamp.
Subtract an hour and thirty minutes from the current time:
```
now | date_modify "-1.5h"
```
## htmlDate
The `htmlDate` function formates a date for inserting into an HTML date picker
input field.
```
now | htmlDate
```
## htmlDateInZone
Same as htmlDate, but with a timezone.
```
htmlDate (now) "UTC"
```

View File

@@ -1,59 +0,0 @@
# Default Functions
Sprig provides tools for setting default values for templates.
## default
To set a simple default value, use `default`:
```
default "foo" .Bar
```
In the above, if `.Bar` evaluates to a non-empty value, it will be used. But if
it is empty, `foo` will be returned instead.
The definition of "empty" depends on type:
- Numeric: 0
- String: ""
- Lists: `[]`
- Dicts: `{}`
- Boolean: `false`
- And always `nil` (aka null)
For structs, there is no definition of empty, so a struct will never return the
default.
## empty
The `empty` function returns `true` if the given value is considered empty, and
`false` otherwise. The empty values are listed in the `default` section.
```
empty .Foo
```
Note that in Go template conditionals, emptiness is calculated for you. Thus,
you rarely need `if empty .Foo`. Instead, just use `if .Foo`.
## coalesce
The `coalesce` function takes a list of values and returns the first non-empty
one.
```
coalesce 0 1 2
```
The above returns `1`.
This function is useful for scanning through multiple variables or values:
```
coalesce .name .parent.name "Matt"
```
The above will first check to see if `.name` is empty. If it is not, it will return
that value. If it _is_ empty, `coalesce` will evaluate `.parent.name` for emptiness.
Finally, if both `.name` and `.parent.name` are empty, it will return `Matt`.

Some files were not shown because too many files have changed in this diff Show More