From 792c96ff799e83ecbfbb079502b06d711cacfab4 Mon Sep 17 00:00:00 2001 From: dyma solovei Date: Wed, 27 Nov 2024 15:38:50 +0100 Subject: [PATCH] feat: add overriden MigratorOptions to the template file on init --- extra/buncli/buncli.go | 1 + extra/buncli/init.go | 119 +++++++++++++++++++++++++++++++-------- extra/buncli/migrator.go | 8 +-- migrate/auto.go | 4 +- migrate/migrator.go | 8 +-- 5 files changed, 105 insertions(+), 35 deletions(-) diff --git a/extra/buncli/buncli.go b/extra/buncli/buncli.go index eb970ac84..06578cde7 100644 --- a/extra/buncli/buncli.go +++ b/extra/buncli/buncli.go @@ -59,6 +59,7 @@ type Config struct { DB *bun.DB AutoMigrator *migrate.AutoMigrator Migrations *migrate.Migrations + MigratorOptions []migrate.MigratorOption MigrateOptions []migrate.MigrationOption GoMigrationOptions []migrate.GoMigrationOption } diff --git a/extra/buncli/init.go b/extra/buncli/init.go index 2874c476c..2f92415e4 100644 --- a/extra/buncli/init.go +++ b/extra/buncli/init.go @@ -30,6 +30,8 @@ func CmdInit() *cli.Command { Flags: []cli.Flag{ flagDSN, flagDriver, + flagTable, + flagLocks, flagBinary, flagMigrations, flagPluginMode, @@ -63,32 +65,45 @@ var ( flagDriver = &cli.StringFlag{ Name: "driver", - Usage: "database driver", + Usage: strings.Join(supportedDrivers, ", "), } - flagPluginMode = &cli.BoolFlag{ - Name: "p", - Aliases: []string{"plugin"}, - Usage: "create a 'main' package to be used as a plugin", + flagTable = &cli.StringFlag{ + Name: "table", + Usage: "override migrations table name", + Value: migrate.DefaultTable, + } + + flagLocks = &cli.StringFlag{ + Name: "locks", + Usage: "override locks table name", + Value: migrate.DefaultLocksTable, } flagBinary = &cli.StringFlag{ Name: "b", Aliases: []string{"binary"}, - Usage: "name of the cmd/ binary", + Usage: "override cmd/ `ENTRYPOINT` name", Value: defaultBin, } flagMigrations = &cli.StringFlag{ Name: "m", - Aliases: []string{"migrations-package"}, - Usage: "name of the migrations package", + Aliases: []string{"migrations-directory"}, + Usage: "override migrations `DIR`", Value: defaultMigrations, } + + flagPluginMode = &cli.BoolFlag{ + Name: "P", + Aliases: []string{"plugin"}, + Usage: "create a 'main' package to be used as a plugin", + DisableDefaultText: true, + } ) func runInit(ctx *cli.Context, c *Config) error { - m := migrate.NewMigrator(c.DB, c.Migrations) + m := migrate.NewMigrator(c.DB, c.Migrations, c.MigratorOptions...) if err := m.Init(ctx.Context); err != nil { return err } @@ -96,13 +111,14 @@ func runInit(ctx *cli.Context, c *Config) error { loc := ctx.Args().Get(0) binName := flagBinary.Get(ctx) migrationsDir := flagMigrations.Get(ctx) + migratorOpts := stringNonDefaultMigratorOptions(ctx) var b interface{ Bootstrap() error } switch { default: - b = &normalMode{Loc: loc, Binary: binName, Migrations: migrationsDir} + b = &normalMode{Loc: loc, Binary: binName, Migrations: migrationsDir, MigratorOptions: migratorOpts} case flagPluginMode.Get(ctx): - b = &pluginMode{Loc: loc, Migrations: migrationsDir} + b = &pluginMode{Loc: loc, Migrations: migrationsDir, MigratorOptions: migratorOpts} } return b.Bootstrap() @@ -118,13 +134,26 @@ func fromCLI(ctx *cli.Context) (*Config, error) { if err != nil { return nil, err } - return &Config{DB: db, Migrations: migrate.NewMigrations()}, nil + return &Config{ + DB: db, + MigratorOptions: addNonDefaultMigratorOptions(ctx), + Migrations: migrate.NewMigrations(), + }, nil } +// normalMode creates the default migrations directory and a cmd/ entrypoint. +// +// . +// └── cmd +// └── bun +// ├── main.go +// └── migrations +// └── main.go type normalMode struct { - Loc string - Binary string - Migrations string + Loc string + Binary string + Migrations string + MigratorOptions []string } const entrypointTemplate = `package main @@ -146,14 +175,15 @@ func main() { // TODO: configure AutoMigrator var _ /* auto */ migrate.AutoMigrator - cfg := buncli.Config{ + cfg := &buncli.Config{ RootName: %q, // DB: db, // AutoMigrator: auto, - Migrations: migrations.Migrations, + Migrations: migrations.Migrations, + MigratorOptions: []migrate.MigratorOption{%s}, } - if err := buncli.Run(os.Args, &cfg); err != nil { + if err := buncli.Run(os.Args, cfg); err != nil { panic(err) } } @@ -175,11 +205,13 @@ func init() { func (n *normalMode) Bootstrap() error { // Create cmd/bun/main.go entrypoint binDir := path.Join(n.Loc, "cmd", n.Binary) - modPath, err := n.pkgMigrations(binDir) + modPath, err := n.migrationsImportPath(binDir) if err != nil { return err } - if err := writef(binDir, maingo, entrypointTemplate, modPath, n.Binary); err != nil { + + migratorOpts := strings.Join(n.MigratorOptions, ", ") + if err := writef(binDir, maingo, entrypointTemplate, modPath, n.Binary, migratorOpts); err != nil { return err } @@ -191,7 +223,7 @@ func (n *normalMode) Bootstrap() error { return nil } -func (n *normalMode) pkgMigrations(binDir string) (string, error) { +func (n *normalMode) migrationsImportPath(binDir string) (string, error) { modPath, err := getModPath() if err != nil { return "", err @@ -199,9 +231,15 @@ func (n *normalMode) pkgMigrations(binDir string) (string, error) { return path.Join(modPath, strings.TrimLeft(binDir, "."), n.Migrations), nil } +// pluginMode creates a layout of a project that can be compiled and imported as a plugin. +// +// . +// └── migrations +// └── main.go type pluginMode struct { - Loc string - Migrations string + Loc string + Migrations string + MigratorOptions []string } var pluginTemplate = `package main @@ -229,14 +267,16 @@ func init() { Config = &buncli.Config{ // DB: db, // AutoMigrator: auto, - Migrations: migrations, + Migrations: migrations, + MigratorOptions: []migrate.MigratorOption{%s}, } } ` func (p *pluginMode) Bootstrap() error { binDir := path.Join(p.Loc, p.Migrations) - if err := writef(binDir, maingo, pluginTemplate); err != nil { + migratorOpts := strings.Join(p.MigratorOptions, ", ") + if err := writef(binDir, maingo, pluginTemplate, migratorOpts); err != nil { return err } return nil @@ -321,3 +361,32 @@ func newDB(ctx *cli.Context) (*bun.DB, error) { return bun.NewDB(sqlDB, dialect), nil } + +// addNonDefaultMigratorOptions collects migrate.MigratorOption for every value overriden by a command-line flag. +func addNonDefaultMigratorOptions(ctx *cli.Context) []migrate.MigratorOption { + var opts []migrate.MigratorOption + + if t := flagTable.Get(ctx); ctx.IsSet(flagTable.Name) { + opts = append(opts, migrate.WithTableName(t)) + } + + if l := flagLocks.Get(ctx); ctx.IsSet(flagLocks.Name) { + opts = append(opts, migrate.WithLocksTableName(l)) + } + return opts +} + +// stringNonDefaultMigratorOptions is like addNonDefaultMigratorOptions, but stringifies options so they can be written to a file. +func stringNonDefaultMigratorOptions(ctx *cli.Context) []string { + var opts []string + + if t := flagTable.Get(ctx); ctx.IsSet(flagTable.Name) { + opts = append(opts, fmt.Sprintf("migrate.WithTableName(%q)", t)) + } + + if l := flagLocks.Get(ctx); ctx.IsSet(flagLocks.Name) { + opts = append(opts, fmt.Sprintf("migrate.WithLocksTableName(%q)", l)) + } + + return opts +} diff --git a/extra/buncli/migrator.go b/extra/buncli/migrator.go index c2450e8fe..8ef0ea051 100644 --- a/extra/buncli/migrator.go +++ b/extra/buncli/migrator.go @@ -17,7 +17,7 @@ func CmdMigrate(c *Config) *cli.Command { } func runMigrate(ctx *cli.Context, c *Config) error { - m := migrate.NewMigrator(c.DB, c.Migrations) + m := migrate.NewMigrator(c.DB, c.Migrations, c.MigratorOptions...) _, err := m.Migrate(ctx.Context, c.MigrateOptions...) return err } @@ -34,7 +34,7 @@ func CmdRollback(c *Config) *cli.Command { } func runRollback(ctx *cli.Context, c *Config) error { - m := migrate.NewMigrator(c.DB, c.Migrations) + m := migrate.NewMigrator(c.DB, c.Migrations, c.MigratorOptions...) _, err := m.Rollback(ctx.Context, c.MigrateOptions...) return err } @@ -90,7 +90,7 @@ var ( func runCreate(ctx *cli.Context, c *Config) error { var err error - m := migrate.NewMigrator(c.DB, c.Migrations) + m := migrate.NewMigrator(c.DB, c.Migrations, c.MigratorOptions...) name := ctx.Args().First() if createGo { @@ -118,6 +118,6 @@ func CmdUnlock(c *Config) *cli.Command { } func runUnlock(ctx *cli.Context, c *Config) error { - m := migrate.NewMigrator(c.DB, c.Migrations) + m := migrate.NewMigrator(c.DB, c.Migrations, c.MigratorOptions...) return m.Unlock(ctx.Context) } diff --git a/migrate/auto.go b/migrate/auto.go index 16804cd99..e56ca2a64 100644 --- a/migrate/auto.go +++ b/migrate/auto.go @@ -140,8 +140,8 @@ type AutoMigrator struct { func NewAutoMigrator(db *bun.DB, opts ...AutoMigratorOption) (*AutoMigrator, error) { am := &AutoMigrator{ db: db, - table: defaultTable, - locksTable: defaultLocksTable, + table: DefaultTable, + locksTable: DefaultLocksTable, schemaName: db.Dialect().DefaultSchema(), } diff --git a/migrate/migrator.go b/migrate/migrator.go index d5a72aec0..7466fbe27 100644 --- a/migrate/migrator.go +++ b/migrate/migrator.go @@ -13,8 +13,8 @@ import ( ) const ( - defaultTable = "bun_migrations" - defaultLocksTable = "bun_migration_locks" + DefaultTable = "bun_migrations" + DefaultLocksTable = "bun_migration_locks" ) type MigratorOption func(m *Migrator) @@ -59,8 +59,8 @@ func NewMigrator(db *bun.DB, migrations *Migrations, opts ...MigratorOption) *Mi ms: migrations.ms, - table: defaultTable, - locksTable: defaultLocksTable, + table: DefaultTable, + locksTable: DefaultLocksTable, } for _, opt := range opts { opt(m)