github.com/supabase/cli@v1.168.1/internal/db/push/push.go (about)

     1  package push
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"io"
     7  	"os"
     8  	"strings"
     9  
    10  	"github.com/go-errors/errors"
    11  	"github.com/jackc/pgconn"
    12  	"github.com/jackc/pgx/v4"
    13  	"github.com/spf13/afero"
    14  	"github.com/supabase/cli/internal/migration/apply"
    15  	"github.com/supabase/cli/internal/migration/up"
    16  	"github.com/supabase/cli/internal/utils"
    17  )
    18  
    19  func Run(ctx context.Context, dryRun, ignoreVersionMismatch bool, includeRoles, includeSeed bool, config pgconn.Config, fsys afero.Fs, options ...func(*pgx.ConnConfig)) error {
    20  	if dryRun {
    21  		fmt.Fprintln(os.Stderr, "DRY RUN: migrations will *not* be pushed to the database.")
    22  	}
    23  	conn, err := utils.ConnectByConfig(ctx, config, options...)
    24  	if err != nil {
    25  		return err
    26  	}
    27  	defer conn.Close(context.Background())
    28  	pending, err := up.GetPendingMigrations(ctx, ignoreVersionMismatch, conn, fsys)
    29  	if err != nil {
    30  		return err
    31  	}
    32  	if len(pending) == 0 {
    33  		fmt.Println("Remote database is up to date.")
    34  		return nil
    35  	}
    36  	// Push pending migrations
    37  	if dryRun {
    38  		if includeRoles {
    39  			fmt.Fprintln(os.Stderr, "Would create custom roles "+utils.Bold(utils.CustomRolesPath)+"...")
    40  		}
    41  		for _, filename := range pending {
    42  			fmt.Fprintln(os.Stderr, "Would push migration "+utils.Bold(filename)+"...")
    43  		}
    44  		if includeSeed {
    45  			fmt.Fprintln(os.Stderr, "Would seed data "+utils.Bold(utils.SeedDataPath)+"...")
    46  		}
    47  	} else {
    48  		msg := fmt.Sprintf("Do you want to push these migrations to the remote database?\n • %s\n\n", strings.Join(pending, "\n • "))
    49  		if shouldPush := utils.NewConsole().PromptYesNo(msg, true); !shouldPush {
    50  			return errors.New(context.Canceled)
    51  		}
    52  		if includeRoles {
    53  			if err := CreateCustomRoles(ctx, conn, os.Stderr, fsys); err != nil {
    54  				return err
    55  			}
    56  		}
    57  		if err := apply.MigrateUp(ctx, conn, pending, fsys); err != nil {
    58  			return err
    59  		}
    60  		if includeSeed {
    61  			if err := apply.SeedDatabase(ctx, conn, fsys); err != nil {
    62  				return err
    63  			}
    64  		}
    65  	}
    66  	fmt.Println("Finished " + utils.Aqua("supabase db push") + ".")
    67  	return nil
    68  }
    69  
    70  func CreateCustomRoles(ctx context.Context, conn *pgx.Conn, w io.Writer, fsys afero.Fs) error {
    71  	roles, err := fsys.Open(utils.CustomRolesPath)
    72  	if errors.Is(err, os.ErrNotExist) {
    73  		return nil
    74  	} else if err != nil {
    75  		return errors.Errorf("failed to load custom roles: %w", err)
    76  	}
    77  	fmt.Fprintln(w, "Creating custom roles "+utils.Bold(utils.CustomRolesPath)+"...")
    78  	return apply.BatchExecDDL(ctx, conn, roles)
    79  }