Add support for specifying output .pb.go package
Add flag -pbout which allows the user to specify a go package for the .pb.go files to be written to.
This commit is contained in:
Родитель
a26f615ecf
Коммит
3ec08eaa64
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
1. Everything required to install `truss`
|
1. Everything required to install `truss`
|
||||||
2. go-bindata for compiling templates into binary `$ go get
|
2. go-bindata for compiling templates into binary `$ go get
|
||||||
github.com/jteeuwen/go-bindata`
|
github.com/jteeuwen/go-bindata/...`
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ this is done with:
|
||||||
$ go generate github.com/TuneLab/go-truss/...
|
$ go generate github.com/TuneLab/go-truss/...
|
||||||
```
|
```
|
||||||
|
|
||||||
Then to build truss and it's two protoc plugins to your $GOPATH/bin directory:
|
Then to build truss and its protoc plugin to your $GOPATH/bin directory:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ go install github.com/TuneLab/go-truss/...
|
$ go install github.com/TuneLab/go-truss/...
|
||||||
|
@ -66,13 +66,3 @@ Additional internal packages of note used by these programs are:
|
||||||
- `deftree`, located in `deftree/`, which makes sense of the protobuf file
|
- `deftree`, located in `deftree/`, which makes sense of the protobuf file
|
||||||
passed to it by `protoc`, and is used by `gengokit` and
|
passed to it by `protoc`, and is used by `gengokit` and
|
||||||
`gendoc`
|
`gendoc`
|
||||||
|
|
||||||
## Docker
|
|
||||||
|
|
||||||
BETA
|
|
||||||
|
|
||||||
To build the docker image `$ docker build -t tunelab/gob/truss .`
|
|
||||||
|
|
||||||
To use the docker image as `truss` on .proto files `$ docker run -it --rm
|
|
||||||
--name test -v $PWD:/gopath/src/microservice -w /gopath/src/microservice
|
|
||||||
tunelab/gob/truss *.proto`
|
|
||||||
|
|
|
@ -36,6 +36,8 @@ func init() {
|
||||||
type templateExecutor struct {
|
type templateExecutor struct {
|
||||||
// import path for the directory containing the definition .proto files
|
// import path for the directory containing the definition .proto files
|
||||||
ImportPath string
|
ImportPath string
|
||||||
|
// import path for .pb.go files containing service structs
|
||||||
|
PBImportPath string
|
||||||
// PackageName is the name of the package containing the service definition
|
// PackageName is the name of the package containing the service definition
|
||||||
PackageName string
|
PackageName string
|
||||||
// GRPC/Protobuff service, with all parameters and return values accessible
|
// GRPC/Protobuff service, with all parameters and return values accessible
|
||||||
|
@ -48,13 +50,12 @@ type templateExecutor struct {
|
||||||
|
|
||||||
// newTemplateExecutor accepts a deftree and a goImportPath to construct a
|
// newTemplateExecutor accepts a deftree and a goImportPath to construct a
|
||||||
// templateExecutor for templating a service
|
// templateExecutor for templating a service
|
||||||
func newTemplateExecutor(dt deftree.Deftree, goImportPath string) (*templateExecutor, error) {
|
func newTemplateExecutor(dt deftree.Deftree, goImportPath, goPBImportPath string) (*templateExecutor, error) {
|
||||||
service, err := getProtoService(dt)
|
service, err := getProtoService(dt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "no service found; aborting generating gokit service")
|
return nil, errors.Wrap(err, "no service found; aborting generating gokit service")
|
||||||
}
|
}
|
||||||
|
|
||||||
importPath := goImportPath
|
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"ToLower": strings.ToLower,
|
"ToLower": strings.ToLower,
|
||||||
"Title": strings.Title,
|
"Title": strings.Title,
|
||||||
|
@ -62,12 +63,13 @@ func newTemplateExecutor(dt deftree.Deftree, goImportPath string) (*templateExec
|
||||||
"TrimPrefix": strings.TrimPrefix,
|
"TrimPrefix": strings.TrimPrefix,
|
||||||
}
|
}
|
||||||
return &templateExecutor{
|
return &templateExecutor{
|
||||||
ImportPath: importPath,
|
ImportPath: goImportPath,
|
||||||
PackageName: dt.GetName(),
|
PBImportPath: goPBImportPath,
|
||||||
Service: service,
|
PackageName: dt.GetName(),
|
||||||
ClientArgs: clientarggen.New(service),
|
Service: service,
|
||||||
HTTPHelper: httptransport.NewHelper(service),
|
ClientArgs: clientarggen.New(service),
|
||||||
funcMap: funcMap,
|
HTTPHelper: httptransport.NewHelper(service),
|
||||||
|
funcMap: funcMap,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,8 +79,8 @@ func newTemplateExecutor(dt deftree.Deftree, goImportPath string) (*templateExec
|
||||||
// templating go code imports. GenerateGokit returns the a
|
// templating go code imports. GenerateGokit returns the a
|
||||||
// []truss.NamedReadWriter representing a generated gokit service file
|
// []truss.NamedReadWriter representing a generated gokit service file
|
||||||
// structure
|
// structure
|
||||||
func GenerateGokit(dt deftree.Deftree, previousFiles []truss.NamedReadWriter, goImportPath string) ([]truss.NamedReadWriter, error) {
|
func GenerateGokit(dt deftree.Deftree, previousFiles []truss.NamedReadWriter, goImportPath, goPBImportPath string) ([]truss.NamedReadWriter, error) {
|
||||||
te, err := newTemplateExecutor(dt, goImportPath)
|
te, err := newTemplateExecutor(dt, goImportPath, goPBImportPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "could not create template executor")
|
return nil, errors.Wrap(err, "could not create template executor")
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ func TestNewTemplateExecutor(t *testing.T) {
|
||||||
|
|
||||||
const goImportPath = "github.com/TuneLab/go-truss/gengokit/general-service"
|
const goImportPath = "github.com/TuneLab/go-truss/gengokit/general-service"
|
||||||
|
|
||||||
te, err := newTemplateExecutor(dt, goImportPath)
|
te, err := newTemplateExecutor(dt, goImportPath, goImportPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -168,7 +168,7 @@ func TestApplyTemplateFromPath(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
te, err := newTemplateExecutor(dt, goImportPath)
|
te, err := newTemplateExecutor(dt, goImportPath, goImportPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ func stringToTemplateExector(def, importPath string) (*templateExecutor, error)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
te, err := newTemplateExecutor(dt, importPath)
|
te, err := newTemplateExecutor(dt, importPath, importPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -339,7 +339,7 @@ func TestUpdateServerMethods(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
te, err := newTemplateExecutor(dt, goImportPath)
|
te, err := newTemplateExecutor(dt, goImportPath, goImportPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -462,7 +462,7 @@ func TestAllTemplates(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
te, err := newTemplateExecutor(dt, goImportPath)
|
te, err := newTemplateExecutor(dt, goImportPath, goImportPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -472,7 +472,7 @@ func TestAllTemplates(t *testing.T) {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
te2, err := newTemplateExecutor(dt2, goImportPath)
|
te2, err := newTemplateExecutor(dt2, goImportPath, goImportPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ import (
|
||||||
clientHandler "{{$templateExecutor.ImportPath -}} /handlers/client"
|
clientHandler "{{$templateExecutor.ImportPath -}} /handlers/client"
|
||||||
grpcclient "{{$templateExecutor.ImportPath -}} /generated/client/grpc"
|
grpcclient "{{$templateExecutor.ImportPath -}} /generated/client/grpc"
|
||||||
httpclient "{{$templateExecutor.ImportPath -}} /generated/client/http"
|
httpclient "{{$templateExecutor.ImportPath -}} /generated/client/http"
|
||||||
pb "{{$templateExecutor.ImportPath -}}"
|
pb "{{$templateExecutor.PBImportPath -}}"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -33,7 +33,7 @@ import (
|
||||||
// This Service
|
// This Service
|
||||||
handler "{{$templateExecutor.ImportPath -}} /handlers/server"
|
handler "{{$templateExecutor.ImportPath -}} /handlers/server"
|
||||||
svc "{{$templateExecutor.ImportPath -}} /generated"
|
svc "{{$templateExecutor.ImportPath -}} /generated"
|
||||||
pb "{{$templateExecutor.ImportPath -}}"
|
pb "{{$templateExecutor.PBImportPath -}}"
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ import (
|
||||||
// This Service
|
// This Service
|
||||||
handler "{{$templateExecutor.ImportPath -}} /handlers/server"
|
handler "{{$templateExecutor.ImportPath -}} /handlers/server"
|
||||||
svc "{{$templateExecutor.ImportPath -}} /generated"
|
svc "{{$templateExecutor.ImportPath -}} /generated"
|
||||||
pb "{{$templateExecutor.ImportPath -}}"
|
pb "{{$templateExecutor.PBImportPath -}}"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New returns an AddService backed by a gRPC client connection. It is the
|
// New returns an AddService backed by a gRPC client connection. It is the
|
||||||
|
|
|
@ -16,7 +16,7 @@ import (
|
||||||
//_ "github.com/go-kit/kit/metrics"
|
//_ "github.com/go-kit/kit/metrics"
|
||||||
|
|
||||||
handler "{{.ImportPath -}} /handlers/server"
|
handler "{{.ImportPath -}} /handlers/server"
|
||||||
pb "{{.ImportPath -}}"
|
pb "{{.PBImportPath -}}"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Endpoints collects all of the endpoints that compose an add service. It's
|
// Endpoints collects all of the endpoints that compose an add service. It's
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
//_ "github.com/go-kit/kit/log"
|
//_ "github.com/go-kit/kit/log"
|
||||||
//_ "github.com/go-kit/kit/metrics"
|
//_ "github.com/go-kit/kit/metrics"
|
||||||
|
|
||||||
//pb "{{.ImportPath -}} "
|
//pb "{{.PBImportPath -}} "
|
||||||
)
|
)
|
||||||
|
|
||||||
// Middleware describes a service (as opposed to endpoint) middleware.
|
// Middleware describes a service (as opposed to endpoint) middleware.
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
grpctransport "github.com/go-kit/kit/transport/grpc"
|
grpctransport "github.com/go-kit/kit/transport/grpc"
|
||||||
|
|
||||||
// This Service
|
// This Service
|
||||||
pb "{{$templateExecutor.ImportPath -}}"
|
pb "{{$templateExecutor.PBImportPath -}}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ import (
|
||||||
httptransport "github.com/go-kit/kit/transport/http"
|
httptransport "github.com/go-kit/kit/transport/http"
|
||||||
|
|
||||||
// This service
|
// This service
|
||||||
pb "{{$templateExecutor.ImportPath -}}"
|
pb "{{$templateExecutor.PBImportPath -}}"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
package clienthandler
|
package clienthandler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
pb "{{$templateExecutor.ImportPath -}}"
|
pb "{{$templateExecutor.PBImportPath -}}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
_ "github.com/go-kit/kit/log"
|
_ "github.com/go-kit/kit/log"
|
||||||
_ "github.com/go-kit/kit/metrics"
|
_ "github.com/go-kit/kit/metrics"
|
||||||
|
|
||||||
pb "{{.ImportPath -}}"
|
pb "{{.PBImportPath -}}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -35,6 +35,12 @@ func TestBasicTypes(t *testing.T) {
|
||||||
testEndToEnd("1-basic", t)
|
testEndToEnd("1-basic", t)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestBasicTypesWithPBOutFlag(t *testing.T) {
|
||||||
|
testEndToEnd("1-basic", t,
|
||||||
|
"-pbout",
|
||||||
|
"github.com/TuneLab/go-truss/truss/_integration-tests/cli/test-service-definitions/1-basic/pbout")
|
||||||
|
}
|
||||||
|
|
||||||
// Disabled until repeated types are implemented for cliclient
|
// Disabled until repeated types are implemented for cliclient
|
||||||
func _TestRepeatedTypes(t *testing.T) {
|
func _TestRepeatedTypes(t *testing.T) {
|
||||||
testEndToEnd("2-repeated", t)
|
testEndToEnd("2-repeated", t)
|
||||||
|
@ -62,13 +68,16 @@ type runReference struct {
|
||||||
serverOutput string
|
serverOutput string
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEndToEnd(defDir string, t *testing.T) {
|
func testEndToEnd(defDir string, t *testing.T, trussOptions ...string) {
|
||||||
port := 45360
|
port := 45360
|
||||||
wd, _ := os.Getwd()
|
wd, _ := os.Getwd()
|
||||||
|
|
||||||
fullpath := filepath.Join(wd, definitionDirectory, defDir)
|
fullpath := filepath.Join(wd, definitionDirectory, defDir)
|
||||||
|
|
||||||
trussOut, err := truss(fullpath)
|
// Remove tests if they exists
|
||||||
|
removeTestFiles(fullpath)
|
||||||
|
|
||||||
|
trussOut, err := truss(fullpath, trussOptions...)
|
||||||
|
|
||||||
// If truss fails, test error and skip communication
|
// If truss fails, test error and skip communication
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -78,7 +87,7 @@ func testEndToEnd(defDir string, t *testing.T) {
|
||||||
// Build the service to be tested
|
// Build the service to be tested
|
||||||
err = buildTestService(fullpath)
|
err = buildTestService(fullpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Could not buld service. Error: %v", err)
|
t.Fatalf("Could not build service. Error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run them save a reference to each run
|
// Run them save a reference to each run
|
||||||
|
@ -97,7 +106,7 @@ func testEndToEnd(defDir string, t *testing.T) {
|
||||||
|
|
||||||
// truss calls truss on *.proto in path
|
// truss calls truss on *.proto in path
|
||||||
// Truss logs to Stdout when generation passes or fails
|
// Truss logs to Stdout when generation passes or fails
|
||||||
func truss(path string) (string, error) {
|
func truss(path string, options ...string) (string, error) {
|
||||||
var protofiles []string
|
var protofiles []string
|
||||||
files, err := ioutil.ReadDir(path)
|
files, err := ioutil.ReadDir(path)
|
||||||
for _, f := range files {
|
for _, f := range files {
|
||||||
|
@ -109,9 +118,11 @@ func truss(path string) (string, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
args := append(options, protofiles...)
|
||||||
|
|
||||||
trussExec := exec.Command(
|
trussExec := exec.Command(
|
||||||
"truss",
|
"truss",
|
||||||
protofiles...,
|
args...,
|
||||||
)
|
)
|
||||||
trussExec.Dir = path
|
trussExec.Dir = path
|
||||||
|
|
||||||
|
@ -203,16 +214,6 @@ func goBuild(name, outputPath, relCodePath string, errChan chan error) {
|
||||||
errChan <- nil
|
errChan <- nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// mkdir acts like $ mkdir -p path
|
|
||||||
func mkdir(path string) error {
|
|
||||||
dir := filepath.Dir(path)
|
|
||||||
|
|
||||||
// 0775 is the file mode that $ mkdir uses when creating a directoru
|
|
||||||
err := os.MkdirAll(dir, 0775)
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// runServerAndClient execs a TEST-server and TEST-client and puts a
|
// runServerAndClient execs a TEST-server and TEST-client and puts a
|
||||||
// runReference to their interaction on the runRefs channel
|
// runReference to their interaction on the runRefs channel
|
||||||
func runServerAndClient(path string, port int, debugPort int) runReference {
|
func runServerAndClient(path string, port int, debugPort int) runReference {
|
||||||
|
@ -342,16 +343,23 @@ func cleanTests(servicesDir string) {
|
||||||
if !d.IsDir() {
|
if !d.IsDir() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
removeTestFiles(servicesDir + "/" + d.Name())
|
removeTestFiles(filepath.Join(servicesDir, d.Name()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// removeTestFiles removes all files created by running truss and building the
|
// removeTestFiles removes all files created by running truss and building the
|
||||||
// service from a single definition directory
|
// service from a single definition directory
|
||||||
func removeTestFiles(defDir string) {
|
func removeTestFiles(defDir string) {
|
||||||
if fileExists(defDir + "/TEST-service") {
|
os.RemoveAll(filepath.Join(defDir, "TEST-service"))
|
||||||
os.RemoveAll(defDir + "/TEST-service")
|
os.RemoveAll(filepath.Join(defDir, "bin"))
|
||||||
os.RemoveAll(defDir + "/third_party")
|
os.RemoveAll(filepath.Join(defDir, "pbout"))
|
||||||
os.RemoveAll(defDir + "/bin")
|
mkdir(filepath.Join(defDir, "pbout"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// mkdir acts like $ mkdir -p path
|
||||||
|
func mkdir(path string) error {
|
||||||
|
// 0775 is the file mode that $ mkdir uses when creating a directoru
|
||||||
|
err := os.MkdirAll(path, 0775)
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
140
truss/main.go
140
truss/main.go
|
@ -12,82 +12,136 @@ import (
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/TuneLab/go-truss/truss/truss"
|
|
||||||
"github.com/TuneLab/go-truss/truss/protostuff"
|
"github.com/TuneLab/go-truss/truss/protostuff"
|
||||||
|
"github.com/TuneLab/go-truss/truss/truss"
|
||||||
|
|
||||||
"github.com/TuneLab/go-truss/deftree"
|
"github.com/TuneLab/go-truss/deftree"
|
||||||
"github.com/TuneLab/go-truss/gendoc"
|
"github.com/TuneLab/go-truss/gendoc"
|
||||||
"github.com/TuneLab/go-truss/gengokit"
|
"github.com/TuneLab/go-truss/gengokit"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var pbOutFlag = flag.String("pbout", "", "The go package path where the protoc-gen-go .pb.go structs will be written.")
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
goPath := os.Getenv("GOPATH")
|
||||||
|
|
||||||
|
var pbOut string
|
||||||
|
if *pbOutFlag != "" {
|
||||||
|
pbOut = filepath.Join(goPath, "src", *pbOutFlag)
|
||||||
|
if !fileExists(pbOut) {
|
||||||
|
exitIfError(errors.Errorf("Go package directory does not exist: %q", pbOut))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(flag.Args()) == 0 {
|
if len(flag.Args()) == 0 {
|
||||||
exitIfError(errors.New("no arguments passed"))
|
flag.Usage()
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
rawDefinitionPaths := flag.Args()
|
rawDefinitionPaths := flag.Args()
|
||||||
|
|
||||||
protoDir, definitionFiles, err := cleanProtofilePath(rawDefinitionPaths)
|
protoDir, definitionFiles, err := cleanProtofilePath(rawDefinitionPaths)
|
||||||
|
exitIfError(err)
|
||||||
// Check truss is running in $GOPATH
|
|
||||||
goPath := os.Getenv("GOPATH")
|
|
||||||
|
|
||||||
if !strings.HasPrefix(protoDir, goPath) {
|
if !strings.HasPrefix(protoDir, goPath) {
|
||||||
exitIfError(errors.New("truss envoked on files outside of $GOPATH"))
|
exitIfError(errors.New("truss envoked on files outside of $GOPATH"))
|
||||||
}
|
}
|
||||||
|
|
||||||
protocOut, err := protostuff.CodeGeneratorRequest(definitionFiles, protoDir)
|
dt, err := buildDeftree(definitionFiles, protoDir)
|
||||||
exitIfError(err)
|
exitIfError(err)
|
||||||
|
|
||||||
svcFile, err := protostuff.ServiceFile(protocOut, protoDir)
|
|
||||||
exitIfError(err)
|
|
||||||
|
|
||||||
// Make a deftree
|
|
||||||
dt, err := deftree.New(protocOut, svcFile)
|
|
||||||
exitIfError(err)
|
|
||||||
|
|
||||||
// Generate the .pb.go files containing the golang data structures
|
|
||||||
// From `$GOPATH/src/org/user/thing` get `org/user/thing` for importing in golang
|
|
||||||
svcName := dt.GetName() + "-service"
|
svcName := dt.GetName() + "-service"
|
||||||
svcDir := filepath.Join(protoDir, svcName)
|
svcDir := filepath.Join(protoDir, svcName)
|
||||||
err = mkdir(svcDir)
|
|
||||||
exitIfError(err)
|
|
||||||
|
|
||||||
err = protostuff.GeneratePBataStructures(definitionFiles, svcDir)
|
|
||||||
exitIfError(err)
|
|
||||||
|
|
||||||
prevGen, err := readPreviousGeneration(protoDir, svcDir)
|
prevGen, err := readPreviousGeneration(protoDir, svcDir)
|
||||||
exitIfError(err)
|
exitIfError(err)
|
||||||
|
|
||||||
// generate docs
|
err = mkdir(svcDir)
|
||||||
genDocFiles := gendoc.GenerateDocs(dt)
|
|
||||||
|
|
||||||
// generate gokit microservice
|
|
||||||
goSvcImportPath, err := filepath.Rel(filepath.Join(goPath, "src"), svcDir)
|
|
||||||
exitIfError(err)
|
|
||||||
genFiles, err := gengokit.GenerateGokit(dt, prevGen, goSvcImportPath)
|
|
||||||
exitIfError(err)
|
exitIfError(err)
|
||||||
|
|
||||||
// append files together
|
// If not output directory for the .pb.go files has been selected then put them in the svcDir
|
||||||
genFiles = append(genFiles, genDocFiles...)
|
if pbOut == "" {
|
||||||
|
pbOut = svcDir
|
||||||
// Write files to disk
|
|
||||||
for _, f := range genFiles {
|
|
||||||
name := f.Name()
|
|
||||||
|
|
||||||
fullPath := filepath.Join(protoDir, name)
|
|
||||||
err := mkdir(fullPath)
|
|
||||||
exitIfError(err)
|
|
||||||
|
|
||||||
file, err := os.Create(fullPath)
|
|
||||||
exitIfError(errors.Wrapf(err, "could create file %v", fullPath))
|
|
||||||
|
|
||||||
_, err = io.Copy(file, f)
|
|
||||||
exitIfError(errors.Wrapf(err, "could not write to %v", fullPath))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = protostuff.GeneratePBDotGo(definitionFiles, svcDir, protoDir, pbOut)
|
||||||
|
exitIfError(err)
|
||||||
|
|
||||||
|
// gokit service
|
||||||
|
goSvcImportPath, goPBImportPath, err := trussGoImports(svcDir, pbOut, goPath)
|
||||||
|
|
||||||
|
genGokitFiles, err := gengokit.GenerateGokit(dt, prevGen, goSvcImportPath, goPBImportPath)
|
||||||
|
exitIfError(err)
|
||||||
|
|
||||||
|
for _, f := range genGokitFiles {
|
||||||
|
err := writeFile(f, protoDir)
|
||||||
|
exitIfError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// docs
|
||||||
|
genDocFiles := gendoc.GenerateDocs(dt)
|
||||||
|
for _, f := range genDocFiles {
|
||||||
|
err := writeFile(f, protoDir)
|
||||||
|
exitIfError(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func trussGoImports(svcDir, pbOutDir, goPath string) (string, string, error) {
|
||||||
|
goSvcImportPath, err := filepath.Rel(filepath.Join(goPath, "src"), svcDir)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
goPBImportPath, err := filepath.Rel(filepath.Join(goPath, "src"), pbOutDir)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return goSvcImportPath, goPBImportPath, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeFile(f truss.NamedReadWriter, protoDir string) error {
|
||||||
|
name := f.Name()
|
||||||
|
|
||||||
|
fullPath := filepath.Join(protoDir, name)
|
||||||
|
err := mkdir(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Create(fullPath)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "could create file %v", fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.Copy(file, f)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "could not write to %v", fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildDeftree(definitionFiles []string, protoDir string) (deftree.Deftree, error) {
|
||||||
|
protocOut, err := protostuff.CodeGeneratorRequest(definitionFiles, protoDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not use create a proto CodeGeneratorRequest")
|
||||||
|
}
|
||||||
|
|
||||||
|
svcFile, err := protostuff.ServiceFile(protocOut, protoDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "coult not find service definition file")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a deftree
|
||||||
|
dt, err := deftree.New(protocOut, svcFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "could not construct deftree")
|
||||||
|
}
|
||||||
|
|
||||||
|
return dt, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanProtofilePath takes a slice of file paths and returns the
|
// cleanProtofilePath takes a slice of file paths and returns the
|
||||||
|
|
|
@ -14,31 +14,34 @@ import (
|
||||||
assets "github.com/TuneLab/go-truss/truss/template"
|
assets "github.com/TuneLab/go-truss/truss/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
// GeneratePBDataStructures expects to be passed
|
// GeneratePBDotGo
|
||||||
// datastructures represened in the .proto files
|
func GeneratePBDotGo(protoFiles []string, svcDir, protoDir, outDir string) error {
|
||||||
func GeneratePBataStructures(protoFiles []string, svcDir string) error {
|
|
||||||
|
|
||||||
err := outputGoogleImport(svcDir)
|
err := outputGoogleImport(svcDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
importPath, err := filepath.Rel(filepath.Join(os.Getenv("GOPATH"), "src"), svcDir)
|
importPath, err := filepath.Rel(filepath.Join(os.Getenv("GOPATH"), "src"), svcDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = mkdir(outDir)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "could not make output directory")
|
||||||
|
}
|
||||||
|
|
||||||
genGoCode := "--go_out=Mgoogle/api/annotations.proto=" +
|
genGoCode := "--go_out=Mgoogle/api/annotations.proto=" +
|
||||||
importPath + "/third_party/googleapis/google/api," +
|
importPath + "/third_party/googleapis/google/api," +
|
||||||
"plugins=grpc:" +
|
"plugins=grpc:" +
|
||||||
svcDir
|
outDir
|
||||||
|
|
||||||
_, err = exec.LookPath("protoc-gen-go")
|
_, err = exec.LookPath("protoc-gen-go")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "protoc-gen-go not exist in $PATH")
|
return errors.Wrap(err, "protoc-gen-go not exist in $PATH")
|
||||||
}
|
}
|
||||||
|
|
||||||
protoDir := filepath.Dir(svcDir)
|
err = protoc(protoFiles, protoDir, svcDir, genGoCode)
|
||||||
err = protoc(protoFiles, protoDir, svcDir, svcDir, genGoCode)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "could not generate go code from .proto files")
|
return errors.Wrap(err, "could not generate go code from .proto files")
|
||||||
}
|
}
|
||||||
|
@ -64,8 +67,7 @@ func CodeGeneratorRequest(protoFiles []string, protoDir string) (*plugin.CodeGen
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServiceFile searches through the files in the request and returns the
|
// ServiceFile searches through the files in the request and returns the
|
||||||
// path to the first one which contains a service declaration. If no file in
|
// file which contains a service declaration.
|
||||||
// the request contains a service, returns an empty string.
|
|
||||||
func ServiceFile(req *plugin.CodeGeneratorRequest, protoFileDir string) (*os.File, error) {
|
func ServiceFile(req *plugin.CodeGeneratorRequest, protoFileDir string) (*os.File, error) {
|
||||||
var svcFileName string
|
var svcFileName string
|
||||||
for _, file := range req.GetProtoFile() {
|
for _, file := range req.GetProtoFile() {
|
||||||
|
@ -107,8 +109,9 @@ func getProtocOutput(protoFiles []string, protoFileDir string) ([]byte, error) {
|
||||||
return nil, errors.Wrapf(err, "could not write protoc imports to dir: %s", protocOutDir)
|
return nil, errors.Wrapf(err, "could not write protoc imports to dir: %s", protocOutDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
const plugin = "--truss-protocast_out=."
|
pluginCall := filepath.Join("--truss-protocast_out=", protocOutDir)
|
||||||
err = protoc(protoFiles, protoFileDir, protocOutDir, protocOutDir, plugin)
|
|
||||||
|
err = protoc(protoFiles, protoFileDir, protocOutDir, pluginCall)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "protoc failed")
|
return nil, errors.Wrap(err, "protoc failed")
|
||||||
}
|
}
|
||||||
|
@ -133,7 +136,7 @@ func getProtocOutput(protoFiles []string, protoFileDir string) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// protoc exec's $ protoc on protoFiles, on their full path which is created with protoDir
|
// protoc exec's $ protoc on protoFiles, on their full path which is created with protoDir
|
||||||
func protoc(protoFiles []string, protoDir, outDir, importDir, plugin string) error {
|
func protoc(protoFiles []string, protoDir, importDir, plugin string) error {
|
||||||
const googleAPIImportPath = "/third_party/googleapis"
|
const googleAPIImportPath = "/third_party/googleapis"
|
||||||
|
|
||||||
var fullPaths []string
|
var fullPaths []string
|
||||||
|
@ -154,8 +157,6 @@ func protoc(protoFiles []string, protoDir, outDir, importDir, plugin string) err
|
||||||
cmdArgs...,
|
cmdArgs...,
|
||||||
)
|
)
|
||||||
|
|
||||||
protocExec.Dir = outDir
|
|
||||||
|
|
||||||
outBytes, err := protocExec.CombinedOutput()
|
outBytes, err := protocExec.CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err,
|
return errors.Wrapf(err,
|
||||||
|
|
Загрузка…
Ссылка в новой задаче