Improved: simplify CLI commands register

This commit is contained in:
Aleksandr Soloshenko 2023-12-06 23:42:14 +07:00
parent 454d3154f7
commit 40cd5a7c37
9 changed files with 93 additions and 128 deletions

View File

@ -1,16 +1,11 @@
package cli
import "go.uber.org/fx"
type Executor any
type Args []string
type Command interface {
Cmd() string
Run(args ...string) error
}
var commands = map[string]Executor{}
func AsCommand(f any) any {
return fx.Annotate(
f,
fx.As(new(Command)),
fx.ResultTags(`group:"commands"`),
)
// Регистрирует консольную команду cmd с испольнителем executor
func Register(cmd string, executor Executor) {
commands[cmd] = executor
}

View File

@ -9,27 +9,24 @@ import (
var DefaultCommand = ""
var Module = fx.Module(
"cli",
fx.Decorate(func(log *zap.Logger) *zap.Logger {
return log.Named("cli")
}),
fx.Invoke(func(params Params) error {
cmd := DefaultCommand
args := []string{}
if len(os.Args) > 1 {
cmd = os.Args[1]
args = os.Args[2:]
}
func GetModule() fx.Option {
cmd := DefaultCommand
args := []string{}
if len(os.Args) > 1 {
cmd = os.Args[1]
}
for _, v := range params.Commands {
if v.Cmd() != cmd {
continue
}
executor, ok := commands[cmd]
if !ok {
return fx.Invoke(func(logger *zap.Logger, shut fx.Shutdowner) error {
logger.Error("Command is not supported", zap.String("cmd", cmd))
return shut.Shutdown()
})
}
return v.Run(args...)
}
params.Logger.Info("Command is not supported", zap.String("command", cmd))
return params.Shut.Shutdown()
}),
)
return fx.Module(
"cli",
fx.Supply(Args(args)),
fx.Invoke(executor),
)
}

View File

@ -1,14 +0,0 @@
package cli
import (
"go.uber.org/fx"
"go.uber.org/zap"
)
type Params struct {
fx.In
Logger *zap.Logger
Commands []Command `group:"commands"`
Shut fx.Shutdowner
}

View File

@ -14,26 +14,8 @@ type CommandMigrateParams struct {
Shut fx.Shutdowner
}
type CommandMigrate struct {
Logger *zap.Logger
DB *gorm.DB
Shut fx.Shutdowner
}
func NewCommandMigrate(params CommandMigrateParams) *CommandMigrate {
return &CommandMigrate{
Logger: params.Logger,
DB: params.DB,
Shut: params.Shut,
}
}
func (c *CommandMigrate) Cmd() string {
return "db:auto-migrate"
}
func (c *CommandMigrate) Run(args ...string) error {
err := c.DB.Transaction(func(tx *gorm.DB) error {
func AutoMigrate(params CommandMigrateParams) error {
err := params.DB.Transaction(func(tx *gorm.DB) error {
for _, v := range migrations {
if err := v(tx); err != nil {
return err
@ -45,7 +27,43 @@ func (c *CommandMigrate) Run(args ...string) error {
return err
}
c.Logger.Info("Migrations completed")
params.Logger.Info("Migrations completed")
return c.Shut.Shutdown()
return params.Shut.Shutdown()
}
// type CommandMigrate struct {
// Logger *zap.Logger
// DB *gorm.DB
// Shut fx.Shutdowner
// }
// func NewCommandMigrate(params CommandMigrateParams) *CommandMigrate {
// return &CommandMigrate{
// Logger: params.Logger,
// DB: params.DB,
// Shut: params.Shut,
// }
// }
// func (c *CommandMigrate) Cmd() string {
// return "db:auto-migrate"
// }
// func (c *CommandMigrate) Run(args ...string) error {
// err := c.DB.Transaction(func(tx *gorm.DB) error {
// for _, v := range migrations {
// if err := v(tx); err != nil {
// return err
// }
// }
// return nil
// })
// if err != nil {
// return err
// }
// c.Logger.Info("Migrations completed")
// return c.Shut.Shutdown()
// }

View File

@ -4,6 +4,7 @@ import (
"database/sql"
"io/fs"
"github.com/capcom6/sms-gateway/internal/infra/cli"
"github.com/pressly/goose/v3"
"go.uber.org/fx"
"go.uber.org/zap"
@ -20,6 +21,8 @@ func RegisterGoose(storage GooseStorage) {
type GooseMigrateParams struct {
fx.In
Args cli.Args
Config Config
Logger *zap.Logger
@ -27,54 +30,34 @@ type GooseMigrateParams struct {
Shut fx.Shutdowner
}
type GooseMigrate struct {
Config Config
DB *sql.DB
Logger *zap.Logger
Shut fx.Shutdowner
}
func NewGooseMigrate(params GooseMigrateParams) *GooseMigrate {
return &GooseMigrate{
Config: params.Config,
Logger: params.Logger,
DB: params.DB,
Shut: params.Shut,
}
}
func (c *GooseMigrate) Cmd() string {
return "db:migrate"
}
func (c *GooseMigrate) Run(args ...string) error {
func Migrate(params GooseMigrateParams) error {
cmd := "up"
if len(args) > 0 {
cmd = args[0]
if len(params.Args) > 0 {
cmd = params.Args[0]
}
if err := goose.SetDialect(c.Config.Dialect); err != nil {
if err := goose.SetDialect(params.Config.Dialect); err != nil {
return err
}
migrationsPath := "migrations/" + c.Config.Dialect
migrationsPath := "migrations/" + params.Config.Dialect
for _, fs := range gooseStorages {
goose.SetBaseFS(fs)
switch cmd {
case "up":
if err := goose.Up(c.DB, migrationsPath); err != nil {
if err := goose.Up(params.DB, migrationsPath); err != nil {
return err
}
case "down":
if err := goose.Down(c.DB, migrationsPath); err != nil {
if err := goose.Down(params.DB, migrationsPath); err != nil {
return err
}
}
}
c.Logger.Info("Migrations completed")
params.Logger.Info("Migrations completed")
return c.Shut.Shutdown()
return params.Shut.Shutdown()
}

View File

@ -14,7 +14,10 @@ var Module = fx.Module(
fx.Provide(
New,
NewSQL,
cli.AsCommand(NewCommandMigrate),
cli.AsCommand(NewGooseMigrate),
),
)
func init() {
cli.Register("db:auto-migrate", AutoMigrate)
cli.Register("db:migrate", Migrate)
}

View File

@ -17,39 +17,19 @@ type RunServerParams struct {
LC fx.Lifecycle
}
type RunServer struct {
Config Config
App *fiber.App
Logger *zap.Logger
LC fx.Lifecycle
}
func NewRunServer(params RunServerParams) *RunServer {
return &RunServer{
Config: configDefault(params.Config),
App: params.App,
Logger: params.Logger,
LC: params.LC,
}
}
func (c *RunServer) Cmd() string {
return "http:run"
}
func (c *RunServer) Run(args ...string) error {
func Run(params RunServerParams) error {
go func() {
c.Logger.Info("Starting server...")
params.Logger.Info("Starting server...")
err := c.App.Listen(c.Config.Listen)
err := params.App.Listen(params.Config.Listen)
if err != nil {
c.Logger.Error("Error starting server", zap.Error(err))
params.Logger.Error("Error starting server", zap.Error(err))
}
}()
c.LC.Append(fx.Hook{
params.LC.Append(fx.Hook{
OnStop: func(ctx context.Context) error {
return c.App.ShutdownWithContext(ctx)
return params.App.ShutdownWithContext(ctx)
},
})

View File

@ -13,6 +13,9 @@ var Module = fx.Module(
}),
fx.Provide(
New,
cli.AsCommand(NewRunServer),
),
)
func init() {
cli.Register("http:run", Run)
}

View File

@ -20,7 +20,6 @@ import (
var Module = fx.Module(
"server",
logger.Module,
cli.Module,
appconfig.Module,
http.Module,
validator.Module,
@ -34,6 +33,7 @@ var Module = fx.Module(
func Run() {
cli.DefaultCommand = "http:run"
fx.New(
cli.GetModule(),
Module,
fx.WithLogger(func(logger *zap.Logger) fxevent.Logger {
logOption := fxevent.ZapLogger{Logger: logger}