From c44794443c5e91ad013d7840c11a9314522c417a Mon Sep 17 00:00:00 2001 From: Roman Zatonskiy Date: Wed, 12 Jul 2023 10:16:17 +0400 Subject: [PATCH] added new cmd command for create a new migration --- go.mod | 4 +- go.sum | 4 ++ internal/command/migrate_create.go | 102 +++++++++++++++++++++++++++++ migrate.go | 3 + 4 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 internal/command/migrate_create.go diff --git a/go.mod b/go.mod index d48f4c5..d9b405e 100644 --- a/go.mod +++ b/go.mod @@ -41,9 +41,11 @@ require ( github.com/subosito/gotenv v1.4.2 // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/sys v0.5.0 // indirect + golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect + golang.org/x/sys v0.10.0 // indirect golang.org/x/term v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect + golang.org/x/tools v0.11.0 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 50ada58..2f97864 100644 --- a/go.sum +++ b/go.sum @@ -528,6 +528,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= @@ -671,6 +672,7 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -749,6 +751,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/command/migrate_create.go b/internal/command/migrate_create.go new file mode 100644 index 0000000..4956be0 --- /dev/null +++ b/internal/command/migrate_create.go @@ -0,0 +1,102 @@ +// Copyright 2018 Sergey Novichkov. All rights reserved. +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. + +package command + +import ( + "context" + "errors" + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/gozix/di" + "github.com/spf13/cobra" + "go.uber.org/zap" +) + +const migrationFileExtension = "sql" + +// NewMigrateCreate is subcommand constructor. +func NewMigrateCreate(ctn di.Container) *cobra.Command { + return &cobra.Command{ + Use: "create", + Short: "Create named migration", + Long: `Normally each migration is run within a transaction. + However some SQL commands (for example creating an index concurrently in PostgreSQL) + cannot be executed inside a transaction. In order to execute such a command in a migration, + the migration can be run using the notransaction option https://github.com/rubenv/sql-migrate`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + return ctn.Call(func(ctx context.Context, logger *zap.Logger) (err error) { + var ( + name = args[0] + path = cmd.Flag("path").Value.String() + fileName string + ) + if !filepath.IsAbs(path) { + var appPath, ok = ctx.Value("app.path").(string) + if !ok { + return errors.New("app.path is undefined") + } + + path = filepath.Join(appPath, path) + } + + if fileName, err = create(path, name, migrationFileExtension); err != nil { + return err + } + + logger.Info("Created migration", zap.String("migration", fileName)) + + return nil + }) + }, + } +} + +func create(migrationDir string, name string, extension string) (string, error) { + var ( + fileName string + fileContent string + file *os.File + err error + ) + + fileName = filepath.Join( + filepath.Clean(migrationDir), + fmt.Sprintf("%s_%s.%s", + // version + strconv.FormatInt(time.Now().Unix(), 10), + name, + extension, + ), + ) + + fileContent = strings.Join([]string{ + "-- +migrate Up", + "-- SQL in section 'Up' is executed when this migration is applied", + "", + "", + "", + "-- +migrate Down", + "-- SQL section 'Down' is executed when this migration is rolled back", + "", + }, "\n") + + file, err = os.OpenFile(fileName, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666) + if err != nil { + return fileName, err + } + defer func() { + _ = file.Close() + }() + + _, err = file.WriteString(fileContent) + + return fileName, err +} diff --git a/migrate.go b/migrate.go index 0d533e8..a20bb53 100644 --- a/migrate.go +++ b/migrate.go @@ -109,6 +109,9 @@ func (b *Bundle) Build(builder di.Builder) error { di.Provide(command.NewMigrateUp, di.Tags{{ Name: tag, }}), + di.Provide(command.NewMigrateCreate, di.Tags{{ + Name: tag, + }}), ) }