Option '-s' causes CREATE to use sequential versioning

pull/215/head
Warren Nelson 2020-05-19 01:27:12 -05:00 committed by Warren Nelson
parent 2769ad7b55
commit 16a9d45b6e
No known key found for this signature in database
GPG Key ID: D8D3949E5A7FA082
4 changed files with 104 additions and 9 deletions

View File

@ -17,6 +17,7 @@ var (
help = flags.Bool("h", false, "print help")
version = flags.Bool("version", false, "print version")
certfile = flags.String("certfile", "", "file path to root CA's certificates in pem format (only support on mysql)")
sequential = flags.Bool("s", false, "use sequential numbering for new migrations")
)
func main() {
@ -30,6 +31,9 @@ func main() {
if *verbose {
goose.SetVerbose(true)
}
if *sequential {
goose.SetSequential(true)
}
goose.SetTableName(*table)
args := flags.Args()

View File

@ -16,9 +16,38 @@ type tmplVars struct {
CamelName string
}
var (
sequential = false
)
// SetSequential set whether to use sequential versioning instead of timestamp based versioning
func SetSequential(s bool) {
sequential = s
}
// Create writes a new blank migration file.
func CreateWithTemplate(db *sql.DB, dir string, tmpl *template.Template, name, migrationType string) error {
version := time.Now().Format(timestampFormat)
var version string
if sequential {
migrations, err := CollectMigrations(dir, minVersion, maxVersion)
if err != nil {
return err
}
vMigrations, err := migrations.versioned()
if err != nil {
return err
}
if last, err := vMigrations.Last(); err == nil {
version = fmt.Sprintf(seqVersionTemplate, last.Version+1)
} else {
version = fmt.Sprintf(seqVersionTemplate, int64(1))
}
} else {
version = time.Now().Format(timestampFormat)
}
filename := fmt.Sprintf("%v_%v.%v", version, snakeCase(name), migrationType)
if tmpl == nil {

55
create_test.go Normal file
View File

@ -0,0 +1,55 @@
package goose
import (
"fmt"
"io/ioutil"
"os"
"os/exec"
"strings"
"testing"
"time"
)
func TestSequential(t *testing.T) {
t.Parallel()
dir, err := ioutil.TempDir("", "tmptest")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir) // clean up
defer os.Remove("./bin/create-goose") // clean up
commands := []string{
"go build -o ./bin/create-goose ./cmd/goose",
fmt.Sprintf("./bin/create-goose -s -dir=%s create create_table", dir),
fmt.Sprintf("./bin/create-goose -s -dir=%s create add_users", dir),
fmt.Sprintf("./bin/create-goose -s -dir=%s create add_indices", dir),
fmt.Sprintf("./bin/create-goose -s -dir=%s create update_users", dir),
}
for _, cmd := range commands {
args := strings.Split(cmd, " ")
time.Sleep(1 * time.Second)
cmd := exec.Command(args[0], args[1:]...)
cmd.Env = os.Environ()
out, err := cmd.CombinedOutput()
if err != nil {
t.Fatalf("%s:\n%v\n\n%s", err, cmd, out)
}
}
files, err := ioutil.ReadDir(dir)
if err != nil {
t.Fatal(err)
}
// check that the files are in order
for i, f := range files {
expected := fmt.Sprintf("%05v", i+1)
if !strings.HasPrefix(f.Name(), expected) {
t.Errorf("failed to find %s prefix in %s", expected, f.Name())
}
}
}

9
fix.go
View File

@ -7,6 +7,8 @@ import (
"strings"
)
const seqVersionTemplate = "%05v"
func Fix(dir string) error {
migrations, err := CollectMigrations(dir, minVersion, maxVersion)
if err != nil {
@ -32,7 +34,12 @@ func Fix(dir string) error {
// fix filenames by replacing timestamps with sequential versions
for _, tsm := range tsMigrations {
oldPath := tsm.Source
newPath := strings.Replace(oldPath, fmt.Sprintf("%d", tsm.Version), fmt.Sprintf("%05v", version), 1)
newPath := strings.Replace(
oldPath,
fmt.Sprintf("%d", tsm.Version),
fmt.Sprintf(seqVersionTemplate, version),
1,
)
if err := os.Rename(oldPath, newPath); err != nil {
return err