diff --git a/.gitignore b/.gitignore index db685ae29..ac0a423c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ main-packr.go packrd -sprout +/sprout diff --git a/Makefile b/Makefile index 55349e27f..b26447b99 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ build: packr2 build -o sprout packr2 clean -build-example: +build-example: build clean-example mkdir -p example cd example && ../sprout create -p "hello-world" cd example/hello-world && ../../sprout generate -l go diff --git a/cmd/create.go b/cmd/create.go index c56036113..1eb64bbe7 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -1,10 +1,9 @@ package cmd import ( + "fmt" "log" "os" - "fmt" - "github.com/spf13/cobra" ) @@ -23,9 +22,13 @@ var createCmd = &cobra.Command{ Short: "Create new project.", Run: func(cmd *cobra.Command, args []string) { - err := os.Mkdir(projectName, os.ModePerm) - if os.IsExist(err){ - log.Fatalf("Directory %v already exists!", projectName) + rootDir := fmt.Sprintf("./%v", projectName) + + err := os.Mkdir(rootDir, 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", projectName) diff --git a/config/config.go b/config/config.go index c8cbc1964..54f453fed 100644 --- a/config/config.go +++ b/config/config.go @@ -13,22 +13,23 @@ type Maintainers struct { } type Grpc struct { + Host string Port int } type Graphql struct { Enabled bool - Port int + Port int } type Http struct { Enabled bool - Port int + Port int } type Network struct { - Grpc Grpc - Http Http + Grpc Grpc + Http Http Graphql Graphql } diff --git a/example/hello-world-idl/go.mod b/example/hello-world-idl/go.mod new file mode 100644 index 000000000..208e33ba3 --- /dev/null +++ b/example/hello-world-idl/go.mod @@ -0,0 +1,3 @@ +module github.com/yourrepo/hello-world-idl + +go 1.12 diff --git a/example/hello-world/go.mod b/example/hello-world/go.mod index 8948ca22f..014127054 100644 --- a/example/hello-world/go.mod +++ b/example/hello-world/go.mod @@ -1,3 +1,10 @@ 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 +) diff --git a/example/hello-world/main.go b/example/hello-world/main.go index da29a2cad..8988f041e 100644 --- a/example/hello-world/main.go +++ b/example/hello-world/main.go @@ -1,4 +1,26 @@ package main +import ( + "context" + "log" + "net" + + health "github.com/yourrepo/hello-world/server/health" + + "google.golang.org/grpc" +) func main() { + lis, err := net.Listen("tcp", "0.0.0.0:3000") + if err != nil { + log.Fatalf("failed to listen: %v", err) + } + s := grpc.NewServer() + + //TODO: Register your servers here + healthServer := health.NewServer() + health.RegisterHealthServer(s, healthServer) + + if err := s.Serve(lis); err != nil { + log.Fatalf("failed to serve: %v", err) + } } diff --git a/example/hello-world/sprout.yml b/example/hello-world/sprout.yml index ceb84c71e..7c0888489 100644 --- a/example/hello-world/sprout.yml +++ b/example/hello-world/sprout.yml @@ -9,6 +9,7 @@ maintainers: network: grpc: + host: 0.0.0.0 port: 3000 http: enabled: true diff --git a/generate/golang/generate.go b/generate/golang/generate.go index 77502d2d0..05a63cb58 100644 --- a/generate/golang/generate.go +++ b/generate/golang/generate.go @@ -18,16 +18,19 @@ func Generate(templator *templator.Templator, config *config.SproutConfig) { } func GenerateGoMain(templator *templator.Templator, config *config.SproutConfig) { - f, err := os.Create("main.go") + if _, err := os.Stat("main.go"); os.IsNotExist(err) { - if err != nil { - log.Printf("Error: %v", err) - } - - templator.Go.GoMain.Execute(f, config) -} + f, err := os.Create("main.go") + if err != nil { + log.Printf("Error: %v", err) + } + templator.Go.GoMain.Execute(f, config) + } else { + log.Printf("main.go already exists. skipping.") + } +} func GenerateGoMod(templator *templator.Templator, config *config.SproutConfig) { f, err := os.Create("go.mod") @@ -50,7 +53,7 @@ func GenerateServers(templator *templator.Templator, config *config.SproutConfig serverLibPath := fmt.Sprintf("%s/%s", serverDirPath, s.Name) err := os.Mkdir(serverLibPath, os.ModePerm) if os.IsExist(err) { - log.Printf("%s service exists skipping.", s.Name) + log.Printf("%s server exists skipping.", s.Name) continue } log.Printf("generating %s", s.Name) @@ -65,10 +68,10 @@ func GenerateServers(templator *templator.Templator, config *config.SproutConfig log.Printf("Error: %v", err) } - data := map[string]string { + data := map[string]string{ "ProjectName": config.Name, "ServiceName": s.Name, - "GitRepo": config.GitRepo, + "GitRepo": config.GitRepo, } templator.Go.GoServer.Execute(f, data) diff --git a/generate/proto/generate.go b/generate/proto/generate.go index d85ba43ee..31c025370 100644 --- a/generate/proto/generate.go +++ b/generate/proto/generate.go @@ -16,6 +16,21 @@ func Generate(templator *templator.Templator, config *config.SproutConfig) { GenerateProtoHealth(templator, config) GenerateProtoServices(templator, config) GenerateProtoServiceLibs(config) + GenerateGoModIDL(templator, config) +} + +func GenerateGoModIDL(templator *templator.Templator, config *config.SproutConfig) { + idlPath := fmt.Sprintf("../%s-idl", config.Name) + idlOutput := fmt.Sprintf("%s/go.mod", idlPath) + + f, err := os.Create(idlOutput) + + err = util.CreateDirIfDoesNotExist(idlPath) + if err != nil { + log.Printf("Error: %v", err) + } + + templator.Go.GoModIDL.Execute(f, config) } func GenerateProtoToolConfig(templator *templator.Templator, config *config.SproutConfig) { @@ -64,6 +79,7 @@ func GenerateProtoServices(templator *templator.Templator, config *config.Sprout protoPath := fmt.Sprintf("%s/%s.proto", s.Name, s.Name) cmd := exec.Command("prototool", "create", protoPath) cmd.Dir = protoToolConfigPath + log.Printf("Generating %v", protoPath) cmd.Run() } @@ -74,6 +90,8 @@ func GenerateProtoServiceLibs(config *config.SproutConfig) { cmd := exec.Command("prototool", "generate") cmd.Dir = protoToolConfigPath bytes, err := cmd.Output() + + log.Print("Generating proto service libs...") if err != nil { log.Printf("Error executing prototool generate: %v", string(bytes)) } diff --git a/go.sum b/go.sum index 6e86e73d4..835175eab 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,7 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/commitdev/sprout/example/hello-world v0.0.0-20190827182108-cfad4c3d94cc h1:zBLjQxkC2LT1e9eMs0I2k26NXXZVT/XGrnuqdAsFt3A= +github.com/commitdev/sprout/example/hello-world v0.0.0-20190827183525-9eeb1651f4f4 h1:pQw2XR8va971sW7QIX18I7FWft54TjLdQex5MHCcVtg= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.3/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -70,6 +71,7 @@ github.com/gofrs/flock v0.7.1 h1:DP+LD/t0njgoPBvT5MJLeliUIVQR03hiKR6vezdwHlc= github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= diff --git a/main.go b/main.go index f793e2a5e..0a2d9fdc5 100644 --- a/main.go +++ b/main.go @@ -7,7 +7,7 @@ import ( ) func main() { - templates := packr.New("templates","./templates") + templates := packr.New("templates", "./templates") templator := templator.NewTemplator(templates) cmd.Execute(templator) } diff --git a/templates/golang/go_mod.tmpl b/templates/golang/go_mod.tmpl index 4e3a641d1..9da7ca367 100644 --- a/templates/golang/go_mod.tmpl +++ b/templates/golang/go_mod.tmpl @@ -1,3 +1,9 @@ module {{ .GitRepo }}/{{ .Name }} go 1.12 + +replace {{ .GitRepo }}/{{ .Name }}-idl => ../{{ .Name }}-idl + +require ( + {{ .GitRepo }}/{{ .Name }}-idl v0.0.0 +) diff --git a/templates/golang/go_mod_idl.tmpl b/templates/golang/go_mod_idl.tmpl new file mode 100644 index 000000000..8deb4bca1 --- /dev/null +++ b/templates/golang/go_mod_idl.tmpl @@ -0,0 +1,3 @@ +module {{ .GitRepo }}/{{ .Name }}-idl + +go 1.12 diff --git a/templates/golang/health_server.tmpl b/templates/golang/health_server.tmpl index ca006c832..ae9be2fe5 100644 --- a/templates/golang/health_server.tmpl +++ b/templates/golang/health_server.tmpl @@ -2,13 +2,17 @@ package health import ( "context" - api "{{ .GitRepo }}/{{ .Name }}-go/health" + api "{{ .GitRepo }}/{{ .Name }}-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, @@ -18,4 +22,4 @@ func (s *HealthServer) Check(ctx context.Context, req *api.HealthCheckRequest) ( func (s *HealthServer) Watch(req *api.HealthCheckRequest, server api.Health_WatchServer) error { return nil -} \ No newline at end of file +} diff --git a/templates/golang/main.tmpl b/templates/golang/main.tmpl index da29a2cad..00b1bb472 100644 --- a/templates/golang/main.tmpl +++ b/templates/golang/main.tmpl @@ -1,4 +1,30 @@ package main +import ( + "log" + "net" + + health "{{ .GitRepo }}/{{ .Name }}/server/health" + healthpb "{{ .GitRepo }}/{{ .Name }}-idl/gen/go/health" + + + "google.golang.org/grpc" +) func main() { + grpcAddr := "{{ .Network.Grpc.Host }}:{{ .Network.Grpc.Port }}" + 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/templates/sprout/sprout.tmpl b/templates/sprout/sprout.tmpl new file mode 100644 index 000000000..1ec3e592e --- /dev/null +++ b/templates/sprout/sprout.tmpl @@ -0,0 +1,23 @@ +organization: mycompany +name: {{.}} +description: +git-repo: github.com/yourrepo +docker-repo: +maintainers: +# - name: bob +# email: bob@test.com + +network: + grpc: + host: 0.0.0.0 + port: 3000 + http: + enabled: true + port: 8080 + graphql: + enabled: true + port: 8082 + +services: + - name: helloworld + description: Hello world!. diff --git a/templator/templator.go b/templator/templator.go index 84afcbeb7..73250f1f5 100644 --- a/templator/templator.go +++ b/templator/templator.go @@ -1,21 +1,21 @@ package templator import ( - "github.com/gobuffalo/packr/v2" "github.com/commitdev/sprout/util" + "github.com/gobuffalo/packr/v2" "text/template" ) type GoTemplator struct { - GoMain *template.Template - GoMod *template.Template - GoServer *template.Template + GoMain *template.Template + GoMod *template.Template + GoModIDL *template.Template + GoServer *template.Template GoHealthServer *template.Template - } type Templator struct { - Sprout *template.Template + Sprout *template.Template ProtoToolTemplate *template.Template ProtoHealthTemplate *template.Template Go *GoTemplator @@ -32,7 +32,7 @@ func NewTemplator(box *packr.Box) *Templator { ProtoToolTemplate: protoToolTemplate, ProtoHealthTemplate: protoHealthTemplate, Go: NewGoTemplator(box), - Sprout: NewSproutTemplator(box), + Sprout: NewSproutTemplator(box), } } @@ -46,13 +46,17 @@ func NewGoTemplator(box *packr.Box) *GoTemplator { goModTemplateSource, _ := box.FindString("golang/go_mod.tmpl") goModTemplate, _ := template.New("GoModTemplate").Parse(goModTemplateSource) + goModIDLTemplateSource, _ := box.FindString("golang/go_mod_idl.tmpl") + goModIDLTemplate, _ := template.New("GoModTemplate").Parse(goModIDLTemplateSource) + goMainTemplateSource, _ := box.FindString("golang/main.tmpl") - goMainTemplate, _ := template.New("GoModTemplate").Parse(goMainTemplateSource) + goMainTemplate, _ := template.New("GoMainTemplate").Parse(goMainTemplateSource) return &GoTemplator{ - GoMain: goMainTemplate, - GoMod: goModTemplate, - GoServer: goServerTemplate, + GoMain: goMainTemplate, + GoMod: goModTemplate, + GoModIDL: goModIDLTemplate, + GoServer: goServerTemplate, GoHealthServer: goHealthServerTemplate, } @@ -64,4 +68,3 @@ func NewSproutTemplator(box *packr.Box) *template.Template { return template } - diff --git a/util/util.go b/util/util.go index e2f9b9c83..68646c046 100644 --- a/util/util.go +++ b/util/util.go @@ -1,9 +1,9 @@ package util import ( - "text/template" - "strings" "os" + "strings" + "text/template" ) func CreateDirIfDoesNotExist(path string) error {