Skip to content

Commit

Permalink
chore: prompt before pushing seed files
Browse files Browse the repository at this point in the history
  • Loading branch information
sweatybridge committed Oct 7, 2024
1 parent dffb8d6 commit b3efd48
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 33 deletions.
65 changes: 45 additions & 20 deletions internal/db/push/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/migration/apply"
"github.com/supabase/cli/internal/migration/up"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/pkg/migration"
Expand All @@ -36,42 +35,68 @@ func Run(ctx context.Context, dryRun, ignoreVersionMismatch bool, includeRoles,
return err
}
}
if len(pending) == 0 && len(seeds) == 0 {
var globals []string
if includeRoles {
if exists, err := afero.Exists(fsys, utils.CustomRolesPath); err != nil {
return errors.Errorf("failed to find custom roles: %w", err)
} else if exists {
globals = append(globals, utils.CustomRolesPath)
}
}
if len(pending) == 0 && len(seeds) == 0 && len(globals) == 0 {
fmt.Println("Remote database is up to date.")
return nil
}
// Push pending migrations
if dryRun {
if includeRoles {
fmt.Fprintln(os.Stderr, "Would create custom roles "+utils.Bold(utils.CustomRolesPath)+"...")
if len(globals) > 0 {
fmt.Fprintln(os.Stderr, "Would create custom roles "+utils.Bold(globals[0])+"...")
}
if len(pending) > 0 {
fmt.Fprintln(os.Stderr, "Would push these migrations:")
fmt.Fprint(os.Stderr, utils.Bold(confirmPushAll(pending)))
fmt.Fprint(os.Stderr, confirmPushAll(pending))
}
if includeSeed && len(seeds) > 0 {
if len(seeds) > 0 {
fmt.Fprintln(os.Stderr, "Would seed these files:")
fmt.Fprint(os.Stderr, utils.Bold(confirmSeedAll(seeds)))
fmt.Fprint(os.Stderr, confirmSeedAll(seeds))
}
} else {
msg := fmt.Sprintf("Do you want to push these migrations to the remote database?\n%s\n", confirmPushAll(pending))
if shouldPush, err := utils.NewConsole().PromptYesNo(ctx, msg, true); err != nil {
return err
} else if !shouldPush {
return errors.New(context.Canceled)
}
if includeRoles {
if err := apply.CreateCustomRoles(ctx, conn, fsys); err != nil {
if len(globals) > 0 {
msg := "Do you want to create custom roles in the database cluster?"
if shouldPush, err := utils.NewConsole().PromptYesNo(ctx, msg, true); err != nil {
return err
} else if !shouldPush {
return errors.New(context.Canceled)
}
if err := migration.SeedGlobals(ctx, globals, conn, afero.NewIOFS(fsys)); err != nil {
return err
}
}
if err := migration.ApplyMigrations(ctx, pending, conn, afero.NewIOFS(fsys)); err != nil {
return err
if len(pending) > 0 {
msg := fmt.Sprintf("Do you want to push these migrations to the remote database?\n%s\n", confirmPushAll(pending))
if shouldPush, err := utils.NewConsole().PromptYesNo(ctx, msg, true); err != nil {
return err
} else if !shouldPush {
return errors.New(context.Canceled)
}
if err := migration.ApplyMigrations(ctx, pending, conn, afero.NewIOFS(fsys)); err != nil {
return err
}
} else {
fmt.Fprintln(os.Stderr, "Schema migrations are up to date.")
}
if includeSeed {
if len(seeds) > 0 {
msg := fmt.Sprintf("Do you want to seed the remote database with these files?\n%s\n", confirmSeedAll(seeds))
if shouldPush, err := utils.NewConsole().PromptYesNo(ctx, msg, true); err != nil {
return err
} else if !shouldPush {
return errors.New(context.Canceled)
}
if err := migration.SeedData(ctx, seeds, conn, afero.NewIOFS(fsys)); err != nil {
return err
}
} else if includeSeed {
fmt.Fprintln(os.Stderr, "Seed files are up to date.")
}
}
fmt.Println("Finished " + utils.Aqua("supabase db push") + ".")
Expand All @@ -81,7 +106,7 @@ func Run(ctx context.Context, dryRun, ignoreVersionMismatch bool, includeRoles,
func confirmPushAll(pending []string) (msg string) {
for _, path := range pending {
filename := filepath.Base(path)
msg += fmt.Sprintf(" • %s\n", filename)
msg += fmt.Sprintf(" • %s\n", utils.Bold(filename))
}
return msg
}
Expand All @@ -92,7 +117,7 @@ func confirmSeedAll(pending []migration.SeedFile) (msg string) {
if seed.Dirty {
notice += " (hash update)"
}
msg += fmt.Sprintf(" • %s\n", notice)
msg += fmt.Sprintf(" • %s\n", utils.Bold(notice))
}
return msg
}
2 changes: 1 addition & 1 deletion internal/db/push/push_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func TestPushAll(t *testing.T) {

t.Run("throws error on roles failure", func(t *testing.T) {
// Setup in-memory fs
fsys := &fstest.OpenErrorFs{DenyPath: utils.CustomRolesPath}
fsys := &fstest.StatErrorFs{DenyPath: utils.CustomRolesPath}
path := filepath.Join(utils.MigrationsDir, "0_test.sql")
require.NoError(t, afero.WriteFile(fsys, path, []byte{}, 0644))
// Setup mock postgres
Expand Down
6 changes: 5 additions & 1 deletion internal/db/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,5 +324,9 @@ func SetupDatabase(ctx context.Context, conn *pgx.Conn, host string, w io.Writer
if err := initSchema(ctx, conn, host, w); err != nil {
return err
}
return apply.CreateCustomRoles(ctx, conn, fsys)
err := migration.SeedGlobals(ctx, []string{utils.CustomRolesPath}, conn, afero.NewIOFS(fsys))
if errors.Is(err, os.ErrNotExist) {
return nil
}
return err
}
10 changes: 0 additions & 10 deletions internal/migration/apply/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package apply

import (
"context"
"os"

"github.com/go-errors/errors"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/migration/list"
Expand Down Expand Up @@ -33,11 +31,3 @@ func applySeedFiles(ctx context.Context, conn *pgx.Conn, fsys afero.Fs) error {
}
return migration.SeedData(ctx, seeds, conn, afero.NewIOFS(fsys))
}

func CreateCustomRoles(ctx context.Context, conn *pgx.Conn, fsys afero.Fs) error {
err := migration.SeedGlobals(ctx, []string{utils.CustomRolesPath}, conn, afero.NewIOFS(fsys))
if errors.Is(err, os.ErrNotExist) {
return nil
}
return err
}
5 changes: 5 additions & 0 deletions internal/utils/flags/db_url.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ func ParseDatabaseConfig(flagSet *pflag.FlagSet, fsys afero.Fs) error {
// Update connection config
switch connType {
case direct:
if err := utils.Config.Load("", utils.NewRootFS(fsys)); err != nil {
if !errors.Is(err, os.ErrNotExist) {
return err
}
}
if flag := flagSet.Lookup("db-url"); flag != nil {
config, err := pgconn.ParseConfig(flag.Value.String())
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/migration/seed.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func GetPendingSeeds(ctx context.Context, locals []string, conn *pgx.Conn, fsys
func SeedData(ctx context.Context, pending []SeedFile, conn *pgx.Conn, fsys fs.FS) error {
for _, seed := range pending {
if seed.Dirty {
fmt.Fprintf(os.Stderr, "Updating seed file hash %s...\n", seed.Path)
fmt.Fprintf(os.Stderr, "Updating seed hash to %s...\n", seed.Path)
} else {
fmt.Fprintf(os.Stderr, "Seeding data from %s...\n", seed.Path)
}
Expand Down

0 comments on commit b3efd48

Please sign in to comment.