diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index a2f7890b..be6a261e 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -38,3 +38,11 @@ jobs: uses: ./ with: entrypoint: example/one-of/entrypoint.sh + - name: Run stub subfolders example + uses: ./ + with: + entrypoint: example/stub-subfolders/entrypoint.sh + - name: Run no go_package example + uses: ./ + with: + entrypoint: example/no-gopackage/entrypoint.sh diff --git a/.gitignore b/.gitignore index 00f277dc..eadf978d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ pkged.go gripmock .idea .DS_Store +protogen diff --git a/example/no-gopackage/bar/bar.proto b/example/no-gopackage/bar/bar.proto new file mode 100644 index 00000000..e8fd8511 --- /dev/null +++ b/example/no-gopackage/bar/bar.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; +package bar; + +message Bar{ + string name = 1; +} diff --git a/example/no-gopackage/bar/deep/bar.proto b/example/no-gopackage/bar/deep/bar.proto new file mode 100644 index 00000000..1befae86 --- /dev/null +++ b/example/no-gopackage/bar/deep/bar.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; +package bar; + +message DeepBar{ + string address = 1; +} diff --git a/example/no-gopackage/client/main.go b/example/no-gopackage/client/main.go new file mode 100644 index 00000000..b2d7c445 --- /dev/null +++ b/example/no-gopackage/client/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "context" + "log" + "os" + "time" + + pb "github.com/tokopedia/gripmock/protogen/example/no-gopackage" + no_gopackage "github.com/tokopedia/gripmock/protogen/example/no-gopackage/bar" + "google.golang.org/grpc" +) + +//go:generate protoc --go_out=plugins=grpc:${GOPATH}/src -I=../../protogen ../hello.proto ../foo.proto ../bar/bar.proto ../bar/deep/bar.proto +func main() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + + // Set up a connection to the server. + conn, err := grpc.DialContext(ctx, "localhost:4770", grpc.WithInsecure(), grpc.WithBlock()) + if err != nil { + log.Fatalf("did not connect: %v", err) + } + defer conn.Close() + + c := pb.NewGripmockClient(conn) + + // Contact the server and print out its response. + name := "tokopedia" + if len(os.Args) > 1 { + name = os.Args[1] + } + r, err := c.Greet(context.Background(), &no_gopackage.Bar{Name: name}) + if err != nil { + log.Fatalf("error from grpc: %v", err) + } + log.Printf("Greeting: %s\nAddress:%s", r.Response, r.Deepbar.Address) +} diff --git a/example/no-gopackage/entrypoint.sh b/example/no-gopackage/entrypoint.sh new file mode 100755 index 00000000..e10bcb63 --- /dev/null +++ b/example/no-gopackage/entrypoint.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env sh + +# this file is used by .github/workflows/integration-test.yml + +gripmock --stub=example/no-gopackage/stub \ + example/no-gopackage/foo.proto example/no-gopackage/hello.proto \ + example/no-gopackage/bar/bar.proto \ + example/no-gopackage/bar/deep/bar.proto & + +# wait for generated files to be available and gripmock is up +sleep 2 + +go run example/no-gopackage/client/*.go \ No newline at end of file diff --git a/example/no-gopackage/foo.proto b/example/no-gopackage/foo.proto new file mode 100644 index 00000000..dfee27c1 --- /dev/null +++ b/example/no-gopackage/foo.proto @@ -0,0 +1,12 @@ +syntax = "proto3"; + +// simulating neighboring .proto file +// but different package +package foo; + +import "bar/deep/bar.proto"; + +message Response { + string response = 1; + bar.DeepBar deepbar = 2; +} diff --git a/example/no-gopackage/hello.proto b/example/no-gopackage/hello.proto new file mode 100644 index 00000000..14435d99 --- /dev/null +++ b/example/no-gopackage/hello.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package multi_package; + +import "bar/bar.proto"; +import "foo.proto"; + +service Gripmock { + rpc Greet (bar.Bar) returns (foo.Response); +} + diff --git a/example/no-gopackage/stub/simple.json b/example/no-gopackage/stub/simple.json new file mode 100644 index 00000000..38c6eb21 --- /dev/null +++ b/example/no-gopackage/stub/simple.json @@ -0,0 +1,17 @@ +{ + "service":"Gripmock", + "method":"Greet", + "input":{ + "equals":{ + "name":"tokopedia" + } + }, + "output":{ + "data":{ + "response":"Hello Tokopedia", + "deepbar": { + "address": "Jakarta" + } + } + } +} \ No newline at end of file diff --git a/fix_gopackage.sh b/fix_gopackage.sh new file mode 100755 index 00000000..94d61119 --- /dev/null +++ b/fix_gopackage.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +protos=("$@") + +for proto in "${protos[@]}" +do + if grep '^option go_package' $proto;then + echo "option go_package detected in $proto, no need to append" + exit 1 + fi +done + +for proto in "${protos[@]}" +do + if [[ -d $proto ]]; then + continue + fi + + dir=${proto%/*} + file=${proto##*/} + + newdir="protogen/$dir" + newfile="$newdir/$file" + # copy to protogen directory + mkdir -p "$newdir" && cp "$proto" "$_" + + syntaxLineNum="$(grep -n "syntax" "$newfile" | head -n 1 | cut -d: -f1)" + + goPackageString="option go_package = \"github.com/tokopedia/gripmock/protogen/$dir\";" + sed -i "${syntaxLineNum}s~$~\n$goPackageString~" $newfile + echo $newfile +done + diff --git a/gripmock.go b/gripmock.go index 18a05f4a..c02ae202 100644 --- a/gripmock.go +++ b/gripmock.go @@ -1,6 +1,7 @@ package main import ( + "bytes" "flag" "fmt" "log" @@ -85,12 +86,6 @@ func main() { } } -func getProtoName(path string) string { - paths := strings.Split(path, "/") - filename := paths[len(paths)-1] - return strings.Split(filename, ".")[0] -} - type protocParam struct { protoPath []string adminPort string @@ -101,6 +96,7 @@ type protocParam struct { } func generateProtoc(param protocParam) { + param.protoPath = fixGoPackage(param.protoPath) protodirs := strings.Split(param.protoPath[0], "/") protodir := "" if len(protodirs) > 0 { @@ -130,16 +126,19 @@ func generateProtoc(param protocParam) { } -func buildServer(output string) { - args := []string{"build", "-o", output + "grpcserver", output} - - build := exec.Command("go", args...) - build.Stdout = os.Stdout - build.Stderr = os.Stderr - err := build.Run() +// append gopackage in proto files if doesn't have any +func fixGoPackage(protoPaths []string) []string { + fixgopackage := exec.Command("fix_gopackage.sh", protoPaths...) + buf := &bytes.Buffer{} + fixgopackage.Stdout = buf + fixgopackage.Stderr = os.Stderr + err := fixgopackage.Run() if err != nil { - log.Fatal(err) + log.Println("error on fixGoPackage", err) + return protoPaths } + + return strings.Split(strings.TrimRight(buf.String(), "\n"), "\n") } func runGrpcServer(output string) (*exec.Cmd, <-chan error) {