diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go index d092d7cdf..11725a335 100644 --- a/dialect/sql/schema/atlas.go +++ b/dialect/sql/schema/atlas.go @@ -33,6 +33,7 @@ type Atlas struct { withFixture bool // deprecated: with fks rename fixture sum bool // deprecated: sum file generation will be required + errNoPlan bool // no plan error enabled universalID bool // global unique ids dropColumns bool // drop deleted columns dropIndexes bool // drop deleted indexes @@ -183,14 +184,17 @@ func (a *Atlas) NamedDiff(ctx context.Context, name string, tables ...*Table) er default: return fmt.Errorf("unknown migration mode: %q", a.mode) } - if err != nil { + switch { + case err != nil: return err - } - // Skip if the plan has no changes. - if len(plan.Changes) == 0 { + case len(plan.Changes) == 0: + if a.errNoPlan { + return migrate.ErrNoPlan + } return nil + default: + return migrate.NewPlanner(nil, a.dir, opts...).WritePlan(plan) } - return migrate.NewPlanner(nil, a.dir, opts...).WritePlan(plan) } func (a *Atlas) cleanSchema(ctx context.Context, name string, err0 error) (err error) { diff --git a/dialect/sql/schema/migrate.go b/dialect/sql/schema/migrate.go index 2fe512324..035d391e9 100644 --- a/dialect/sql/schema/migrate.go +++ b/dialect/sql/schema/migrate.go @@ -41,6 +41,14 @@ func WithGlobalUniqueID(b bool) MigrateOption { } } +// WithErrNoPlan sets Atlas to returns a migrate.ErrNoPlan in case +// the migration plan is empty. Defaults to false. +func WithErrNoPlan(b bool) MigrateOption { + return func(a *Atlas) { + a.errNoPlan = b + } +} + // WithDropColumn sets the columns dropping option to the migration. // Defaults to false. func WithDropColumn(b bool) MigrateOption { diff --git a/dialect/sql/schema/migrate_test.go b/dialect/sql/schema/migrate_test.go index 4a482713f..9d7bfd000 100644 --- a/dialect/sql/schema/migrate_test.go +++ b/dialect/sql/schema/migrate_test.go @@ -305,6 +305,13 @@ func TestMigrate_Diff(t *testing.T) { // Checksum will be updated as well. require.NoError(t, migrate.Validate(d)) + + require.NoError(t, m.NamedDiff(ctx, "no_changes"), "should not error if WithErrNoPlan is not set") + // Enable WithErrNoPlan. + m, err = NewMigrate(db, WithFormatter(f), WithDir(d), WithGlobalUniqueID(true), WithErrNoPlan(true)) + require.NoError(t, err) + err = m.NamedDiff(ctx, "no_changes") + require.ErrorIs(t, err, migrate.ErrNoPlan) } func requireFileEqual(t *testing.T, name, contents string) {