From 0469452e830b5db1e0f31ede4509592a0282ed7b Mon Sep 17 00:00:00 2001 From: Anthony Bible Date: Wed, 3 Apr 2024 20:01:38 -0600 Subject: [PATCH] Add atlas migrate diff --- atlasexec/atlas.go | 57 +++++++++++++++++++++++++++++++++++++++++ atlasexec/atlas_test.go | 51 ++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/atlasexec/atlas.go b/atlasexec/atlas.go index 58f3a4a..2ca1c0c 100644 --- a/atlasexec/atlas.go +++ b/atlasexec/atlas.go @@ -24,6 +24,21 @@ type ( LoginParams struct { Token string } + // MigrateDiffParams are the parameters for the `migrate diff` command. + MigrateDiffParams struct { + ToURL string + DevURL string + DirURL string + DirFormat string + Schema string + LockTimeout string + Format string + Qualifier string + Context *RunContext + ConfigURL string + Env string + Vars Vars + } // MigratePushParams are the parameters for the `migrate push` command. MigratePushParams struct { Name string @@ -248,6 +263,48 @@ func (c *Client) MigratePush(ctx context.Context, params *MigratePushParams) (st return strings.TrimSpace(resp), err } +// MigrateDiff runs the 'migrate diff' command. +func (c *Client) MigrateDiff(ctx context.Context, params *MigrateDiffParams) (string, error) { + args := []string{"migrate", "diff", "--format", "{{ sql }}"} + if params.ToURL != "" { + args = append(args, "--to", params.ToURL) + } + if params.DevURL != "" { + args = append(args, "--dev-url", params.DevURL) + } + if params.DirURL != "" { + args = append(args, "--dir", params.DirURL) + } + if params.DirFormat != "" { + args = append(args, "--dir-format", params.DirFormat) + } + if params.Schema != "" { + args = append(args, "--schema", params.Schema) + } + if params.LockTimeout != "" { + args = append(args, "--lock-timeout", params.LockTimeout) + } + if params.Qualifier != "" { + args = append(args, "--qualifier", params.Qualifier) + } + if params.Context != nil { + buf, err := json.Marshal(params.Context) + if err != nil { + return "", err + } + args = append(args, "--context", string(buf)) + } + if params.ConfigURL != "" { + args = append(args, "--config", params.ConfigURL) + } + if params.Env != "" { + args = append(args, "--env", params.Env) + } + args = append(args, params.Vars.AsArgs()...) + resp, err := stringVal(c.runCommand(ctx, args)) + return strings.TrimSpace(resp), err +} + // MigrateApply runs the 'migrate apply' command. func (c *Client) MigrateApply(ctx context.Context, params *MigrateApplyParams) (*MigrateApply, error) { return firstResult(c.MigrateApplySlice(ctx, params)) diff --git a/atlasexec/atlas_test.go b/atlasexec/atlas_test.go index 7ca1c4a..7bfaccc 100644 --- a/atlasexec/atlas_test.go +++ b/atlasexec/atlas_test.go @@ -460,6 +460,57 @@ func TestMigrateLintWithLogin(t *testing.T) { require.True(t, found) }) } +func Test_MigrateDiff(t *testing.T) { + wd, err := os.Getwd() + require.NoError(t, err) + // Mock the client with a script that just prints the arguments to stderr and + // exit with an error code. + c, err := atlasexec.NewClient(t.TempDir(), filepath.Join(wd, "./mock-args.sh")) + require.NoError(t, err) + + for _, tt := range []struct { + name string + params *atlasexec.MigrateDiffParams + expect string + }{ + { + name: "no params", + params: &atlasexec.MigrateDiffParams{}, + expect: "migrate diff --format {{ sql }}", + }, + { + name: "with env", + params: &atlasexec.MigrateDiffParams{ + Env: "test", + }, + expect: "migrate diff --format {{ sql }} --env test", + }, + { + name: "with url", + params: &atlasexec.MigrateDiffParams{ + DevURL: "sqlite://file?_fk=1&cache=shared&mode=memory", + }, + expect: "migrate diff --format {{ sql }} --dev-url sqlite://file?_fk=1&cache=shared&mode=memory", + }, + { + name: "with exec order", + params: &atlasexec.MigrateDiffParams{ + Env: "gorm", + }, + expect: "migrate diff --format {{ sql }} --env gorm", + }, + } { + t.Run(tt.name, func(t *testing.T) { + _, err := c.MigrateDiff(context.Background(), tt.params) + require.Error(t, err) + // The script mock-args.sh exit with an error code. + // So, our atlasexec.MigrateApply should return a cliError. + // Which contains all output from the script (both stdout and stderr). + require.Equal(t, tt.expect, err.Error()) + }) + } +} + func TestMigratePush(t *testing.T) { type (