Skip to content
Merged
85 changes: 82 additions & 3 deletions atlasexec/atlas_migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,27 @@ type (
URL string
RevisionsSchema string
}
// MigrateLsParams are the parameters for the `migrate ls` command.
MigrateLsParams struct {
ConfigURL string
Env string
Vars VarArgs

DirURL string
Short bool // -s: print only migration version (omit description and .sql suffix)
Latest bool // -l: print only the latest migration file
}
// MigrateSetParams are the parameters for the `migrate set` command.
MigrateSetParams struct {
ConfigURL string
Env string
Vars VarArgs

DirURL string
URL string
RevisionsSchema string
Version string
}
// MigrateDiffParams are the parameters for the `migrate diff` command.
MigrateDiffParams struct {
ConfigURL string
Expand Down Expand Up @@ -419,6 +440,58 @@ func (c *Client) MigrateStatus(ctx context.Context, params *MigrateStatusParams)
return firstResult(jsonDecode[MigrateStatus](c.runCommand(ctx, args)))
}

// MigrateLs runs the 'migrate ls' command and returns the listed migration file names (or versions when Short is true), one per line.
func (c *Client) MigrateLs(ctx context.Context, params *MigrateLsParams) (string, error) {
args := []string{"migrate", "ls"}
if params.ConfigURL != "" {
args = append(args, "--config", params.ConfigURL)
}
if params.Env != "" {
args = append(args, "--env", params.Env)
}
if params.DirURL != "" {
args = append(args, "--dir", params.DirURL)
}
if params.Vars != nil {
args = append(args, params.Vars.AsArgs()...)
}
if params.Short {
args = append(args, "--short")
}
if params.Latest {
args = append(args, "--latest")
}
return stringVal(c.runCommand(ctx, args))
}

// MigrateSet runs the 'migrate set' command.
func (c *Client) MigrateSet(ctx context.Context, params *MigrateSetParams) error {
args := []string{"migrate", "set"}
if params.Env != "" {
args = append(args, "--env", params.Env)
}
if params.ConfigURL != "" {
args = append(args, "--config", params.ConfigURL)
}
if params.URL != "" {
args = append(args, "--url", params.URL)
}
if params.DirURL != "" {
args = append(args, "--dir", params.DirURL)
}
if params.RevisionsSchema != "" {
args = append(args, "--revisions-schema", params.RevisionsSchema)
}
if params.Vars != nil {
args = append(args, params.Vars.AsArgs()...)
}
if params.Version != "" {
args = append(args, params.Version)
}
_, err := c.runCommand(ctx, args)
return err
}

// MigrateDiff runs the 'migrate diff --dry-run' command and returns the generated migration files without changing the filesystem.
// Requires atlas CLI to be logged in to the cloud.
func (c *Client) MigrateDiff(ctx context.Context, params *MigrateDiffParams) (*MigrateDiff, error) {
Expand Down Expand Up @@ -526,7 +599,7 @@ func (c *Client) MigrateRebase(ctx context.Context, params *MigrateRebaseParams)
if params.DirURL != "" {
args = append(args, "--dir", params.DirURL)
}
args = append(args, strings.Join(params.Files, " "))
args = append(args, params.Files...)
_, err := c.runCommand(ctx, args)
return err
}
Expand Down Expand Up @@ -734,10 +807,16 @@ func newMigrateApplyError(r []*MigrateApply, stderr string) error {

// Error implements the error interface.
func (e *MigrateApplyError) Error() string {
var errs []string
for _, r := range e.Result {
if r.Error != "" {
errs = append(errs, r.Error)
}
}
if e.Stderr != "" {
return e.Stderr
errs = append(errs, e.Stderr)
}
return last(e.Result).Error
return strings.Join(errs, "\n")
}

func plural(n int) (s string) {
Expand Down
30 changes: 30 additions & 0 deletions atlasexec/atlas_migrate_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,33 @@ func ExampleClient_MigrateApply() {
}
fmt.Printf("Applied %d migrations\n", len(res.Applied))
}

func ExampleClient_MigrateSet() {
// Define the execution context, supplying a migration directory
// and potentially an `atlas.hcl` configuration file using `atlasexec.WithHCL`.
workdir, err := atlasexec.NewWorkingDir(
atlasexec.WithMigrations(
os.DirFS("./migrations"),
),
)
if err != nil {
log.Fatalf("failed to load working directory: %v", err)
}
// atlasexec works on a temporary directory, so we need to close it
defer workdir.Close()

// Initialize the client.
client, err := atlasexec.NewClient(workdir.Path(), "atlas")
if err != nil {
log.Fatalf("failed to initialize client: %v", err)
}
// Run `atlas migrate set` to mark migrations as applied up to version "3".
err = client.MigrateSet(context.Background(), &atlasexec.MigrateSetParams{
URL: "sqlite:///tmp/demo.db?_fk=1&cache=shared",
Version: "3",
})
if err != nil {
log.Fatalf("failed to set migrations: %v", err)
}
fmt.Println("Migration version set successfully")
}
Loading
Loading