supabase-cli/internal/migration/up/up.go

68 lines
2.2 KiB
Go

package up
import (
"context"
"fmt"
"strings"
"github.com/go-errors/errors"
"github.com/jackc/pgconn"
"github.com/jackc/pgx/v4"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/utils"
"github.com/supabase/cli/pkg/migration"
"github.com/supabase/cli/pkg/vault"
)
func Run(ctx context.Context, includeAll bool, config pgconn.Config, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
conn, err := utils.ConnectByConfig(ctx, config, options...)
if err != nil {
return err
}
defer conn.Close(context.Background())
pending, err := GetPendingMigrations(ctx, includeAll, conn, fsys)
if err != nil {
return err
}
if err := vault.UpsertVaultSecrets(ctx, utils.Config.Db.Vault, conn); err != nil {
return err
}
return migration.ApplyMigrations(ctx, pending, conn, afero.NewIOFS(fsys))
}
func GetPendingMigrations(ctx context.Context, includeAll bool, conn *pgx.Conn, fsys afero.Fs) ([]string, error) {
remoteMigrations, err := migration.ListRemoteMigrations(ctx, conn)
if err != nil {
return nil, err
}
localMigrations, err := migration.ListLocalMigrations(utils.MigrationsDir, afero.NewIOFS(fsys))
if err != nil {
return nil, err
}
diff, err := migration.FindPendingMigrations(localMigrations, remoteMigrations)
if errors.Is(err, migration.ErrMissingLocal) {
utils.CmdSuggestion = suggestRevertHistory(diff)
} else if errors.Is(err, migration.ErrMissingRemote) {
if includeAll {
pending := localMigrations[len(remoteMigrations)+len(diff):]
return append(diff, pending...), nil
}
utils.CmdSuggestion = suggestIgnoreFlag(diff)
}
return diff, err
}
func suggestRevertHistory(versions []string) string {
result := fmt.Sprintln("\nMake sure your local git repo is up-to-date. If the error persists, try repairing the migration history table:")
result += fmt.Sprintln(utils.Bold("supabase migration repair --status reverted " + strings.Join(versions, " ")))
result += fmt.Sprintln("\nAnd update local migrations to match remote database:")
result += fmt.Sprintln(utils.Bold("supabase db pull"))
return result
}
func suggestIgnoreFlag(paths []string) string {
result := "\nRerun the command with --include-all flag to apply these migrations:\n"
result += fmt.Sprintln(utils.Bold(strings.Join(paths, "\n")))
return result
}