Repository: ariga/atlas
Pull request #931 (2022-07-11 00:25:22)

cmd/atlascmd: add supported format for dbmate
to use github.com/amacneil/dbmate easily

Re-open #899 

a8m: Tests fail on 1.17 because it does not recognize the `go.work` file and does not use the `replace` directive there. 

I'm OK with running the unit tests only on 1.18 only. @rotemtam, @masseelch - WDYT?

Patch:
diff --git a/cmd/atlas/internal/cmdapi/migrate.go b/cmd/atlas/internal/cmdapi/migrate.go
index 5fa29837..513389fd 100644
--- a/cmd/atlas/internal/cmdapi/migrate.go
+++ b/cmd/atlas/internal/cmdapi/migrate.go
@@ -612,6 +612,7 @@ const (
 	formatGoose         = "goose"
 	formatFlyway        = "flyway"
 	formatLiquibase     = "liquibase"
+	formatDbmate        = "dbmate"
 )
 
 func formatter() (migrate.Formatter, error) {
@@ -626,6 +627,8 @@ func formatter() (migrate.Formatter, error) {
 		return sqltool.FlywayFormatter, nil
 	case formatLiquibase:
 		return sqltool.LiquibaseFormatter, nil
+	case formatDbmate:
+		return sqltool.DbmateFormatter, nil
 	default:
 		return nil, fmt.Errorf("unknown format %q", MigrateFlags.Format)
 	}
diff --git a/sql/sqltool/tool.go b/sql/sqltool/tool.go
index 08d4cda4..5e6fa02c 100644
--- a/sql/sqltool/tool.go
+++ b/sql/sqltool/tool.go
@@ -51,6 +51,14 @@ var (
 {{ with $change.Reverse }}--rollback: {{ . }};{{ end }}
 {{ end }}`,
 	)
+	// DbmateFormatter returns a migrate.Formatter compatible with amacneil/dbmate.
+	DbmateFormatter = templateFormatter(
+		"{{ now }}{{ with .Name }}_{{ . }}{{ end }}.sql",
+		`-- migrate:up
+{{ range .Changes }}{{ with .Comment }}-- {{ println . }}{{ end }}{{ printf "%s;\n" .Cmd }}{{ end }}
+-- migrate:down
+{{ range rev .Changes }}{{ if .Reverse }}{{ with .Comment }}-- reverse: {{ println . }}{{ end }}{{ printf "%s;\n" .Reverse }}{{ end }}{{ end }}`,
+	)
 )
 
 // GolangMigrateDir wraps a migrate.LocalDir and provides a migrate.Scanner


Test patch:
diff --git a/cmd/atlas/internal/cmdapi/migrate_test.go b/cmd/atlas/internal/cmdapi/migrate_test.go
index 10ab7ea8..7489add6 100644
--- a/cmd/atlas/internal/cmdapi/migrate_test.go
+++ b/cmd/atlas/internal/cmdapi/migrate_test.go
@@ -236,6 +236,12 @@ func TestMigrate_New(t *testing.T) {
 	require.FileExists(t, filepath.Join(p, v+"_liquibase.sql"))
 	require.Equal(t, 9, countFiles(t, p))
 
+	s, err = runCmd(Root, "migrate", "new", "dbmate", "--dir", "file://"+p, "--format", formatDbmate)
+	require.Zero(t, s)
+	require.NoError(t, err)
+	require.FileExists(t, filepath.Join(p, v+"_dbmate.sql"))
+	require.Equal(t, 10, countFiles(t, p))
+
 	f := filepath.Join("testdata", "mysql", "new.sql")
 	require.NoError(t, os.WriteFile(f, []byte("contents"), 0600))
 	t.Cleanup(func() { os.Remove(f) })
diff --git a/sql/sqltool/tool_test.go b/sql/sqltool/tool_test.go
index 0f0f245a..abaa7f2a 100644
--- a/sql/sqltool/tool_test.go
+++ b/sql/sqltool/tool_test.go
@@ -98,6 +98,24 @@ CREATE TABLE t2(c int);
 `, v, v),
 			},
 		},
+		{
+			"amacneil/dbmate",
+			sqltool.DbmateFormatter,
+			map[string]string{
+				v + "_tooling-plan.sql": `-- migrate:up
+-- create table t1
+CREATE TABLE t1(c int);
+-- create table t2
+CREATE TABLE t2(c int);
+
+-- migrate:down
+-- reverse: create table t2
+DROP TABLE t2;
+-- reverse: create table t1
+DROP TABLE t1 IF EXISTS;
+`,
+			},
+		},
 	} {
 		t.Run(tt.name, func(t *testing.T) {
 			d := dir(t)