From eba25fefd42ece9f717999994a63a47c14099dfb Mon Sep 17 00:00:00 2001 From: pritesh-patel Date: Fri, 4 Oct 2019 19:52:36 -0700 Subject: [PATCH 1/2] move idl into project dir on generation --- Dockerfile | 17 ++++++++ Makefile | 17 ++++---- README.md | 30 ++++++++------ cmd/create.go | 18 ++++++++- cmd/generate.go | 1 - example/hello-world/.gitignore | 1 + example/hello-world/go.mod | 2 +- .../hello-world-idl/Makefile | 20 ++-------- .../gen/go/health/health.pb.go | 40 ++++++++----------- .../gen/go/helloworld/helloworld.pb.go | 0 .../gen/web/health/health_pb.d.ts | 3 -- .../gen/web/helloworld/helloworld_pb.d.ts | 0 .../{ => hello-world}/hello-world-idl/go.mod | 0 .../hello-world-idl/proto/health/health.proto | 15 +------ .../proto/helloworld/helloworld.proto | 0 example/hello-world/sprout.yml | 4 -- generate/proto/generate.go | 10 ++--- go.mod | 4 +- templates/golang/go_mod.tmpl | 2 +- templates/util/gitignore.tmpl | 1 + templator/templator.go | 8 ++++ test/hello-world/go.mod | 9 +++++ test/hello-world/main.go | 30 ++++++++++++++ test/hello-world/server/health/health.go | 25 ++++++++++++ .../server/helloworld/helloworld.go | 14 +++++++ test/hello-world/sprout.yml | 20 ++++++++++ 26 files changed, 197 insertions(+), 94 deletions(-) create mode 100644 Dockerfile create mode 100644 example/hello-world/.gitignore rename example/{ => hello-world}/hello-world-idl/Makefile (63%) rename example/{ => hello-world}/hello-world-idl/gen/go/health/health.pb.go (81%) rename example/{ => hello-world}/hello-world-idl/gen/go/helloworld/helloworld.pb.go (100%) rename example/{ => hello-world}/hello-world-idl/gen/web/health/health_pb.d.ts (89%) rename example/{ => hello-world}/hello-world-idl/gen/web/helloworld/helloworld_pb.d.ts (100%) rename example/{ => hello-world}/hello-world-idl/go.mod (100%) rename example/{ => hello-world}/hello-world-idl/proto/health/health.proto (50%) rename example/{ => hello-world}/hello-world-idl/proto/helloworld/helloworld.proto (100%) create mode 100644 templates/util/gitignore.tmpl create mode 100644 test/hello-world/go.mod create mode 100644 test/hello-world/main.go create mode 100644 test/hello-world/server/health/health.go create mode 100644 test/hello-world/server/helloworld/helloworld.go create mode 100644 test/hello-world/sprout.yml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..e4341e3a9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +FROM golang:1.12.6@sha256:83e8267be041b3ddf6a5792c7e464528408f75c446745642db08cfe4e8d58d18 AS build +WORKDIR /cache +COPY go.mod . +COPY go.sum . +RUN go mod tidy && go mod download +COPY . . +RUN apt-get update && apt-get -y install sudo && apt-get -y install unzip +RUN make deps-linux && mv /go/bin/protoc-* /usr/local/bin/ +RUN make install-go && \ + mv /go/bin/sprout /usr/local/bin/ + + +FROM alpine +WORKDIR project +RUN apk add --update make +COPY --from=build /usr/local/bin /usr/local/bin +COPY --from=build /usr/local/include /usr/include diff --git a/Makefile b/Makefile index 00e10fc78..7646a8b10 100644 --- a/Makefile +++ b/Makefile @@ -14,8 +14,8 @@ deps-linux: deps-go deps-protoc-linux deps-grpc-web-linux deps-protoc-linux: curl -OL https://github.com/google/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-linux-x86_64.zip unzip protoc-$(PROTOC_VERSION)-linux-x86_64.zip -d protoc3 - sudo mv protoc3/bin/* /usr/local/bin/ - sudo mv protoc3/include/* /usr/local/include/ + sudo mv protoc3/bin/* /usr/local/bin + sudo mv protoc3/include/* /usr/local/include rm -rf protoc3 protoc-$(PROTOC_VERSION)-linux-x86_64.zip deps-grpc-web-linux: @@ -36,7 +36,7 @@ run: go run main.go build: - packr2 build -o sprout + CGO_ENABLED=0 packr2 build -o sprout packr2 clean build-example: build clean-example @@ -44,11 +44,12 @@ build-example: build clean-example cd example && ../sprout create "hello-world" cd example/hello-world && ../../sprout generate -l go +build-docker-local: + docker build . -t sprout:v0 + clean-example: rm -rf example -install-linux: build - mkdir -p ${HOME}/bin - cp sprout ${HOME}/bin/sprout - chmod +x ${HOME}/bin/sprout - @printf "\n Please run 'source ~/.profile' to add this installation to the path." +install-go: + CGO_ENABLED=0 packr2 build -o ${GOPATH}/bin/sprout + packr2 clean diff --git a/README.md b/README.md index bed4ae1a9..e1c4527a0 100644 --- a/README.md +++ b/README.md @@ -18,24 +18,30 @@ It will also live with your project, when you add a new service to the config it ## What does it generate? -The generation will create 2 folders. +The generation will create project folder, within this there will be your implementation and an IDL folder -* A repo for the IDL's, this folder will also contain generated artifacts from the IDL under 'gen' -* A repo that implements the interfaces of the generated artifacts +* A parrent directory that implements a skeleton and sets up your service implementation of the generated artifacts +* A child directory for the IDL's, this folder will also contain generated artifacts from the IDL under 'gen' -`NOTE: It only creates the folders for these repos, you will still need to create the git repos on your respected platform. Aswell as initialise each folder as a git repo and push when there have been changes. (if there is a strong desire we can look at how to make this process easier.)` + +`NOTE: You` ## The development cycle -1) Make folder with the name of your project and within that folder execute `sprout create [PROJECT_NAME]` +1) To create a project run `sprout create [PROJECT_NAME]` 2) A folder will be created and within that update the `sprout.yml` and then run `sprout generate -l=[LANGUAGE OF CHOICE] eg. go` -3) Move back to the root folder and you will see that there is now an idl folder created. -4) Modify the the protobuf services generated with your desired methods -5) Either run `make generate` or return to the application folder and re run `sprout generate` -6) Push up the IDL repo -6) Implement these methods on the main application repo -7) Push up the IDL repo & remove the replace function in the go.mod in the implementation project (this will swap it over to using the live IDL pushed up to git instead of your local one) -8) When you feel the need to add more services add them to the sprout config and re-run `sprout generate` and repeat steps 4 - 7. +3) You will see that there is now an idl folder created. +4) Within the idl folder modify the the protobuf services generated with your desired methods +5) Go up to the parrent directory and re run `sprout generate -l=[LANGUAGE OF CHOICE]` +6) Return back to the parent directory and implement the methods +7) Once you have tested your implementation and are happy with it return to the idl repo push that directory up to git +8) Return to the parent directory and check the depency file, for go it will be the go.mod file remove the lines that point it to your local directory, this will now point it to the version on git that was pushed up previously +10) Test and push up your implementation! +9) When you feel the need to add more services add them to the sprout config and re-run `sprout generate` and repeat steps 4 - 7. + +## Usage & installation + +As there alot of dependencies it will be easier to use this tool within the provided image, clone the repo and then run `make build-docker-local`. The best way then to use this is to alias `docker run -v "$(pwd):/project" sprout:local` as sprout from then you can use the CLI as if it was installed as usual on your machine. ## Dependencies diff --git a/cmd/create.go b/cmd/create.go index 172cf2f50..2acad6621 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -24,6 +24,7 @@ var createCmd = &cobra.Command{ projectName := args[0] rootDir := fmt.Sprintf("./%v", projectName) + idlDir := fmt.Sprintf("./%v-idl", rootDir) log.Printf("Creating project %s.", projectName) @@ -34,13 +35,26 @@ var createCmd = &cobra.Command{ log.Fatalf("Error creating root: %v ", err) } - sproutConfigPath := fmt.Sprintf("%v/sprout.yml", projectName) + err = os.Mkdir(idlDir, os.ModePerm) + if os.IsExist(err) { + log.Fatalf("Directory %v already exists! Error: %v", projectName, err) + } else if err != nil { + log.Fatalf("Error creating root: %v ", err) + } + + sproutConfigPath := fmt.Sprintf("%v/sprout.yml", rootDir) f, err := os.Create(sproutConfigPath) if err != nil { log.Printf("Error creating sprout config: %v", err) } - Templator.Sprout.Execute(f, projectName) + + gitIgnorePath := fmt.Sprintf("%v/.gitignore", rootDir) + f, err = os.Create(gitIgnorePath) + if err != nil { + log.Printf("Error creating sprout config: %v", err) + } + Templator.GitIgnore.Execute(f, projectName) }, } diff --git a/cmd/generate.go b/cmd/generate.go index ab1f4a02c..9281dcf93 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -39,7 +39,6 @@ var generateCmd = &cobra.Command{ cfg.Print() proto.Generate(Templator, cfg) - switch language { case Go: golang.Generate(Templator, cfg) diff --git a/example/hello-world/.gitignore b/example/hello-world/.gitignore new file mode 100644 index 000000000..35ec3b9d7 --- /dev/null +++ b/example/hello-world/.gitignore @@ -0,0 +1 @@ +/ \ No newline at end of file diff --git a/example/hello-world/go.mod b/example/hello-world/go.mod index 595883132..8d5234aaa 100644 --- a/example/hello-world/go.mod +++ b/example/hello-world/go.mod @@ -2,7 +2,7 @@ module github.com/yourrepo/hello-world go 1.12 -replace github.com/yourrepo/hello-world-idl => ../hello-world-idl +replace github.com/yourrepo/hello-world-idl => hello-world-idl require ( github.com/yourrepo/hello-world-idl v0.0.0 diff --git a/example/hello-world-idl/Makefile b/example/hello-world/hello-world-idl/Makefile similarity index 63% rename from example/hello-world-idl/Makefile rename to example/hello-world/hello-world-idl/Makefile index e97a9724e..314e76634 100644 --- a/example/hello-world-idl/Makefile +++ b/example/hello-world/hello-world-idl/Makefile @@ -1,13 +1,11 @@ PROTOC_VERSION := 3.9.2 PROTOC_WEB_VERSION := 1.0.6 - PROTO_SOURCES := -I /usr/local/include PROTO_SOURCES += -I . PROTO_SOURCES += -I ${GOPATH}/src PROTO_SOURCES += -I ${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis -PROTO_SOURCES += -I ${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway -deps-linux: deps-protoc-linux deps-grpc-web-linux deps-go +deps-linux: deps-protoc-linux deps-grpc-web-linux deps-protoc-linux: curl -OL https://github.com/google/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-linux-x86_64.zip @@ -21,14 +19,9 @@ deps-grpc-web-linux: sudo mv protoc-gen-grpc-web-$(PROTOC_WEB_VERSION)-linux-x86_64 /usr/local/bin/protoc-gen-grpc-web chmod +x /usr/local/bin/protoc-gen-grpc-web -deps-go: - go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway - go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger - go get -u github.com/golang/protobuf/protoc-gen-go - -generate: generate-grpc generate-web generate-http +generate: generate-grpc generate-web -generate-grpc: +generate-grpc: mkdir -p gen/go protoc ${PROTO_SOURCES} --go_out=plugins=grpc:./gen/go ./proto/health/*.proto protoc ${PROTO_SOURCES} --go_out=plugins=grpc:./gen/go ./proto/helloworld/*.proto @@ -40,11 +33,4 @@ generate-web: protoc ${PROTO_SOURCES} --grpc-web_out=import_style=typescript,mode=grpcwebtext:gen/web ./proto/helloworld/*.proto cp -f -rv gen/web/proto/* gen/web rm -rf gen/web/Proto gen/web/proto -generate-http: - mkdir -p gen/http gen/swagger - protoc ${PROTO_SOURCES} --grpc-gateway_out=logtostderr=true:gen/http --swagger_out=logtostderr=true:gen/swagger ./proto/health/*.proto - protoc ${PROTO_SOURCES} --grpc-gateway_out=logtostderr=true:gen/http --swagger_out=logtostderr=true:gen/swagger ./proto/helloworld/*.proto - cp -f -rv gen/http/proto/* gen/http - cp -f -rv gen/swagger/proto/* gen/swagger - rm -rf gen/swagger/proto diff --git a/example/hello-world-idl/gen/go/health/health.pb.go b/example/hello-world/hello-world-idl/gen/go/health/health.pb.go similarity index 81% rename from example/hello-world-idl/gen/go/health/health.pb.go rename to example/hello-world/hello-world-idl/gen/go/health/health.pb.go index f4e617e8b..db6a6eb6c 100644 --- a/example/hello-world-idl/gen/go/health/health.pb.go +++ b/example/hello-world/hello-world-idl/gen/go/health/health.pb.go @@ -7,8 +7,6 @@ import ( context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" - _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options" - _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -144,28 +142,22 @@ func init() { func init() { proto.RegisterFile("proto/health/health.proto", fileDescriptor_7bb2e9a145ccb86d) } var fileDescriptor_7bb2e9a145ccb86d = []byte{ - // 324 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x51, 0xcd, 0x4e, 0x02, 0x31, - 0x10, 0xb6, 0x10, 0x20, 0x0e, 0x22, 0x64, 0x30, 0x06, 0x88, 0x07, 0xb2, 0xd1, 0xc4, 0x83, 0x74, - 0xf9, 0x79, 0x02, 0x25, 0x44, 0x0d, 0xc9, 0x92, 0x2c, 0x0a, 0x47, 0x52, 0x37, 0x4d, 0x97, 0x08, - 0xed, 0x4a, 0x0b, 0x86, 0xab, 0x8f, 0xa0, 0x8f, 0xe2, 0x5b, 0x78, 0xf5, 0x15, 0x7c, 0x10, 0x43, - 0x17, 0x0e, 0xa8, 0x89, 0x1e, 0x3c, 0x4d, 0x66, 0xbe, 0x9f, 0xf9, 0xda, 0x81, 0x72, 0x34, 0x53, - 0x46, 0xb9, 0x21, 0x67, 0x13, 0x13, 0xae, 0x0b, 0xb5, 0x33, 0x2c, 0x4c, 0x97, 0x81, 0x9a, 0x46, - 0x4c, 0x2e, 0x69, 0x3c, 0xaf, 0x1c, 0x09, 0xa5, 0xc4, 0x84, 0xbb, 0x2c, 0x1a, 0xbb, 0x4c, 0x4a, - 0x65, 0x98, 0x19, 0x2b, 0xa9, 0x63, 0x7e, 0xe5, 0xcc, 0x96, 0xa0, 0x26, 0xb8, 0xac, 0xe9, 0x47, - 0x26, 0x04, 0x9f, 0xb9, 0x2a, 0xb2, 0x8c, 0xef, 0x6c, 0x87, 0x02, 0x5e, 0x59, 0xd7, 0x76, 0xc8, - 0x83, 0x7b, 0x9f, 0x3f, 0xcc, 0xb9, 0x36, 0x58, 0x82, 0x8c, 0xe6, 0xb3, 0xc5, 0x38, 0xe0, 0x25, - 0x52, 0x25, 0xa7, 0xbb, 0xfe, 0xa6, 0x75, 0x5e, 0x09, 0x14, 0xb7, 0x04, 0x3a, 0x52, 0x52, 0x73, - 0xec, 0x42, 0x5a, 0x1b, 0x66, 0xe6, 0xda, 0x0a, 0xf6, 0x9b, 0x2d, 0xfa, 0x35, 0x36, 0xfd, 0x41, - 0x46, 0xfb, 0x2b, 0x5b, 0x29, 0xfa, 0x56, 0xea, 0xaf, 0x2d, 0x9c, 0x1e, 0xe4, 0xb6, 0x00, 0xcc, - 0x42, 0xe6, 0xd6, 0xeb, 0x7a, 0xbd, 0xa1, 0x57, 0xd8, 0x59, 0x35, 0xfd, 0x8e, 0x3f, 0xb8, 0xf6, - 0x2e, 0x0b, 0x04, 0xf3, 0x90, 0xf5, 0x7a, 0x37, 0xa3, 0xcd, 0x20, 0x81, 0x45, 0xc8, 0xdb, 0xa6, - 0xdd, 0x19, 0x6d, 0x24, 0xc9, 0xe6, 0x1b, 0x81, 0x74, 0xbc, 0x1e, 0x43, 0x48, 0xd9, 0x08, 0x78, - 0xfc, 0x4b, 0x42, 0xfb, 0x13, 0x95, 0x93, 0x3f, 0xbd, 0xc3, 0xc1, 0xa7, 0xf7, 0x8f, 0x97, 0xc4, - 0x1e, 0x82, 0xbb, 0x68, 0xac, 0xcf, 0x87, 0x03, 0x48, 0x0d, 0x99, 0x09, 0xc2, 0x7f, 0xdd, 0x54, - 0x27, 0x17, 0xe5, 0xe7, 0xf3, 0x43, 0x3c, 0x80, 0x5c, 0x8c, 0x56, 0x2d, 0xac, 0x9b, 0xc9, 0x06, - 0xad, 0xdf, 0xa5, 0xed, 0x51, 0x5b, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x27, 0xce, 0xfd, 0xfa, - 0x4f, 0x02, 0x00, 0x00, + // 238 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2c, 0x28, 0xca, 0x2f, + 0xc9, 0xd7, 0xcf, 0x48, 0x4d, 0xcc, 0x29, 0xc9, 0x80, 0x52, 0x7a, 0x60, 0x31, 0x21, 0x81, 0xdc, + 0xca, 0xe4, 0xfc, 0xdc, 0x82, 0xc4, 0xbc, 0x4a, 0x3d, 0x88, 0xb8, 0x92, 0x1e, 0x97, 0x90, 0x07, + 0x98, 0xe5, 0x9c, 0x91, 0x9a, 0x9c, 0x1d, 0x94, 0x5a, 0x58, 0x9a, 0x5a, 0x5c, 0x22, 0x24, 0xc1, + 0xc5, 0x5e, 0x9c, 0x5a, 0x54, 0x96, 0x99, 0x9c, 0x2a, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x19, 0x04, + 0xe3, 0x2a, 0x6d, 0x66, 0xe4, 0x12, 0x46, 0xd1, 0x50, 0x5c, 0x90, 0x9f, 0x57, 0x9c, 0x2a, 0xe4, + 0xcd, 0xc5, 0x56, 0x5c, 0x92, 0x58, 0x52, 0x5a, 0x0c, 0xd6, 0xc0, 0x67, 0x64, 0xac, 0x87, 0x6e, + 0x95, 0x1e, 0x16, 0x6d, 0x7a, 0xc1, 0x20, 0x63, 0xf3, 0xd2, 0x83, 0xc1, 0x5a, 0x83, 0xa0, 0x46, + 0x28, 0xf9, 0x73, 0xf1, 0xa2, 0x48, 0x08, 0x71, 0x73, 0xb1, 0x87, 0xfa, 0x79, 0xfb, 0xf9, 0x87, + 0xfb, 0x09, 0x30, 0x80, 0x38, 0xc1, 0xae, 0x41, 0x61, 0x9e, 0x7e, 0xee, 0x02, 0x8c, 0x42, 0xfc, + 0x5c, 0xdc, 0x7e, 0xfe, 0x21, 0xf1, 0x30, 0x01, 0x26, 0x21, 0x61, 0x2e, 0x7e, 0x30, 0xc7, 0xd9, + 0x35, 0x1e, 0xa6, 0x85, 0xd9, 0x68, 0x1b, 0x23, 0x17, 0x1b, 0xc4, 0x7a, 0xa1, 0x10, 0x2e, 0x56, + 0xb0, 0x13, 0x84, 0x54, 0x08, 0xb8, 0x10, 0x1c, 0x12, 0x52, 0xaa, 0x44, 0xf9, 0x43, 0x28, 0x8c, + 0x8b, 0x35, 0x3c, 0xb1, 0x24, 0x39, 0x83, 0xaa, 0xa6, 0x1a, 0x30, 0x26, 0xb1, 0x81, 0xe3, 0xcd, + 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x6e, 0xa9, 0x0a, 0x0e, 0xd4, 0x01, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/example/hello-world-idl/gen/go/helloworld/helloworld.pb.go b/example/hello-world/hello-world-idl/gen/go/helloworld/helloworld.pb.go similarity index 100% rename from example/hello-world-idl/gen/go/helloworld/helloworld.pb.go rename to example/hello-world/hello-world-idl/gen/go/helloworld/helloworld.pb.go diff --git a/example/hello-world-idl/gen/web/health/health_pb.d.ts b/example/hello-world/hello-world-idl/gen/web/health/health_pb.d.ts similarity index 89% rename from example/hello-world-idl/gen/web/health/health_pb.d.ts rename to example/hello-world/hello-world-idl/gen/web/health/health_pb.d.ts index 015e32a18..57a475723 100644 --- a/example/hello-world-idl/gen/web/health/health_pb.d.ts +++ b/example/hello-world/hello-world-idl/gen/web/health/health_pb.d.ts @@ -1,8 +1,5 @@ import * as jspb from "google-protobuf" -import * as google_api_annotations_pb from '../../google/api/annotations_pb'; -import * as protoc$gen$swagger_options_annotations_pb from '../../protoc-gen-swagger/options/annotations_pb'; - export class HealthCheckRequest extends jspb.Message { getService(): string; setService(value: string): void; diff --git a/example/hello-world-idl/gen/web/helloworld/helloworld_pb.d.ts b/example/hello-world/hello-world-idl/gen/web/helloworld/helloworld_pb.d.ts similarity index 100% rename from example/hello-world-idl/gen/web/helloworld/helloworld_pb.d.ts rename to example/hello-world/hello-world-idl/gen/web/helloworld/helloworld_pb.d.ts diff --git a/example/hello-world-idl/go.mod b/example/hello-world/hello-world-idl/go.mod similarity index 100% rename from example/hello-world-idl/go.mod rename to example/hello-world/hello-world-idl/go.mod diff --git a/example/hello-world-idl/proto/health/health.proto b/example/hello-world/hello-world-idl/proto/health/health.proto similarity index 50% rename from example/hello-world-idl/proto/health/health.proto rename to example/hello-world/hello-world-idl/proto/health/health.proto index 1068fcfa2..fcdae025f 100644 --- a/example/hello-world-idl/proto/health/health.proto +++ b/example/hello-world/hello-world-idl/proto/health/health.proto @@ -1,15 +1,6 @@ syntax = "proto3"; package mycompany.health; -import "google/api/annotations.proto"; -import "protoc-gen-swagger/options/annotations.proto"; - -option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { - info: { - title: "Health Checks"; - version: "1.0"; - } -}; message HealthCheckRequest { string service = 1; @@ -26,11 +17,7 @@ message HealthCheckResponse { } service Health { - rpc Check(HealthCheckRequest) returns (HealthCheckResponse){ - option (google.api.http) = { - get: "/v1/health" - }; - } + rpc Check(HealthCheckRequest) returns (HealthCheckResponse); rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); } diff --git a/example/hello-world-idl/proto/helloworld/helloworld.proto b/example/hello-world/hello-world-idl/proto/helloworld/helloworld.proto similarity index 100% rename from example/hello-world-idl/proto/helloworld/helloworld.proto rename to example/hello-world/hello-world-idl/proto/helloworld/helloworld.proto diff --git a/example/hello-world/sprout.yml b/example/hello-world/sprout.yml index 8192e2d54..8077398d5 100644 --- a/example/hello-world/sprout.yml +++ b/example/hello-world/sprout.yml @@ -14,10 +14,6 @@ network: http: enabled: true port: 8080 - web: - enabled: true - port: 8090 - services: - name: helloworld diff --git a/generate/proto/generate.go b/generate/proto/generate.go index d354fbf0c..8ef643e17 100644 --- a/generate/proto/generate.go +++ b/generate/proto/generate.go @@ -20,7 +20,7 @@ func Generate(templator *templator.Templator, config *config.SproutConfig) { } func GenerateGoModIDL(templator *templator.Templator, config *config.SproutConfig) { - idlPath := fmt.Sprintf("../%s-idl", config.Name) + idlPath := fmt.Sprintf("%s-idl", config.Name) idlOutput := fmt.Sprintf("%s/go.mod", idlPath) f, err := os.Create(idlOutput) @@ -34,7 +34,7 @@ func GenerateGoModIDL(templator *templator.Templator, config *config.SproutConfi } func GenerateIDLMakefile(templator *templator.Templator, config *config.SproutConfig) { - makeFilePath := fmt.Sprintf("../%s-idl", config.Name) + makeFilePath := fmt.Sprintf("%s-idl", config.Name) makeFileOutput := fmt.Sprintf("%s/Makefile", makeFilePath) err := util.CreateDirIfDoesNotExist(makeFilePath) @@ -50,7 +50,7 @@ func GenerateIDLMakefile(templator *templator.Templator, config *config.SproutCo } func GenerateProtoHealth(templator *templator.Templator, config *config.SproutConfig) { - protoHealthPath := fmt.Sprintf("../%s-idl/proto/health", config.Name) + protoHealthPath := fmt.Sprintf("%s-idl/proto/health", config.Name) protoHealthOutput := fmt.Sprintf("%s/health.proto", protoHealthPath) err := util.CreateDirIfDoesNotExist(protoHealthPath) @@ -67,7 +67,7 @@ func GenerateProtoHealth(templator *templator.Templator, config *config.SproutCo } func GenerateServiceProtobufFiles(templator *templator.Templator, config *config.SproutConfig) { - protoPath := fmt.Sprintf("../%s-idl/proto", config.Name) + protoPath := fmt.Sprintf("%s-idl/proto", config.Name) for _, s := range config.Services { serviceProtoDir := fmt.Sprintf("%s/%s", protoPath, s.Name) err := os.Mkdir(serviceProtoDir, os.ModePerm) @@ -91,7 +91,7 @@ func GenerateServiceProtobufFiles(templator *templator.Templator, config *config } func GenerateProtoServiceLibs(config *config.SproutConfig) { - idlRoot := fmt.Sprintf("../%s-idl", config.Name) + idlRoot := fmt.Sprintf("%s-idl", config.Name) cmd := exec.Command("make", "generate") cmd.Dir = idlRoot bytes, err := cmd.Output() diff --git a/go.mod b/go.mod index 60ba9e0eb..a750cb243 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/golang/protobuf v1.3.2 github.com/google/go-cmp v0.3.1 // indirect github.com/google/pprof v0.0.0-20190908185732-236ed259b199 // indirect - github.com/grpc-ecosystem/grpc-gateway v1.11.2 // indirect + github.com/grpc-ecosystem/grpc-gateway v1.11.2 github.com/hashicorp/golang-lru v0.5.3 // indirect github.com/k0kubun/pp v3.0.1+incompatible github.com/kisielk/errcheck v1.2.0 // indirect @@ -51,7 +51,7 @@ require ( golang.org/x/tools v0.0.0-20190923195354-c85f9fa9581e // indirect google.golang.org/api v0.10.0 // indirect google.golang.org/appengine v1.6.3 // indirect - google.golang.org/genproto v0.0.0-20190916214212-f660b8655731 // indirect + google.golang.org/genproto v0.0.0-20190916214212-f660b8655731 google.golang.org/grpc v1.23.1 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/yaml.v2 v2.2.2 diff --git a/templates/golang/go_mod.tmpl b/templates/golang/go_mod.tmpl index 9da7ca367..9def1532a 100644 --- a/templates/golang/go_mod.tmpl +++ b/templates/golang/go_mod.tmpl @@ -2,7 +2,7 @@ module {{ .GitRepo }}/{{ .Name }} go 1.12 -replace {{ .GitRepo }}/{{ .Name }}-idl => ../{{ .Name }}-idl +replace {{ .GitRepo }}/{{ .Name }}-idl => {{ .Name }}-idl require ( {{ .GitRepo }}/{{ .Name }}-idl v0.0.0 diff --git a/templates/util/gitignore.tmpl b/templates/util/gitignore.tmpl new file mode 100644 index 000000000..90ed41949 --- /dev/null +++ b/templates/util/gitignore.tmpl @@ -0,0 +1 @@ +/{{ .Name }}-idl diff --git a/templator/templator.go b/templator/templator.go index 6e97f2798..6667e375e 100644 --- a/templator/templator.go +++ b/templator/templator.go @@ -16,6 +16,7 @@ type GoTemplator struct { type Templator struct { Sprout *template.Template + GitIgnore *template.Template MakefileTemplate *template.Template ProtoHealthTemplate *template.Template ProtoServiceTemplate *template.Template @@ -38,6 +39,7 @@ func NewTemplator(box *packr.Box) *Templator { ProtoServiceTemplate: protoServiceTemplate, Go: NewGoTemplator(box), Sprout: NewSproutTemplator(box), + GitIgnore: NewGitIgnoreTemplator(box), } } @@ -73,3 +75,9 @@ func NewSproutTemplator(box *packr.Box) *template.Template { return template } + +func NewGitIgnoreTemplator(box *packr.Box) *template.Template { + templateSource, _ := box.FindString("util/gitignore.tmpl") + template, _ := template.New("GitIgnore").Parse(templateSource) + return template +} diff --git a/test/hello-world/go.mod b/test/hello-world/go.mod new file mode 100644 index 000000000..595883132 --- /dev/null +++ b/test/hello-world/go.mod @@ -0,0 +1,9 @@ +module github.com/yourrepo/hello-world + +go 1.12 + +replace github.com/yourrepo/hello-world-idl => ../hello-world-idl + +require ( + github.com/yourrepo/hello-world-idl v0.0.0 +) diff --git a/test/hello-world/main.go b/test/hello-world/main.go new file mode 100644 index 000000000..7002bd2d3 --- /dev/null +++ b/test/hello-world/main.go @@ -0,0 +1,30 @@ +package main +import ( + "log" + "net" + + health "github.com/yourrepo/hello-world/server/health" + healthpb "github.com/yourrepo/hello-world-idl/gen/go/health" + + + "google.golang.org/grpc" +) + +func main() { + grpcAddr := "0.0.0.0:3000" + lis, err := net.Listen("tcp", grpcAddr) + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + + //TODO: Register your servers here + healthServer := health.NewHealthServer() + healthpb.RegisterHealthServer(s, healthServer) + + log.Printf("Starting grpc server on %v...", grpcAddr) + + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } +} diff --git a/test/hello-world/server/health/health.go b/test/hello-world/server/health/health.go new file mode 100644 index 000000000..cd276d311 --- /dev/null +++ b/test/hello-world/server/health/health.go @@ -0,0 +1,25 @@ +package health + +import ( + "context" + api "github.com/yourrepo/hello-world-idl/gen/go/health" +) + +type HealthServer struct { + +} + +func NewHealthServer() *HealthServer { + return &HealthServer{} +} + +func (s *HealthServer) Check(ctx context.Context, req *api.HealthCheckRequest) (*api.HealthCheckResponse, error) { + resp := &api.HealthCheckResponse{ + Status: api.HealthCheckResponse_SERVING, + } + return resp,nil +} + +func (s *HealthServer) Watch(req *api.HealthCheckRequest, server api.Health_WatchServer) error { + return nil +} diff --git a/test/hello-world/server/helloworld/helloworld.go b/test/hello-world/server/helloworld/helloworld.go new file mode 100644 index 000000000..8423d3208 --- /dev/null +++ b/test/hello-world/server/helloworld/helloworld.go @@ -0,0 +1,14 @@ +package helloworld + +import ( + "context" + api "github.com/yourrepo/hello-world-idl/gen/go/helloworld" +) + +type HelloworldServer struct { + +} + +func NewHelloworldServer() *HelloworldServer { + return &HelloworldServer{} +} diff --git a/test/hello-world/sprout.yml b/test/hello-world/sprout.yml new file mode 100644 index 000000000..b0bec7889 --- /dev/null +++ b/test/hello-world/sprout.yml @@ -0,0 +1,20 @@ +organization: mycompany +name: hello-world +description: +git-repo: github.com/yourrepo +docker-repo: +maintainers: +# - name: bob +# email: bob@test.com + +network: + grpc: + host: 0.0.0.0 + port: 3000 + web: + enabled: true + port: 8080 + +services: + - name: helloworld + description: Hello world!. From eeb085b8a360f75fe763c19f8b77e52f01977f47 Mon Sep 17 00:00:00 2001 From: pritesh-patel Date: Sun, 6 Oct 2019 10:40:47 -0700 Subject: [PATCH 2/2] move to one project directory, dockerize cli --- Dockerfile | 70 ++++++-- Makefile | 16 +- README.md | 7 +- cmd/create.go | 8 - .../gen/http/health/health.pb.gw.go | 159 ------------------ .../gen/http/proto/health/health.pb.gw.go | 159 ------------------ .../gen/swagger/health/health.swagger.json | 117 ------------- .../helloworld/helloworld.swagger.json | 19 --- example/hello-world/.gitignore | 2 +- example/hello-world/hello-world-idl/Makefile | 20 ++- .../gen/go/health/health.pb.go | 53 +++--- .../gen/web/health/health_pb.d.ts | 3 + .../hello-world-idl/proto/health/health.proto | 15 +- example/hello-world/sprout.yml | 4 + generate/proto/generate.go | 13 +- go.sum | 2 + templates/util/gitignore.tmpl | 2 +- test/hello-world/go.mod | 9 - test/hello-world/main.go | 30 ---- test/hello-world/server/health/health.go | 25 --- .../server/helloworld/helloworld.go | 14 -- test/hello-world/sprout.yml | 20 --- 22 files changed, 146 insertions(+), 621 deletions(-) delete mode 100644 example/hello-world-idl/gen/http/health/health.pb.gw.go delete mode 100644 example/hello-world-idl/gen/http/proto/health/health.pb.gw.go delete mode 100644 example/hello-world-idl/gen/swagger/health/health.swagger.json delete mode 100644 example/hello-world-idl/gen/swagger/helloworld/helloworld.swagger.json delete mode 100644 test/hello-world/go.mod delete mode 100644 test/hello-world/main.go delete mode 100644 test/hello-world/server/health/health.go delete mode 100644 test/hello-world/server/helloworld/helloworld.go delete mode 100644 test/hello-world/sprout.yml diff --git a/Dockerfile b/Dockerfile index e4341e3a9..23127a7e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,63 @@ -FROM golang:1.12.6@sha256:83e8267be041b3ddf6a5792c7e464528408f75c446745642db08cfe4e8d58d18 AS build -WORKDIR /cache +FROM golang:1.12.4-alpine3.9 as builder + +ENV GO111MODULE=on +ENV GOLANG_PROTOBUF_VERSION=1.3.1 +ENV GRPC_GATEWAY_VERSION=1.11.3 +ENV GRPC_WEB_VERSION=1.0.6 +ENV PROTOBUF_VERSION=3.9.2 + +RUN apk add --update --no-cache build-base curl git upx && \ + rm -rf /var/cache/apk/* + +RUN go get \ + github.com/golang/protobuf/protoc-gen-go@v${GOLANG_PROTOBUF_VERSION} &&\ + mv /go/bin/protoc-gen-go* /usr/local/bin/ + +RUN curl -sSL \ + https://github.com/grpc-ecosystem/grpc-gateway/releases/download/v${GRPC_GATEWAY_VERSION}/protoc-gen-grpc-gateway-v${GRPC_GATEWAY_VERSION}-linux-x86_64 \ + -o /usr/local/bin/protoc-gen-grpc-gateway && \ + curl -sSL \ + https://github.com/grpc-ecosystem/grpc-gateway/releases/download/v${GRPC_GATEWAY_VERSION}/protoc-gen-swagger-v${GRPC_GATEWAY_VERSION}-linux-x86_64 \ + -o /usr/local/bin/protoc-gen-swagger && \ + chmod +x /usr/local/bin/protoc-gen-grpc-gateway && \ + chmod +x /usr/local/bin/protoc-gen-swagger + +RUN curl -sSL \ + https://github.com/grpc/grpc-web/releases/download/${GRPC_WEB_VERSION}/protoc-gen-grpc-web-${GRPC_WEB_VERSION}-linux-x86_64 \ + -o /usr/local/bin/protoc-gen-grpc-web && \ + chmod +x /usr/local/bin/protoc-gen-grpc-web + +RUN mkdir -p /tmp/protoc && \ + curl -sSL \ + https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOBUF_VERSION}/protoc-${PROTOBUF_VERSION}-linux-x86_64.zip \ + -o /tmp/protoc/protoc.zip && \ + cd /tmp/protoc && \ + unzip protoc.zip && \ + mv /tmp/protoc/include /usr/local/include + +RUN GO111MODULE=off go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway + +WORKDIR tmp/sprout COPY go.mod . COPY go.sum . RUN go mod tidy && go mod download COPY . . -RUN apt-get update && apt-get -y install sudo && apt-get -y install unzip -RUN make deps-linux && mv /go/bin/protoc-* /usr/local/bin/ -RUN make install-go && \ - mv /go/bin/sprout /usr/local/bin/ - +RUN make build-deps && make build && \ + mv sprout /usr/local/bin +RUN upx --lzma /usr/local/bin/* -FROM alpine -WORKDIR project -RUN apk add --update make -COPY --from=build /usr/local/bin /usr/local/bin -COPY --from=build /usr/local/include /usr/include +FROM alpine:edge +ENV \ + PROTOTOOL_PROTOC_BIN_PATH=/usr/bin/protoc \ + PROTOTOOL_PROTOC_WKT_PATH=/usr/local/include \ + PROTOBUF_VERSION=3.9.2 \ + ALPINE_PROTOBUF_VERSION_SUFFIX=r0 \ + GOPATH=/proto-libs +RUN mkdir ${GOPATH} +COPY --from=builder /usr/local/bin /usr/local/bin +COPY --from=builder /usr/local/include /usr/local/include +COPY --from=builder /go/src/github.com/grpc-ecosystem/grpc-gateway ${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway +WORKDIR /project +RUN apk add --update --no-cache make bash curl git protobuf=${PROTOBUF_VERSION}-${ALPINE_PROTOBUF_VERSION_SUFFIX} && \ + rm -rf /var/cache/apk/* +ENTRYPOINT ["sprout"] diff --git a/Makefile b/Makefile index 7646a8b10..21b0bcf4f 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,6 @@ PROTOC_WEB_VERSION := 1.0.6 PROTO_SOURCES := -I /usr/local/include PROTO_SOURCES += -I . PROTO_SOURCES += -I ${GOPATH}/src -PROTO_SOURCES += -I ${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis PROTO_SOURCES += -I ${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway VERSION:= 0.0.1 @@ -14,21 +13,23 @@ deps-linux: deps-go deps-protoc-linux deps-grpc-web-linux deps-protoc-linux: curl -OL https://github.com/google/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-linux-x86_64.zip unzip protoc-$(PROTOC_VERSION)-linux-x86_64.zip -d protoc3 - sudo mv protoc3/bin/* /usr/local/bin - sudo mv protoc3/include/* /usr/local/include + mv protoc3/bin/protoc /usr/local/bin + mv protoc3/include/* /usr/local/include rm -rf protoc3 protoc-$(PROTOC_VERSION)-linux-x86_64.zip deps-grpc-web-linux: curl -OL https://github.com/grpc/grpc-web/releases/download/$(PROTOC_WEB_VERSION)/protoc-gen-grpc-web-$(PROTOC_WEB_VERSION)-linux-x86_64 - sudo mv protoc-gen-grpc-web-$(PROTOC_WEB_VERSION)-linux-x86_64 /usr/local/bin/protoc-gen-grpc-web + mv protoc-gen-grpc-web-$(PROTOC_WEB_VERSION)-linux-x86_64 /usr/local/bin/protoc-gen-grpc-web chmod +x /usr/local/bin/protoc-gen-grpc-web deps-go: - go get -u github.com/gobuffalo/packr/v2/packr2 go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger go get -u github.com/golang/protobuf/protoc-gen-go +build-deps: + go install github.com/gobuffalo/packr/v2/packr2 + fmt: go fmt ./... @@ -44,6 +45,11 @@ build-example: build clean-example cd example && ../sprout create "hello-world" cd example/hello-world && ../../sprout generate -l go +build-example-docker: clean-example + mkdir -p example + docker run -v "$(shell pwd)/example:/project" --user $(shell id -u):$(shell id -g) sprout:v0 create "hello-world" + docker run -v "$(shell pwd)/example/hello-world:/project" --user $(shell id -u):$(shell id -g) sprout:v0 generate -l go + build-docker-local: docker build . -t sprout:v0 diff --git a/README.md b/README.md index e1c4527a0..6870ffdd9 100644 --- a/README.md +++ b/README.md @@ -20,12 +20,9 @@ It will also live with your project, when you add a new service to the config it The generation will create project folder, within this there will be your implementation and an IDL folder -* A parrent directory that implements a skeleton and sets up your service implementation of the generated artifacts +* A parent directory that implements a skeleton and sets up your service implementation of the generated artifacts * A child directory for the IDL's, this folder will also contain generated artifacts from the IDL under 'gen' - -`NOTE: You` - ## The development cycle 1) To create a project run `sprout create [PROJECT_NAME]` @@ -41,7 +38,7 @@ The generation will create project folder, within this there will be your implem ## Usage & installation -As there alot of dependencies it will be easier to use this tool within the provided image, clone the repo and then run `make build-docker-local`. The best way then to use this is to alias `docker run -v "$(pwd):/project" sprout:local` as sprout from then you can use the CLI as if it was installed as usual on your machine. +As there alot of dependencies it will be easier to use this tool within the provided image, clone the repo and then run `make build-docker-local`. The best way then to use this is to alias `docker run -v "$(pwd):/project" --user $(id -u):$(id -g) sprout:v0` as sprout from then you can use the CLI as if it was installed as usual on your machine. ## Dependencies diff --git a/cmd/create.go b/cmd/create.go index 2acad6621..1d4a22ae2 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -24,7 +24,6 @@ var createCmd = &cobra.Command{ projectName := args[0] rootDir := fmt.Sprintf("./%v", projectName) - idlDir := fmt.Sprintf("./%v-idl", rootDir) log.Printf("Creating project %s.", projectName) @@ -35,13 +34,6 @@ var createCmd = &cobra.Command{ log.Fatalf("Error creating root: %v ", err) } - err = os.Mkdir(idlDir, os.ModePerm) - if os.IsExist(err) { - log.Fatalf("Directory %v already exists! Error: %v", projectName, err) - } else if err != nil { - log.Fatalf("Error creating root: %v ", err) - } - sproutConfigPath := fmt.Sprintf("%v/sprout.yml", rootDir) f, err := os.Create(sproutConfigPath) diff --git a/example/hello-world-idl/gen/http/health/health.pb.gw.go b/example/hello-world-idl/gen/http/health/health.pb.gw.go deleted file mode 100644 index 0e2602738..000000000 --- a/example/hello-world-idl/gen/http/health/health.pb.gw.go +++ /dev/null @@ -1,159 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: proto/health/health.proto - -/* -Package mycompany_health is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package mycompany_health - -import ( - "context" - "io" - "net/http" - - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/status" -) - -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray - -var ( - filter_Health_Check_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - -func request_Health_Check_0(ctx context.Context, marshaler runtime.Marshaler, client HealthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq HealthCheckRequest - var metadata runtime.ServerMetadata - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Health_Check_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.Check(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Health_Check_0(ctx context.Context, marshaler runtime.Marshaler, server HealthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq HealthCheckRequest - var metadata runtime.ServerMetadata - - if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_Health_Check_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.Check(ctx, &protoReq) - return msg, metadata, err - -} - -// RegisterHealthHandlerServer registers the http handlers for service Health to "mux". -// UnaryRPC :call HealthServer directly. -// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -func RegisterHealthHandlerServer(ctx context.Context, mux *runtime.ServeMux, server HealthServer) error { - - mux.Handle("GET", pattern_Health_Check_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Health_Check_0(rctx, inboundMarshaler, server, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Health_Check_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -// RegisterHealthHandlerFromEndpoint is same as RegisterHealthHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterHealthHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterHealthHandler(ctx, mux, conn) -} - -// RegisterHealthHandler registers the http handlers for service Health to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterHealthHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterHealthHandlerClient(ctx, mux, NewHealthClient(conn)) -} - -// RegisterHealthHandlerClient registers the http handlers for service Health -// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "HealthClient". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "HealthClient" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "HealthClient" to call the correct interceptors. -func RegisterHealthHandlerClient(ctx context.Context, mux *runtime.ServeMux, client HealthClient) error { - - mux.Handle("GET", pattern_Health_Check_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Health_Check_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Health_Check_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_Health_Check_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "health"}, "", runtime.AssumeColonVerbOpt(true))) -) - -var ( - forward_Health_Check_0 = runtime.ForwardResponseMessage -) diff --git a/example/hello-world-idl/gen/http/proto/health/health.pb.gw.go b/example/hello-world-idl/gen/http/proto/health/health.pb.gw.go deleted file mode 100644 index 0e2602738..000000000 --- a/example/hello-world-idl/gen/http/proto/health/health.pb.gw.go +++ /dev/null @@ -1,159 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: proto/health/health.proto - -/* -Package mycompany_health is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package mycompany_health - -import ( - "context" - "io" - "net/http" - - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/status" -) - -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray - -var ( - filter_Health_Check_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - -func request_Health_Check_0(ctx context.Context, marshaler runtime.Marshaler, client HealthClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq HealthCheckRequest - var metadata runtime.ServerMetadata - - if err := req.ParseForm(); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_Health_Check_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.Check(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func local_request_Health_Check_0(ctx context.Context, marshaler runtime.Marshaler, server HealthServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq HealthCheckRequest - var metadata runtime.ServerMetadata - - if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_Health_Check_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := server.Check(ctx, &protoReq) - return msg, metadata, err - -} - -// RegisterHealthHandlerServer registers the http handlers for service Health to "mux". -// UnaryRPC :call HealthServer directly. -// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. -func RegisterHealthHandlerServer(ctx context.Context, mux *runtime.ServeMux, server HealthServer) error { - - mux.Handle("GET", pattern_Health_Check_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := local_request_Health_Check_0(rctx, inboundMarshaler, server, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Health_Check_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -// RegisterHealthHandlerFromEndpoint is same as RegisterHealthHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterHealthHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterHealthHandler(ctx, mux, conn) -} - -// RegisterHealthHandler registers the http handlers for service Health to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterHealthHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterHealthHandlerClient(ctx, mux, NewHealthClient(conn)) -} - -// RegisterHealthHandlerClient registers the http handlers for service Health -// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "HealthClient". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "HealthClient" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "HealthClient" to call the correct interceptors. -func RegisterHealthHandlerClient(ctx context.Context, mux *runtime.ServeMux, client HealthClient) error { - - mux.Handle("GET", pattern_Health_Check_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_Health_Check_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_Health_Check_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_Health_Check_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "health"}, "", runtime.AssumeColonVerbOpt(true))) -) - -var ( - forward_Health_Check_0 = runtime.ForwardResponseMessage -) diff --git a/example/hello-world-idl/gen/swagger/health/health.swagger.json b/example/hello-world-idl/gen/swagger/health/health.swagger.json deleted file mode 100644 index 5ecef0a83..000000000 --- a/example/hello-world-idl/gen/swagger/health/health.swagger.json +++ /dev/null @@ -1,117 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "title": "Health Checks", - "version": "1.0" - }, - "schemes": [ - "http", - "https" - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "paths": { - "/v1/health": { - "get": { - "operationId": "Check", - "responses": { - "200": { - "description": "A successful response.", - "schema": { - "$ref": "#/definitions/healthHealthCheckResponse" - } - } - }, - "parameters": [ - { - "name": "service", - "in": "query", - "required": false, - "type": "string" - } - ], - "tags": [ - "Health" - ] - } - } - }, - "definitions": { - "HealthCheckResponseServingStatus": { - "type": "string", - "enum": [ - "UNKNOWN", - "SERVING", - "NOT_SERVING", - "SERVICE_UNKNOWN" - ], - "default": "UNKNOWN" - }, - "healthHealthCheckResponse": { - "type": "object", - "properties": { - "status": { - "$ref": "#/definitions/HealthCheckResponseServingStatus" - } - } - }, - "protobufAny": { - "type": "object", - "properties": { - "type_url": { - "type": "string", - "description": "A URL/resource name that uniquely identifies the type of the serialized\nprotocol buffer message. This string must contain at least\none \"/\" character. The last segment of the URL's path must represent\nthe fully qualified name of the type (as in\n`path/google.protobuf.Duration`). The name should be in a canonical form\n(e.g., leading \".\" is not accepted).\n\nIn practice, teams usually precompile into the binary all types that they\nexpect it to use in the context of Any. However, for URLs which use the\nscheme `http`, `https`, or no scheme, one can optionally set up a type\nserver that maps type URLs to message definitions as follows:\n\n* If no scheme is provided, `https` is assumed.\n* An HTTP GET on the URL must yield a [google.protobuf.Type][]\n value in binary format, or produce an error.\n* Applications are allowed to cache lookup results based on the\n URL, or have them precompiled into a binary to avoid any\n lookup. Therefore, binary compatibility needs to be preserved\n on changes to types. (Use versioned type names to manage\n breaking changes.)\n\nNote: this functionality is not currently available in the official\nprotobuf release, and it is not used for type URLs beginning with\ntype.googleapis.com.\n\nSchemes other than `http`, `https` (or the empty scheme) might be\nused with implementation specific semantics." - }, - "value": { - "type": "string", - "format": "byte", - "description": "Must be a valid serialized protocol buffer of the above specified type." - } - }, - "description": "`Any` contains an arbitrary serialized protocol buffer message along with a\nURL that describes the type of the serialized message.\n\nProtobuf library provides support to pack/unpack Any values in the form\nof utility functions or additional generated methods of the Any type.\n\nExample 1: Pack and unpack a message in C++.\n\n Foo foo = ...;\n Any any;\n any.PackFrom(foo);\n ...\n if (any.UnpackTo(\u0026foo)) {\n ...\n }\n\nExample 2: Pack and unpack a message in Java.\n\n Foo foo = ...;\n Any any = Any.pack(foo);\n ...\n if (any.is(Foo.class)) {\n foo = any.unpack(Foo.class);\n }\n\n Example 3: Pack and unpack a message in Python.\n\n foo = Foo(...)\n any = Any()\n any.Pack(foo)\n ...\n if any.Is(Foo.DESCRIPTOR):\n any.Unpack(foo)\n ...\n\n Example 4: Pack and unpack a message in Go\n\n foo := \u0026pb.Foo{...}\n any, err := ptypes.MarshalAny(foo)\n ...\n foo := \u0026pb.Foo{}\n if err := ptypes.UnmarshalAny(any, foo); err != nil {\n ...\n }\n\nThe pack methods provided by protobuf library will by default use\n'type.googleapis.com/full.type.name' as the type URL and the unpack\nmethods only use the fully qualified type name after the last '/'\nin the type URL, for example \"foo.bar.com/x/y.z\" will yield type\nname \"y.z\".\n\n\nJSON\n====\nThe JSON representation of an `Any` value uses the regular\nrepresentation of the deserialized, embedded message, with an\nadditional field `@type` which contains the type URL. Example:\n\n package google.profile;\n message Person {\n string first_name = 1;\n string last_name = 2;\n }\n\n {\n \"@type\": \"type.googleapis.com/google.profile.Person\",\n \"firstName\": \u003cstring\u003e,\n \"lastName\": \u003cstring\u003e\n }\n\nIf the embedded message type is well-known and has a custom JSON\nrepresentation, that representation will be embedded adding a field\n`value` which holds the custom JSON in addition to the `@type`\nfield. Example (for message [google.protobuf.Duration][]):\n\n {\n \"@type\": \"type.googleapis.com/google.protobuf.Duration\",\n \"value\": \"1.212s\"\n }" - }, - "runtimeStreamError": { - "type": "object", - "properties": { - "grpc_code": { - "type": "integer", - "format": "int32" - }, - "http_code": { - "type": "integer", - "format": "int32" - }, - "message": { - "type": "string" - }, - "http_status": { - "type": "string" - }, - "details": { - "type": "array", - "items": { - "$ref": "#/definitions/protobufAny" - } - } - } - } - }, - "x-stream-definitions": { - "healthHealthCheckResponse": { - "type": "object", - "properties": { - "result": { - "$ref": "#/definitions/healthHealthCheckResponse" - }, - "error": { - "$ref": "#/definitions/runtimeStreamError" - } - }, - "title": "Stream result of healthHealthCheckResponse" - } - } -} diff --git a/example/hello-world-idl/gen/swagger/helloworld/helloworld.swagger.json b/example/hello-world-idl/gen/swagger/helloworld/helloworld.swagger.json deleted file mode 100644 index 3d9104b74..000000000 --- a/example/hello-world-idl/gen/swagger/helloworld/helloworld.swagger.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "swagger": "2.0", - "info": { - "title": "proto/helloworld/helloworld.proto", - "version": "version not set" - }, - "schemes": [ - "http", - "https" - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "paths": {}, - "definitions": {} -} diff --git a/example/hello-world/.gitignore b/example/hello-world/.gitignore index 35ec3b9d7..55283c232 100644 --- a/example/hello-world/.gitignore +++ b/example/hello-world/.gitignore @@ -1 +1 @@ -/ \ No newline at end of file +/hello-world-idl diff --git a/example/hello-world/hello-world-idl/Makefile b/example/hello-world/hello-world-idl/Makefile index 314e76634..e97a9724e 100644 --- a/example/hello-world/hello-world-idl/Makefile +++ b/example/hello-world/hello-world-idl/Makefile @@ -1,11 +1,13 @@ PROTOC_VERSION := 3.9.2 PROTOC_WEB_VERSION := 1.0.6 + PROTO_SOURCES := -I /usr/local/include PROTO_SOURCES += -I . PROTO_SOURCES += -I ${GOPATH}/src PROTO_SOURCES += -I ${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis +PROTO_SOURCES += -I ${GOPATH}/src/github.com/grpc-ecosystem/grpc-gateway -deps-linux: deps-protoc-linux deps-grpc-web-linux +deps-linux: deps-protoc-linux deps-grpc-web-linux deps-go deps-protoc-linux: curl -OL https://github.com/google/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)-linux-x86_64.zip @@ -19,9 +21,14 @@ deps-grpc-web-linux: sudo mv protoc-gen-grpc-web-$(PROTOC_WEB_VERSION)-linux-x86_64 /usr/local/bin/protoc-gen-grpc-web chmod +x /usr/local/bin/protoc-gen-grpc-web -generate: generate-grpc generate-web +deps-go: + go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway + go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger + go get -u github.com/golang/protobuf/protoc-gen-go + +generate: generate-grpc generate-web generate-http -generate-grpc: +generate-grpc: mkdir -p gen/go protoc ${PROTO_SOURCES} --go_out=plugins=grpc:./gen/go ./proto/health/*.proto protoc ${PROTO_SOURCES} --go_out=plugins=grpc:./gen/go ./proto/helloworld/*.proto @@ -33,4 +40,11 @@ generate-web: protoc ${PROTO_SOURCES} --grpc-web_out=import_style=typescript,mode=grpcwebtext:gen/web ./proto/helloworld/*.proto cp -f -rv gen/web/proto/* gen/web rm -rf gen/web/Proto gen/web/proto +generate-http: + mkdir -p gen/http gen/swagger + protoc ${PROTO_SOURCES} --grpc-gateway_out=logtostderr=true:gen/http --swagger_out=logtostderr=true:gen/swagger ./proto/health/*.proto + protoc ${PROTO_SOURCES} --grpc-gateway_out=logtostderr=true:gen/http --swagger_out=logtostderr=true:gen/swagger ./proto/helloworld/*.proto + cp -f -rv gen/http/proto/* gen/http + cp -f -rv gen/swagger/proto/* gen/swagger + rm -rf gen/swagger/proto diff --git a/example/hello-world/hello-world-idl/gen/go/health/health.pb.go b/example/hello-world/hello-world-idl/gen/go/health/health.pb.go index db6a6eb6c..3a477870f 100644 --- a/example/hello-world/hello-world-idl/gen/go/health/health.pb.go +++ b/example/hello-world/hello-world-idl/gen/go/health/health.pb.go @@ -7,9 +7,9 @@ import ( context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" + _ "github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger/options" + _ "google.golang.org/genproto/googleapis/api/annotations" grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" math "math" ) @@ -142,22 +142,28 @@ func init() { func init() { proto.RegisterFile("proto/health/health.proto", fileDescriptor_7bb2e9a145ccb86d) } var fileDescriptor_7bb2e9a145ccb86d = []byte{ - // 238 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2c, 0x28, 0xca, 0x2f, - 0xc9, 0xd7, 0xcf, 0x48, 0x4d, 0xcc, 0x29, 0xc9, 0x80, 0x52, 0x7a, 0x60, 0x31, 0x21, 0x81, 0xdc, - 0xca, 0xe4, 0xfc, 0xdc, 0x82, 0xc4, 0xbc, 0x4a, 0x3d, 0x88, 0xb8, 0x92, 0x1e, 0x97, 0x90, 0x07, - 0x98, 0xe5, 0x9c, 0x91, 0x9a, 0x9c, 0x1d, 0x94, 0x5a, 0x58, 0x9a, 0x5a, 0x5c, 0x22, 0x24, 0xc1, - 0xc5, 0x5e, 0x9c, 0x5a, 0x54, 0x96, 0x99, 0x9c, 0x2a, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x19, 0x04, - 0xe3, 0x2a, 0x6d, 0x66, 0xe4, 0x12, 0x46, 0xd1, 0x50, 0x5c, 0x90, 0x9f, 0x57, 0x9c, 0x2a, 0xe4, - 0xcd, 0xc5, 0x56, 0x5c, 0x92, 0x58, 0x52, 0x5a, 0x0c, 0xd6, 0xc0, 0x67, 0x64, 0xac, 0x87, 0x6e, - 0x95, 0x1e, 0x16, 0x6d, 0x7a, 0xc1, 0x20, 0x63, 0xf3, 0xd2, 0x83, 0xc1, 0x5a, 0x83, 0xa0, 0x46, - 0x28, 0xf9, 0x73, 0xf1, 0xa2, 0x48, 0x08, 0x71, 0x73, 0xb1, 0x87, 0xfa, 0x79, 0xfb, 0xf9, 0x87, - 0xfb, 0x09, 0x30, 0x80, 0x38, 0xc1, 0xae, 0x41, 0x61, 0x9e, 0x7e, 0xee, 0x02, 0x8c, 0x42, 0xfc, - 0x5c, 0xdc, 0x7e, 0xfe, 0x21, 0xf1, 0x30, 0x01, 0x26, 0x21, 0x61, 0x2e, 0x7e, 0x30, 0xc7, 0xd9, - 0x35, 0x1e, 0xa6, 0x85, 0xd9, 0x68, 0x1b, 0x23, 0x17, 0x1b, 0xc4, 0x7a, 0xa1, 0x10, 0x2e, 0x56, - 0xb0, 0x13, 0x84, 0x54, 0x08, 0xb8, 0x10, 0x1c, 0x12, 0x52, 0xaa, 0x44, 0xf9, 0x43, 0x28, 0x8c, - 0x8b, 0x35, 0x3c, 0xb1, 0x24, 0x39, 0x83, 0xaa, 0xa6, 0x1a, 0x30, 0x26, 0xb1, 0x81, 0xe3, 0xcd, - 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x6e, 0xa9, 0x0a, 0x0e, 0xd4, 0x01, 0x00, 0x00, + // 324 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x51, 0xcd, 0x4e, 0x02, 0x31, + 0x10, 0xb6, 0x10, 0x20, 0x0e, 0x22, 0x64, 0x30, 0x06, 0x88, 0x07, 0xb2, 0xd1, 0xc4, 0x83, 0x74, + 0xf9, 0x79, 0x02, 0x25, 0x44, 0x0d, 0xc9, 0x92, 0x2c, 0x0a, 0x47, 0x52, 0x37, 0x4d, 0x97, 0x08, + 0xed, 0x4a, 0x0b, 0x86, 0xab, 0x8f, 0xa0, 0x8f, 0xe2, 0x5b, 0x78, 0xf5, 0x15, 0x7c, 0x10, 0x43, + 0x17, 0x0e, 0xa8, 0x89, 0x1e, 0x3c, 0x4d, 0x66, 0xbe, 0x9f, 0xf9, 0xda, 0x81, 0x72, 0x34, 0x53, + 0x46, 0xb9, 0x21, 0x67, 0x13, 0x13, 0xae, 0x0b, 0xb5, 0x33, 0x2c, 0x4c, 0x97, 0x81, 0x9a, 0x46, + 0x4c, 0x2e, 0x69, 0x3c, 0xaf, 0x1c, 0x09, 0xa5, 0xc4, 0x84, 0xbb, 0x2c, 0x1a, 0xbb, 0x4c, 0x4a, + 0x65, 0x98, 0x19, 0x2b, 0xa9, 0x63, 0x7e, 0xe5, 0xcc, 0x96, 0xa0, 0x26, 0xb8, 0xac, 0xe9, 0x47, + 0x26, 0x04, 0x9f, 0xb9, 0x2a, 0xb2, 0x8c, 0xef, 0x6c, 0x87, 0x02, 0x5e, 0x59, 0xd7, 0x76, 0xc8, + 0x83, 0x7b, 0x9f, 0x3f, 0xcc, 0xb9, 0x36, 0x58, 0x82, 0x8c, 0xe6, 0xb3, 0xc5, 0x38, 0xe0, 0x25, + 0x52, 0x25, 0xa7, 0xbb, 0xfe, 0xa6, 0x75, 0x5e, 0x09, 0x14, 0xb7, 0x04, 0x3a, 0x52, 0x52, 0x73, + 0xec, 0x42, 0x5a, 0x1b, 0x66, 0xe6, 0xda, 0x0a, 0xf6, 0x9b, 0x2d, 0xfa, 0x35, 0x36, 0xfd, 0x41, + 0x46, 0xfb, 0x2b, 0x5b, 0x29, 0xfa, 0x56, 0xea, 0xaf, 0x2d, 0x9c, 0x1e, 0xe4, 0xb6, 0x00, 0xcc, + 0x42, 0xe6, 0xd6, 0xeb, 0x7a, 0xbd, 0xa1, 0x57, 0xd8, 0x59, 0x35, 0xfd, 0x8e, 0x3f, 0xb8, 0xf6, + 0x2e, 0x0b, 0x04, 0xf3, 0x90, 0xf5, 0x7a, 0x37, 0xa3, 0xcd, 0x20, 0x81, 0x45, 0xc8, 0xdb, 0xa6, + 0xdd, 0x19, 0x6d, 0x24, 0xc9, 0xe6, 0x1b, 0x81, 0x74, 0xbc, 0x1e, 0x43, 0x48, 0xd9, 0x08, 0x78, + 0xfc, 0x4b, 0x42, 0xfb, 0x13, 0x95, 0x93, 0x3f, 0xbd, 0xc3, 0xc1, 0xa7, 0xf7, 0x8f, 0x97, 0xc4, + 0x1e, 0x82, 0xbb, 0x68, 0xac, 0xcf, 0x87, 0x03, 0x48, 0x0d, 0x99, 0x09, 0xc2, 0x7f, 0xdd, 0x54, + 0x27, 0x17, 0xe5, 0xe7, 0xf3, 0x43, 0x3c, 0x80, 0x5c, 0x8c, 0x56, 0x2d, 0xac, 0x9b, 0xc9, 0x06, + 0xad, 0xdf, 0xa5, 0xed, 0x51, 0x5b, 0x9f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x27, 0xce, 0xfd, 0xfa, + 0x4f, 0x02, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -231,17 +237,6 @@ type HealthServer interface { Watch(*HealthCheckRequest, Health_WatchServer) error } -// UnimplementedHealthServer can be embedded to have forward compatible implementations. -type UnimplementedHealthServer struct { -} - -func (*UnimplementedHealthServer) Check(ctx context.Context, req *HealthCheckRequest) (*HealthCheckResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Check not implemented") -} -func (*UnimplementedHealthServer) Watch(req *HealthCheckRequest, srv Health_WatchServer) error { - return status.Errorf(codes.Unimplemented, "method Watch not implemented") -} - func RegisterHealthServer(s *grpc.Server, srv HealthServer) { s.RegisterService(&_Health_serviceDesc, srv) } diff --git a/example/hello-world/hello-world-idl/gen/web/health/health_pb.d.ts b/example/hello-world/hello-world-idl/gen/web/health/health_pb.d.ts index 57a475723..015e32a18 100644 --- a/example/hello-world/hello-world-idl/gen/web/health/health_pb.d.ts +++ b/example/hello-world/hello-world-idl/gen/web/health/health_pb.d.ts @@ -1,5 +1,8 @@ import * as jspb from "google-protobuf" +import * as google_api_annotations_pb from '../../google/api/annotations_pb'; +import * as protoc$gen$swagger_options_annotations_pb from '../../protoc-gen-swagger/options/annotations_pb'; + export class HealthCheckRequest extends jspb.Message { getService(): string; setService(value: string): void; diff --git a/example/hello-world/hello-world-idl/proto/health/health.proto b/example/hello-world/hello-world-idl/proto/health/health.proto index fcdae025f..1068fcfa2 100644 --- a/example/hello-world/hello-world-idl/proto/health/health.proto +++ b/example/hello-world/hello-world-idl/proto/health/health.proto @@ -1,6 +1,15 @@ syntax = "proto3"; package mycompany.health; +import "google/api/annotations.proto"; +import "protoc-gen-swagger/options/annotations.proto"; + +option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = { + info: { + title: "Health Checks"; + version: "1.0"; + } +}; message HealthCheckRequest { string service = 1; @@ -17,7 +26,11 @@ message HealthCheckResponse { } service Health { - rpc Check(HealthCheckRequest) returns (HealthCheckResponse); + rpc Check(HealthCheckRequest) returns (HealthCheckResponse){ + option (google.api.http) = { + get: "/v1/health" + }; + } rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); } diff --git a/example/hello-world/sprout.yml b/example/hello-world/sprout.yml index 8077398d5..8192e2d54 100644 --- a/example/hello-world/sprout.yml +++ b/example/hello-world/sprout.yml @@ -14,6 +14,10 @@ network: http: enabled: true port: 8080 + web: + enabled: true + port: 8090 + services: - name: helloworld diff --git a/generate/proto/generate.go b/generate/proto/generate.go index 8ef643e17..a2b12b607 100644 --- a/generate/proto/generate.go +++ b/generate/proto/generate.go @@ -2,6 +2,7 @@ package proto import ( "fmt" + "bytes" "github.com/commitdev/sprout/util" "github.com/commitdev/sprout/config" @@ -22,10 +23,9 @@ func Generate(templator *templator.Templator, config *config.SproutConfig) { func GenerateGoModIDL(templator *templator.Templator, config *config.SproutConfig) { idlPath := fmt.Sprintf("%s-idl", config.Name) idlOutput := fmt.Sprintf("%s/go.mod", idlPath) - + err := util.CreateDirIfDoesNotExist(idlPath) f, err := os.Create(idlOutput) - err = util.CreateDirIfDoesNotExist(idlPath) if err != nil { log.Printf("Error: %v", err) } @@ -94,11 +94,16 @@ func GenerateProtoServiceLibs(config *config.SproutConfig) { idlRoot := fmt.Sprintf("%s-idl", config.Name) cmd := exec.Command("make", "generate") cmd.Dir = idlRoot - bytes, err := cmd.Output() + var out bytes.Buffer + var stderr bytes.Buffer + cmd.Stdout = &out + cmd.Stderr = &stderr + + err := cmd.Run() log.Print("Generating proto service libs...") if err != nil { log.Printf("Failed running command in: %v", cmd.Dir) - log.Printf("Error executing protoc generation: %v %v", err, string(bytes)) + log.Printf("Error executing protoc generation: %v %v", err, stderr.String()) } } diff --git a/go.sum b/go.sum index 45d64d530..3baec019a 100644 --- a/go.sum +++ b/go.sum @@ -312,6 +312,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -365,6 +366,7 @@ golang.org/x/tools v0.0.0-20190820205717-547ecf7b1ef1 h1:gROLVIjNoz8KE0CWNRbGt7m golang.org/x/tools v0.0.0-20190820205717-547ecf7b1ef1/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190909214602-067311248421/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190923195354-c85f9fa9581e h1:w9vD9GwY/Ge6MYjzCtwcw9S9fesidgGH7LtFxAO/u4s= golang.org/x/tools v0.0.0-20190923195354-c85f9fa9581e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= diff --git a/templates/util/gitignore.tmpl b/templates/util/gitignore.tmpl index 90ed41949..21a2f1738 100644 --- a/templates/util/gitignore.tmpl +++ b/templates/util/gitignore.tmpl @@ -1 +1 @@ -/{{ .Name }}-idl +/{{.}}-idl diff --git a/test/hello-world/go.mod b/test/hello-world/go.mod deleted file mode 100644 index 595883132..000000000 --- a/test/hello-world/go.mod +++ /dev/null @@ -1,9 +0,0 @@ -module github.com/yourrepo/hello-world - -go 1.12 - -replace github.com/yourrepo/hello-world-idl => ../hello-world-idl - -require ( - github.com/yourrepo/hello-world-idl v0.0.0 -) diff --git a/test/hello-world/main.go b/test/hello-world/main.go deleted file mode 100644 index 7002bd2d3..000000000 --- a/test/hello-world/main.go +++ /dev/null @@ -1,30 +0,0 @@ -package main -import ( - "log" - "net" - - health "github.com/yourrepo/hello-world/server/health" - healthpb "github.com/yourrepo/hello-world-idl/gen/go/health" - - - "google.golang.org/grpc" -) - -func main() { - grpcAddr := "0.0.0.0:3000" - lis, err := net.Listen("tcp", grpcAddr) - if err != nil { - log.Fatalf("failed to listen: %v", err) - } - s := grpc.NewServer() - - //TODO: Register your servers here - healthServer := health.NewHealthServer() - healthpb.RegisterHealthServer(s, healthServer) - - log.Printf("Starting grpc server on %v...", grpcAddr) - - if err := s.Serve(lis); err != nil { - log.Fatalf("failed to serve: %v", err) - } -} diff --git a/test/hello-world/server/health/health.go b/test/hello-world/server/health/health.go deleted file mode 100644 index cd276d311..000000000 --- a/test/hello-world/server/health/health.go +++ /dev/null @@ -1,25 +0,0 @@ -package health - -import ( - "context" - api "github.com/yourrepo/hello-world-idl/gen/go/health" -) - -type HealthServer struct { - -} - -func NewHealthServer() *HealthServer { - return &HealthServer{} -} - -func (s *HealthServer) Check(ctx context.Context, req *api.HealthCheckRequest) (*api.HealthCheckResponse, error) { - resp := &api.HealthCheckResponse{ - Status: api.HealthCheckResponse_SERVING, - } - return resp,nil -} - -func (s *HealthServer) Watch(req *api.HealthCheckRequest, server api.Health_WatchServer) error { - return nil -} diff --git a/test/hello-world/server/helloworld/helloworld.go b/test/hello-world/server/helloworld/helloworld.go deleted file mode 100644 index 8423d3208..000000000 --- a/test/hello-world/server/helloworld/helloworld.go +++ /dev/null @@ -1,14 +0,0 @@ -package helloworld - -import ( - "context" - api "github.com/yourrepo/hello-world-idl/gen/go/helloworld" -) - -type HelloworldServer struct { - -} - -func NewHelloworldServer() *HelloworldServer { - return &HelloworldServer{} -} diff --git a/test/hello-world/sprout.yml b/test/hello-world/sprout.yml deleted file mode 100644 index b0bec7889..000000000 --- a/test/hello-world/sprout.yml +++ /dev/null @@ -1,20 +0,0 @@ -organization: mycompany -name: hello-world -description: -git-repo: github.com/yourrepo -docker-repo: -maintainers: -# - name: bob -# email: bob@test.com - -network: - grpc: - host: 0.0.0.0 - port: 3000 - web: - enabled: true - port: 8080 - -services: - - name: helloworld - description: Hello world!.