92 Commits

Author SHA1 Message Date
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
Manfred Touron
30b0ec5000 Merge pull request #62 from moul/dev/moul/improve-dependency-support
Support Dependency Lookup
2017-05-19 09:37:35 +02:00
Manfred Touron
4e25b6e83a Improve imports support (imports lookup)
* Add `--single-package-mode option`
    * Add `getMessageType` helper
    * Add `getProtoFile` helper
    * Add `examples/single-package-mode` example
2017-05-19 09:33:03 +02:00
Manfred Touron
5448f25fd6 glide up 2017-05-18 23:33:43 +02:00
Manfred Touron
dc386661ca Merge pull request #61 from moul/dev/jhayotte/getenum
add helper getEnumValue
2017-05-15 15:03:02 +02:00
jhayotte
e1486970f7 add helper getEnumValue 2017-05-12 20:48:34 +02:00
Manfred Touron
c750f5de81 Merge pull request #60 from moul/dev/jhayotte/gotype
get package name only for descriptor message typed
2017-05-03 06:41:38 +02:00
jhayotte
266eb3707c get package name only for descriptor message typed 2017-05-02 12:23:34 +02:00
Manfred Touron
d37b141a64 Merge pull request #59 from moul/dev/moul/remove-env
Remove Environment
2017-05-02 11:51:40 +02:00
Manfred Touron
47ef416835 Remove Environment as we already have env and expandenv filters from sprig 2017-05-02 11:50:37 +02:00
Manfred Touron
69cc91572b Merge pull request #58 from moul/dev/jhayotte/import
handle import of proto file
2017-05-02 11:39:23 +02:00
jhayotte
91ebb6e521 handle statement import of proto file 2017-05-02 11:12:26 +02:00
Manfred Touron
c73a4b8c46 Merge pull request #57 from moul/dev/moul/go-generate-example
Add go:generate example
2017-04-24 11:35:01 +02:00
Manfred Touron
a68198f386 Add go:generate example (#56) 2017-04-24 09:20:30 +02:00
Mathieu Acthernoene
21cba66d10 Merge pull request #55 from moul/dev/gfanton/add-js-reserved-prefix-helper
Add jsSuffixReservedKeyword helper
2017-04-13 13:47:58 +02:00
gfanton
fcfaf82ebd Add jsSuffixReservedKeyword helper 2017-04-13 13:15:40 +02:00
Manfred Touron
a4fbdd0369 Merge pull request #54 from moul/dev/proullon/gotype
fix (gotype helper): when leading pkg is empty string, remove leading dot
2017-04-06 15:11:35 +02:00
Pierre Roullon
263cb87b9c fix (gotype helper): when leading pkg is empty string, remove leading dot 2017-04-06 14:43:00 +02:00
Manfred Touron
7393098e01 Merge pull request #53 from moul/vgheri/annotations
Moved to google.golang.org/genproto/googleapis/api/annotations
2017-04-01 23:29:18 +02:00
Manfred Touron
b4a019192c Temporarily disabling go-kit example in the test-suite 2017-04-01 21:50:10 +02:00
Manfred Touron
ff370a965d Update Glide install method 2017-04-01 09:20:29 +02:00
Valerio Gheri
1594e18f3c Remove unneeded dep on grpc-gateway 2017-03-31 18:27:30 +02:00
Valerio Gheri
c40779224f Moved to google.golang.org/genproto/googleapis/api/annotations
Fixes #52
2017-03-31 18:01:58 +02:00
Manfred Touron
024c5a4e4e Add sitemap (non-code) example 2017-03-16 17:47:54 +01:00
Manfred Touron
266d42dc25 Merge pull request #51 from moul/dev/moul/enable-tests
Enable all tests
2017-03-16 17:34:26 +01:00
Manfred Touron
9da682760b Fix Go-Kit test (#25) 2017-03-16 17:20:57 +01:00
Manfred Touron
97cfa60fc8 Enable all tests (fix #25) 2017-03-16 16:15:34 +01:00
Manfred Touron
191df6c8ec Update README.md 2017-03-16 16:15:10 +01:00
Manfred Touron
6d0ee10322 Add *philosophy* and *under the hood* sections 2017-03-16 16:10:39 +01:00
Mathieu Acthernoene
b3496838ad Merge pull request #48 from gfanton/gfanton/full-namespace
Get full namespace
2017-02-11 17:54:00 +01:00
gfanton
7758db8357 Create a full namespace 2017-02-11 17:49:51 +01:00
Manfred Touron
cf5e1b7064 Merge pull request #47 from moul/vgheri/fixarrays
goType helper can now correctly detect arrays of built-in types
2017-02-07 19:20:48 +01:00
Valerio Gheri
bc937830d2 goType can now correctly detect arrays of built-in types 2017-02-07 15:21:32 +01:00
Manfred Touron
6202a3f762 Merge pull request #46 from moul/vgheri/urlHasVarsFromMessage
Added helper to detect if a url contains variables in the form of url parameters with the same name of the fields of a specific protobuf  message
2017-02-01 15:39:46 +01:00
Valerio Gheri
c1f10d57e9 Added helper to detect if a url contains variables in the form of url parameters with the same name of the fields of a specific protobuf message 2017-02-01 14:38:14 +01:00
Mathieu Acthernoene
199050ce6f Merge pull request #45 from gfanton/namespaced-type
Namespaced type
2017-01-17 17:46:03 +01:00
gfanton
1006df3564 Expose namespaced type 2017-01-17 17:40:35 +01:00
Manfred Touron
99cff16e71 Merge pull request #44 from gfanton/feature/concat
Concatenate if file already exist
2017-01-17 17:17:27 +01:00
gfanton
fee245f5d4 Add concat example 2017-01-17 16:13:19 +01:00
gfanton
99d310ac79 Concatenate if file already exist 2017-01-17 12:20:16 +01:00
Manfred Touron
5a65b0fca4 Merge pull request #43 from gfanton/feature/add-all-argument
Feature/add all argument
2017-01-12 15:32:28 +01:00
gfanton
0d32837e5d Remove useless dependencies 2017-01-12 15:14:36 +01:00
gfanton
72880bafe5 Add all arguments 2017-01-12 14:46:43 +01:00
Guilhem Fanton
4d3b9c31b6 Merge pull request #42 from moul/feature/flow-getter-setter
Feature/flow getter setter
2017-01-11 16:37:18 +01:00
Mathieu Acthernoene
4149bd5c25 Support List / Message types 2017-01-11 16:33:03 +01:00
Mathieu Acthernoene
0ce8ebe54b Basic getter & setter support 2017-01-11 15:39:51 +01:00
Mathieu Acthernoene
b3b9aec439 Update example, remove strict types 2017-01-11 15:20:01 +01:00
Mathieu Acthernoene
47277242ae Array<number> -> Uint8Array 2017-01-11 14:52:00 +01:00
Manfred Touron
5fa1ea5cba Merge pull request #41 from moul/feature/nested-types
Feature/nested types
2017-01-10 14:07:17 +01:00
Mathieu Acthernoene
738a68fd4c Add type namespaces 2017-01-10 12:24:06 +01:00
Mathieu Acthernoene
dc8e191077 Add nested message usage example 2017-01-10 11:43:26 +01:00
Mathieu Acthernoene
acbd1bf87b Plain support of Nested Enums 2017-01-10 11:40:48 +01:00
Mathieu Acthernoene
66e9d20e1f Basic support for nested Enums / Messages 2017-01-10 11:22:18 +01:00
455 changed files with 64667 additions and 27466 deletions

View File

@@ -1,11 +1,15 @@
language: go language: go
go: 1.7.x go: 1.8.x
install: install:
- wget https://raw.githubusercontent.com/grpc-ecosystem/grpc-gateway/master/.travis/install-protoc.sh && chmod +x install-protoc.sh && ./install-protoc.sh 3.1.0 - go get github.com/Masterminds/glide
- go get github.com/gogo/protobuf/protoc-gen-gogo - 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
- go get -u github.com/alecthomas/gometalinter
- gometalinter --install
script: script:
- make install - make install
- make test - make test
- make lint
cache: cache:
directories: directories:
- $HOME/local - $HOME/local

View File

@@ -1,5 +1,13 @@
FROM znly/protoc FROM znly/protoc
RUN apk --update add make git go rsync
ENV GOPATH=/go \
PATH=/go/bin:${PATH}
# Install deps and common tools
RUN apk --update add make git go rsync libc-dev \
&& go get -u golang.org/x/tools/cmd/goimports
# Install protoc-gen-gotemplate
COPY . /go/src/github.com/moul/protoc-gen-gotemplate COPY . /go/src/github.com/moul/protoc-gen-gotemplate
WORKDIR /go/src/github.com/moul/protoc-gen-gotemplate WORKDIR /go/src/github.com/moul/protoc-gen-gotemplate
RUN go install . RUN go install . ./cmd/web-editor

View File

@@ -1,15 +1,26 @@
.PHONY: build .PHONY: build
build: build:
go build -o protoc-gen-gotemplate . go build -v -i -o protoc-gen-gotemplate .
.PHONY: install .PHONY: install
install: install:
go install . go install .
go install ./cmd/web-editor
.PHONY: test .PHONY: test
test: build test: install
cd examples/time && make
cd examples/enum && make
cd examples/import && make
cd examples/dummy && make cd examples/dummy && make
cd examples/flow && make cd examples/flow && make
cd examples/concat && make
cd examples/flow && make
cd examples/sitemap && make
cd examples/go-generate && make
cd examples/single-package-mode && make
cd examples/helpers && make
# cd examples/go-kit && make
.PHONY: docker.build .PHONY: docker.build
docker.build: docker.build:
@@ -18,3 +29,7 @@ docker.build:
.PHONY: docker.push .PHONY: docker.push
docker.push: docker.build docker.push: docker.build
docker push moul/protoc-gen-gotemplate docker push moul/protoc-gen-gotemplate
.PHONY: lint
lint:
gometalinter --disable-all --enable=errcheck --enable=vet --enable=vetshadow --enable=golint --enable=gas --enable=ineffassign --enable=goconst --enable=goimports --enable=gofmt --exclude="Binds to all network interfaces" --exclude="should have comment" --enable=staticcheck --enable=gosimple --enable=misspell --deadline=120s . ./cmd/... ./helpers/...

View File

@@ -1,19 +1,38 @@
# `protoc-gen-gotemplate` # `protoc-gen-gotemplate`
:open_file_folder: protocol generator + golang text/template (protobuf) :open_file_folder: protocol generator + golang text/template (protobuf)
Generic protocol buffer generator backed by Golang's [text/template](https://golang.org/pkg/text/template). A generic **code**/script/data generator based on [Protobuf](https://developers.google.com/protocol-buffers/).
--- ---
This is a generator plugin for the Google Protocol Buffers compiler (`protoc`). This project is a generator plugin for the Google Protocol Buffers compiler (`protoc`).
The plugin can generate files based on a template directory using the [Golang's `text/template`](https://golang.org/pkg/text/template/) engine. The plugin parses **protobuf** files, generates an **ast**, and walks a local **templates directory** to generate files using the [Golang's `text/template` engine](https://golang.org/pkg/text/template/).
## Philosophy
* protobuf-first
* no built-in template, only user defined templates
* kiss, *keep it stupid simple*
## Under the hood
1. the *user* `protobuf` files are parsed by [`protoc`](https://github.com/google/protobuf/releases)
2. the `ast` is generated by [`protoc-gen-go` helpers](https://github.com/golang/protobuf/tree/master/protoc-gen-go)
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
## 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`)*.
Every files ending with `.tmpl` will be processed and written in the destination folder, following the file hierarchy of the `template_dir`, and removing the `.tmpl` extension. Every file ending with `.tmpl` will be processed and written to the destination folder, following the file hierarchy of the `template_dir`, and remove the `.tmpl` extension.
--- ---
@@ -26,15 +45,27 @@ input.proto templates/doc.txt.tmpl templates/config.json.tmpl
doc.txt config.json doc.txt config.json
``` ```
--- ### Options
You can specify a custom `template_dir` or enable `debug`: You can specify custom options, as follow:
```console ```console
$> protoc --gotemplate_out=debug=true,template_dir=/path/to/template/directory:. input.proto $> protoc --gotemplate_out=debug=true,template_dir=/path/to/template/directory:. input.proto
``` ```
--- | Option | Default Value | Accepted Values | Description
|-----------------------|---------------|---------------------------|-----------------------
| `template_dir`       | `./template` | absolute or relative path | path to look for templates
| `destination_dir`     | `.`           | absolute or relative path | base path to write output
| `single-package-mode` | *false* | `true` or `false` | if *true*, `protoc` won't accept multiple packages to be compiled at once (*!= from `all`*), but will support `Message` lookup across the imported protobuf dependencies
| `debug`               | *false*       | `true` or `false` | if *true*, `protoc` will generate a more verbose output
| `all`                 | *false*       | `true` or `false`         | if *true*, protobuf files without `Service` will also be parsed
##### Hints
Shipping the templates with your project is very smart and useful when contributing on git-based projects.
Another workflow consists in having a dedicated repository for generic templates which is then versioned and vendored with multiple projects (npm package, golang vendor package, ...)
See [examples](./examples). See [examples](./examples).
@@ -42,13 +73,34 @@ 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: Non-exhaustive list of new helpers:s
* **all the functions from [sprig](https://github.com/Masterminds/sprig)** * **all the functions from [sprig](https://github.com/Masterminds/sprig)**
* `json` * `json`
* `prettyjson` * `prettyjson`
* `first` * `first`
* `last` * `last`
* `splitArray`
* `upperFirst`
* `lowerFirst`
* `camelCase`
* `lowerCamelCase`
* `kebabCase`
* `snakeCase`
* `getProtoFile`
* `getMessageType`
* `getEnumValue`
* `isFieldMessage`
* `isFieldRepeated`
* `goType`
* `goTypeWithPackage`
* `jsType`
* `jsSuffixReserved`
* `namespacedFlowType`
* `httpVerb`
* `httpPath`
* `shortType`
* `urlHasVarsFromMessage`
See the project helpers for the complete list. See the project helpers for the complete list.
@@ -58,6 +110,17 @@ See the project helpers for the complete list.
* 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 github.com/moul/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`
* [kafka-gateway](https://github.com/moul/kafka-gateway/): Kafka gateway/proxy (gRPC + http) using Go-Kit * [kafka-gateway](https://github.com/moul/kafka-gateway/): Kafka gateway/proxy (gRPC + http) using Go-Kit

BIN
assets/web-editor.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

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

@@ -0,0 +1,118 @@
package main
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"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"))
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()
r.Handle("/", http.FileServer(http.Dir("static")))
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%; }</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://github.com/moul/protoc-gen-gotemplate">protoc-gen-gotemplate</a></div>
</div>
</div>
</div>
<a href="https://github.com/moul/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

@@ -11,12 +11,15 @@ import (
"github.com/golang/protobuf/protoc-gen-go/descriptor" "github.com/golang/protobuf/protoc-gen-go/descriptor"
"github.com/golang/protobuf/protoc-gen-go/plugin" "github.com/golang/protobuf/protoc-gen-go/plugin"
pgghelpers "github.com/moul/protoc-gen-gotemplate/helpers"
) )
type GenericTemplateBasedEncoder struct { type GenericTemplateBasedEncoder struct {
templateDir string templateDir string
service *descriptor.ServiceDescriptorProto service *descriptor.ServiceDescriptorProto
file *descriptor.FileDescriptorProto file *descriptor.FileDescriptorProto
enum []*descriptor.EnumDescriptorProto
debug bool debug bool
destinationDir string destinationDir string
} }
@@ -34,18 +37,18 @@ type Ast struct {
Filename string `json:"filename"` Filename string `json:"filename"`
TemplateDir string `json:"template-dir"` TemplateDir string `json:"template-dir"`
Service *descriptor.ServiceDescriptorProto `json:"service"` Service *descriptor.ServiceDescriptorProto `json:"service"`
Environment []string `json:"environment"` Enum []*descriptor.EnumDescriptorProto `json:"enum"`
} }
func NewGenericTemplateBasedEncoder(templateDir string, service *descriptor.ServiceDescriptorProto, file *descriptor.FileDescriptorProto, debug bool, destinationDir string) (e *GenericTemplateBasedEncoder) { func NewGenericServiceTemplateBasedEncoder(templateDir string, service *descriptor.ServiceDescriptorProto, file *descriptor.FileDescriptorProto, debug bool, destinationDir string) (e *GenericTemplateBasedEncoder) {
e = &GenericTemplateBasedEncoder{ e = &GenericTemplateBasedEncoder{
service: service, service: service,
file: file, file: file,
templateDir: templateDir, templateDir: templateDir,
debug: debug, debug: debug,
destinationDir: destinationDir, destinationDir: destinationDir,
enum: file.GetEnumType(),
} }
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)
} }
@@ -53,6 +56,22 @@ func NewGenericTemplateBasedEncoder(templateDir string, service *descriptor.Serv
return return
} }
func NewGenericTemplateBasedEncoder(templateDir string, file *descriptor.FileDescriptorProto, debug bool, destinationDir string) (e *GenericTemplateBasedEncoder) {
e = &GenericTemplateBasedEncoder{
service: nil,
file: file,
templateDir: templateDir,
enum: file.GetEnumType(),
debug: debug,
destinationDir: destinationDir,
}
if debug {
log.Printf("new encoder: file=%q template-dir=%q", file.GetName(), templateDir)
}
return
}
func (e *GenericTemplateBasedEncoder) templates() ([]string, error) { func (e *GenericTemplateBasedEncoder) templates() ([]string, error) {
filenames := []string{} filenames := []string{}
@@ -81,11 +100,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 = ""
} }
@@ -101,11 +129,11 @@ func (e *GenericTemplateBasedEncoder) genAst(templateFilename string) (*Ast, err
DestinationDir: e.destinationDir, DestinationDir: e.destinationDir,
RawFilename: templateFilename, RawFilename: templateFilename,
Filename: "", Filename: "",
Environment: os.Environ(),
Service: e.service, Service: e.service,
Enum: e.enum,
} }
buffer := new(bytes.Buffer) buffer := new(bytes.Buffer)
tmpl, err := template.New("").Funcs(ProtoHelpersFuncMap).Parse(templateFilename) tmpl, err := template.New("").Funcs(pgghelpers.ProtoHelpersFuncMap).Parse(templateFilename)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -120,7 +148,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
} }
@@ -151,7 +179,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

13
examples/concat/Makefile Normal file
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,3 @@
I'm Eric
I'm Francis
I'm Arnold

View File

@@ -0,0 +1 @@
This is static text.This is static text.This is static text.

View File

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

View File

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

View File

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

View File

@@ -0,0 +1 @@
I'm {{.File.Package}}

View File

@@ -0,0 +1 @@
This is static text.

View File

@@ -1,9 +1,8 @@
{ {
"build-date": "2016-12-20T11:30:36.474403064+01:00", "build-date": "2017-05-19T20:09:45.954357761+02:00",
"build-hostname": "Zoon-MacBook.local", "build-hostname": "manfred-spacegray.aircard",
"build-user": "zoon", "build-user": "moul",
"go-pwd": "github.com/protoc-gen-gotemplate/examples/dummy", "pwd": "/Users/moul/Git/moul/protoc-gen-gotemplate/examples/dummy",
"pwd": "/Users/zoon/Projects/gopath/src/github.com/protoc-gen-gotemplate/examples/dummy",
"debug": false, "debug": false,
"destination-dir": ".", "destination-dir": ".",
"file": { "file": {
@@ -841,41 +840,5 @@
} }
] ]
}, },
"environment": [ "enum": null
"TERM_PROGRAM=iTerm.app",
"ANDROID_HOME=/usr/local/opt/android-sdk",
"TERM=xterm-256color",
"SHELL=/bin/zsh",
"MAKEFLAGS=",
"TMPDIR=/var/folders/sq/wlptrlpn4v52xv7xpsgw0fc80000gn/T/",
"Apple_PubSub_Socket_Render=/private/tmp/com.apple.launchd.q9vxeee00S/Render",
"TERM_PROGRAM_VERSION=3.0.12",
"TERM_SESSION_ID=w0t0p0:6D29EB08-1B96-41B8-8672-0B035605AEE5",
"ZSH=/Users/zoon/.oh-my-zsh",
"USER=zoon",
"SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.5ZcNGIwTRZ/Listeners",
"__CF_USER_TEXT_ENCODING=0x1F5:0x0:0x0",
"MAKELEVEL=2",
"PAGER=less",
"MFLAGS=",
"LSCOLORS=Gxfxcxdxbxegedabagacad",
"PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Users/zoon/Projects/gopath/bin",
"_=/usr/local/bin/protoc",
"PWD=/Users/zoon/Projects/gopath/src/github.com/protoc-gen-gotemplate/examples/dummy",
"JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_112.jdk/Contents/Home",
"EDITOR=micro",
"LANG=en_US.UTF-8",
"ANDROID_SDK=/usr/local/opt/android-sdk",
"ITERM_PROFILE=Default",
"XPC_FLAGS=0x0",
"XPC_SERVICE_NAME=0",
"COLORFGBG=15;0",
"SHLVL=3",
"HOME=/Users/zoon",
"ITERM_SESSION_ID=w0t0p0:6D29EB08-1B96-41B8-8672-0B035605AEE5",
"LESS=-R",
"LOGNAME=zoon",
"LC_CTYPE=UTF-8",
"GOPATH=/Users/zoon/Projects/gopath"
]
} }

13
examples/enum/Makefile Normal file
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,9 @@
-red
-blue
-black
-yellow
-green
-dark
-white
-gray
-orange

View File

@@ -0,0 +1,14 @@
syntax = "proto3";
package Sample;
enum Colors {
red = 0;
blue = 1;
black = 2;
yellow = 3;
green = 4;
dark = 5;
white = 6;
gray = 7;
orange = 8;
}

View File

@@ -0,0 +1,2 @@
{{range $m := "colors" | getEnumValue .Enum }}-{{$m.Name}}
{{end}}

View File

@@ -1,165 +1,272 @@
// @flow // @flow
// GENERATED CODE -- DO NOT EDIT! // GENERATED CODE -- DO NOT EDIT!
import grpc from 'grpc' import base64 from 'base64-js'
import pbFile from './pbFile.js' import test_pb from './test_pb'
export type TestEnum =
| 'ELEMENT_A'
| 'ELEMENT_B'
;
export type TestMessage = {| export type TestEnum = {|
a?: string; ELEMENT_A?: 0;
b?: number; ELEMENT_B?: 1;
c?: number;
d?: number;
e?: number;
n?: Array<string>;
o?: Array<number>;
p?: Array<number>;
q?: Array<number>;
r?: Array<number>;
s?:
| 'ELEMENT_C'
| 'ELEMENT_D'
;
|};
export type TestNoStreamRequest = {|
message?: TestMessage;
|};
export type TestNoStreamReply = {|
message?: TestMessage;
err_msg?: string;
|};
export type TestStreamRequestRequest = {|
message?: TestMessage;
|};
export type TestStreamRequestReply = {|
message?: TestMessage;
err_msg?: string;
|};
export type TestStreamReplyRequest = {|
message?: TestMessage;
|};
export type TestStreamReplyReply = {|
message?: TestMessage;
err_msg?: string;
|};
export type TestStreamBothRequest = {|
message?: TestMessage;
|};
export type TestStreamBothReply = {|
message?: TestMessage;
err_msg?: string;
|}; |};
function serialize_test_TestNoStreamRequest(arg: TestNoStreamRequest) { export type TestMessage$TestNestedEnum = {|
if (!(arg instanceof pbFile.TestNoStreamRequest)) { ELEMENT_C?: 0;
ELEMENT_D?: 1;
|};
export type TestMessage$TestNestedMessage = {
getS?: () => string;
setS?: (s: string) => void;
getT?: () => number;
setT?: (t: number) => void;
};
export type TestMessage = {
getA?: () => string;
setA?: (a: string) => void;
getB?: () => number;
setB?: (b: number) => void;
getC?: () => number;
setC?: (c: number) => void;
getD?: () => number;
setD?: (d: number) => void;
getE?: () => number;
setE?: (e: number) => void;
getNList?: () => Array<string>;
setNList?: (n: Array<string>) => void;
addN?: (n: string) => void;
clearNList?: () => void;
getOList?: () => Array<number>;
setOList?: (o: Array<number>) => void;
addO?: (o: number) => void;
clearOList?: () => void;
getPList?: () => Array<number>;
setPList?: (p: Array<number>) => void;
addP?: (p: number) => void;
clearPList?: () => void;
getQList?: () => Array<number>;
setQList?: (q: Array<number>) => void;
addQ?: (q: number) => void;
clearQList?: () => void;
getRList?: () => Array<number>;
setRList?: (r: Array<number>) => void;
addR?: (r: number) => void;
clearRList?: () => void;
getU?: () => test$TestEnum;
setU?: (u: test$TestEnum) => void;
getV?: () => test$TestMessage$TestNestedEnum;
setV?: (v: test$TestMessage$TestNestedEnum) => void;
getWList?: () => Array<test$TestMessage$TestNestedMessage>;
setWList?: (w: Array<test$TestMessage$TestNestedMessage>) => void;
addW?: (w: test$TestMessage$TestNestedMessage) => void;
clearWList?: () => void;
};
export type TestNoStreamRequest = {
getMessage?: () => test$TestMessage;
setMessage?: (message: test$TestMessage) => void;
clearMessage?: () => void;
hasMessage?: () => boolean;
};
export type TestNoStreamReply = {
getMessage?: () => test$TestMessage;
setMessage?: (message: test$TestMessage) => void;
clearMessage?: () => void;
hasMessage?: () => boolean;
getErrMsg?: () => string;
setErrMsg?: (err_msg: string) => void;
};
export type TestStreamRequestRequest = {
getMessage?: () => test$TestMessage;
setMessage?: (message: test$TestMessage) => void;
clearMessage?: () => void;
hasMessage?: () => boolean;
};
export type TestStreamRequestReply = {
getMessage?: () => test$TestMessage;
setMessage?: (message: test$TestMessage) => void;
clearMessage?: () => void;
hasMessage?: () => boolean;
getErrMsg?: () => string;
setErrMsg?: (err_msg: string) => void;
};
export type TestStreamReplyRequest = {
getMessage?: () => test$TestMessage;
setMessage?: (message: test$TestMessage) => void;
clearMessage?: () => void;
hasMessage?: () => boolean;
};
export type TestStreamReplyReply = {
getMessage?: () => test$TestMessage;
setMessage?: (message: test$TestMessage) => void;
clearMessage?: () => void;
hasMessage?: () => boolean;
getErrMsg?: () => string;
setErrMsg?: (err_msg: string) => void;
};
export type TestStreamBothRequest = {
getMessage?: () => test$TestMessage;
setMessage?: (message: test$TestMessage) => void;
clearMessage?: () => void;
hasMessage?: () => boolean;
};
export type TestStreamBothReply = {
getMessage?: () => test$TestMessage;
setMessage?: (message: test$TestMessage) => void;
clearMessage?: () => void;
hasMessage?: () => boolean;
getErrMsg?: () => string;
setErrMsg?: (err_msg: string) => void;
};
const serializeToBase64 = (byteArray: Uint8Array): string => base64.fromByteArray(byteArray)
const deserializeFromBase64 = (base64Encoded: string): Uint8Array => new Uint8Array(base64.toByteArray(base64Encoded))
function serialize_test_TestNoStreamRequest(arg : TestNoStreamRequest): string {
if (!(arg instanceof test_pb.TestNoStreamRequest)) {
throw new Error('Expected argument of type TestNoStreamRequest') throw new Error('Expected argument of type TestNoStreamRequest')
} }
return new Buffer(arg.serializeBinary()) return serializeToBase64(arg.serializeBinary())
} }
function deserialize_test_TestNoStreamRequest(buffer_arg: Array<number>) { function deserialize_test_TestNoStreamRequest(base64Encoded: string): TestNoStreamRequest {
return pbFile.TestNoStreamRequest.deserializeBinary(new Uint8Array(buffer_arg)) return test_pb.TestNoStreamRequest.deserializeBinary(deserializeFromBase64(base64Encoded))
} }
function serialize_test_TestNoStreamReply(arg: TestNoStreamReply) { function serialize_test_TestNoStreamReply(arg : TestNoStreamReply): string {
if (!(arg instanceof pbFile.TestNoStreamReply)) { if (!(arg instanceof test_pb.TestNoStreamReply)) {
throw new Error('Expected argument of type TestNoStreamReply') throw new Error('Expected argument of type TestNoStreamReply')
} }
return new Buffer(arg.serializeBinary()) return serializeToBase64(arg.serializeBinary())
} }
function deserialize_test_TestNoStreamReply(buffer_arg: Array<number>) { function deserialize_test_TestNoStreamReply(base64Encoded: string): TestNoStreamReply {
return pbFile.TestNoStreamReply.deserializeBinary(new Uint8Array(buffer_arg)) return test_pb.TestNoStreamReply.deserializeBinary(deserializeFromBase64(base64Encoded))
} }
function serialize_test_TestStreamRequestRequest(arg: TestStreamRequestRequest) {
if (!(arg instanceof pbFile.TestStreamRequestRequest)) { function serialize_test_TestStreamRequestRequest(arg : TestStreamRequestRequest): string {
if (!(arg instanceof test_pb.TestStreamRequestRequest)) {
throw new Error('Expected argument of type TestStreamRequestRequest') throw new Error('Expected argument of type TestStreamRequestRequest')
} }
return new Buffer(arg.serializeBinary()) return serializeToBase64(arg.serializeBinary())
} }
function deserialize_test_TestStreamRequestRequest(buffer_arg: Array<number>) { function deserialize_test_TestStreamRequestRequest(base64Encoded: string): TestStreamRequestRequest {
return pbFile.TestStreamRequestRequest.deserializeBinary(new Uint8Array(buffer_arg)) return test_pb.TestStreamRequestRequest.deserializeBinary(deserializeFromBase64(base64Encoded))
} }
function serialize_test_TestStreamRequestReply(arg: TestStreamRequestReply) { function serialize_test_TestStreamRequestReply(arg : TestStreamRequestReply): string {
if (!(arg instanceof pbFile.TestStreamRequestReply)) { if (!(arg instanceof test_pb.TestStreamRequestReply)) {
throw new Error('Expected argument of type TestStreamRequestReply') throw new Error('Expected argument of type TestStreamRequestReply')
} }
return new Buffer(arg.serializeBinary()) return serializeToBase64(arg.serializeBinary())
} }
function deserialize_test_TestStreamRequestReply(buffer_arg: Array<number>) { function deserialize_test_TestStreamRequestReply(base64Encoded: string): TestStreamRequestReply {
return pbFile.TestStreamRequestReply.deserializeBinary(new Uint8Array(buffer_arg)) return test_pb.TestStreamRequestReply.deserializeBinary(deserializeFromBase64(base64Encoded))
} }
function serialize_test_TestStreamReplyRequest(arg: TestStreamReplyRequest) {
if (!(arg instanceof pbFile.TestStreamReplyRequest)) { function serialize_test_TestStreamReplyRequest(arg : TestStreamReplyRequest): string {
if (!(arg instanceof test_pb.TestStreamReplyRequest)) {
throw new Error('Expected argument of type TestStreamReplyRequest') throw new Error('Expected argument of type TestStreamReplyRequest')
} }
return new Buffer(arg.serializeBinary()) return serializeToBase64(arg.serializeBinary())
} }
function deserialize_test_TestStreamReplyRequest(buffer_arg: Array<number>) { function deserialize_test_TestStreamReplyRequest(base64Encoded: string): TestStreamReplyRequest {
return pbFile.TestStreamReplyRequest.deserializeBinary(new Uint8Array(buffer_arg)) return test_pb.TestStreamReplyRequest.deserializeBinary(deserializeFromBase64(base64Encoded))
} }
function serialize_test_TestStreamReplyReply(arg: TestStreamReplyReply) { function serialize_test_TestStreamReplyReply(arg : TestStreamReplyReply): string {
if (!(arg instanceof pbFile.TestStreamReplyReply)) { if (!(arg instanceof test_pb.TestStreamReplyReply)) {
throw new Error('Expected argument of type TestStreamReplyReply') throw new Error('Expected argument of type TestStreamReplyReply')
} }
return new Buffer(arg.serializeBinary()) return serializeToBase64(arg.serializeBinary())
} }
function deserialize_test_TestStreamReplyReply(buffer_arg: Array<number>) { function deserialize_test_TestStreamReplyReply(base64Encoded: string): TestStreamReplyReply {
return pbFile.TestStreamReplyReply.deserializeBinary(new Uint8Array(buffer_arg)) return test_pb.TestStreamReplyReply.deserializeBinary(deserializeFromBase64(base64Encoded))
} }
function serialize_test_TestStreamBothRequest(arg: TestStreamBothRequest) {
if (!(arg instanceof pbFile.TestStreamBothRequest)) { function serialize_test_TestStreamBothRequest(arg : TestStreamBothRequest): string {
if (!(arg instanceof test_pb.TestStreamBothRequest)) {
throw new Error('Expected argument of type TestStreamBothRequest') throw new Error('Expected argument of type TestStreamBothRequest')
} }
return new Buffer(arg.serializeBinary()) return serializeToBase64(arg.serializeBinary())
} }
function deserialize_test_TestStreamBothRequest(buffer_arg: Array<number>) { function deserialize_test_TestStreamBothRequest(base64Encoded: string): TestStreamBothRequest {
return pbFile.TestStreamBothRequest.deserializeBinary(new Uint8Array(buffer_arg)) return test_pb.TestStreamBothRequest.deserializeBinary(deserializeFromBase64(base64Encoded))
} }
function serialize_test_TestStreamBothReply(arg: TestStreamBothReply) { function serialize_test_TestStreamBothReply(arg : TestStreamBothReply): string {
if (!(arg instanceof pbFile.TestStreamBothReply)) { if (!(arg instanceof test_pb.TestStreamBothReply)) {
throw new Error('Expected argument of type TestStreamBothReply') throw new Error('Expected argument of type TestStreamBothReply')
} }
return new Buffer(arg.serializeBinary()) return serializeToBase64(arg.serializeBinary())
} }
function deserialize_test_TestStreamBothReply(buffer_arg: Array<number>) { function deserialize_test_TestStreamBothReply(base64Encoded: string): TestStreamBothReply {
return pbFile.TestStreamBothReply.deserializeBinary(new Uint8Array(buffer_arg)) return test_pb.TestStreamBothReply.deserializeBinary(deserializeFromBase64(base64Encoded))
} }
export const TestServiceService = { export default {
TestService: {
testNoStream: { testNoStream: {
path: '/test.TestService/TestNoStream', path: '/test.TestService/TestNoStream',
requestStream: false, requestStream: false,
responseStream: false, responseStream: false,
requestType: pbFile.TestNoStreamRequest, requestType: test_pb.TestNoStreamRequest,
responseType: pbFile.TestNoStreamReply, responseType: test_pb.TestNoStreamReply,
requestSerialize: serialize_test_TestNoStreamRequest, requestSerialize: serialize_test_TestNoStreamRequest,
requestDeserialize: deserialize_test_TestNoStreamRequest, requestDeserialize: deserialize_test_TestNoStreamRequest,
responseSerialize: serialize_test_TestNoStreamReply, responseSerialize: serialize_test_TestNoStreamReply,
@@ -169,8 +276,8 @@ export const TestServiceService = {
path: '/test.TestService/TestStreamRequest', path: '/test.TestService/TestStreamRequest',
requestStream: true, requestStream: true,
responseStream: false, responseStream: false,
requestType: pbFile.TestStreamRequestRequest, requestType: test_pb.TestStreamRequestRequest,
responseType: pbFile.TestStreamRequestReply, responseType: test_pb.TestStreamRequestReply,
requestSerialize: serialize_test_TestStreamRequestRequest, requestSerialize: serialize_test_TestStreamRequestRequest,
requestDeserialize: deserialize_test_TestStreamRequestRequest, requestDeserialize: deserialize_test_TestStreamRequestRequest,
responseSerialize: serialize_test_TestStreamRequestReply, responseSerialize: serialize_test_TestStreamRequestReply,
@@ -180,8 +287,8 @@ export const TestServiceService = {
path: '/test.TestService/TestStreamReply', path: '/test.TestService/TestStreamReply',
requestStream: false, requestStream: false,
responseStream: true, responseStream: true,
requestType: pbFile.TestStreamReplyRequest, requestType: test_pb.TestStreamReplyRequest,
responseType: pbFile.TestStreamReplyReply, responseType: test_pb.TestStreamReplyReply,
requestSerialize: serialize_test_TestStreamReplyRequest, requestSerialize: serialize_test_TestStreamReplyRequest,
requestDeserialize: deserialize_test_TestStreamReplyRequest, requestDeserialize: deserialize_test_TestStreamReplyRequest,
responseSerialize: serialize_test_TestStreamReplyReply, responseSerialize: serialize_test_TestStreamReplyReply,
@@ -191,14 +298,14 @@ export const TestServiceService = {
path: '/test.TestService/TestStreamBoth', path: '/test.TestService/TestStreamBoth',
requestStream: true, requestStream: true,
responseStream: true, responseStream: true,
requestType: pbFile.TestStreamBothRequest, requestType: test_pb.TestStreamBothRequest,
responseType: pbFile.TestStreamBothReply, responseType: test_pb.TestStreamBothReply,
requestSerialize: serialize_test_TestStreamBothRequest, requestSerialize: serialize_test_TestStreamBothRequest,
requestDeserialize: deserialize_test_TestStreamBothRequest, requestDeserialize: deserialize_test_TestStreamBothRequest,
responseSerialize: serialize_test_TestStreamBothReply, responseSerialize: serialize_test_TestStreamBothReply,
responseDeserialize: deserialize_test_TestStreamBothReply, responseDeserialize: deserialize_test_TestStreamBothReply,
}, },
} }
export const TestServiceClient = grpc.makeGenericClientConstructor(TestServiceService) }

View File

@@ -27,10 +27,19 @@ message TestMessage {
repeated int64 p = 16; repeated int64 p = 16;
repeated float q = 17; repeated float q = 17;
repeated double r = 18; repeated double r = 18;
enum s {
message TestNestedMessage {
string s = 1;
int32 t = 2;
}
enum TestNestedEnum {
ELEMENT_C = 0; ELEMENT_C = 0;
ELEMENT_D = 1; ELEMENT_D = 1;
} }
TestEnum u = 19;
TestNestedEnum v = 20;
repeated TestNestedMessage w = 21;
} }
message TestNoStreamRequest { TestMessage message = 1; } message TestNoStreamRequest { TestMessage message = 1; }

View File

@@ -1,58 +1,110 @@
// @flow // @flow
// GENERATED CODE -- DO NOT EDIT! // GENERATED CODE -- DO NOT EDIT!
{{$Package:=.File.Package}}
import grpc from 'grpc' {{- $Package:=.File.Package}}
import pbFile from './pbFile.js'
import base64 from 'base64-js'
import {{$Package}}_pb from './{{$Package}}_pb'
{{- range .File.Dependency}}
import {{. | replace "/" "_" | trimSuffix ".proto" }}_pb from '../{{. | trimSuffix ".proto" }}_pb'
{{- end}}
{{- define "fieldMethods"}}
{{- if isFieldRepeated .}}
get{{.Name | camelCase}}List?: () => {{. | jsType}};
set{{.Name | camelCase}}List?: ({{.Name}}: {{. | jsType}}) => void;
add{{.Name | camelCase}}?: ({{.Name}}: {{. | jsType | trimPrefix "Array<" | trimSuffix ">"}}) => void;
clear{{.Name | camelCase}}List?: () => void;
{{- else}}
get{{.Name | camelCase}}?: () => {{. | jsType}};
set{{.Name | camelCase}}?: ({{.Name}}: {{. | jsType}}) => void;
{{- if isFieldMessage .}}
clear{{.Name | camelCase}}?: () => void;
has{{.Name | camelCase}}?: () => boolean;
{{- end}}
{{- end}}
{{- end}}
{{range .File.EnumType}} {{range .File.EnumType}}
export type {{.Name}} = {{range .Value}} export type {{.Name}} = {|
| '{{.Name}}'{{end}} {{- range .Value}}
;{{end}} {{.Name}}?: {{.Number}};
{{range .File.MessageType}} {{- end}}
export type {{.Name}} = {|{{range .Field}}
{{.Name}}?: {{. | jsType}};{{end}}{{range .EnumType}}
{{.Name}}?:{{range .Value}}
| '{{.Name}}'{{end}}
;{{end}}
|}; |};
{{end}} {{- end}}
{{- range .File.MessageType}}
{{- $MessageType := .Name}}
{{range .EnumType}}
export type {{$MessageType}}${{.Name}} = {|
{{- range .Value}}
{{.Name}}?: {{.Number}};
{{- end}}
|};
{{- end}}
{{range .NestedType}}
export type {{$MessageType}}${{.Name}} = {
{{- range .Field}}
{{- template "fieldMethods" .}}
{{- end}}
};
{{- end}}
export type {{.Name}} = {
{{- range .Field}}
{{- template "fieldMethods" .}}
{{- end}}
};
{{- end}}
const serializeToBase64 = (byteArray: Uint8Array): string => base64.fromByteArray(byteArray)
const deserializeFromBase64 = (base64Encoded: string): Uint8Array => new Uint8Array(base64.toByteArray(base64Encoded))
{{range .File.Service}}{{range .Method}} {{range .File.Service}}{{range .Method}}
function serialize_{{$Package}}_{{.InputType | shortType}}(arg: {{.InputType | shortType}}) { function serialize_{{$Package}}_{{.InputType | shortType}}(arg : {{.InputType | shortType}}): string {
if (!(arg instanceof pbFile.{{.InputType | shortType}})) { if (!(arg instanceof {{$Package}}_pb.{{.InputType | shortType}})) {
throw new Error('Expected argument of type {{.InputType | shortType}}') throw new Error('Expected argument of type {{.InputType | shortType}}')
} }
return new Buffer(arg.serializeBinary()) return serializeToBase64(arg.serializeBinary())
} }
function deserialize_{{$Package}}_{{.InputType | shortType}}(buffer_arg: Array<number>) { function deserialize_{{$Package}}_{{.InputType | shortType}}(base64Encoded: string): {{.InputType | shortType}} {
return pbFile.{{.InputType | shortType}}.deserializeBinary(new Uint8Array(buffer_arg)) return {{$Package}}_pb.{{.InputType | shortType}}.deserializeBinary(deserializeFromBase64(base64Encoded))
} }
function serialize_{{$Package}}_{{.OutputType | shortType}}(arg: {{.OutputType | shortType}}) { function serialize_{{$Package}}_{{.OutputType | shortType}}(arg : {{.OutputType | shortType}}): string {
if (!(arg instanceof pbFile.{{.OutputType | shortType}})) { if (!(arg instanceof {{$Package}}_pb.{{.OutputType | shortType}})) {
throw new Error('Expected argument of type {{.OutputType | shortType}}') throw new Error('Expected argument of type {{.OutputType | shortType}}')
} }
return new Buffer(arg.serializeBinary()) return serializeToBase64(arg.serializeBinary())
} }
function deserialize_{{$Package}}_{{.OutputType | shortType}}(buffer_arg: Array<number>) { function deserialize_{{$Package}}_{{.OutputType | shortType}}(base64Encoded: string): {{.OutputType | shortType}} {
return pbFile.{{.OutputType | shortType}}.deserializeBinary(new Uint8Array(buffer_arg)) return {{$Package}}_pb.{{.OutputType | shortType}}.deserializeBinary(deserializeFromBase64(base64Encoded))
} }
{{end}}{{end}} {{end}}{{end}}
{{range .File.Service}} export default {
export const {{.Name}}Service = { {{range .File.Service}}
{{.Name}}: {
{{$serviceName:=.Name}} {{$serviceName:=.Name}}
{{range .Method}}{{.Name | lowerCamelCase}}: { {{range .Method}}{{.Name | lowerCamelCase}}: {
path: '/{{$Package}}.{{$serviceName}}/{{.Name}}', path: '/{{$Package}}.{{$serviceName}}/{{.Name}}',
requestStream: {{.ClientStreaming | default "false"}}, requestStream: {{.ClientStreaming | default "false"}},
responseStream: {{.ServerStreaming | default "false"}}, responseStream: {{.ServerStreaming | default "false"}},
requestType: pbFile.{{.InputType | shortType}}, requestType: {{$Package}}_pb.{{.InputType | shortType}},
responseType: pbFile.{{.OutputType | shortType}}, responseType: {{$Package}}_pb.{{.OutputType | shortType}},
requestSerialize: serialize_{{$Package}}_{{.InputType | shortType}}, requestSerialize: serialize_{{$Package}}_{{.InputType | shortType}},
requestDeserialize: deserialize_{{$Package}}_{{.InputType | shortType}}, requestDeserialize: deserialize_{{$Package}}_{{.InputType | shortType}},
responseSerialize: serialize_{{$Package}}_{{.OutputType | shortType}}, responseSerialize: serialize_{{$Package}}_{{.OutputType | shortType}},
responseDeserialize: deserialize_{{$Package}}_{{.OutputType | shortType}}, responseDeserialize: deserialize_{{$Package}}_{{.OutputType | shortType}},
}, },
{{end}} {{end}}
}
{{end}}
} }
export const {{.Name}}Client = grpc.makeGenericClientConstructor({{.Name}}Service){{end}}

View File

@@ -0,0 +1,2 @@
all:
go generate

View File

@@ -0,0 +1,4 @@
package example
//go:generate protoc --go_out=./gen/ example.proto
//go:generate protoc --gotemplate_out=./gen/ example.proto

View File

@@ -0,0 +1,16 @@
syntax = "proto3";
package example;
service Sum {
rpc Sum(SumRequest) returns (SumReply) {};
}
message SumRequest {
int32 a = 1;
int32 b = 2;
}
message SumReply {
int32 c = 1;
}

View File

@@ -0,0 +1,11 @@
// Code generated by protoc-gen-gotemplate
package example
// Methods
// -------
// * Sum
//
// Message types
// -------------
// * SumRequest
// * SumReply

View File

@@ -0,0 +1,89 @@
// Code generated by protoc-gen-go.
// source: example.proto
// DO NOT EDIT!
/*
Package example is a generated protocol buffer package.
It is generated from these files:
example.proto
It has these top-level messages:
SumRequest
SumReply
*/
package example
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type SumRequest struct {
A int32 `protobuf:"varint,1,opt,name=a" json:"a,omitempty"`
B int32 `protobuf:"varint,2,opt,name=b" json:"b,omitempty"`
}
func (m *SumRequest) Reset() { *m = SumRequest{} }
func (m *SumRequest) String() string { return proto.CompactTextString(m) }
func (*SumRequest) ProtoMessage() {}
func (*SumRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *SumRequest) GetA() int32 {
if m != nil {
return m.A
}
return 0
}
func (m *SumRequest) GetB() int32 {
if m != nil {
return m.B
}
return 0
}
type SumReply struct {
C int32 `protobuf:"varint,1,opt,name=c" json:"c,omitempty"`
}
func (m *SumReply) Reset() { *m = SumReply{} }
func (m *SumReply) String() string { return proto.CompactTextString(m) }
func (*SumReply) ProtoMessage() {}
func (*SumReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *SumReply) GetC() int32 {
if m != nil {
return m.C
}
return 0
}
func init() {
proto.RegisterType((*SumRequest)(nil), "example.SumRequest")
proto.RegisterType((*SumReply)(nil), "example.SumReply")
}
func init() { proto.RegisterFile("example.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 124 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4d, 0xad, 0x48, 0xcc,
0x2d, 0xc8, 0x49, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x87, 0x72, 0x95, 0x34, 0xb8,
0xb8, 0x82, 0x4b, 0x73, 0x83, 0x52, 0x0b, 0x4b, 0x53, 0x8b, 0x4b, 0x84, 0x78, 0xb8, 0x18, 0x13,
0x25, 0x18, 0x15, 0x18, 0x35, 0x58, 0x83, 0x18, 0x13, 0x41, 0xbc, 0x24, 0x09, 0x26, 0x08, 0x2f,
0x49, 0x49, 0x82, 0x8b, 0x03, 0xac, 0xb2, 0x20, 0xa7, 0x12, 0x24, 0x93, 0x0c, 0x53, 0x97, 0x6c,
0x64, 0xc6, 0xc5, 0x1c, 0x5c, 0x9a, 0x2b, 0xa4, 0x0f, 0xa1, 0x84, 0xf5, 0x60, 0x56, 0x21, 0x0c,
0x96, 0x12, 0x44, 0x15, 0x2c, 0xc8, 0xa9, 0x54, 0x62, 0x48, 0x62, 0x03, 0xbb, 0xc5, 0x18, 0x10,
0x00, 0x00, 0xff, 0xff, 0x2b, 0xf1, 0xe9, 0x56, 0x9c, 0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,14 @@
// Code generated by protoc-gen-gotemplate
package {{.File.Package}}
// Methods
// -------
{{- range .Service.Method}}
// * {{.Name}}
{{- end}}
//
// Message types
// -------------
{{- range .File.MessageType}}
// * {{.Name}}
{{- end}}

View File

@@ -1 +1,2 @@
/vendor/
/server /server

View File

@@ -9,10 +9,11 @@ service_name = $(word 2,$(subst /, ,$1))
build: server build: server
server: $(TARGETS_GO) $(TARGETS_TMPL) server: $(TARGETS_GO) $(TARGETS_TMPL)
glide install
go build -o server . go build -o server .
$(TARGETS_GO): %_go: $(TARGETS_GO): %_go:
protoc --gogo_out=plugins=grpc:. "$*" protoc --go_out=plugins=grpc:. "$*"
@mkdir -p services/$(call service_name,$*)/gen/pb @mkdir -p services/$(call service_name,$*)/gen/pb
@mv ./services/$(call service_name,$*)/$(call service_name,$*).pb.go ./services/$(call service_name,$*)/gen/pb/pb.go @mv ./services/$(call service_name,$*)/$(call service_name,$*).pb.go ./services/$(call service_name,$*)/gen/pb/pb.go

48
examples/go-kit/glide.lock generated Normal file
View File

@@ -0,0 +1,48 @@
hash: e225ab17b49f8d6601b2bd813d43ad34ee04380d29c278c11919efd454c7b2d7
updated: 2017-03-16T17:03:34.437968115+01:00
imports:
- name: github.com/dgrijalva/jwt-go
version: 2268707a8f0843315e2004ee4f1d021dc08baedf
- name: github.com/go-kit/kit
version: fadad6fffe0466b19df9efd9acde5c9a52df5fa4
subpackages:
- auth/jwt
- endpoint
- log
- transport/grpc
- transport/http
- name: github.com/go-logfmt/logfmt
version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5
- name: github.com/go-stack/stack
version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82
- name: github.com/golang/protobuf
version: c9c7427a2a70d2eb3bafa0ab2dc163e45f143317
subpackages:
- proto
- name: github.com/gorilla/handlers
version: 3a5767ca75ece5f7f1440b1d16975247f8d8b221
- name: github.com/kr/logfmt
version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0
- name: golang.org/x/net
version: a6577fac2d73be281a500b310739095313165611
subpackages:
- context
- context/ctxhttp
- http2
- http2/hpack
- idna
- internal/timeseries
- lex/httplex
- trace
- name: google.golang.org/grpc
version: 777daa17ff9b5daef1cfdf915088a2ada3332bf0
subpackages:
- codes
- credentials
- grpclog
- internal
- metadata
- naming
- peer
- transport
testImports: []

View File

@@ -0,0 +1,20 @@
package: github.com/moul/protoc-gen-gotemplate/examples/go-kit
import:
- package: github.com/go-kit/kit
subpackages:
- auth/jwt
- endpoint
- log
- transport/grpc
- transport/http
- package: github.com/golang/protobuf
subpackages:
- proto
version: c9c7427a2a70d2eb3bafa0ab2dc163e45f143317
- package: github.com/gorilla/handlers
- package: golang.org/x/net
subpackages:
- context
- http2
version: a6577fac2d73be281a500b310739095313165611
- package: google.golang.org/grpc

View File

@@ -1,7 +1,6 @@
package main package main
import ( import (
"context"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
@@ -34,37 +33,36 @@ import (
func main() { func main() {
mux := http.NewServeMux() mux := http.NewServeMux()
ctx := context.Background()
errc := make(chan error) errc := make(chan error)
s := grpc.NewServer() s := grpc.NewServer()
var logger log.Logger var logger log.Logger
{ {
logger = log.NewLogfmtLogger(os.Stdout) logger = log.NewLogfmtLogger(os.Stdout)
logger = log.NewContext(logger).With("ts", log.DefaultTimestampUTC) logger = log.With(logger, "ts", log.DefaultTimestampUTC)
logger = log.NewContext(logger).With("caller", log.DefaultCaller) logger = log.With(logger, "caller", log.DefaultCaller)
} }
// initialize services // initialize services
{ {
svc := session_svc.New() svc := session_svc.New()
endpoints := session_endpoints.MakeEndpoints(svc) endpoints := session_endpoints.MakeEndpoints(svc)
srv := session_grpctransport.MakeGRPCServer(ctx, endpoints) srv := session_grpctransport.MakeGRPCServer(endpoints)
session_pb.RegisterSessionServiceServer(s, srv) session_pb.RegisterSessionServiceServer(s, srv)
session_httptransport.RegisterHandlers(ctx, svc, mux, endpoints) session_httptransport.RegisterHandlers(svc, mux, endpoints)
} }
{ {
svc := sprint_svc.New() svc := sprint_svc.New()
endpoints := sprint_endpoints.MakeEndpoints(svc) endpoints := sprint_endpoints.MakeEndpoints(svc)
srv := sprint_grpctransport.MakeGRPCServer(ctx, endpoints) srv := sprint_grpctransport.MakeGRPCServer(endpoints)
sprint_pb.RegisterSprintServiceServer(s, srv) sprint_pb.RegisterSprintServiceServer(s, srv)
sprint_httptransport.RegisterHandlers(ctx, svc, mux, endpoints) sprint_httptransport.RegisterHandlers(svc, mux, endpoints)
} }
{ {
svc := user_svc.New() svc := user_svc.New()
endpoints := user_endpoints.MakeEndpoints(svc) endpoints := user_endpoints.MakeEndpoints(svc)
srv := user_grpctransport.MakeGRPCServer(ctx, endpoints) srv := user_grpctransport.MakeGRPCServer(endpoints)
user_pb.RegisterUserServiceServer(s, srv) user_pb.RegisterUserServiceServer(s, srv)
user_httptransport.RegisterHandlers(ctx, svc, mux, endpoints) user_httptransport.RegisterHandlers(svc, mux, endpoints)
} }
// start servers // start servers
@@ -75,13 +73,13 @@ func main() {
}() }()
go func() { go func() {
logger := log.NewContext(logger).With("transport", "HTTP") logger := log.With(logger, "transport", "HTTP")
logger.Log("addr", ":8000") logger.Log("addr", ":8000")
errc <- http.ListenAndServe(":8000", handlers.LoggingHandler(os.Stderr, mux)) errc <- http.ListenAndServe(":8000", handlers.LoggingHandler(os.Stderr, mux))
}() }()
go func() { go func() {
logger := log.NewContext(logger).With("transport", "gRPC") logger := log.With(logger, "transport", "gRPC")
ln, err := net.Listen("tcp", ":9000") ln, err := net.Listen("tcp", ":9000")
if err != nil { if err != nil {
errc <- err errc <- err

View File

@@ -1,11 +1,12 @@
package session_clientgrpc package session_clientgrpc
import ( import (
context "context"
jwt "github.com/go-kit/kit/auth/jwt" jwt "github.com/go-kit/kit/auth/jwt"
"github.com/go-kit/kit/endpoint" "github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/log" "github.com/go-kit/kit/log"
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
context "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints" endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/endpoints"

View File

@@ -1,14 +1,17 @@
package session_endpoints package session_endpoints
import ( import (
context "context"
"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" pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
context "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
) )
var _ = endpoint.Chain
var _ = fmt.Errorf var _ = fmt.Errorf
var _ = context.Background
type StreamEndpoint func(server interface{}, req interface{}) (err error) type StreamEndpoint func(server interface{}, req interface{}) (err error)
@@ -16,7 +19,7 @@ type Endpoints struct {
LoginEndpoint endpoint.Endpoint LoginEndpoint endpoint.Endpoint
} }
func (e *Endpoints) Login(ctx context.Context, in *pb.LoginRequest) (*pb.LoginResponse, error) { func (e *Endpoints) Login(ctx oldcontext.Context, in *pb.LoginRequest) (*pb.LoginResponse, error) {
out, err := e.LoginEndpoint(ctx, in) out, err := e.LoginEndpoint(ctx, in)
if err != nil { if err != nil {
return &pb.LoginResponse{ErrMsg: err.Error()}, err return &pb.LoginResponse{ErrMsg: err.Error()}, err

View File

@@ -1,4 +1,4 @@
// Code generated by protoc-gen-gogo. // Code generated by protoc-gen-go.
// source: services/session/session.proto // source: services/session/session.proto
// DO NOT EDIT! // DO NOT EDIT!
@@ -14,7 +14,7 @@ It has these top-level messages:
*/ */
package session package session
import proto "github.com/gogo/protobuf/proto" import proto "github.com/golang/protobuf/proto"
import fmt "fmt" import fmt "fmt"
import math "math" import math "math"
@@ -32,17 +32,17 @@ var _ = math.Inf
// is compatible with the proto package it is being compiled against. // is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the // A compilation error at this line likely means your copy of the
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type LoginRequest struct { type LoginRequest struct {
Username string `protobuf:"bytes,1,opt,name=username,proto3" json:"username,omitempty"` Username string `protobuf:"bytes,1,opt,name=username" json:"username,omitempty"`
Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` Password string `protobuf:"bytes,2,opt,name=password" json:"password,omitempty"`
} }
func (m *LoginRequest) Reset() { *m = LoginRequest{} } func (m *LoginRequest) Reset() { *m = LoginRequest{} }
func (m *LoginRequest) String() string { return proto.CompactTextString(m) } func (m *LoginRequest) String() string { return proto.CompactTextString(m) }
func (*LoginRequest) ProtoMessage() {} func (*LoginRequest) ProtoMessage() {}
func (*LoginRequest) Descriptor() ([]byte, []int) { return fileDescriptorSession, []int{0} } func (*LoginRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *LoginRequest) GetUsername() string { func (m *LoginRequest) GetUsername() string {
if m != nil { if m != nil {
@@ -59,14 +59,14 @@ func (m *LoginRequest) GetPassword() string {
} }
type LoginResponse struct { type LoginResponse struct {
Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` Token string `protobuf:"bytes,1,opt,name=token" json:"token,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg" json:"err_msg,omitempty"`
} }
func (m *LoginResponse) Reset() { *m = LoginResponse{} } func (m *LoginResponse) Reset() { *m = LoginResponse{} }
func (m *LoginResponse) String() string { return proto.CompactTextString(m) } func (m *LoginResponse) String() string { return proto.CompactTextString(m) }
func (*LoginResponse) ProtoMessage() {} func (*LoginResponse) ProtoMessage() {}
func (*LoginResponse) Descriptor() ([]byte, []int) { return fileDescriptorSession, []int{1} } func (*LoginResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *LoginResponse) GetToken() string { func (m *LoginResponse) GetToken() string {
if m != nil { if m != nil {
@@ -159,9 +159,9 @@ var _SessionService_serviceDesc = grpc.ServiceDesc{
Metadata: "services/session/session.proto", Metadata: "services/session/session.proto",
} }
func init() { proto.RegisterFile("services/session/session.proto", fileDescriptorSession) } func init() { proto.RegisterFile("services/session/session.proto", fileDescriptor0) }
var fileDescriptorSession = []byte{ var fileDescriptor0 = []byte{
// 188 bytes of a gzipped FileDescriptorProto // 188 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0x2b, 0x4e, 0x2d, 0x2a, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0x2b, 0x4e, 0x2d, 0x2a,
0xcb, 0x4c, 0x4e, 0x2d, 0xd6, 0x2f, 0x4e, 0x2d, 0x2e, 0xce, 0xcc, 0xcf, 0x83, 0xd1, 0x7a, 0x05, 0xcb, 0x4c, 0x4e, 0x2d, 0xd6, 0x2f, 0x4e, 0x2d, 0x2e, 0xce, 0xcc, 0xcf, 0x83, 0xd1, 0x7a, 0x05,

View File

@@ -1,10 +1,11 @@
package session_grpctransport package session_grpctransport
import ( import (
context "context"
"fmt" "fmt"
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
context "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 "github.com/moul/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 "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
@@ -13,12 +14,12 @@ import (
// avoid import errors // avoid import errors
var _ = fmt.Errorf var _ = fmt.Errorf
func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.SessionServiceServer { func MakeGRPCServer(endpoints endpoints.Endpoints) pb.SessionServiceServer {
options := []grpctransport.ServerOption{} var options []grpctransport.ServerOption
_ = options
return &grpcServer{ return &grpcServer{
login: grpctransport.NewServer( login: grpctransport.NewServer(
ctx,
endpoints.LoginEndpoint, endpoints.LoginEndpoint,
decodeRequest, decodeRequest,
encodeLoginResponse, encodeLoginResponse,
@@ -31,7 +32,7 @@ type grpcServer struct {
login grpctransport.Handler login grpctransport.Handler
} }
func (s *grpcServer) Login(ctx context.Context, req *pb.LoginRequest) (*pb.LoginResponse, error) { func (s *grpcServer) Login(ctx oldcontext.Context, req *pb.LoginRequest) (*pb.LoginResponse, error) {
_, rep, err := s.login.ServeGRPC(ctx, req) _, rep, err := s.login.ServeGRPC(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -1,8 +1,8 @@
package session_httptransport package session_httptransport
import ( import (
"context"
"encoding/json" "encoding/json"
context "golang.org/x/net/context"
"log" "log"
"net/http" "net/http"
@@ -12,9 +12,12 @@ import (
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb" pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/session/gen/pb"
) )
func MakeLoginHandler(ctx context.Context, svc pb.SessionServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server { var _ = log.Printf
var _ = gokit_endpoint.Chain
var _ = httptransport.NewClient
func MakeLoginHandler(svc pb.SessionServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer( return httptransport.NewServer(
ctx,
endpoint, endpoint,
decodeLoginRequest, decodeLoginRequest,
encodeResponse, encodeResponse,
@@ -34,10 +37,10 @@ func encodeResponse(ctx context.Context, w http.ResponseWriter, response interfa
return json.NewEncoder(w).Encode(response) return json.NewEncoder(w).Encode(response)
} }
func RegisterHandlers(ctx context.Context, svc pb.SessionServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error { func RegisterHandlers(svc pb.SessionServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error {
log.Println("new HTTP endpoint: \"/Login\" (service=Session)") log.Println("new HTTP endpoint: \"/Login\" (service=Session)")
mux.Handle("/Login", MakeLoginHandler(ctx, svc, endpoints.LoginEndpoint)) mux.Handle("/Login", MakeLoginHandler(svc, endpoints.LoginEndpoint))
return nil return nil
} }

View File

@@ -1,11 +1,12 @@
package sprint_clientgrpc package sprint_clientgrpc
import ( import (
context "context"
jwt "github.com/go-kit/kit/auth/jwt" jwt "github.com/go-kit/kit/auth/jwt"
"github.com/go-kit/kit/endpoint" "github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/log" "github.com/go-kit/kit/log"
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
context "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints" endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/endpoints"

View File

@@ -1,14 +1,17 @@
package sprint_endpoints package sprint_endpoints
import ( import (
context "context"
"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" pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
context "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
) )
var _ = endpoint.Chain
var _ = fmt.Errorf var _ = fmt.Errorf
var _ = context.Background
type StreamEndpoint func(server interface{}, req interface{}) (err error) type StreamEndpoint func(server interface{}, req interface{}) (err error)
@@ -20,7 +23,7 @@ type Endpoints struct {
GetSprintEndpoint endpoint.Endpoint GetSprintEndpoint endpoint.Endpoint
} }
func (e *Endpoints) AddSprint(ctx context.Context, in *pb.AddSprintRequest) (*pb.AddSprintResponse, error) { func (e *Endpoints) AddSprint(ctx oldcontext.Context, in *pb.AddSprintRequest) (*pb.AddSprintResponse, error) {
out, err := e.AddSprintEndpoint(ctx, in) out, err := e.AddSprintEndpoint(ctx, in)
if err != nil { if err != nil {
return &pb.AddSprintResponse{ErrMsg: err.Error()}, err return &pb.AddSprintResponse{ErrMsg: err.Error()}, err
@@ -28,7 +31,7 @@ func (e *Endpoints) AddSprint(ctx context.Context, in *pb.AddSprintRequest) (*pb
return out.(*pb.AddSprintResponse), err return out.(*pb.AddSprintResponse), err
} }
func (e *Endpoints) CloseSprint(ctx context.Context, in *pb.CloseSprintRequest) (*pb.CloseSprintResponse, error) { func (e *Endpoints) CloseSprint(ctx oldcontext.Context, in *pb.CloseSprintRequest) (*pb.CloseSprintResponse, error) {
out, err := e.CloseSprintEndpoint(ctx, in) out, err := e.CloseSprintEndpoint(ctx, in)
if err != nil { if err != nil {
return &pb.CloseSprintResponse{ErrMsg: err.Error()}, err return &pb.CloseSprintResponse{ErrMsg: err.Error()}, err
@@ -36,7 +39,7 @@ func (e *Endpoints) CloseSprint(ctx context.Context, in *pb.CloseSprintRequest)
return out.(*pb.CloseSprintResponse), err return out.(*pb.CloseSprintResponse), err
} }
func (e *Endpoints) GetSprint(ctx context.Context, in *pb.GetSprintRequest) (*pb.GetSprintResponse, error) { func (e *Endpoints) GetSprint(ctx oldcontext.Context, in *pb.GetSprintRequest) (*pb.GetSprintResponse, error) {
out, err := e.GetSprintEndpoint(ctx, in) out, err := e.GetSprintEndpoint(ctx, in)
if err != nil { if err != nil {
return &pb.GetSprintResponse{ErrMsg: err.Error()}, err return &pb.GetSprintResponse{ErrMsg: err.Error()}, err

View File

@@ -1,4 +1,4 @@
// Code generated by protoc-gen-gogo. // Code generated by protoc-gen-go.
// source: services/sprint/sprint.proto // source: services/sprint/sprint.proto
// DO NOT EDIT! // DO NOT EDIT!
@@ -19,7 +19,7 @@ It has these top-level messages:
*/ */
package sprint package sprint
import proto "github.com/gogo/protobuf/proto" import proto "github.com/golang/protobuf/proto"
import fmt "fmt" import fmt "fmt"
import math "math" import math "math"
@@ -37,16 +37,16 @@ var _ = math.Inf
// is compatible with the proto package it is being compiled against. // is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the // A compilation error at this line likely means your copy of the
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type AddSprintRequest struct { type AddSprintRequest struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
} }
func (m *AddSprintRequest) Reset() { *m = AddSprintRequest{} } func (m *AddSprintRequest) Reset() { *m = AddSprintRequest{} }
func (m *AddSprintRequest) String() string { return proto.CompactTextString(m) } func (m *AddSprintRequest) String() string { return proto.CompactTextString(m) }
func (*AddSprintRequest) ProtoMessage() {} func (*AddSprintRequest) ProtoMessage() {}
func (*AddSprintRequest) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{0} } func (*AddSprintRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *AddSprintRequest) GetName() string { func (m *AddSprintRequest) GetName() string {
if m != nil { if m != nil {
@@ -57,13 +57,13 @@ func (m *AddSprintRequest) GetName() string {
type AddSprintResponse struct { type AddSprintResponse struct {
Sprint *Sprint `protobuf:"bytes,1,opt,name=sprint" json:"sprint,omitempty"` Sprint *Sprint `protobuf:"bytes,1,opt,name=sprint" json:"sprint,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg" json:"err_msg,omitempty"`
} }
func (m *AddSprintResponse) Reset() { *m = AddSprintResponse{} } func (m *AddSprintResponse) Reset() { *m = AddSprintResponse{} }
func (m *AddSprintResponse) String() string { return proto.CompactTextString(m) } func (m *AddSprintResponse) String() string { return proto.CompactTextString(m) }
func (*AddSprintResponse) ProtoMessage() {} func (*AddSprintResponse) ProtoMessage() {}
func (*AddSprintResponse) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{1} } func (*AddSprintResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *AddSprintResponse) GetSprint() *Sprint { func (m *AddSprintResponse) GetSprint() *Sprint {
if m != nil { if m != nil {
@@ -80,13 +80,13 @@ func (m *AddSprintResponse) GetErrMsg() string {
} }
type CloseSprintRequest struct { type CloseSprintRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
} }
func (m *CloseSprintRequest) Reset() { *m = CloseSprintRequest{} } func (m *CloseSprintRequest) Reset() { *m = CloseSprintRequest{} }
func (m *CloseSprintRequest) String() string { return proto.CompactTextString(m) } func (m *CloseSprintRequest) String() string { return proto.CompactTextString(m) }
func (*CloseSprintRequest) ProtoMessage() {} func (*CloseSprintRequest) ProtoMessage() {}
func (*CloseSprintRequest) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{2} } func (*CloseSprintRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *CloseSprintRequest) GetId() string { func (m *CloseSprintRequest) GetId() string {
if m != nil { if m != nil {
@@ -96,13 +96,13 @@ func (m *CloseSprintRequest) GetId() string {
} }
type CloseSprintResponse struct { type CloseSprintResponse struct {
ErrMsg string `protobuf:"bytes,1,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` ErrMsg string `protobuf:"bytes,1,opt,name=err_msg,json=errMsg" json:"err_msg,omitempty"`
} }
func (m *CloseSprintResponse) Reset() { *m = CloseSprintResponse{} } func (m *CloseSprintResponse) Reset() { *m = CloseSprintResponse{} }
func (m *CloseSprintResponse) String() string { return proto.CompactTextString(m) } func (m *CloseSprintResponse) String() string { return proto.CompactTextString(m) }
func (*CloseSprintResponse) ProtoMessage() {} func (*CloseSprintResponse) ProtoMessage() {}
func (*CloseSprintResponse) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{3} } func (*CloseSprintResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *CloseSprintResponse) GetErrMsg() string { func (m *CloseSprintResponse) GetErrMsg() string {
if m != nil { if m != nil {
@@ -112,13 +112,13 @@ func (m *CloseSprintResponse) GetErrMsg() string {
} }
type GetSprintRequest struct { type GetSprintRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
} }
func (m *GetSprintRequest) Reset() { *m = GetSprintRequest{} } func (m *GetSprintRequest) Reset() { *m = GetSprintRequest{} }
func (m *GetSprintRequest) String() string { return proto.CompactTextString(m) } func (m *GetSprintRequest) String() string { return proto.CompactTextString(m) }
func (*GetSprintRequest) ProtoMessage() {} func (*GetSprintRequest) ProtoMessage() {}
func (*GetSprintRequest) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{4} } func (*GetSprintRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *GetSprintRequest) GetId() string { func (m *GetSprintRequest) GetId() string {
if m != nil { if m != nil {
@@ -129,13 +129,13 @@ func (m *GetSprintRequest) GetId() string {
type GetSprintResponse struct { type GetSprintResponse struct {
Sprint *Sprint `protobuf:"bytes,1,opt,name=sprint" json:"sprint,omitempty"` Sprint *Sprint `protobuf:"bytes,1,opt,name=sprint" json:"sprint,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg" json:"err_msg,omitempty"`
} }
func (m *GetSprintResponse) Reset() { *m = GetSprintResponse{} } func (m *GetSprintResponse) Reset() { *m = GetSprintResponse{} }
func (m *GetSprintResponse) String() string { return proto.CompactTextString(m) } func (m *GetSprintResponse) String() string { return proto.CompactTextString(m) }
func (*GetSprintResponse) ProtoMessage() {} func (*GetSprintResponse) ProtoMessage() {}
func (*GetSprintResponse) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{5} } func (*GetSprintResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
func (m *GetSprintResponse) GetSprint() *Sprint { func (m *GetSprintResponse) GetSprint() *Sprint {
if m != nil { if m != nil {
@@ -152,15 +152,15 @@ func (m *GetSprintResponse) GetErrMsg() string {
} }
type Sprint struct { type Sprint struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
CreatedAt uint32 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` CreatedAt uint32 `protobuf:"varint,2,opt,name=created_at,json=createdAt" json:"created_at,omitempty"`
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"`
} }
func (m *Sprint) Reset() { *m = Sprint{} } func (m *Sprint) Reset() { *m = Sprint{} }
func (m *Sprint) String() string { return proto.CompactTextString(m) } func (m *Sprint) String() string { return proto.CompactTextString(m) }
func (*Sprint) ProtoMessage() {} func (*Sprint) ProtoMessage() {}
func (*Sprint) Descriptor() ([]byte, []int) { return fileDescriptorSprint, []int{6} } func (*Sprint) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *Sprint) GetId() string { func (m *Sprint) GetId() string {
if m != nil { if m != nil {
@@ -331,9 +331,9 @@ var _SprintService_serviceDesc = grpc.ServiceDesc{
Metadata: "services/sprint/sprint.proto", Metadata: "services/sprint/sprint.proto",
} }
func init() { proto.RegisterFile("services/sprint/sprint.proto", fileDescriptorSprint) } func init() { proto.RegisterFile("services/sprint/sprint.proto", fileDescriptor0) }
var fileDescriptorSprint = []byte{ var fileDescriptor0 = []byte{
// 290 bytes of a gzipped FileDescriptorProto // 290 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x52, 0x4d, 0x4b, 0xc3, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x52, 0x4d, 0x4b, 0xc3, 0x40,
0x10, 0x6d, 0xaa, 0x44, 0x32, 0xa5, 0xa5, 0x1d, 0x0f, 0xc6, 0xa8, 0x20, 0x8b, 0x14, 0x4f, 0x11, 0x10, 0x6d, 0xaa, 0x44, 0x32, 0xa5, 0xa5, 0x1d, 0x0f, 0xc6, 0xa8, 0x20, 0x8b, 0x14, 0x4f, 0x11,

View File

@@ -1,10 +1,11 @@
package sprint_grpctransport package sprint_grpctransport
import ( import (
context "context"
"fmt" "fmt"
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
context "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 "github.com/moul/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 "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
@@ -13,12 +14,12 @@ import (
// avoid import errors // avoid import errors
var _ = fmt.Errorf var _ = fmt.Errorf
func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.SprintServiceServer { func MakeGRPCServer(endpoints endpoints.Endpoints) pb.SprintServiceServer {
options := []grpctransport.ServerOption{} var options []grpctransport.ServerOption
_ = options
return &grpcServer{ return &grpcServer{
addsprint: grpctransport.NewServer( addsprint: grpctransport.NewServer(
ctx,
endpoints.AddSprintEndpoint, endpoints.AddSprintEndpoint,
decodeRequest, decodeRequest,
encodeAddSprintResponse, encodeAddSprintResponse,
@@ -26,7 +27,6 @@ func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.Sprin
), ),
closesprint: grpctransport.NewServer( closesprint: grpctransport.NewServer(
ctx,
endpoints.CloseSprintEndpoint, endpoints.CloseSprintEndpoint,
decodeRequest, decodeRequest,
encodeCloseSprintResponse, encodeCloseSprintResponse,
@@ -34,7 +34,6 @@ func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.Sprin
), ),
getsprint: grpctransport.NewServer( getsprint: grpctransport.NewServer(
ctx,
endpoints.GetSprintEndpoint, endpoints.GetSprintEndpoint,
decodeRequest, decodeRequest,
encodeGetSprintResponse, encodeGetSprintResponse,
@@ -51,7 +50,7 @@ type grpcServer struct {
getsprint grpctransport.Handler getsprint grpctransport.Handler
} }
func (s *grpcServer) AddSprint(ctx context.Context, req *pb.AddSprintRequest) (*pb.AddSprintResponse, error) { func (s *grpcServer) AddSprint(ctx oldcontext.Context, req *pb.AddSprintRequest) (*pb.AddSprintResponse, error) {
_, rep, err := s.addsprint.ServeGRPC(ctx, req) _, rep, err := s.addsprint.ServeGRPC(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -64,7 +63,7 @@ func encodeAddSprintResponse(ctx context.Context, response interface{}) (interfa
return resp, nil return resp, nil
} }
func (s *grpcServer) CloseSprint(ctx context.Context, req *pb.CloseSprintRequest) (*pb.CloseSprintResponse, error) { func (s *grpcServer) CloseSprint(ctx oldcontext.Context, req *pb.CloseSprintRequest) (*pb.CloseSprintResponse, error) {
_, rep, err := s.closesprint.ServeGRPC(ctx, req) _, rep, err := s.closesprint.ServeGRPC(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -77,7 +76,7 @@ func encodeCloseSprintResponse(ctx context.Context, response interface{}) (inter
return resp, nil return resp, nil
} }
func (s *grpcServer) GetSprint(ctx context.Context, req *pb.GetSprintRequest) (*pb.GetSprintResponse, error) { func (s *grpcServer) GetSprint(ctx oldcontext.Context, req *pb.GetSprintRequest) (*pb.GetSprintResponse, error) {
_, rep, err := s.getsprint.ServeGRPC(ctx, req) _, rep, err := s.getsprint.ServeGRPC(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -1,8 +1,8 @@
package sprint_httptransport package sprint_httptransport
import ( import (
"context"
"encoding/json" "encoding/json"
context "golang.org/x/net/context"
"log" "log"
"net/http" "net/http"
@@ -12,9 +12,12 @@ import (
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb" pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/sprint/gen/pb"
) )
func MakeAddSprintHandler(ctx context.Context, svc pb.SprintServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server { var _ = log.Printf
var _ = gokit_endpoint.Chain
var _ = httptransport.NewClient
func MakeAddSprintHandler(svc pb.SprintServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer( return httptransport.NewServer(
ctx,
endpoint, endpoint,
decodeAddSprintRequest, decodeAddSprintRequest,
encodeResponse, encodeResponse,
@@ -30,9 +33,8 @@ func decodeAddSprintRequest(ctx context.Context, r *http.Request) (interface{},
return &req, nil return &req, nil
} }
func MakeCloseSprintHandler(ctx context.Context, svc pb.SprintServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server { func MakeCloseSprintHandler(svc pb.SprintServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer( return httptransport.NewServer(
ctx,
endpoint, endpoint,
decodeCloseSprintRequest, decodeCloseSprintRequest,
encodeResponse, encodeResponse,
@@ -48,9 +50,8 @@ func decodeCloseSprintRequest(ctx context.Context, r *http.Request) (interface{}
return &req, nil return &req, nil
} }
func MakeGetSprintHandler(ctx context.Context, svc pb.SprintServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server { func MakeGetSprintHandler(svc pb.SprintServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer( return httptransport.NewServer(
ctx,
endpoint, endpoint,
decodeGetSprintRequest, decodeGetSprintRequest,
encodeResponse, encodeResponse,
@@ -70,16 +71,16 @@ func encodeResponse(ctx context.Context, w http.ResponseWriter, response interfa
return json.NewEncoder(w).Encode(response) return json.NewEncoder(w).Encode(response)
} }
func RegisterHandlers(ctx context.Context, svc pb.SprintServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error { func RegisterHandlers(svc pb.SprintServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error {
log.Println("new HTTP endpoint: \"/AddSprint\" (service=Sprint)") log.Println("new HTTP endpoint: \"/AddSprint\" (service=Sprint)")
mux.Handle("/AddSprint", MakeAddSprintHandler(ctx, svc, endpoints.AddSprintEndpoint)) mux.Handle("/AddSprint", MakeAddSprintHandler(svc, endpoints.AddSprintEndpoint))
log.Println("new HTTP endpoint: \"/CloseSprint\" (service=Sprint)") log.Println("new HTTP endpoint: \"/CloseSprint\" (service=Sprint)")
mux.Handle("/CloseSprint", MakeCloseSprintHandler(ctx, svc, endpoints.CloseSprintEndpoint)) mux.Handle("/CloseSprint", MakeCloseSprintHandler(svc, endpoints.CloseSprintEndpoint))
log.Println("new HTTP endpoint: \"/GetSprint\" (service=Sprint)") log.Println("new HTTP endpoint: \"/GetSprint\" (service=Sprint)")
mux.Handle("/GetSprint", MakeGetSprintHandler(ctx, svc, endpoints.GetSprintEndpoint)) mux.Handle("/GetSprint", MakeGetSprintHandler(svc, endpoints.GetSprintEndpoint))
return nil return nil
} }

View File

@@ -1,11 +1,12 @@
package user_clientgrpc package user_clientgrpc
import ( import (
context "context"
jwt "github.com/go-kit/kit/auth/jwt" jwt "github.com/go-kit/kit/auth/jwt"
"github.com/go-kit/kit/endpoint" "github.com/go-kit/kit/endpoint"
"github.com/go-kit/kit/log" "github.com/go-kit/kit/log"
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
context "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints" endpoints "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/endpoints"

View File

@@ -1,14 +1,17 @@
package user_endpoints package user_endpoints
import ( import (
context "context"
"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" pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
context "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
) )
var _ = endpoint.Chain
var _ = fmt.Errorf var _ = fmt.Errorf
var _ = context.Background
type StreamEndpoint func(server interface{}, req interface{}) (err error) type StreamEndpoint func(server interface{}, req interface{}) (err error)
@@ -18,7 +21,7 @@ type Endpoints struct {
GetUserEndpoint endpoint.Endpoint GetUserEndpoint endpoint.Endpoint
} }
func (e *Endpoints) CreateUser(ctx context.Context, in *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { func (e *Endpoints) CreateUser(ctx oldcontext.Context, in *pb.CreateUserRequest) (*pb.CreateUserResponse, error) {
out, err := e.CreateUserEndpoint(ctx, in) out, err := e.CreateUserEndpoint(ctx, in)
if err != nil { if err != nil {
return &pb.CreateUserResponse{ErrMsg: err.Error()}, err return &pb.CreateUserResponse{ErrMsg: err.Error()}, err
@@ -26,7 +29,7 @@ func (e *Endpoints) CreateUser(ctx context.Context, in *pb.CreateUserRequest) (*
return out.(*pb.CreateUserResponse), err return out.(*pb.CreateUserResponse), err
} }
func (e *Endpoints) GetUser(ctx context.Context, in *pb.GetUserRequest) (*pb.GetUserResponse, error) { func (e *Endpoints) GetUser(ctx oldcontext.Context, in *pb.GetUserRequest) (*pb.GetUserResponse, error) {
out, err := e.GetUserEndpoint(ctx, in) out, err := e.GetUserEndpoint(ctx, in)
if err != nil { if err != nil {
return &pb.GetUserResponse{ErrMsg: err.Error()}, err return &pb.GetUserResponse{ErrMsg: err.Error()}, err

View File

@@ -1,4 +1,4 @@
// Code generated by protoc-gen-gogo. // Code generated by protoc-gen-go.
// source: services/user/user.proto // source: services/user/user.proto
// DO NOT EDIT! // DO NOT EDIT!
@@ -17,7 +17,7 @@ It has these top-level messages:
*/ */
package user package user
import proto "github.com/gogo/protobuf/proto" import proto "github.com/golang/protobuf/proto"
import fmt "fmt" import fmt "fmt"
import math "math" import math "math"
@@ -35,16 +35,16 @@ var _ = math.Inf
// is compatible with the proto package it is being compiled against. // is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the // A compilation error at this line likely means your copy of the
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type CreateUserRequest struct { type CreateUserRequest struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
} }
func (m *CreateUserRequest) Reset() { *m = CreateUserRequest{} } func (m *CreateUserRequest) Reset() { *m = CreateUserRequest{} }
func (m *CreateUserRequest) String() string { return proto.CompactTextString(m) } func (m *CreateUserRequest) String() string { return proto.CompactTextString(m) }
func (*CreateUserRequest) ProtoMessage() {} func (*CreateUserRequest) ProtoMessage() {}
func (*CreateUserRequest) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{0} } func (*CreateUserRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *CreateUserRequest) GetName() string { func (m *CreateUserRequest) GetName() string {
if m != nil { if m != nil {
@@ -55,13 +55,13 @@ func (m *CreateUserRequest) GetName() string {
type CreateUserResponse struct { type CreateUserResponse struct {
User *User `protobuf:"bytes,1,opt,name=user" json:"user,omitempty"` User *User `protobuf:"bytes,1,opt,name=user" json:"user,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg" json:"err_msg,omitempty"`
} }
func (m *CreateUserResponse) Reset() { *m = CreateUserResponse{} } func (m *CreateUserResponse) Reset() { *m = CreateUserResponse{} }
func (m *CreateUserResponse) String() string { return proto.CompactTextString(m) } func (m *CreateUserResponse) String() string { return proto.CompactTextString(m) }
func (*CreateUserResponse) ProtoMessage() {} func (*CreateUserResponse) ProtoMessage() {}
func (*CreateUserResponse) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{1} } func (*CreateUserResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *CreateUserResponse) GetUser() *User { func (m *CreateUserResponse) GetUser() *User {
if m != nil { if m != nil {
@@ -78,13 +78,13 @@ func (m *CreateUserResponse) GetErrMsg() string {
} }
type GetUserRequest struct { type GetUserRequest struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
} }
func (m *GetUserRequest) Reset() { *m = GetUserRequest{} } func (m *GetUserRequest) Reset() { *m = GetUserRequest{} }
func (m *GetUserRequest) String() string { return proto.CompactTextString(m) } func (m *GetUserRequest) String() string { return proto.CompactTextString(m) }
func (*GetUserRequest) ProtoMessage() {} func (*GetUserRequest) ProtoMessage() {}
func (*GetUserRequest) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{2} } func (*GetUserRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *GetUserRequest) GetId() string { func (m *GetUserRequest) GetId() string {
if m != nil { if m != nil {
@@ -95,13 +95,13 @@ func (m *GetUserRequest) GetId() string {
type GetUserResponse struct { type GetUserResponse struct {
User *User `protobuf:"bytes,1,opt,name=user" json:"user,omitempty"` User *User `protobuf:"bytes,1,opt,name=user" json:"user,omitempty"`
ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg,proto3" json:"err_msg,omitempty"` ErrMsg string `protobuf:"bytes,2,opt,name=err_msg,json=errMsg" json:"err_msg,omitempty"`
} }
func (m *GetUserResponse) Reset() { *m = GetUserResponse{} } func (m *GetUserResponse) Reset() { *m = GetUserResponse{} }
func (m *GetUserResponse) String() string { return proto.CompactTextString(m) } func (m *GetUserResponse) String() string { return proto.CompactTextString(m) }
func (*GetUserResponse) ProtoMessage() {} func (*GetUserResponse) ProtoMessage() {}
func (*GetUserResponse) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{3} } func (*GetUserResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *GetUserResponse) GetUser() *User { func (m *GetUserResponse) GetUser() *User {
if m != nil { if m != nil {
@@ -118,14 +118,14 @@ func (m *GetUserResponse) GetErrMsg() string {
} }
type User struct { type User struct {
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
} }
func (m *User) Reset() { *m = User{} } func (m *User) Reset() { *m = User{} }
func (m *User) String() string { return proto.CompactTextString(m) } func (m *User) String() string { return proto.CompactTextString(m) }
func (*User) ProtoMessage() {} func (*User) ProtoMessage() {}
func (*User) Descriptor() ([]byte, []int) { return fileDescriptorUser, []int{4} } func (*User) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *User) GetId() string { func (m *User) GetId() string {
if m != nil { if m != nil {
@@ -254,9 +254,9 @@ var _UserService_serviceDesc = grpc.ServiceDesc{
Metadata: "services/user/user.proto", Metadata: "services/user/user.proto",
} }
func init() { proto.RegisterFile("services/user/user.proto", fileDescriptorUser) } func init() { proto.RegisterFile("services/user/user.proto", fileDescriptor0) }
var fileDescriptorUser = []byte{ var fileDescriptor0 = []byte{
// 236 bytes of a gzipped FileDescriptorProto // 236 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0x28, 0x4e, 0x2d, 0x2a, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0x92, 0x28, 0x4e, 0x2d, 0x2a,
0xcb, 0x4c, 0x4e, 0x2d, 0xd6, 0x2f, 0x2d, 0x4e, 0x2d, 0x02, 0x13, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xcb, 0x4c, 0x4e, 0x2d, 0xd6, 0x2f, 0x2d, 0x4e, 0x2d, 0x02, 0x13, 0x7a, 0x05, 0x45, 0xf9, 0x25,

View File

@@ -1,10 +1,11 @@
package user_grpctransport package user_grpctransport
import ( import (
context "context"
"fmt" "fmt"
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
context "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 "github.com/moul/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 "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
@@ -13,12 +14,12 @@ import (
// avoid import errors // avoid import errors
var _ = fmt.Errorf var _ = fmt.Errorf
func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.UserServiceServer { func MakeGRPCServer(endpoints endpoints.Endpoints) pb.UserServiceServer {
options := []grpctransport.ServerOption{} var options []grpctransport.ServerOption
_ = options
return &grpcServer{ return &grpcServer{
createuser: grpctransport.NewServer( createuser: grpctransport.NewServer(
ctx,
endpoints.CreateUserEndpoint, endpoints.CreateUserEndpoint,
decodeRequest, decodeRequest,
encodeCreateUserResponse, encodeCreateUserResponse,
@@ -26,7 +27,6 @@ func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.UserS
), ),
getuser: grpctransport.NewServer( getuser: grpctransport.NewServer(
ctx,
endpoints.GetUserEndpoint, endpoints.GetUserEndpoint,
decodeRequest, decodeRequest,
encodeGetUserResponse, encodeGetUserResponse,
@@ -41,7 +41,7 @@ type grpcServer struct {
getuser grpctransport.Handler getuser grpctransport.Handler
} }
func (s *grpcServer) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) { func (s *grpcServer) CreateUser(ctx oldcontext.Context, req *pb.CreateUserRequest) (*pb.CreateUserResponse, error) {
_, rep, err := s.createuser.ServeGRPC(ctx, req) _, rep, err := s.createuser.ServeGRPC(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -54,7 +54,7 @@ func encodeCreateUserResponse(ctx context.Context, response interface{}) (interf
return resp, nil return resp, nil
} }
func (s *grpcServer) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) { func (s *grpcServer) GetUser(ctx oldcontext.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
_, rep, err := s.getuser.ServeGRPC(ctx, req) _, rep, err := s.getuser.ServeGRPC(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -1,8 +1,8 @@
package user_httptransport package user_httptransport
import ( import (
"context"
"encoding/json" "encoding/json"
context "golang.org/x/net/context"
"log" "log"
"net/http" "net/http"
@@ -12,9 +12,12 @@ import (
pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb" pb "github.com/moul/protoc-gen-gotemplate/examples/go-kit/services/user/gen/pb"
) )
func MakeCreateUserHandler(ctx context.Context, svc pb.UserServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server { var _ = log.Printf
var _ = gokit_endpoint.Chain
var _ = httptransport.NewClient
func MakeCreateUserHandler(svc pb.UserServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer( return httptransport.NewServer(
ctx,
endpoint, endpoint,
decodeCreateUserRequest, decodeCreateUserRequest,
encodeResponse, encodeResponse,
@@ -30,9 +33,8 @@ func decodeCreateUserRequest(ctx context.Context, r *http.Request) (interface{},
return &req, nil return &req, nil
} }
func MakeGetUserHandler(ctx context.Context, svc pb.UserServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server { func MakeGetUserHandler(svc pb.UserServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer( return httptransport.NewServer(
ctx,
endpoint, endpoint,
decodeGetUserRequest, decodeGetUserRequest,
encodeResponse, encodeResponse,
@@ -52,13 +54,13 @@ func encodeResponse(ctx context.Context, w http.ResponseWriter, response interfa
return json.NewEncoder(w).Encode(response) return json.NewEncoder(w).Encode(response)
} }
func RegisterHandlers(ctx context.Context, svc pb.UserServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error { func RegisterHandlers(svc pb.UserServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error {
log.Println("new HTTP endpoint: \"/CreateUser\" (service=User)") log.Println("new HTTP endpoint: \"/CreateUser\" (service=User)")
mux.Handle("/CreateUser", MakeCreateUserHandler(ctx, svc, endpoints.CreateUserEndpoint)) mux.Handle("/CreateUser", MakeCreateUserHandler(svc, endpoints.CreateUserEndpoint))
log.Println("new HTTP endpoint: \"/GetUser\" (service=User)") log.Println("new HTTP endpoint: \"/GetUser\" (service=User)")
mux.Handle("/GetUser", MakeGetUserHandler(ctx, svc, endpoints.GetUserEndpoint)) mux.Handle("/GetUser", MakeGetUserHandler(svc, endpoints.GetUserEndpoint))
return nil return nil
} }

View File

@@ -1,8 +1,9 @@
package {{.File.Package}}_clientgrpc package {{.File.Package}}_clientgrpc
import ( import (
context "context"
"github.com/go-kit/kit/log" "github.com/go-kit/kit/log"
context "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
"github.com/go-kit/kit/endpoint" "github.com/go-kit/kit/endpoint"

View File

@@ -3,9 +3,10 @@ package {{.File.Package}}_endpoints
{{$file := .File}} {{$file := .File}}
import ( import (
context "context"
"fmt" "fmt"
context "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
pb "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/pb" pb "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/pb"
"github.com/go-kit/kit/endpoint" "github.com/go-kit/kit/endpoint"
) )
@@ -43,7 +44,7 @@ type Endpoints struct {
return fmt.Errorf("not implemented") return fmt.Errorf("not implemented")
} }
{{else}} {{else}}
func (e *Endpoints){{.Name}}(ctx context.Context, in *pb.{{.InputType | splitArray "." | last}}) (*pb.{{.OutputType | splitArray "." | last}}, error) { func (e *Endpoints){{.Name}}(ctx oldcontext.Context, in *pb.{{.InputType | splitArray "." | last}}) (*pb.{{.OutputType | splitArray "." | last}}, error) {
out, err := e.{{.Name}}Endpoint(ctx, in) out, err := e.{{.Name}}Endpoint(ctx, in)
if err != nil { if err != nil {
return &pb.{{.OutputType | splitArray "." | last}}{ErrMsg: err.Error()}, err return &pb.{{.OutputType | splitArray "." | last}}{ErrMsg: err.Error()}, err

View File

@@ -3,9 +3,10 @@ package {{.File.Package}}_grpctransport
{{$file := .File}} {{$file := .File}}
import ( import (
context "context"
"fmt" "fmt"
context "golang.org/x/net/context" oldcontext "golang.org/x/net/context"
grpctransport "github.com/go-kit/kit/transport/grpc" grpctransport "github.com/go-kit/kit/transport/grpc"
pb "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/pb" pb "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/pb"
@@ -15,7 +16,7 @@ import (
// avoid import errors // avoid import errors
var _ = fmt.Errorf var _ = fmt.Errorf
func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.{{.File.Package | title}}ServiceServer { func MakeGRPCServer(endpoints endpoints.Endpoints) pb.{{.File.Package | title}}ServiceServer {
var options []grpctransport.ServerOption var options []grpctransport.ServerOption
_ = options _ = options
return &grpcServer{ return &grpcServer{
@@ -26,7 +27,6 @@ func MakeGRPCServer(ctx context.Context, endpoints endpoints.Endpoints) pb.{{.Fi
}, },
{{else}} {{else}}
{{.Name | lower}}: grpctransport.NewServer( {{.Name | lower}}: grpctransport.NewServer(
ctx,
endpoints.{{.Name}}Endpoint, endpoints.{{.Name}}Endpoint,
decodeRequest, decodeRequest,
encode{{.Name}}Response, encode{{.Name}}Response,
@@ -57,7 +57,7 @@ type grpcServer struct {
return s.{{.Name | lower}}.Do(server, req) return s.{{.Name | lower}}.Do(server, req)
} }
{{else}} {{else}}
func (s *grpcServer) {{.Name}}(ctx context.Context, req *pb.{{.InputType | splitArray "." | last}}) (*pb.{{.OutputType | splitArray "." | last}}, error) { func (s *grpcServer) {{.Name}}(ctx oldcontext.Context, req *pb.{{.InputType | splitArray "." | last}}) (*pb.{{.OutputType | splitArray "." | last}}, error) {
_, rep, err := s.{{.Name | lower}}.ServeGRPC(ctx, req) _, rep, err := s.{{.Name | lower}}.ServeGRPC(ctx, req)
if err != nil { if err != nil {
return nil, err return nil, err

View File

@@ -6,7 +6,7 @@ import (
"log" "log"
"net/http" "net/http"
"encoding/json" "encoding/json"
context "golang.org/x/net/context" "context"
pb "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/pb" pb "{{cat .GoPWD "/" .DestinationDir | nospace | clean}}/pb"
gokit_endpoint "github.com/go-kit/kit/endpoint" gokit_endpoint "github.com/go-kit/kit/endpoint"
@@ -21,9 +21,8 @@ var _ = httptransport.NewClient
{{range .Service.Method}} {{range .Service.Method}}
{{if and (not .ServerStreaming) (not .ClientStreaming)}} {{if and (not .ServerStreaming) (not .ClientStreaming)}}
func Make{{.Name}}Handler(ctx context.Context, svc pb.{{$file.Package | title}}ServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server { func Make{{.Name}}Handler(svc pb.{{$file.Package | title}}ServiceServer, endpoint gokit_endpoint.Endpoint) *httptransport.Server {
return httptransport.NewServer( return httptransport.NewServer(
ctx,
endpoint, endpoint,
decode{{.Name}}Request, decode{{.Name}}Request,
encodeResponse, encodeResponse,
@@ -45,11 +44,11 @@ func encodeResponse(ctx context.Context, w http.ResponseWriter, response interfa
return json.NewEncoder(w).Encode(response) return json.NewEncoder(w).Encode(response)
} }
func RegisterHandlers(ctx context.Context, svc pb.{{$file.Package | title}}ServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error { func RegisterHandlers(svc pb.{{$file.Package | title}}ServiceServer, mux *http.ServeMux, endpoints endpoints.Endpoints) error {
{{range .Service.Method}} {{range .Service.Method}}
{{if and (not .ServerStreaming) (not .ClientStreaming)}} {{if and (not .ServerStreaming) (not .ClientStreaming)}}
log.Println("new HTTP endpoint: \"/{{.Name}}\" (service={{$file.Package | title}})") log.Println("new HTTP endpoint: \"/{{.Name}}\" (service={{$file.Package | title}})")
mux.Handle("/{{.Name}}", Make{{.Name}}Handler(ctx, svc, endpoints.{{.Name}}Endpoint)) mux.Handle("/{{.Name}}", Make{{.Name}}Handler(svc, endpoints.{{.Name}}Endpoint))
{{end}} {{end}}
{{end}} {{end}}
return nil return nil

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,55 @@
# 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}}: 146
{{- /*{{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]
# 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,56 @@
# 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}}
# 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 = "github.com/moul/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) {}
}

18
examples/import/Makefile Normal file
View File

@@ -0,0 +1,18 @@
.PHONY: build
build:
mkdir -p output
# 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=,plugins=grpc:./output proto/common.proto
# build our go file based on our template
protoc -I. --gotemplate_out=template_dir=templates,debug=true:output proto/article.proto
.PHONY: re
re: clean build
.PHONY: clean
clean:
rm -rf output

View File

@@ -0,0 +1,113 @@
// Code generated by protoc-gen-go.
// 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
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import common "github.com/moul/protoc-gen-gotemplate/examples/import/output/models/common"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type GetArticleRequest struct {
Getarticle *common.GetArticle `protobuf:"bytes,1,opt,name=getarticle" json:"getarticle,omitempty"`
}
func (m *GetArticleRequest) Reset() { *m = GetArticleRequest{} }
func (m *GetArticleRequest) String() string { return proto.CompactTextString(m) }
func (*GetArticleRequest) ProtoMessage() {}
func (*GetArticleRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *GetArticleRequest) GetGetarticle() *common.GetArticle {
if m != nil {
return m.Getarticle
}
return nil
}
type GetArticleResponse struct {
Article *Article `protobuf:"bytes,1,opt,name=article" json:"article,omitempty"`
}
func (m *GetArticleResponse) Reset() { *m = GetArticleResponse{} }
func (m *GetArticleResponse) String() string { return proto.CompactTextString(m) }
func (*GetArticleResponse) ProtoMessage() {}
func (*GetArticleResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *GetArticleResponse) GetArticle() *Article {
if m != nil {
return m.Article
}
return nil
}
type Article struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
}
func (m *Article) Reset() { *m = Article{} }
func (m *Article) String() string { return proto.CompactTextString(m) }
func (*Article) ProtoMessage() {}
func (*Article) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
func (m *Article) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *Article) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func init() {
proto.RegisterType((*GetArticleRequest)(nil), "article.GetArticleRequest")
proto.RegisterType((*GetArticleResponse)(nil), "article.GetArticleResponse")
proto.RegisterType((*Article)(nil), "article.Article")
}
func init() { proto.RegisterFile("proto/article.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 208 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2e, 0x28, 0xca, 0x2f,
0xc9, 0xd7, 0x4f, 0x2c, 0x2a, 0xc9, 0x4c, 0xce, 0x49, 0xd5, 0x03, 0xf3, 0x84, 0xd8, 0xa1, 0x5c,
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,
0x53, 0x85, 0xb4, 0xb8, 0xd8, 0x51, 0x8d, 0x11, 0xd0, 0x83, 0x39, 0x0e, 0xa6, 0x14, 0xa6, 0x40,
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,
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,
0x21, 0x66, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x16, 0x18, 0x87, 0xc4, 0x65, 0x01, 0x00, 0x00,
}

View File

@@ -0,0 +1,70 @@
// Code generated by protoc-gen-go.
// source: proto/common.proto
// DO NOT EDIT!
/*
Package common is a generated protocol buffer package.
It is generated from these files:
proto/common.proto
It has these top-level messages:
GetArticle
*/
package common
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type GetArticle struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
Tenant string `protobuf:"bytes,2,opt,name=tenant" json:"tenant,omitempty"`
}
func (m *GetArticle) Reset() { *m = GetArticle{} }
func (m *GetArticle) String() string { return proto.CompactTextString(m) }
func (*GetArticle) ProtoMessage() {}
func (*GetArticle) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *GetArticle) GetId() string {
if m != nil {
return m.Id
}
return ""
}
func (m *GetArticle) GetTenant() string {
if m != nil {
return m.Tenant
}
return ""
}
func init() {
proto.RegisterType((*GetArticle)(nil), "common.GetArticle")
}
func init() { proto.RegisterFile("proto/common.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 110 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x2a, 0x28, 0xca, 0x2f,
0xc9, 0xd7, 0x4f, 0xce, 0xcf, 0xcd, 0xcd, 0xcf, 0xd3, 0x03, 0x73, 0x84, 0xd8, 0x20, 0x3c, 0x25,
0x13, 0x2e, 0x2e, 0xf7, 0xd4, 0x12, 0xc7, 0xa2, 0x92, 0xcc, 0xe4, 0x9c, 0x54, 0x21, 0x3e, 0x2e,
0xa6, 0xcc, 0x14, 0x09, 0x46, 0x05, 0x46, 0x0d, 0xce, 0x20, 0xa6, 0xcc, 0x14, 0x21, 0x31, 0x2e,
0xb6, 0x92, 0xd4, 0xbc, 0xc4, 0xbc, 0x12, 0x09, 0x26, 0xb0, 0x18, 0x94, 0xe7, 0x24, 0x16, 0x25,
0x92, 0x9b, 0x9f, 0x92, 0x9a, 0x53, 0x0c, 0x35, 0xd4, 0x1a, 0x42, 0x25, 0xb1, 0x81, 0x0d, 0x37,
0x06, 0x04, 0x00, 0x00, 0xff, 0xff, 0x89, 0x5a, 0x1d, 0x73, 0x72, 0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,11 @@
// Code generated by protoc-gen-gotemplate
package article
import (
"github.com/moul/protoc-gen-gotemplate/examples/import/output/models/article"
"github.com/moul/protoc-gen-gotemplate/examples/import/output/models/common"
)
type Repository interface {
GetArticle(getarticle *common.GetArticle ) (*article.Article, error)
}

View File

@@ -0,0 +1,19 @@
syntax = "proto3";
package article;
option go_package = "models/article;article";
import "proto/common.proto";
message GetArticleRequest { common.GetArticle getarticle = 1;}
message GetArticleResponse { Article article = 1;}
message Article{
string id = 1;
string name = 2;
}
service articlesvc {
rpc GetArticle (GetArticleRequest) returns (GetArticleResponse){}
}

View File

@@ -0,0 +1,10 @@
syntax = "proto3";
package common;
option go_package = "models/common;common";
message GetArticle{
string id = 1;
string tenant = 2;
}

View File

@@ -0,0 +1,11 @@
// Code generated by protoc-gen-gotemplate
package {{.File.Package}}
import (
"github.com/moul/protoc-gen-gotemplate/examples/import/output/models/article"
"github.com/moul/protoc-gen-gotemplate/examples/import/output/models/common"
)
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}}
}

View File

@@ -0,0 +1,26 @@
.PHONY: re
re: clean build test
.PHONY: build
build:
@mkdir -p output
@# proto-gen-go
protoc -I./proto --go_out=plugins=grpc:output proto/aaa/aaa.proto
protoc -I./proto --go_out=plugins=grpc:output proto/bbb/bbb.proto
@rm -rf output/aaa output/bbb
@mv output/github.com/moul/protoc-gen-gotemplate/examples/single-package-mode/output/* output/
@rm -rf output/github.com
@# protoc-gen-gotemplate
protoc -I./proto --gotemplate_out=template_dir=templates,single-package-mode=true:output proto/bbb/bbb.proto
gofmt -w .
.PHONY: test
test:
go test -i ./output/...
go test -v ./output/...
.PHONY: clean
clean:
rm -rf output

View File

@@ -0,0 +1,84 @@
// Code generated by protoc-gen-go.
// source: aaa/aaa.proto
// DO NOT EDIT!
/*
Package aaa is a generated protocol buffer package.
It is generated from these files:
aaa/aaa.proto
It has these top-level messages:
AaaRequest
AaaReply
*/
package aaa
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type AaaRequest struct {
Blah string `protobuf:"bytes,1,opt,name=blah" json:"blah,omitempty"`
}
func (m *AaaRequest) Reset() { *m = AaaRequest{} }
func (m *AaaRequest) String() string { return proto.CompactTextString(m) }
func (*AaaRequest) ProtoMessage() {}
func (*AaaRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *AaaRequest) GetBlah() string {
if m != nil {
return m.Blah
}
return ""
}
type AaaReply struct {
Error string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"`
}
func (m *AaaReply) Reset() { *m = AaaReply{} }
func (m *AaaReply) String() string { return proto.CompactTextString(m) }
func (*AaaReply) ProtoMessage() {}
func (*AaaReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *AaaReply) GetError() string {
if m != nil {
return m.Error
}
return ""
}
func init() {
proto.RegisterType((*AaaRequest)(nil), "the.aaa.package.AaaRequest")
proto.RegisterType((*AaaReply)(nil), "the.aaa.package.AaaReply")
}
func init() { proto.RegisterFile("aaa/aaa.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 172 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x2c, 0x8e, 0x31, 0x0b, 0xc2, 0x30,
0x10, 0x46, 0x29, 0xa8, 0x68, 0x40, 0x84, 0xe0, 0xe0, 0x58, 0x3a, 0xb9, 0xa4, 0x19, 0xfc, 0x05,
0xba, 0x8b, 0xd0, 0xd1, 0xed, 0x5a, 0x8f, 0xb4, 0x78, 0xe9, 0xc5, 0xf4, 0x02, 0xfa, 0xef, 0xc5,
0xd8, 0xed, 0x1e, 0xbc, 0xe3, 0x7b, 0x6a, 0x0b, 0x00, 0x16, 0x00, 0xea, 0x10, 0x59, 0x58, 0xef,
0xa4, 0xc7, 0x3a, 0x23, 0x74, 0x4f, 0x70, 0x58, 0x95, 0x4a, 0x9d, 0x01, 0x1a, 0x7c, 0x25, 0x9c,
0x44, 0x6b, 0xb5, 0x68, 0x09, 0xfa, 0x43, 0x51, 0x16, 0xc7, 0x4d, 0x93, 0xef, 0xaa, 0x54, 0xeb,
0x6c, 0x04, 0xfa, 0xe8, 0xbd, 0x5a, 0x62, 0x8c, 0x1c, 0x67, 0xe1, 0x0f, 0x97, 0xdb, 0xfd, 0xea,
0x06, 0xe9, 0x53, 0x5b, 0x77, 0xec, 0xad, 0xe7, 0x44, 0x36, 0xaf, 0x75, 0xc6, 0xe1, 0x68, 0x1c,
0x0b, 0xfa, 0x40, 0x20, 0x68, 0xf1, 0x0d, 0x3e, 0x10, 0x4e, 0x76, 0x1a, 0x46, 0x47, 0x68, 0xe6,
0x08, 0xe3, 0xf9, 0x81, 0x96, 0x93, 0x84, 0x24, 0xbf, 0xd6, 0x76, 0x95, 0xdf, 0x4f, 0xdf, 0x00,
0x00, 0x00, 0xff, 0xff, 0x93, 0x24, 0x48, 0x9c, 0xbd, 0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,200 @@
// Code generated by protoc-gen-go.
// source: bbb/bbb.proto
// DO NOT EDIT!
/*
Package bbb is a generated protocol buffer package.
It is generated from these files:
bbb/bbb.proto
It has these top-level messages:
BbbRequest
BbbReply
*/
package bbb
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import the_aaa_package "github.com/moul/protoc-gen-gotemplate/examples/single-package-mode/output/aaa"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type BbbRequest struct {
Enable bool `protobuf:"varint,1,opt,name=enable" json:"enable,omitempty"`
}
func (m *BbbRequest) Reset() { *m = BbbRequest{} }
func (m *BbbRequest) String() string { return proto.CompactTextString(m) }
func (*BbbRequest) ProtoMessage() {}
func (*BbbRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *BbbRequest) GetEnable() bool {
if m != nil {
return m.Enable
}
return false
}
type BbbReply struct {
Done bool `protobuf:"varint,1,opt,name=done" json:"done,omitempty"`
}
func (m *BbbReply) Reset() { *m = BbbReply{} }
func (m *BbbReply) String() string { return proto.CompactTextString(m) }
func (*BbbReply) ProtoMessage() {}
func (*BbbReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *BbbReply) GetDone() bool {
if m != nil {
return m.Done
}
return false
}
func init() {
proto.RegisterType((*BbbRequest)(nil), "the.bbb.package.BbbRequest")
proto.RegisterType((*BbbReply)(nil), "the.bbb.package.BbbReply")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for BbbService service
type BbbServiceClient interface {
Aaa(ctx context.Context, in *the_aaa_package.AaaRequest, opts ...grpc.CallOption) (*the_aaa_package.AaaReply, error)
Bbb(ctx context.Context, in *BbbRequest, opts ...grpc.CallOption) (*BbbReply, error)
}
type bbbServiceClient struct {
cc *grpc.ClientConn
}
func NewBbbServiceClient(cc *grpc.ClientConn) BbbServiceClient {
return &bbbServiceClient{cc}
}
func (c *bbbServiceClient) Aaa(ctx context.Context, in *the_aaa_package.AaaRequest, opts ...grpc.CallOption) (*the_aaa_package.AaaReply, error) {
out := new(the_aaa_package.AaaReply)
err := grpc.Invoke(ctx, "/the.bbb.package.BbbService/Aaa", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *bbbServiceClient) Bbb(ctx context.Context, in *BbbRequest, opts ...grpc.CallOption) (*BbbReply, error) {
out := new(BbbReply)
err := grpc.Invoke(ctx, "/the.bbb.package.BbbService/Bbb", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for BbbService service
type BbbServiceServer interface {
Aaa(context.Context, *the_aaa_package.AaaRequest) (*the_aaa_package.AaaReply, error)
Bbb(context.Context, *BbbRequest) (*BbbReply, error)
}
func RegisterBbbServiceServer(s *grpc.Server, srv BbbServiceServer) {
s.RegisterService(&_BbbService_serviceDesc, srv)
}
func _BbbService_Aaa_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(the_aaa_package.AaaRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BbbServiceServer).Aaa(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/the.bbb.package.BbbService/Aaa",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BbbServiceServer).Aaa(ctx, req.(*the_aaa_package.AaaRequest))
}
return interceptor(ctx, in, info, handler)
}
func _BbbService_Bbb_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(BbbRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(BbbServiceServer).Bbb(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/the.bbb.package.BbbService/Bbb",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(BbbServiceServer).Bbb(ctx, req.(*BbbRequest))
}
return interceptor(ctx, in, info, handler)
}
var _BbbService_serviceDesc = grpc.ServiceDesc{
ServiceName: "the.bbb.package.BbbService",
HandlerType: (*BbbServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Aaa",
Handler: _BbbService_Aaa_Handler,
},
{
MethodName: "Bbb",
Handler: _BbbService_Bbb_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "bbb/bbb.proto",
}
func init() { proto.RegisterFile("bbb/bbb.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 242 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x41, 0x4b, 0x03, 0x31,
0x10, 0x85, 0x59, 0x2a, 0xa5, 0x04, 0x8a, 0x90, 0x83, 0x68, 0x05, 0x91, 0xe2, 0xc1, 0xcb, 0x26,
0xa0, 0xe7, 0x1e, 0xba, 0x77, 0x11, 0xea, 0xcd, 0xdb, 0xcc, 0x76, 0x48, 0x17, 0x93, 0x9d, 0xd8,
0x9d, 0x88, 0xfd, 0x0b, 0xfe, 0x6a, 0xd9, 0x34, 0xa2, 0x60, 0x6f, 0x19, 0xde, 0xbc, 0xf7, 0xbd,
0x8c, 0x9a, 0x23, 0xa2, 0x45, 0x44, 0x13, 0xf7, 0x2c, 0xac, 0xcf, 0x65, 0x47, 0x26, 0x8f, 0xd0,
0xbe, 0x81, 0xa3, 0xc5, 0x1c, 0x00, 0x2c, 0x00, 0x1c, 0xf5, 0xe5, 0x9d, 0x52, 0x0d, 0xe2, 0x86,
0xde, 0x13, 0x0d, 0xa2, 0x2f, 0xd4, 0x94, 0x7a, 0x40, 0x4f, 0x97, 0xd5, 0x6d, 0x75, 0x3f, 0xdb,
0x94, 0x69, 0x79, 0xa3, 0x66, 0x79, 0x2b, 0xfa, 0x83, 0xd6, 0xea, 0x6c, 0xcb, 0xfd, 0xcf, 0x46,
0x7e, 0x3f, 0x7c, 0x55, 0x39, 0xe6, 0x85, 0xf6, 0x1f, 0x5d, 0x4b, 0x7a, 0xa5, 0x26, 0x6b, 0x00,
0x7d, 0x6d, 0x46, 0x78, 0x66, 0x1d, 0xe1, 0x66, 0x0d, 0x50, 0x50, 0x8b, 0xab, 0xd3, 0xe2, 0x48,
0x58, 0xa9, 0x49, 0x83, 0x58, 0xec, 0x7f, 0xba, 0x9b, 0xdf, 0xa6, 0xc5, 0xfe, 0x4f, 0x8c, 0xfe,
0xd0, 0x3c, 0xbf, 0x3e, 0xb9, 0x4e, 0x76, 0x09, 0x4d, 0xcb, 0xc1, 0x06, 0x4e, 0xde, 0xe6, 0xbf,
0xb6, 0xb5, 0xa3, 0xbe, 0x76, 0x2c, 0x14, 0xa2, 0x07, 0x21, 0x4b, 0x9f, 0x10, 0xa2, 0xa7, 0xc1,
0x0e, 0x5d, 0xef, 0x3c, 0xd5, 0x25, 0xa9, 0x0e, 0xbc, 0x25, 0xcb, 0x49, 0x62, 0x92, 0xf1, 0x92,
0x38, 0xcd, 0xf6, 0xc7, 0xef, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe0, 0xe1, 0x26, 0xcb, 0x5b, 0x01,
0x00, 0x00,
}

View File

@@ -0,0 +1,19 @@
// file generated with protoc-gen-gotemplate
package bbb
import (
"fmt"
"github.com/moul/protoc-gen-gotemplate/examples/single-package-mode/output/aaa"
"golang.org/x/net/context"
)
type Service struct{}
func (service Service) Aaa(ctx context.Context, input *aaa.AaaRequest) (*aaa.AaaReply, error) {
return nil, fmt.Errorf("method not implemented")
}
func (service Service) Bbb(ctx context.Context, input *BbbRequest) (*BbbReply, error) {
return nil, fmt.Errorf("method not implemented")
}

View File

@@ -0,0 +1,12 @@
syntax = "proto3";
option go_package = "github.com/moul/protoc-gen-gotemplate/examples/single-package-mode/output/aaa";
package the.aaa.package;
message AaaRequest {
string blah = 1;
}
message AaaReply {
string error = 1;
}

View File

@@ -0,0 +1,19 @@
syntax = "proto3";
package the.bbb.package;
option go_package = "github.com/moul/protoc-gen-gotemplate/examples/single-package-mode/output/bbb";
import "aaa/aaa.proto";
service BbbService {
rpc Aaa(the.aaa.package.AaaRequest) returns (the.aaa.package.AaaReply);
rpc Bbb(BbbRequest) returns (BbbReply);
}
message BbbRequest {
bool enable = 1;
}
message BbbReply {
bool done = 1;
}

View File

@@ -0,0 +1,26 @@
// file generated with protoc-gen-gotemplate
package {{.File.Name | dir}}
{{- $file := .File}}
{{- $currentFile := $file.Name | getProtoFile}}
import (
"fmt"
"golang.org/x/net/context"
{{- range .File.Dependency}}
{{- $dependency := . | getProtoFile}}
{{$dependency.GoPkg}}
{{end}}
)
type Service struct {}
{{- range .Service.Method}}
{{- $in := .InputType | getMessageType $file}}
{{- $out := .OutputType | getMessageType $file}}
func (service Service) {{.Name}}(ctx context.Context, input *{{$in.GoType $currentFile.GoPkg.Path}}) (*{{$out.GoType $currentFile.GoPkg.Path}}, error) {
return nil, fmt.Errorf("method not implemented")
}
{{end}}

View File

@@ -0,0 +1,3 @@
.PHONY: build
build:
protoc -I. --gotemplate_out=template_dir=.:. sitemap.proto

View File

@@ -0,0 +1,12 @@
syntax = "proto3";
package sitemap;
service DummyService {
rpc Posts(Request) returns (Response) {}
rpc Authors(Request) returns (Response) {}
rpc Comments(Request) returns (Response) {}
}
message Request {}
message Response {}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>/posts</loc>
<priority>0.5</priority>
<changefreq>monthly</changefreq>
<lastmod>2017-05-19</lastmod>
</url>
<url>
<loc>/authors</loc>
<priority>0.5</priority>
<changefreq>monthly</changefreq>
<lastmod>2017-05-19</lastmod>
</url>
<url>
<loc>/comments</loc>
<priority>0.5</priority>
<changefreq>monthly</changefreq>
<lastmod>2017-05-19</lastmod>
</url>
</urlset>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">{{range .Service.Method}}
<url>
<loc>/{{.Name | lower}}</loc>
<priority>0.5</priority>
<changefreq>monthly</changefreq>
<lastmod>{{now | date "2006-01-02"}}</lastmod>
</url>{{end}}
</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 ) (*timestamp.Timestamp, 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}}
}

21
glide.lock generated
View File

@@ -1,21 +0,0 @@
hash: 488701437e53b39667ed5a84ed1500e727ea8d4902d804c3ea7eb50b1fc022a1
updated: 2016-12-21T10:24:42.512734471+01:00
imports:
- name: github.com/aokoli/goutils
version: 9c37978a95bd5c709a15883b6242714ea6709e64
- name: github.com/golang/protobuf
version: 8ee79997227bf9b34611aee7946ae64735e6fd93
subpackages:
- proto
- protoc-gen-go/descriptor
- protoc-gen-go/generator
- protoc-gen-go/plugin
- name: github.com/huandu/xstrings
version: 3959339b333561bf62a38b424fd41517c2c90f40
- name: github.com/kr/fs
version: 2788f0dbd16903de03cb8186e5c7d97b69ad387b
- name: github.com/Masterminds/sprig
version: 69011c0cd9b4d2e0733c4d9e2c8e2a5a0d0a2f2f
- name: github.com/satori/go.uuid
version: 879c5887cd475cd7864858769793b2ceb0d44feb
testImports: []

View File

@@ -1,11 +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

View File

@@ -1,240 +0,0 @@
package main
import (
"encoding/json"
"fmt"
"strings"
"text/template"
"github.com/Masterminds/sprig"
"github.com/huandu/xstrings"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/protoc-gen-go/descriptor"
options "github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api"
)
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:]
},
"snakeCase": func(s string) string {
return xstrings.ToSnakeCase(s)
},
"kebabCase": func(s string) string {
return strings.Replace(xstrings.ToSnakeCase(s), "_", "-", -1)
},
"getMessageType": getMessageType,
"isFieldMessage": isFieldMessage,
"isFieldRepeated": isFieldRepeated,
"goType": goType,
"jsType": jsType,
"httpVerb": httpVerb,
"httpPath": httpPath,
"shortType": shortType,
}
func init() {
for k, v := range sprig.TxtFuncMap() {
ProtoHelpersFuncMap[k] = v
}
}
func getMessageType(f *descriptor.FileDescriptorProto, name string) *descriptor.DescriptorProto {
// 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 m
}
}
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 goType(pkg string, f *descriptor.FieldDescriptorProto) string {
switch *f.Type {
case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
return "float64"
case descriptor.FieldDescriptorProto_TYPE_FLOAT:
return "float32"
case descriptor.FieldDescriptorProto_TYPE_INT64:
return "int64"
case descriptor.FieldDescriptorProto_TYPE_UINT64:
return "uint64"
case descriptor.FieldDescriptorProto_TYPE_INT32:
return "uint32"
case descriptor.FieldDescriptorProto_TYPE_BOOL:
return "bool"
case descriptor.FieldDescriptorProto_TYPE_STRING:
return "string"
case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
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:
return "byte"
case descriptor.FieldDescriptorProto_TYPE_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:
return fmt.Sprintf(template, shortType(*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, "Array<number>")
case descriptor.FieldDescriptorProto_TYPE_STRING:
return fmt.Sprintf(template, "string")
case descriptor.FieldDescriptorProto_TYPE_ENUM:
return fmt.Sprintf(template, "Object")
default:
return fmt.Sprintf(template, "any")
}
}
func shortType(s string) string {
t := strings.Split(s, ".")
return t[len(t)-1]
}
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
}
}

504
helpers/helpers.go Normal file
View File

@@ -0,0 +1,504 @@
package pgghelpers
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.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 (
registry *ggdescriptor.Registry // some helpers need access to registry
)
func SetRegistry(reg *ggdescriptor.Registry) {
registry = reg
}
var ProtoHelpersFuncMap = template.FuncMap{
"string": func(i interface {
String() string
}) string {
return i.String()
},
"json": func(v interface{}) string {
a, err := json.Marshal(v)
if err != nil {
return err.Error()
}
return string(a)
},
"prettyjson": func(v interface{}) string {
a, err := json.MarshalIndent(v, "", " ")
if err != nil {
return err.Error()
}
return string(a)
},
"splitArray": func(sep string, s string) []interface{} {
var r []interface{}
t := strings.Split(s, sep)
for i := range t {
if t[i] != "" {
r = append(r, t[i])
}
}
return r
},
"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)
},
"contains": func(sub, s string) bool {
return strings.Contains(s, sub)
},
"trimstr": func(cutset, s string) string {
return strings.Trim(s, cutset)
},
"snakeCase": xstrings.ToSnakeCase,
"getProtoFile": getProtoFile,
"getMessageType": getMessageType,
"getEnumValue": getEnumValue,
"isFieldMessage": isFieldMessage,
"isFieldMessageTimeStamp": isFieldMessageTimeStamp,
"isFieldRepeated": isFieldRepeated,
"haskellType": haskellType,
"goType": goType,
"goTypeWithPackage": goTypeWithPackage,
"jsType": jsType,
"jsSuffixReserved": jsSuffixReservedKeyword,
"namespacedFlowType": namespacedFlowType,
"httpVerb": httpVerb,
"httpPath": httpPath,
"httpBody": httpBody,
"shortType": shortType,
"urlHasVarsFromMessage": urlHasVarsFromMessage,
"lowerGoNormalize": lowerGoNormalize,
"goNormalize": goNormalize,
}
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 isFieldMessageTimeStamp(f *descriptor.FieldDescriptorProto) bool {
if f.Type != nil && *f.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE {
if strings.Compare(*f.TypeName, ".google.protobuf.Timestamp") == 0 {
return true
}
}
return false
}
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 || *f.Type == descriptor.FieldDescriptorProto_TYPE_ENUM {
pkg = getPackageTypeName(*f.TypeName)
}
return goType(pkg, f)
}
func haskellType(pkg string, f *descriptor.FieldDescriptorProto) string {
switch *f.Type {
case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[Float]"
}
return "Float"
case descriptor.FieldDescriptorProto_TYPE_FLOAT:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[Float]"
}
return "Float"
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 "[Word]"
}
return "Word"
case descriptor.FieldDescriptorProto_TYPE_INT32:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[Int]"
}
return "Int"
case descriptor.FieldDescriptorProto_TYPE_UINT32:
if *f.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED {
return "[Word]"
}
return "Word"
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 "[Text]"
}
return "Text"
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 "[Word8]"
}
return "Word8"
case descriptor.FieldDescriptorProto_TYPE_ENUM:
return fmt.Sprintf("%s%s", pkg, shortType(*f.TypeName))
default:
return "Generic"
}
}
func goType(pkg string, f *descriptor.FieldDescriptorProto) string {
if pkg != "" {
pkg = pkg + "."
}
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 "[]int32"
}
return "int32"
case descriptor.FieldDescriptorProto_TYPE_UINT32:
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 *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_ENUM:
return fmt.Sprintf("*%s%s", pkg, shortType(*f.TypeName))
default:
return "interface{}"
}
}
func jsType(f *descriptor.FieldDescriptorProto) string {
template := "%s"
if isFieldRepeated(f) {
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.Compare(s, ".google.protobuf.Timestamp") == 0 {
return "timestamp"
}
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 httpBody(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)
}
return opts.Body
}
func urlHasVarsFromMessage(path string, d *ggdescriptor.Message) bool {
for _, field := range d.Field {
if !isFieldMessage(field) {
if strings.Contains(path, fmt.Sprintf("{%s}", *field.Name)) {
return true
}
}
}
return false
}
// lowerGoNormalize takes a string and applies formatting
// rules to conform to Golang convention. It applies a camel
// case filter, lowers the first character and formats fields
// with `id` to `ID`.
func lowerGoNormalize(s string) string {
fmtd := xstrings.ToCamelCase(s)
fmtd = xstrings.FirstRuneToLower(fmtd)
return formatID(s, fmtd)
}
// goNormalize takes a string and applies formatting rules
// to conform to Golang convention. It applies a camel case
// filter and formats fields with `id` to `ID`.
func goNormalize(s string) string {
fmtd := xstrings.ToCamelCase(s)
return formatID(s, fmtd)
}
// formatID takes a base string alonsgide a formatted string.
// It acts as a transformation filter for fields containing
// `id` in order to conform to Golang convention.
func formatID(base string, formatted string) string {
if formatted == "" {
return formatted
}
switch {
case base == "id":
// id -> ID
return "ID"
case strings.HasPrefix(base, "id_"):
// id_some -> IDSome
return "ID" + formatted[2:]
case strings.HasSuffix(base, "_id"):
// some_id -> SomeID
return formatted[:len(formatted)-2] + "ID"
case strings.HasSuffix(base, "_ids"):
// some_ids -> SomeIDs
return formatted[:len(formatted)-3] + "IDs"
}
return formatted
}

86
main.go
View File

@@ -8,6 +8,19 @@ 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"
ggdescriptor "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway/descriptor"
pgghelpers "github.com/moul/protoc-gen-gotemplate/helpers"
)
var (
registry *ggdescriptor.Registry // some helpers need access to registry
)
const (
boolTrue = "true"
boolFalse = "false"
) )
func main() { func main() {
@@ -18,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")
} }
@@ -29,9 +42,13 @@ func main() {
g.CommandLineParameters(g.Request.GetParameter()) g.CommandLineParameters(g.Request.GetParameter())
// Parse parameters // Parse parameters
templateDir := "./templates" var (
destinationDir := "." templateDir = "./templates"
debug := false destinationDir = "."
debug = false
all = false
singlePackageMode = 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, ",") {
parts := strings.Split(param, "=") parts := strings.Split(param, "=")
@@ -42,30 +59,77 @@ 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":
switch strings.ToLower(parts[1]) {
case boolTrue, "t":
singlePackageMode = true
case boolFalse, "f":
default:
log.Printf("Err: invalid value for single-package-mode: %q", parts[1])
}
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:
log.Printf("Err: invalid value for debug: %q", parts[1])
}
case "all":
switch strings.ToLower(parts[1]) {
case boolTrue, "t":
all = true
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
default: default:
log.Printf("Err: unknown parameter: %q", param) log.Printf("Err: unknown parameter: %q", param)
} }
} }
} }
tmplMap := make(map[string]*plugin_go.CodeGeneratorResponse_File)
concatOrAppend := func(file *plugin_go.CodeGeneratorResponse_File) {
if val, ok := tmplMap[file.GetName()]; ok {
*val.Content += file.GetContent()
} else {
tmplMap[file.GetName()] = file
g.Response.File = append(g.Response.File, file)
}
}
if singlePackageMode {
registry = ggdescriptor.NewRegistry()
pgghelpers.SetRegistry(registry)
if err = registry.Load(g.Request); err != nil {
g.Error(err, "registry: failed to load the request")
}
}
// Generate the encoders // Generate the encoders
for _, file := range g.Request.GetProtoFile() { for _, file := range g.Request.GetProtoFile() {
if all {
if singlePackageMode {
if _, err = registry.LookupFile(file.GetName()); err != nil {
g.Error(err, "registry: failed to lookup file %q", file.GetName())
}
}
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 := NewGenericTemplateBasedEncoder(templateDir, service, file, debug, destinationDir) encoder := NewGenericServiceTemplateBasedEncoder(templateDir, service, file, debug, destinationDir)
g.Response.File = append(g.Response.File, encoder.Files()...) for _, tmpl := range encoder.Files() {
concatOrAppend(tmpl)
}
} }
} }

45
vendor/github.com/Masterminds/semver/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,45 @@
# Release 1.2.2 (2016-12-13)
## Fixed
- #34: Fixed issue where hyphen range was not working with pre-release parsing.
# Release 1.2.1 (2016-11-28)
## Fixed
- #24: Fixed edge case issue where constraint "> 0" does not handle "0.0.1-alpha"
properly.
# Release 1.2.0 (2016-11-04)
## Added
- #20: Added MustParse function for versions (thanks @adamreese)
- #15: Added increment methods on versions (thanks @mh-cbon)
## Fixed
- Issue #21: Per the SemVer spec (section 9) a pre-release is unstable and
might not satisfy the intended compatibility. The change here ignores pre-releases
on constraint checks (e.g., ~ or ^) when a pre-release is not part of the
constraint. For example, `^1.2.3` will ignore pre-releases while
`^1.2.3-alpha` will include them.
# Release 1.1.1 (2016-06-30)
## Changed
- Issue #9: Speed up version comparison performance (thanks @sdboyer)
- Issue #8: Added benchmarks (thanks @sdboyer)
- Updated Go Report Card URL to new location
- Updated Readme to add code snippet formatting (thanks @mh-cbon)
- Updating tagging to v[SemVer] structure for compatibility with other tools.
# Release 1.1.0 (2016-03-11)
- Issue #2: Implemented validation to provide reasons a versions failed a
constraint.
# Release 1.0.1 (2015-12-31)
- Fixed #1: * constraint failing on valid versions.
# Release 1.0.0 (2015-10-20)
- Initial release

20
vendor/github.com/Masterminds/semver/LICENSE.txt generated vendored Normal file
View File

@@ -0,0 +1,20 @@
The Masterminds
Copyright (C) 2014-2015, Matt Butcher and Matt Farina
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

36
vendor/github.com/Masterminds/semver/Makefile generated vendored Normal file
View File

@@ -0,0 +1,36 @@
.PHONY: setup
setup:
go get -u gopkg.in/alecthomas/gometalinter.v1
gometalinter.v1 --install
.PHONY: test
test: validate lint
@echo "==> Running tests"
go test -v
.PHONY: validate
validate:
@echo "==> Running static validations"
@gometalinter.v1 \
--disable-all \
--enable deadcode \
--severity deadcode:error \
--enable gofmt \
--enable gosimple \
--enable ineffassign \
--enable misspell \
--enable vet \
--tests \
--vendor \
--deadline 60s \
./... || exit_code=1
.PHONY: lint
lint:
@echo "==> Running linters"
@gometalinter.v1 \
--disable-all \
--enable golint \
--vendor \
--deadline 60s \
./... || :

163
vendor/github.com/Masterminds/semver/README.md generated vendored Normal file
View File

@@ -0,0 +1,163 @@
# SemVer
The `semver` package provides the ability to work with [Semantic Versions](http://semver.org) in Go. Specifically it provides the ability to:
* Parse semantic versions
* Sort semantic versions
* Check if a semantic version fits within a set of constraints
* Optionally work with a `v` prefix
[![Build Status](https://travis-ci.org/Masterminds/semver.svg)](https://travis-ci.org/Masterminds/semver) [![Build status](https://ci.appveyor.com/api/projects/status/jfk66lib7hb985k8/branch/master?svg=true&passingText=windows%20build%20passing&failingText=windows%20build%20failing)](https://ci.appveyor.com/project/mattfarina/semver/branch/master) [![GoDoc](https://godoc.org/github.com/Masterminds/semver?status.png)](https://godoc.org/github.com/Masterminds/semver) [![Go Report Card](https://goreportcard.com/badge/github.com/Masterminds/semver)](https://goreportcard.com/report/github.com/Masterminds/semver)
## Parsing Semantic Versions
To parse a semantic version use the `NewVersion` function. For example,
```go
v, err := semver.NewVersion("1.2.3-beta.1+build345")
```
If there is an error the version wasn't parseable. The version object has methods
to get the parts of the version, compare it to other versions, convert the
version back into a string, and get the original string. For more details
please see the [documentation](https://godoc.org/github.com/Masterminds/semver).
## Sorting Semantic Versions
A set of versions can be sorted using the [`sort`](https://golang.org/pkg/sort/)
package from the standard library. For example,
```go
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
vs := make([]*semver.Version, len(raw))
for i, r := range raw {
v, err := semver.NewVersion(r)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
vs[i] = v
}
sort.Sort(semver.Collection(vs))
```
## Checking Version Constraints
Checking a version against version constraints is one of the most featureful
parts of the package.
```go
c, err := semver.NewConstraint(">= 1.2.3")
if err != nil {
// Handle constraint not being parseable.
}
v, _ := semver.NewVersion("1.3")
if err != nil {
// Handle version not being parseable.
}
// Check if the version meets the constraints. The a variable will be true.
a := c.Check(v)
```
## Basic Comparisons
There are two elements to the comparisons. First, a comparison string is a list
of comma separated and comparisons. These are then separated by || separated or
comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
greater than or equal to 4.2.3.
The basic comparisons are:
* `=`: equal (aliased to no operator)
* `!=`: not equal
* `>`: greater than
* `<`: less than
* `>=`: greater than or equal to
* `<=`: less than or equal to
_Note, according to the Semantic Version specification pre-releases may not be
API compliant with their release counterpart. It says,_
> _A pre-release version indicates that the version is unstable and might not satisfy the intended compatibility requirements as denoted by its associated normal version._
_SemVer comparisons without a pre-release value will skip pre-release versions.
For example, `>1.2.3` will skip pre-releases when looking at a list of values
while `>1.2.3-alpha.1` will evaluate pre-releases._
## Hyphen Range Comparisons
There are multiple methods to handle ranges and the first is hyphens ranges.
These look like:
* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5`
## Wildcards In Comparisons
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
for all comparison operators. When used on the `=` operator it falls
back to the pack level comparison (see tilde below). For example,
* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `>= 1.2.x` is equivalent to `>= 1.2.0`
* `<= 2.x` is equivalent to `<= 3`
* `*` is equivalent to `>= 0.0.0`
## Tilde Range Comparisons (Patch)
The tilde (`~`) comparison operator is for patch level ranges when a minor
version is specified and major level changes when the minor number is missing.
For example,
* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
* `~1` is equivalent to `>= 1, < 2`
* `~2.3` is equivalent to `>= 2.3, < 2.4`
* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `~1.x` is equivalent to `>= 1, < 2`
## Caret Range Comparisons (Major)
The caret (`^`) comparison operator is for major level changes. This is useful
when comparisons of API versions as a major change is API breaking. For example,
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
* `^2.3` is equivalent to `>= 2.3, < 3`
* `^2.x` is equivalent to `>= 2.0.0, < 3`
# Validation
In addition to testing a version against a constraint, a version can be validated
against a constraint. When validation fails a slice of errors containing why a
version didn't meet the constraint is returned. For example,
```go
c, err := semver.NewConstraint("<= 1.2.3, >= 1.4")
if err != nil {
// Handle constraint not being parseable.
}
v, _ := semver.NewVersion("1.3")
if err != nil {
// Handle version not being parseable.
}
// Validate a version against a constraint.
a, msgs := c.Validate(v)
// a is false
for _, m := range msgs {
fmt.Println(m)
// Loops over the errors which would read
// "1.3 is greater than 1.2.3"
// "1.3 is less than 1.4"
}
```
# Contribute
If you find an issue or want to contribute please file an [issue](https://github.com/Masterminds/semver/issues)
or [create a pull request](https://github.com/Masterminds/semver/pulls).

44
vendor/github.com/Masterminds/semver/appveyor.yml generated vendored Normal file
View File

@@ -0,0 +1,44 @@
version: build-{build}.{branch}
clone_folder: C:\gopath\src\github.com\Masterminds\semver
shallow_clone: true
environment:
GOPATH: C:\gopath
platform:
- x64
install:
- go version
- go env
- go get -u gopkg.in/alecthomas/gometalinter.v1
- set PATH=%PATH%;%GOPATH%\bin
- gometalinter.v1.exe --install
build_script:
- go install -v ./...
test_script:
- "gometalinter.v1 \
--disable-all \
--enable deadcode \
--severity deadcode:error \
--enable gofmt \
--enable gosimple \
--enable ineffassign \
--enable misspell \
--enable vet \
--tests \
--vendor \
--deadline 60s \
./... || exit_code=1"
- "gometalinter.v1 \
--disable-all \
--enable golint \
--vendor \
--deadline 60s \
./... || :"
- go test -v
deploy: off

24
vendor/github.com/Masterminds/semver/collection.go generated vendored Normal file
View File

@@ -0,0 +1,24 @@
package semver
// Collection is a collection of Version instances and implements the sort
// interface. See the sort package for more details.
// https://golang.org/pkg/sort/
type Collection []*Version
// Len returns the length of a collection. The number of Version instances
// on the slice.
func (c Collection) Len() int {
return len(c)
}
// Less is needed for the sort interface to compare two Version objects on the
// slice. If checks if one is less than the other.
func (c Collection) Less(i, j int) bool {
return c[i].LessThan(c[j])
}
// Swap is needed for the sort interface to replace the Version objects
// at two different positions in the slice.
func (c Collection) Swap(i, j int) {
c[i], c[j] = c[j], c[i]
}

421
vendor/github.com/Masterminds/semver/constraints.go generated vendored Normal file
View File

@@ -0,0 +1,421 @@
package semver
import (
"errors"
"fmt"
"regexp"
"strings"
)
// Constraints is one or more constraint that a semantic version can be
// checked against.
type Constraints struct {
constraints [][]*constraint
}
// NewConstraint returns a Constraints instance that a Version instance can
// be checked against. If there is a parse error it will be returned.
func NewConstraint(c string) (*Constraints, error) {
// Rewrite - ranges into a comparison operation.
c = rewriteRange(c)
ors := strings.Split(c, "||")
or := make([][]*constraint, len(ors))
for k, v := range ors {
cs := strings.Split(v, ",")
result := make([]*constraint, len(cs))
for i, s := range cs {
pc, err := parseConstraint(s)
if err != nil {
return nil, err
}
result[i] = pc
}
or[k] = result
}
o := &Constraints{constraints: or}
return o, nil
}
// Check tests if a version satisfies the constraints.
func (cs Constraints) Check(v *Version) bool {
// loop over the ORs and check the inner ANDs
for _, o := range cs.constraints {
joy := true
for _, c := range o {
if !c.check(v) {
joy = false
break
}
}
if joy {
return true
}
}
return false
}
// Validate checks if a version satisfies a constraint. If not a slice of
// reasons for the failure are returned in addition to a bool.
func (cs Constraints) Validate(v *Version) (bool, []error) {
// loop over the ORs and check the inner ANDs
var e []error
for _, o := range cs.constraints {
joy := true
for _, c := range o {
if !c.check(v) {
em := fmt.Errorf(c.msg, v, c.orig)
e = append(e, em)
joy = false
}
}
if joy {
return true, []error{}
}
}
return false, e
}
var constraintOps map[string]cfunc
var constraintMsg map[string]string
var constraintRegex *regexp.Regexp
func init() {
constraintOps = map[string]cfunc{
"": constraintTildeOrEqual,
"=": constraintTildeOrEqual,
"!=": constraintNotEqual,
">": constraintGreaterThan,
"<": constraintLessThan,
">=": constraintGreaterThanEqual,
"=>": constraintGreaterThanEqual,
"<=": constraintLessThanEqual,
"=<": constraintLessThanEqual,
"~": constraintTilde,
"~>": constraintTilde,
"^": constraintCaret,
}
constraintMsg = map[string]string{
"": "%s is not equal to %s",
"=": "%s is not equal to %s",
"!=": "%s is equal to %s",
">": "%s is less than or equal to %s",
"<": "%s is greater than or equal to %s",
">=": "%s is less than %s",
"=>": "%s is less than %s",
"<=": "%s is greater than %s",
"=<": "%s is greater than %s",
"~": "%s does not have same major and minor version as %s",
"~>": "%s does not have same major and minor version as %s",
"^": "%s does not have same major version as %s",
}
ops := make([]string, 0, len(constraintOps))
for k := range constraintOps {
ops = append(ops, regexp.QuoteMeta(k))
}
constraintRegex = regexp.MustCompile(fmt.Sprintf(
`^\s*(%s)\s*(%s)\s*$`,
strings.Join(ops, "|"),
cvRegex))
constraintRangeRegex = regexp.MustCompile(fmt.Sprintf(
`\s*(%s)\s+-\s+(%s)\s*`,
cvRegex, cvRegex))
}
// An individual constraint
type constraint struct {
// The callback function for the restraint. It performs the logic for
// the constraint.
function cfunc
msg string
// The version used in the constraint check. For example, if a constraint
// is '<= 2.0.0' the con a version instance representing 2.0.0.
con *Version
// The original parsed version (e.g., 4.x from != 4.x)
orig string
// When an x is used as part of the version (e.g., 1.x)
minorDirty bool
dirty bool
}
// Check if a version meets the constraint
func (c *constraint) check(v *Version) bool {
return c.function(v, c)
}
type cfunc func(v *Version, c *constraint) bool
func parseConstraint(c string) (*constraint, error) {
m := constraintRegex.FindStringSubmatch(c)
if m == nil {
return nil, fmt.Errorf("improper constraint: %s", c)
}
ver := m[2]
orig := ver
minorDirty := false
dirty := false
if isX(m[3]) {
ver = "0.0.0"
dirty = true
} else if isX(strings.TrimPrefix(m[4], ".")) {
minorDirty = true
dirty = true
ver = fmt.Sprintf("%s.0.0%s", m[3], m[6])
} else if isX(strings.TrimPrefix(m[5], ".")) {
dirty = true
ver = fmt.Sprintf("%s%s.0%s", m[3], m[4], m[6])
}
con, err := NewVersion(ver)
if err != nil {
// The constraintRegex should catch any regex parsing errors. So,
// we should never get here.
return nil, errors.New("constraint Parser Error")
}
cs := &constraint{
function: constraintOps[m[1]],
msg: constraintMsg[m[1]],
con: con,
orig: orig,
minorDirty: minorDirty,
dirty: dirty,
}
return cs, nil
}
// Constraint functions
func constraintNotEqual(v *Version, c *constraint) bool {
if c.dirty {
// If there is a pre-release on the version but the constraint isn't looking
// for them assume that pre-releases are not compatible. See issue 21 for
// more details.
if v.Prerelease() != "" && c.con.Prerelease() == "" {
return false
}
if c.con.Major() != v.Major() {
return true
}
if c.con.Minor() != v.Minor() && !c.minorDirty {
return true
} else if c.minorDirty {
return false
}
return false
}
return !v.Equal(c.con)
}
func constraintGreaterThan(v *Version, c *constraint) bool {
// An edge case the constraint is 0.0.0 and the version is 0.0.0-someprerelease
// exists. This that case.
if !isNonZero(c.con) && isNonZero(v) {
return true
}
// If there is a pre-release on the version but the constraint isn't looking
// for them assume that pre-releases are not compatible. See issue 21 for
// more details.
if v.Prerelease() != "" && c.con.Prerelease() == "" {
return false
}
return v.Compare(c.con) == 1
}
func constraintLessThan(v *Version, c *constraint) bool {
// If there is a pre-release on the version but the constraint isn't looking
// for them assume that pre-releases are not compatible. See issue 21 for
// more details.
if v.Prerelease() != "" && c.con.Prerelease() == "" {
return false
}
if !c.dirty {
return v.Compare(c.con) < 0
}
if v.Major() > c.con.Major() {
return false
} else if v.Minor() > c.con.Minor() && !c.minorDirty {
return false
}
return true
}
func constraintGreaterThanEqual(v *Version, c *constraint) bool {
// An edge case the constraint is 0.0.0 and the version is 0.0.0-someprerelease
// exists. This that case.
if !isNonZero(c.con) && isNonZero(v) {
return true
}
// If there is a pre-release on the version but the constraint isn't looking
// for them assume that pre-releases are not compatible. See issue 21 for
// more details.
if v.Prerelease() != "" && c.con.Prerelease() == "" {
return false
}
return v.Compare(c.con) >= 0
}
func constraintLessThanEqual(v *Version, c *constraint) bool {
// If there is a pre-release on the version but the constraint isn't looking
// for them assume that pre-releases are not compatible. See issue 21 for
// more details.
if v.Prerelease() != "" && c.con.Prerelease() == "" {
return false
}
if !c.dirty {
return v.Compare(c.con) <= 0
}
if v.Major() > c.con.Major() {
return false
} else if v.Minor() > c.con.Minor() && !c.minorDirty {
return false
}
return true
}
// ~*, ~>* --> >= 0.0.0 (any)
// ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0, <3.0.0
// ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0, <2.1.0
// ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0, <1.3.0
// ~1.2.3, ~>1.2.3 --> >=1.2.3, <1.3.0
// ~1.2.0, ~>1.2.0 --> >=1.2.0, <1.3.0
func constraintTilde(v *Version, c *constraint) bool {
// If there is a pre-release on the version but the constraint isn't looking
// for them assume that pre-releases are not compatible. See issue 21 for
// more details.
if v.Prerelease() != "" && c.con.Prerelease() == "" {
return false
}
if v.LessThan(c.con) {
return false
}
// ~0.0.0 is a special case where all constraints are accepted. It's
// equivalent to >= 0.0.0.
if c.con.Major() == 0 && c.con.Minor() == 0 && c.con.Patch() == 0 {
return true
}
if v.Major() != c.con.Major() {
return false
}
if v.Minor() != c.con.Minor() && !c.minorDirty {
return false
}
return true
}
// When there is a .x (dirty) status it automatically opts in to ~. Otherwise
// it's a straight =
func constraintTildeOrEqual(v *Version, c *constraint) bool {
// If there is a pre-release on the version but the constraint isn't looking
// for them assume that pre-releases are not compatible. See issue 21 for
// more details.
if v.Prerelease() != "" && c.con.Prerelease() == "" {
return false
}
if c.dirty {
c.msg = constraintMsg["~"]
return constraintTilde(v, c)
}
return v.Equal(c.con)
}
// ^* --> (any)
// ^2, ^2.x, ^2.x.x --> >=2.0.0, <3.0.0
// ^2.0, ^2.0.x --> >=2.0.0, <3.0.0
// ^1.2, ^1.2.x --> >=1.2.0, <2.0.0
// ^1.2.3 --> >=1.2.3, <2.0.0
// ^1.2.0 --> >=1.2.0, <2.0.0
func constraintCaret(v *Version, c *constraint) bool {
// If there is a pre-release on the version but the constraint isn't looking
// for them assume that pre-releases are not compatible. See issue 21 for
// more details.
if v.Prerelease() != "" && c.con.Prerelease() == "" {
return false
}
if v.LessThan(c.con) {
return false
}
if v.Major() != c.con.Major() {
return false
}
return true
}
var constraintRangeRegex *regexp.Regexp
const cvRegex string = `v?([0-9|x|X|\*]+)(\.[0-9|x|X|\*]+)?(\.[0-9|x|X|\*]+)?` +
`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
func isX(x string) bool {
switch x {
case "x", "*", "X":
return true
default:
return false
}
}
func rewriteRange(i string) string {
m := constraintRangeRegex.FindAllStringSubmatch(i, -1)
if m == nil {
return i
}
o := i
for _, v := range m {
t := fmt.Sprintf(">= %s, <= %s", v[1], v[11])
o = strings.Replace(o, v[0], t, 1)
}
return o
}
// Detect if a version is not zero (0.0.0)
func isNonZero(v *Version) bool {
if v.Major() != 0 || v.Minor() != 0 || v.Patch() != 0 || v.Prerelease() != "" {
return true
}
return false
}

115
vendor/github.com/Masterminds/semver/doc.go generated vendored Normal file
View File

@@ -0,0 +1,115 @@
/*
Package semver provides the ability to work with Semantic Versions (http://semver.org) in Go.
Specifically it provides the ability to:
* Parse semantic versions
* Sort semantic versions
* Check if a semantic version fits within a set of constraints
* Optionally work with a `v` prefix
Parsing Semantic Versions
To parse a semantic version use the `NewVersion` function. For example,
v, err := semver.NewVersion("1.2.3-beta.1+build345")
If there is an error the version wasn't parseable. The version object has methods
to get the parts of the version, compare it to other versions, convert the
version back into a string, and get the original string. For more details
please see the documentation at https://godoc.org/github.com/Masterminds/semver.
Sorting Semantic Versions
A set of versions can be sorted using the `sort` package from the standard library.
For example,
raw := []string{"1.2.3", "1.0", "1.3", "2", "0.4.2",}
vs := make([]*semver.Version, len(raw))
for i, r := range raw {
v, err := semver.NewVersion(r)
if err != nil {
t.Errorf("Error parsing version: %s", err)
}
vs[i] = v
}
sort.Sort(semver.Collection(vs))
Checking Version Constraints
Checking a version against version constraints is one of the most featureful
parts of the package.
c, err := semver.NewConstraint(">= 1.2.3")
if err != nil {
// Handle constraint not being parseable.
}
v, _ := semver.NewVersion("1.3")
if err != nil {
// Handle version not being parseable.
}
// Check if the version meets the constraints. The a variable will be true.
a := c.Check(v)
Basic Comparisons
There are two elements to the comparisons. First, a comparison string is a list
of comma separated and comparisons. These are then separated by || separated or
comparisons. For example, `">= 1.2, < 3.0.0 || >= 4.2.3"` is looking for a
comparison that's greater than or equal to 1.2 and less than 3.0.0 or is
greater than or equal to 4.2.3.
The basic comparisons are:
* `=`: equal (aliased to no operator)
* `!=`: not equal
* `>`: greater than
* `<`: less than
* `>=`: greater than or equal to
* `<=`: less than or equal to
Hyphen Range Comparisons
There are multiple methods to handle ranges and the first is hyphens ranges.
These look like:
* `1.2 - 1.4.5` which is equivalent to `>= 1.2, <= 1.4.5`
* `2.3.4 - 4.5` which is equivalent to `>= 2.3.4, <= 4.5`
Wildcards In Comparisons
The `x`, `X`, and `*` characters can be used as a wildcard character. This works
for all comparison operators. When used on the `=` operator it falls
back to the pack level comparison (see tilde below). For example,
* `1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `>= 1.2.x` is equivalent to `>= 1.2.0`
* `<= 2.x` is equivalent to `<= 3`
* `*` is equivalent to `>= 0.0.0`
Tilde Range Comparisons (Patch)
The tilde (`~`) comparison operator is for patch level ranges when a minor
version is specified and major level changes when the minor number is missing.
For example,
* `~1.2.3` is equivalent to `>= 1.2.3, < 1.3.0`
* `~1` is equivalent to `>= 1, < 2`
* `~2.3` is equivalent to `>= 2.3, < 2.4`
* `~1.2.x` is equivalent to `>= 1.2.0, < 1.3.0`
* `~1.x` is equivalent to `>= 1, < 2`
Caret Range Comparisons (Major)
The caret (`^`) comparison operator is for major level changes. This is useful
when comparisons of API versions as a major change is API breaking. For example,
* `^1.2.3` is equivalent to `>= 1.2.3, < 2.0.0`
* `^1.2.x` is equivalent to `>= 1.2.0, < 2.0.0`
* `^2.3` is equivalent to `>= 2.3, < 3`
* `^2.x` is equivalent to `>= 2.0.0, < 3`
*/
package semver

375
vendor/github.com/Masterminds/semver/version.go generated vendored Normal file
View File

@@ -0,0 +1,375 @@
package semver
import (
"bytes"
"errors"
"fmt"
"regexp"
"strconv"
"strings"
)
// The compiled version of the regex created at init() is cached here so it
// only needs to be created once.
var versionRegex *regexp.Regexp
var validPrereleaseRegex *regexp.Regexp
var (
// ErrInvalidSemVer is returned a version is found to be invalid when
// being parsed.
ErrInvalidSemVer = errors.New("Invalid Semantic Version")
// ErrInvalidMetadata is returned when the metadata is an invalid format
ErrInvalidMetadata = errors.New("Invalid Metadata string")
// ErrInvalidPrerelease is returned when the pre-release is an invalid format
ErrInvalidPrerelease = errors.New("Invalid Prerelease string")
)
// SemVerRegex is the regular expression used to parse a semantic version.
const SemVerRegex string = `v?([0-9]+)(\.[0-9]+)?(\.[0-9]+)?` +
`(-([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?` +
`(\+([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*))?`
// ValidPrerelease is the regular expression which validates
// both prerelease and metadata values.
const ValidPrerelease string = `^([0-9A-Za-z\-]+(\.[0-9A-Za-z\-]+)*)`
// Version represents a single semantic version.
type Version struct {
major, minor, patch int64
pre string
metadata string
original string
}
func init() {
versionRegex = regexp.MustCompile("^" + SemVerRegex + "$")
validPrereleaseRegex = regexp.MustCompile(ValidPrerelease)
}
// NewVersion parses a given version and returns an instance of Version or
// an error if unable to parse the version.
func NewVersion(v string) (*Version, error) {
m := versionRegex.FindStringSubmatch(v)
if m == nil {
return nil, ErrInvalidSemVer
}
sv := &Version{
metadata: m[8],
pre: m[5],
original: v,
}
var temp int64
temp, err := strconv.ParseInt(m[1], 10, 32)
if err != nil {
return nil, fmt.Errorf("Error parsing version segment: %s", err)
}
sv.major = temp
if m[2] != "" {
temp, err = strconv.ParseInt(strings.TrimPrefix(m[2], "."), 10, 32)
if err != nil {
return nil, fmt.Errorf("Error parsing version segment: %s", err)
}
sv.minor = temp
} else {
sv.minor = 0
}
if m[3] != "" {
temp, err = strconv.ParseInt(strings.TrimPrefix(m[3], "."), 10, 32)
if err != nil {
return nil, fmt.Errorf("Error parsing version segment: %s", err)
}
sv.patch = temp
} else {
sv.patch = 0
}
return sv, nil
}
// MustParse parses a given version and panics on error.
func MustParse(v string) *Version {
sv, err := NewVersion(v)
if err != nil {
panic(err)
}
return sv
}
// String converts a Version object to a string.
// Note, if the original version contained a leading v this version will not.
// See the Original() method to retrieve the original value. Semantic Versions
// don't contain a leading v per the spec. Instead it's optional on
// impelementation.
func (v *Version) String() string {
var buf bytes.Buffer
fmt.Fprintf(&buf, "%d.%d.%d", v.major, v.minor, v.patch)
if v.pre != "" {
fmt.Fprintf(&buf, "-%s", v.pre)
}
if v.metadata != "" {
fmt.Fprintf(&buf, "+%s", v.metadata)
}
return buf.String()
}
// Original returns the original value passed in to be parsed.
func (v *Version) Original() string {
return v.original
}
// Major returns the major version.
func (v *Version) Major() int64 {
return v.major
}
// Minor returns the minor version.
func (v *Version) Minor() int64 {
return v.minor
}
// Patch returns the patch version.
func (v *Version) Patch() int64 {
return v.patch
}
// Prerelease returns the pre-release version.
func (v *Version) Prerelease() string {
return v.pre
}
// Metadata returns the metadata on the version.
func (v *Version) Metadata() string {
return v.metadata
}
// originalVPrefix returns the original 'v' prefix if any.
func (v *Version) originalVPrefix() string {
// Note, only lowercase v is supported as a prefix by the parser.
if v.original != "" && v.original[:1] == "v" {
return v.original[:1]
}
return ""
}
// IncPatch produces the next patch version.
// If the current version does not have prerelease/metadata information,
// it unsets metadata and prerelease values, increments patch number.
// If the current version has any of prerelease or metadata information,
// it unsets both values and keeps curent patch value
func (v Version) IncPatch() Version {
vNext := v
// according to http://semver.org/#spec-item-9
// Pre-release versions have a lower precedence than the associated normal version.
// according to http://semver.org/#spec-item-10
// Build metadata SHOULD be ignored when determining version precedence.
if v.pre != "" {
vNext.metadata = ""
vNext.pre = ""
} else {
vNext.metadata = ""
vNext.pre = ""
vNext.patch = v.patch + 1
}
vNext.original = v.originalVPrefix() + "" + vNext.String()
return vNext
}
// IncMinor produces the next minor version.
// Sets patch to 0.
// Increments minor number.
// Unsets metadata.
// Unsets prerelease status.
func (v Version) IncMinor() Version {
vNext := v
vNext.metadata = ""
vNext.pre = ""
vNext.patch = 0
vNext.minor = v.minor + 1
vNext.original = v.originalVPrefix() + "" + vNext.String()
return vNext
}
// IncMajor produces the next major version.
// Sets patch to 0.
// Sets minor to 0.
// Increments major number.
// Unsets metadata.
// Unsets prerelease status.
func (v Version) IncMajor() Version {
vNext := v
vNext.metadata = ""
vNext.pre = ""
vNext.patch = 0
vNext.minor = 0
vNext.major = v.major + 1
vNext.original = v.originalVPrefix() + "" + vNext.String()
return vNext
}
// SetPrerelease defines the prerelease value.
// Value must not include the required 'hypen' prefix.
func (v Version) SetPrerelease(prerelease string) (Version, error) {
vNext := v
if len(prerelease) > 0 && !validPrereleaseRegex.MatchString(prerelease) {
return vNext, ErrInvalidPrerelease
}
vNext.pre = prerelease
vNext.original = v.originalVPrefix() + "" + vNext.String()
return vNext, nil
}
// SetMetadata defines metadata value.
// Value must not include the required 'plus' prefix.
func (v Version) SetMetadata(metadata string) (Version, error) {
vNext := v
if len(metadata) > 0 && !validPrereleaseRegex.MatchString(metadata) {
return vNext, ErrInvalidMetadata
}
vNext.metadata = metadata
vNext.original = v.originalVPrefix() + "" + vNext.String()
return vNext, nil
}
// LessThan tests if one version is less than another one.
func (v *Version) LessThan(o *Version) bool {
return v.Compare(o) < 0
}
// GreaterThan tests if one version is greater than another one.
func (v *Version) GreaterThan(o *Version) bool {
return v.Compare(o) > 0
}
// Equal tests if two versions are equal to each other.
// Note, versions can be equal with different metadata since metadata
// is not considered part of the comparable version.
func (v *Version) Equal(o *Version) bool {
return v.Compare(o) == 0
}
// Compare compares this version to another one. It returns -1, 0, or 1 if
// the version smaller, equal, or larger than the other version.
//
// Versions are compared by X.Y.Z. Build metadata is ignored. Prerelease is
// lower than the version without a prerelease.
func (v *Version) Compare(o *Version) int {
// Compare the major, minor, and patch version for differences. If a
// difference is found return the comparison.
if d := compareSegment(v.Major(), o.Major()); d != 0 {
return d
}
if d := compareSegment(v.Minor(), o.Minor()); d != 0 {
return d
}
if d := compareSegment(v.Patch(), o.Patch()); d != 0 {
return d
}
// At this point the major, minor, and patch versions are the same.
ps := v.pre
po := o.Prerelease()
if ps == "" && po == "" {
return 0
}
if ps == "" {
return 1
}
if po == "" {
return -1
}
return comparePrerelease(ps, po)
}
func compareSegment(v, o int64) int {
if v < o {
return -1
}
if v > o {
return 1
}
return 0
}
func comparePrerelease(v, o string) int {
// split the prelease versions by their part. The separator, per the spec,
// is a .
sparts := strings.Split(v, ".")
oparts := strings.Split(o, ".")
// Find the longer length of the parts to know how many loop iterations to
// go through.
slen := len(sparts)
olen := len(oparts)
l := slen
if olen > slen {
l = olen
}
// Iterate over each part of the prereleases to compare the differences.
for i := 0; i < l; i++ {
// Since the lentgh of the parts can be different we need to create
// a placeholder. This is to avoid out of bounds issues.
stemp := ""
if i < slen {
stemp = sparts[i]
}
otemp := ""
if i < olen {
otemp = oparts[i]
}
d := comparePrePart(stemp, otemp)
if d != 0 {
return d
}
}
// Reaching here means two versions are of equal value but have different
// metadata (the part following a +). They are not identical in string form
// but the version comparison finds them to be equal.
return 0
}
func comparePrePart(s, o string) int {
// Fastpath if they are equal
if s == o {
return 0
}
// When s or o are empty we can use the other in an attempt to determine
// the response.
if o == "" {
_, n := strconv.ParseInt(s, 10, 64)
if n != nil {
return -1
}
return 1
}
if s == "" {
_, n := strconv.ParseInt(o, 10, 64)
if n != nil {
return 1
}
return -1
}
if s > o {
return 1
}
return -1
}

View File

@@ -1 +0,0 @@
vendor/

View File

@@ -1,21 +0,0 @@
language: go
go:
- 1.3
- 1.4
- 1.5
- 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
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

13
vendor/github.com/Masterminds/sprig/Makefile generated vendored Normal file
View File

@@ -0,0 +1,13 @@
HAS_GLIDE := $(shell command -v glide;)
.PHONY: test
test:
go test -v .
.PHONY: setup
setup:
ifndef HAS_GLIDE
go get -u github.com/Masterminds/glide
endif
glide install

View File

@@ -1,4 +1,6 @@
# Sprig: Template functions for Go templates # Sprig: Template functions for Go templates
[![Stability: Sustained](https://masterminds.github.io/stability/sustained.svg)](https://masterminds.github.io/stability/sustained.html)
[![Build Status](https://travis-ci.org/Masterminds/sprig.svg?branch=master)](https://travis-ci.org/Masterminds/sprig)
The Go language comes with a [built-in template The Go language comes with a [built-in template
language](http://golang.org/pkg/text/template/), but not language](http://golang.org/pkg/text/template/), but not
@@ -6,12 +8,15 @@ very many template functions. This library provides a group of commonly
used template functions. used template functions.
It is inspired by the template functions found in It is inspired by the template functions found in
[Twig](http://twig.sensiolabs.org/documentation). [Twig](http://twig.sensiolabs.org/documentation) and also in various
JavaScript libraries, such as [underscore.js](http://underscorejs.org/).
[![Build Status](https://travis-ci.org/Masterminds/sprig.svg?branch=master)](https://travis-ci.org/Masterminds/sprig)
## Usage ## Usage
Template developers can read the [Sprig function documentation](http://masterminds.github.io/sprig/) to
learn about the >100 template functions available.
For Go developers wishing to include Sprig as a library in their programs,
API documentation is available [at GoDoc.org](http://godoc.org/github.com/Masterminds/sprig), but API documentation is available [at GoDoc.org](http://godoc.org/github.com/Masterminds/sprig), but
read on for standard usage. read on for standard usage.
@@ -54,168 +59,6 @@ Produces:
HELLO!HELLO!HELLO!HELLO!HELLO! HELLO!HELLO!HELLO!HELLO!HELLO!
``` ```
## Functions
### Date Functions
- date: Format a date, where a date is an integer type or a time.Time type, and
format is a time.Format formatting string.
- dateModify: Given a date, modify it with a duration: `date_modify "-1.5h" now`. If the duration doesn't
parse, it returns the time unaltered. See `time.ParseDuration` for info on duration strings.
- now: Current time.Time, for feeding into date-related functions.
- htmlDate: Format a date for use in the value field of an HTML "date" form element.
- dateInZone: Like date, but takes three arguments: format, timestamp,
timezone.
- htmlDateInZone: Like htmlDate, but takes two arguments: timestamp,
timezone.
### String Functions
- trim: strings.TrimSpace
- trimAll: strings.Trim, but with the argument order reversed `trimAll "$" "$5.00"` or `"$5.00 | trimAll "$"`
- trimSuffix: strings.TrimSuffix, but with the argument order reversed `trimSuffix "-" "5-"`
- trimPrefix: strings.TrimPrefix, but with the argument order reversed `trimPrefix "$" "$5"`
- upper: strings.ToUpper
- lower: strings.ToLower
- title: strings.Title
- repeat: strings.Repeat, but with the arguments switched: `repeat count str`. (This simplifies common pipelines)
- substr: Given string, start, and length, return a substr.
- nospace: Remove all spaces from a string. `h e l l o` becomes
`hello`.
- abbrev: Truncate a string with ellipses
- trunc: Truncate a string (no suffix). `trunc 5 "Hello World"` yields "hello".
- abbrevboth: Truncate both sides of a string with ellipses
- untitle: Remove title case
- intials: Given multiple words, return the first letter of each
word
- randAlphaNum: Generate a random alpha-numeric string
- randAlpha: Generate a random alphabetic string
- randAscii: Generate a random ASCII string, including symbols
- randNumeric: Generate a random numeric string
- wrap: Wrap text at the given column count
- wrapWith: Wrap text at the given column count, and with the given
string for a line terminator: `wrap 50 "\n\t" $string`
- contains: strings.Contains, but with the arguments switched: `contains "cat" "uncatch"`. (This simplifies common pipelines)
- hasPrefix: strings.hasPrefix, but with the arguments switched: `hasPrefix "cat" "catch"`.
- hasSuffix: strings.hasSuffix, but with the arguments switched: `hasSuffix "cat" "ducat"`.
- quote: Wrap strings in double quotes. `quote "a" "b"` returns `"a"
"b"`
- squote: Wrap strings in single quotes.
- 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"
- 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"`
- uuidv4: Generate a UUID v4 string
- sha256sum: Generate a hex encoded sha256 hash of the input
### String Slice Functions:
- join: strings.Join, but as `join SEP SLICE`
- split: strings.Split, but as `split SEP STRING`. The results are returned
as a map with the indexes set to _N, where N is an integer starting from 0.
Use it like this: `{{$v := "foo/bar/baz" | split "/"}}{{$v._0}}` (Prints `foo`)
### Integer Slice Functions:
- until: Given an integer, returns a slice of counting integers from 0 to one
less than the given integer: `range $i, $e := until 5`
- untilStep: Given start, stop, and step, return an integer slice starting at
'start', stopping at `stop`, and incrementing by 'step'. This is the same
as Python's long-form of 'range'.
### Conversions:
- atoi: Convert a string to an integer. 0 if the integer could not be parsed.
- int: Convert a string or numeric to an int
- int64: Convert a string or numeric to an int64
- float64: Convert a string or numeric to a float64
### Defaults:
- default: Give a default value. Used like this: {{trim " "| default "empty"}}.
Since trim produces an empty string, the default value is returned. For
things with a length (strings, slices, maps), len(0) will trigger the default.
For numbers, the value 0 will trigger the default. For booleans, false will
trigger the default. For structs, the default is never returned (there is
no clear empty condition). For everything else, nil value triggers a default.
- empty: Returns true if the given value is the zero value for that
type. Structs are always non-empty.
### OS:
- env: Read an environment variable.
- expandenv: Expand all environment variables in a string.
### Encoding:
- b32enc: Encode a string into a Base32 string
- b32dec: Decode a string from a Base32 string
- b64enc: Encode a string into a Base64 string
- b64dec: Decode a string from a Base64 string
### Data Structures:
- tuple: A sequence of related objects. It is implemented as a
`[]interface{}`, where each item can be accessed using `index`.
- dict: Takes a list of name/values and returns a map[string]interface{}.
The first parameter is converted to a string and stored as a key, the
second parameter is treated as the value. And so on, with odds as keys and
evens as values. If the function call ends with an odd, the last key will
be assigned the empty string. Non-string keys are converted to strings as
follows: []byte are converted, fmt.Stringers will have String() called.
errors will have Error() called. All others will be passed through
fmt.Sprtinf("%v").
- set: Takes a dict, a key, and a value, and sets that key/value pair in
the dict. `set $dict $key $value`. For convenience, it returns the dict,
even though the dict was modified in place.
- unset: Takes a dict and a key, and deletes that key/value pair from the
dict. `unset $dict $key`. This returns the dict for convenience.
- hasKey: Takes a dict and a key, and returns boolean true if the key is in
the dict.
```
{{$t := tuple 1 "a" "foo"}}
{{index $t 2}}{{index $t 0 }}{{index $t 1}}
{{/* Prints foo1a *}}
```
### Reflection:
- typeOf: Takes an interface and returns a string representation of the type.
For pointers, this will return a type prefixed with an asterisk(`*`). So
a pointer to type `Foo` will be `*Foo`.
- typeIs: Compares an interface with a string name, and returns true if they match.
Note that a pointer will not match a reference. For example `*Foo` will not
match `Foo`.
- typeIsLike: returns true if the interface is of the given type, or
is a pointer to the given type.
- kindOf: Takes an interface and returns a string representation of its kind.
- kindIs: Returns true if the given string matches the kind of the given interface.
Note: None of these can test whether or not something implements a given
interface, since doing so would require compiling the interface in ahead of
time.
### Math Functions:
Integer functions will convert integers of any width to `int64`. If a
string is passed in, functions will attempt to conver with
`strconv.ParseInt(s, 1064)`. If this fails, the value will be treated as 0.
- add1: Increment an integer by 1
- add: Sum integers. `add 1 2 3` renders `6`
- sub: Subtract the second integer from the first
- div: Divide the first integer by the second
- mod: Module of first integer divided by second
- mul: Multiply integers integers
- max (biggest): Return the biggest of a series of integers. `max 1 2 3`
returns `3`.
- min: Return the smallest of a series of integers. `min 1 2 3` returns
`1`.
## Principles: ## Principles:
The following principles were used in deciding on which functions to add, and The following principles were used in deciding on which functions to add, and

380
vendor/github.com/Masterminds/sprig/crypto.go generated vendored Normal file
View File

@@ -0,0 +1,380 @@
package sprig
import (
"bytes"
"crypto/dsa"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/hmac"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/binary"
"encoding/hex"
"encoding/pem"
"errors"
"fmt"
"math/big"
"net"
"time"
uuid "github.com/satori/go.uuid"
"golang.org/x/crypto/scrypt"
)
func sha256sum(input string) string {
hash := sha256.Sum256([]byte(input))
return hex.EncodeToString(hash[:])
}
// uuidv4 provides a safe and secure UUID v4 implementation
func uuidv4() string {
return fmt.Sprintf("%s", uuid.NewV4())
}
var master_password_seed = "com.lyndir.masterpassword"
var password_type_templates = map[string][][]byte{
"maximum": {[]byte("anoxxxxxxxxxxxxxxxxx"), []byte("axxxxxxxxxxxxxxxxxno")},
"long": {[]byte("CvcvnoCvcvCvcv"), []byte("CvcvCvcvnoCvcv"), []byte("CvcvCvcvCvcvno"), []byte("CvccnoCvcvCvcv"), []byte("CvccCvcvnoCvcv"),
[]byte("CvccCvcvCvcvno"), []byte("CvcvnoCvccCvcv"), []byte("CvcvCvccnoCvcv"), []byte("CvcvCvccCvcvno"), []byte("CvcvnoCvcvCvcc"),
[]byte("CvcvCvcvnoCvcc"), []byte("CvcvCvcvCvccno"), []byte("CvccnoCvccCvcv"), []byte("CvccCvccnoCvcv"), []byte("CvccCvccCvcvno"),
[]byte("CvcvnoCvccCvcc"), []byte("CvcvCvccnoCvcc"), []byte("CvcvCvccCvccno"), []byte("CvccnoCvcvCvcc"), []byte("CvccCvcvnoCvcc"),
[]byte("CvccCvcvCvccno")},
"medium": {[]byte("CvcnoCvc"), []byte("CvcCvcno")},
"short": {[]byte("Cvcn")},
"basic": {[]byte("aaanaaan"), []byte("aannaaan"), []byte("aaannaaa")},
"pin": {[]byte("nnnn")},
}
var template_characters = map[byte]string{
'V': "AEIOU",
'C': "BCDFGHJKLMNPQRSTVWXYZ",
'v': "aeiou",
'c': "bcdfghjklmnpqrstvwxyz",
'A': "AEIOUBCDFGHJKLMNPQRSTVWXYZ",
'a': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz",
'n': "0123456789",
'o': "@&%?,=[]_:-+*$#!'^~;()/.",
'x': "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()",
}
func derivePassword(counter uint32, password_type, password, user, site string) string {
var templates = password_type_templates[password_type]
if templates == nil {
return fmt.Sprintf("cannot find password template %s", password_type)
}
var buffer bytes.Buffer
buffer.WriteString(master_password_seed)
binary.Write(&buffer, binary.BigEndian, uint32(len(user)))
buffer.WriteString(user)
salt := buffer.Bytes()
key, err := scrypt.Key([]byte(password), salt, 32768, 8, 2, 64)
if err != nil {
return fmt.Sprintf("failed to derive password: %s", err)
}
buffer.Truncate(len(master_password_seed))
binary.Write(&buffer, binary.BigEndian, uint32(len(site)))
buffer.WriteString(site)
binary.Write(&buffer, binary.BigEndian, counter)
var hmacv = hmac.New(sha256.New, key)
hmacv.Write(buffer.Bytes())
var seed = hmacv.Sum(nil)
var temp = templates[int(seed[0])%len(templates)]
buffer.Truncate(0)
for i, element := range temp {
pass_chars := template_characters[element]
pass_char := pass_chars[int(seed[i+1])%len(pass_chars)]
buffer.WriteByte(pass_char)
}
return buffer.String()
}
func generatePrivateKey(typ string) string {
var priv interface{}
var err error
switch typ {
case "", "rsa":
// good enough for government work
priv, err = rsa.GenerateKey(rand.Reader, 4096)
case "dsa":
key := new(dsa.PrivateKey)
// again, good enough for government work
if err = dsa.GenerateParameters(&key.Parameters, rand.Reader, dsa.L2048N256); err != nil {
return fmt.Sprintf("failed to generate dsa params: %s", err)
}
err = dsa.GenerateKey(key, rand.Reader)
priv = key
case "ecdsa":
// again, good enough for government work
priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
default:
return "Unknown type " + typ
}
if err != nil {
return fmt.Sprintf("failed to generate private key: %s", err)
}
return string(pem.EncodeToMemory(pemBlockForKey(priv)))
}
type DSAKeyFormat struct {
Version int
P, Q, G, Y, X *big.Int
}
func pemBlockForKey(priv interface{}) *pem.Block {
switch k := priv.(type) {
case *rsa.PrivateKey:
return &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(k)}
case *dsa.PrivateKey:
val := DSAKeyFormat{
P: k.P, Q: k.Q, G: k.G,
Y: k.Y, X: k.X,
}
bytes, _ := asn1.Marshal(val)
return &pem.Block{Type: "DSA PRIVATE KEY", Bytes: bytes}
case *ecdsa.PrivateKey:
b, _ := x509.MarshalECPrivateKey(k)
return &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}
default:
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
}

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