github.com/profzone/eden-framework@v1.0.10/internal/generator/service_generator.go (about)

     1  package generator
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/profzone/eden-framework/internal/generator/files"
     6  	"github.com/sirupsen/logrus"
     7  	"os"
     8  	"path"
     9  )
    10  
    11  type ServiceOption struct {
    12  	FrameworkVersion string `survey:"framework_version"`
    13  	Name             string
    14  	PackageName      string      `survey:"package_name"`
    15  	DatabaseSupport  expressBool `survey:"database_support"`
    16  	ApolloSupport    expressBool `survey:"apollo_support"`
    17  
    18  	Group           string
    19  	Owner           string
    20  	Desc            string
    21  	Version         string
    22  	ProgramLanguage string `survey:"project_language"`
    23  	Workflow        string
    24  }
    25  
    26  type ServiceGenerator struct {
    27  	opt ServiceOption
    28  }
    29  
    30  func NewServiceGenerator(opt ServiceOption) *ServiceGenerator {
    31  	s := &ServiceGenerator{
    32  		opt: opt,
    33  	}
    34  
    35  	return s
    36  }
    37  
    38  func (s *ServiceGenerator) Load(path string) {
    39  }
    40  
    41  func (s *ServiceGenerator) Pick() {
    42  }
    43  
    44  func (s *ServiceGenerator) Output(outputPath string) Outputs {
    45  	outputs := Outputs{}
    46  
    47  	// create service directory
    48  	p := path.Join(outputPath, s.opt.Name)
    49  	createPath(p)
    50  
    51  	// go.mod file
    52  	mod := files.NewModFile(s.opt.PackageName, "1.14")
    53  	mod.AddReplace("k8s.io/client-go", "", "k8s.io/client-go", "v0.18.8")
    54  	mod.AddRequired("github.com/profzone/eden-framework", s.opt.FrameworkVersion)
    55  	mod.AddRequired("github.com/sirupsen/logrus", "v1.6.0")
    56  	mod.AddRequired("github.com/spf13/cobra", "v0.0.5")
    57  	outputs.WriteFile(path.Join(p, "go.mod"), mod.String())
    58  
    59  	err := os.Chdir(p)
    60  	if err != nil {
    61  		logrus.Panicf("os.Chdir failed: %v", err)
    62  	}
    63  
    64  	// apollo config file
    65  	if s.opt.ApolloSupport {
    66  		apolloFile := s.createApolloFile()
    67  		outputs.WriteFile(path.Join(p, "internal/global/apollo.go"), apolloFile.String())
    68  	}
    69  
    70  	// db config file
    71  	if s.opt.DatabaseSupport {
    72  		dbFile := s.createDbConfigFile()
    73  		outputs.WriteFile(path.Join(p, "internal/databases/db.go"), dbFile.String())
    74  	}
    75  
    76  	// general config file
    77  	configFile := s.createConfigFile(p)
    78  	outputs.WriteFile(path.Join(p, "internal/global/config.go"), configFile.String())
    79  
    80  	// router v0 root files
    81  	routerV0RootFile := s.createRouterV0RootFile()
    82  	outputs.WriteFile(path.Join(p, "internal/routers/v0/root.go"), routerV0RootFile.String())
    83  
    84  	// router root files
    85  	routerRootFile := s.createRouterRootFile(p)
    86  	outputs.WriteFile(path.Join(p, "internal/routers/root.go"), routerRootFile.String())
    87  
    88  	// main file
    89  	mainFile := s.createMainFile(p)
    90  	outputs.Add(path.Join(p, "cmd/main.go"), mainFile.String())
    91  
    92  	return outputs
    93  }
    94  
    95  func createPath(p string) {
    96  	if !PathExist(p) {
    97  		err := os.Mkdir(p, 0755)
    98  		if err != nil {
    99  			logrus.Panicf("os.Mkdir failed: %v, path: %s", err, p)
   100  		}
   101  		return
   102  	}
   103  	logrus.Panicf("os.Stat exist: %s", p)
   104  }
   105  
   106  func (s *ServiceGenerator) createApolloFile() *files.GoFile {
   107  	file := files.NewGoFile("global")
   108  	file.WithBlock(fmt.Sprintf(`
   109  var ApolloConfig = {{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/conf/apollo" "" }}.ApolloBaseConfig{
   110  	AppId:            "%s",
   111  	Host:             "localhost:8080",
   112  	BackupConfigPath: "./apollo_config",
   113  	Cluster:          "default",
   114  }
   115  `, s.opt.Name))
   116  
   117  	return file
   118  }
   119  
   120  func (s *ServiceGenerator) createDbConfigFile() *files.GoFile {
   121  	file := files.NewGoFile("databases")
   122  	file.WithBlock(`
   123  var Config = struct {
   124  	DBTest *{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/sqlx" "" }}.Database
   125  }{
   126  	DBTest: &{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/sqlx" "" }}.Database{},
   127  }
   128  `)
   129  
   130  	return file
   131  }
   132  
   133  func (s *ServiceGenerator) createConfigFile(cwd string) *files.GoFile {
   134  	file := files.NewGoFile("global")
   135  
   136  	file.WithBlock(`
   137  var Config = struct {
   138  	LogLevel {{ .UseWithoutAlias "github.com/sirupsen/logrus" "" }}.Level
   139  `)
   140  	if s.opt.DatabaseSupport {
   141  		file.WithBlock(`
   142  	// db
   143  	MasterDB *{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/client/mysql" "" }}.MySQL
   144  	SlaveDB  *{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/client/mysql" "" }}.MySQL
   145  `)
   146  	}
   147  	file.WithBlock(`
   148  	// administrator
   149  	GRPCServer *{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/courier/transport_grpc" "" }}.ServeGRPC
   150  	HTTPServer *{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/courier/transport_http" "" }}.ServeHTTP
   151  }{
   152  	LogLevel: {{ .UseWithoutAlias "github.com/sirupsen/logrus" "" }}.DebugLevel,
   153  `)
   154  	if s.opt.DatabaseSupport {
   155  		dbUse := path.Join(s.opt.PackageName, "internal/databases")
   156  		dbPath := path.Join(cwd, "internal/databases")
   157  		file.WithBlock(fmt.Sprintf(`
   158  	MasterDB: &{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/client/mysql" "" }}.MySQL{Database: {{ .UseWithoutAlias "%s" "%s" }}.Config.DBTest},
   159  	SlaveDB:  &{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/client/mysql" "" }}.MySQL{Database: {{ .UseWithoutAlias "%s" "%s" }}.Config.DBTest},
   160  `, dbUse, dbPath, dbUse, dbPath))
   161  	}
   162  	file.WithBlock(`
   163  	GRPCServer: &{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/courier/transport_grpc" "" }}.ServeGRPC{
   164  		Port: 8900,
   165  	},
   166  	HTTPServer: &{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/courier/transport_http" "" }}.ServeHTTP{
   167  		Port:     8800,
   168  		WithCORS: true,
   169  	},
   170  }
   171  `)
   172  
   173  	return file
   174  }
   175  
   176  func (s *ServiceGenerator) createRouterV0RootFile() *files.GoFile {
   177  	file := files.NewGoFile("v0")
   178  	file.WithBlock(`
   179  var Router = {{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/courier" "" }}.NewRouter(V0Router{})
   180  
   181  type V0Router struct {
   182  	{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/courier" "" }}.EmptyOperator
   183  }
   184  
   185  func (V0Router) Path() string {
   186  	return "/v0"
   187  }
   188  `)
   189  
   190  	return file
   191  }
   192  
   193  func (s *ServiceGenerator) createRouterRootFile(cwd string) *files.GoFile {
   194  	pkgPath := path.Join(s.opt.PackageName, "internal/routers/v0")
   195  	filePath := path.Join(cwd, "internal/routers/v0")
   196  
   197  	file := files.NewGoFile("routers")
   198  	file.WithBlock(fmt.Sprintf(`
   199  var Router = {{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/courier" "" }}.NewRouter(RootRouter{})
   200  
   201  func init() {
   202  	Router.Register({{ .UseWithoutAlias "%s" "%s" }}.Router)
   203  }
   204  
   205  type RootRouter struct {
   206  	{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/courier" "" }}.EmptyOperator
   207  }
   208  
   209  func (RootRouter) Path() string {
   210  	return "/%s"
   211  }
   212  `, pkgPath, filePath, GetServiceName(s.opt.Name)))
   213  
   214  	return file
   215  }
   216  
   217  func (s *ServiceGenerator) createMainFile(cwd string) *files.GoFile {
   218  	globalPkgPath := path.Join(s.opt.PackageName, "internal/global")
   219  	globalFilePath := path.Join(cwd, "internal/global")
   220  
   221  	file := files.NewGoFile("main")
   222  	file.WithBlock(`
   223  func main() {
   224  	app := application.NewApplication(runner`)
   225  
   226  	if s.opt.ApolloSupport {
   227  		file.WithBlock(fmt.Sprintf(`, {{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/application" "" }}.WithApollo(&{{ .UseWithoutAlias "%s" "%s" }}.ApolloConfig)`, globalPkgPath, globalFilePath))
   228  	}
   229  
   230  	file.WithBlock(fmt.Sprintf(`, application.WithConfig(&{{ .UseWithoutAlias "%s" "%s" }}.Config`, globalPkgPath, globalFilePath))
   231  
   232  	if s.opt.DatabaseSupport {
   233  		pkgPath := path.Join(s.opt.PackageName, "internal/databases")
   234  		filePath := path.Join(cwd, "internal/databases")
   235  		file.WithBlock(fmt.Sprintf(`, &{{ .UseWithoutAlias "%s" "%s" }}.Config`, pkgPath, filePath))
   236  	}
   237  
   238  	file.WithBlock(`))
   239  	app.AddCommand(&{{ .UseWithoutAlias "github.com/spf13/cobra" "" }}.Command{
   240  		Use: "migrate",
   241  		Run: func(cmd *{{ .UseWithoutAlias "github.com/spf13/cobra" "" }}.Command, args []string) {
   242  			migrate(args)
   243  		},
   244  	})
   245  
   246  	app.Start()
   247  }
   248  `)
   249  
   250  	routerPkgPath := path.Join(s.opt.PackageName, "internal/routers")
   251  	routerFilePath := path.Join(cwd, "internal/routers")
   252  
   253  	file.WithBlock(fmt.Sprintf(`
   254  func runner(ctx *{{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/context" "" }}.WaitStopContext) error {
   255  	{{ .UseWithoutAlias "github.com/sirupsen/logrus" "" }}.SetLevel({{ .UseWithoutAlias "%s" "%s" }}.Config.LogLevel)
   256  	go {{ .UseWithoutAlias "%s" "%s" }}.Config.GRPCServer.Serve({{ .UseWithoutAlias "%s" "%s" }}.Router)
   257  	return {{ .UseWithoutAlias "%s" "%s" }}.Config.HTTPServer.Serve({{ .UseWithoutAlias "%s" "%s" }}.Router)
   258  }
   259  `, globalPkgPath, globalFilePath, globalPkgPath, globalFilePath, routerPkgPath, routerFilePath, globalPkgPath, globalFilePath, routerPkgPath, routerFilePath))
   260  
   261  	file.WithBlock(fmt.Sprintf(`
   262  func migrate(args []string) {
   263  	if err := {{ .UseWithoutAlias "github.com/profzone/eden-framework/pkg/sqlx/migration" "" }}.Migrate({{ .UseWithoutAlias "%s" "%s" }}.Config.MasterDB, nil); err != nil {
   264  		panic(err)
   265  	}
   266  }
   267  `, globalPkgPath, globalFilePath))
   268  
   269  	return file
   270  }