1
0
mirror of https://github.com/go-micro/go-micro.git synced 2025-05-25 21:53:14 +02:00
2021-11-01 14:34:09 +00:00

205 lines
4.7 KiB
Go

package new
import (
"fmt"
"os"
"path"
"strings"
"github.com/urfave/cli/v2"
mcli "go-micro.dev/v4/cmd/micro/cli"
"go-micro.dev/v4/cmd/micro/generator"
tmpl "go-micro.dev/v4/cmd/micro/generator/template"
)
var flags []cli.Flag = []cli.Flag{
&cli.BoolFlag{
Name: "jaeger",
Usage: "Generate Jaeger tracer files",
},
&cli.BoolFlag{
Name: "kubernetes",
Usage: "Generate Kubernetes resource files",
},
&cli.BoolFlag{
Name: "skaffold",
Usage: "Generate Skaffold files",
},
}
// NewCommand returns a new new cli command.
func init() {
mcli.Register(&cli.Command{
Name: "new",
Usage: "Create a project template",
Subcommands: []*cli.Command{
{
Name: "client",
Usage: "Create a client template, e.g. " + mcli.App().Name + " new client [github.com/auditemarlow/]helloworld",
Action: Client,
Flags: flags,
},
{
Name: "function",
Usage: "Create a function template, e.g. " + mcli.App().Name + " new function [github.com/auditemarlow/]helloworld",
Action: Function,
Flags: flags,
},
{
Name: "service",
Usage: "Create a service template, e.g. " + mcli.App().Name + " new service [github.com/auditemarlow/]helloworld",
Action: Service,
Flags: flags,
},
},
})
}
func Client(ctx *cli.Context) error {
return createProject(ctx, "client")
}
// Function creates a new function project template. Exits on error.
func Function(ctx *cli.Context) error {
return createProject(ctx, "function")
}
// Service creates a new service project template. Exits on error.
func Service(ctx *cli.Context) error {
return createProject(ctx, "service")
}
func createProject(ctx *cli.Context, pt string) error {
arg := ctx.Args().First()
if len(arg) == 0 {
return cli.ShowSubcommandHelp(ctx)
}
client := pt == "client"
name, vendor := getNameAndVendor(arg)
dir := name
if client {
dir += "-client"
}
if path.IsAbs(dir) {
fmt.Println("must provide a relative path as service name")
return nil
}
if _, err := os.Stat(dir); !os.IsNotExist(err) {
return fmt.Errorf("%s already exists", dir)
}
fmt.Printf("creating %s %s\n", pt, name)
g := generator.New(
generator.Service(name),
generator.Vendor(vendor),
generator.Directory(dir),
generator.Client(client),
generator.Jaeger(ctx.Bool("jaeger")),
generator.Skaffold(ctx.Bool("skaffold")),
)
files := []generator.File{
{".dockerignore", tmpl.DockerIgnore},
{".gitignore", tmpl.GitIgnore},
{"Dockerfile", tmpl.Dockerfile},
{"Makefile", tmpl.Makefile},
{"go.mod", tmpl.Module},
}
switch pt {
case "client":
files = append(files, []generator.File{
{"main.go", tmpl.MainCLT},
}...)
case "function":
files = append(files, []generator.File{
{"handler/" + name + ".go", tmpl.HandlerFNC},
{"main.go", tmpl.MainFNC},
{"proto/" + name + ".proto", tmpl.ProtoFNC},
}...)
case "service":
files = append(files, []generator.File{
{"handler/" + name + ".go", tmpl.HandlerSRV},
{"main.go", tmpl.MainSRV},
{"proto/" + name + ".proto", tmpl.ProtoSRV},
}...)
default:
return fmt.Errorf("%s project type not supported", pt)
}
if ctx.Bool("kubernetes") || ctx.Bool("skaffold") {
files = append(files, []generator.File{
{"plugins.go", tmpl.Plugins},
{"resources/clusterrole.yaml", tmpl.KubernetesClusterRole},
{"resources/configmap.yaml", tmpl.KubernetesEnv},
{"resources/deployment.yaml", tmpl.KubernetesDeployment},
{"resources/rolebinding.yaml", tmpl.KubernetesRoleBinding},
}...)
}
if ctx.Bool("skaffold") {
files = append(files, []generator.File{
{"skaffold.yaml", tmpl.SkaffoldCFG},
}...)
}
if err := g.Generate(files); err != nil {
return err
}
var comments []string
if client {
comments = clientComments(name, dir)
} else {
comments = protoComments(name, dir)
}
for _, comment := range comments {
fmt.Println(comment)
}
return nil
}
func clientComments(name, dir string) []string {
return []string{
"\ninstall dependencies:",
"\ncd " + dir,
"make update tidy",
}
}
func protoComments(name, dir string) []string {
return []string{
"\ndownload protoc zip packages (protoc-$VERSION-$PLATFORM.zip) and install:",
"\nvisit https://github.com/protocolbuffers/protobuf/releases/latest",
"\ndownload protobuf for go-micro:",
"\ngo get -u google.golang.org/protobuf/proto",
"go install github.com/golang/protobuf/protoc-gen-go@latest",
"go install github.com/asim/go-micro/cmd/protoc-gen-micro/v4@latest",
"\ncompile the proto file " + name + ".proto and install dependencies:",
"\ncd " + dir,
"make proto update tidy",
}
}
func getNameAndVendor(s string) (string, string) {
var n string
var v string
if i := strings.LastIndex(s, "/"); i == -1 {
n = s
v = ""
} else {
n = s[i+1:]
v = s[:i+1]
}
return n, v
}