mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-11-10 10:29:12 +03:00
cli: add All option for migrate
sub-commands (apply, delete and status) and seed apply
command
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/2509 Co-authored-by: Aravind K P <8335904+scriptonist@users.noreply.github.com> GitOrigin-RevId: 03ee878072b58c6dc7f43af9d26d30a5594d9a50
This commit is contained in:
parent
5ad04cc58d
commit
f0bef2b482
@ -9,6 +9,7 @@
|
||||
(Add entries below in the order of server, console, cli, docs, others)
|
||||
|
||||
- server: extend support for insert mutations to tables without primary key constraint in a MSSQL backend
|
||||
- cli: migrate and seed subcommands has an option in prompt to choose and apply operation on all available databases
|
||||
|
||||
## v2.1.1
|
||||
|
||||
|
@ -451,6 +451,9 @@ type ExecutionContext struct {
|
||||
Source Source
|
||||
HasMetadataV3 bool
|
||||
|
||||
// AllDatabases should be taken only incase if database isn't mentioned
|
||||
AllDatabases bool
|
||||
|
||||
// after a `scripts update-config-v3` all migrate commands will try to automatically
|
||||
// move cli state from hdb_catalog.* tables to catalog state if that hasn't happened
|
||||
// already this configuration option will disable this step
|
||||
|
@ -93,8 +93,9 @@ func (opts *DeployOptions) Run() error {
|
||||
if configV2FSM.Current == failedOperation {
|
||||
return fmt.Errorf("operation failed: %w", context.err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
configV3FSM := newConfigV3DeployFSM()
|
||||
if err := configV3FSM.SendEvent(applyInitialMetadata, context); err != nil {
|
||||
return err
|
||||
@ -177,8 +178,8 @@ func (a *applyingMigrationsAction) Execute(ctx fsm.EventContext) eventType {
|
||||
context.ec.Config.DisableInteractive = true
|
||||
opts := MigrateApplyOptions{
|
||||
EC: context.ec,
|
||||
AllDatabases: true,
|
||||
}
|
||||
opts.EC.AllDatabases = true
|
||||
if err := opts.Run(); err != nil {
|
||||
context.err = err
|
||||
return applyMigrationsFailed
|
||||
|
@ -118,6 +118,60 @@ func executeStatus(t *migrate.Migrate) (*migrate.Status, error) {
|
||||
}
|
||||
|
||||
func validateConfigV3Flags(cmd *cobra.Command, ec *cli.ExecutionContext) error {
|
||||
if err := validateConfigV3Prechecks(cmd, ec); err != nil {
|
||||
return err
|
||||
}
|
||||
if ec.Config.Version < cli.V3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := databaseChooser(ec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateSourceInfo(ec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// check if migration ops are supported for the database
|
||||
if !migrate.IsMigrationsSupported(ec.Source.Kind) {
|
||||
return fmt.Errorf("migrations on source %s of kind %s is not supported", ec.Source.Name, ec.Source.Kind)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateConfigV3FlagsWithAll(cmd *cobra.Command, ec *cli.ExecutionContext) error {
|
||||
if err := validateConfigV3Prechecks(cmd, ec); err != nil {
|
||||
return err
|
||||
}
|
||||
if ec.Config.Version < cli.V3 {
|
||||
return nil
|
||||
}
|
||||
// if --all-databases flag is present, ignore --database-name and showing UI prompt for choosing a single database
|
||||
if cmd.Flags().Changed("all-databases") {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := databaseChooserWithAllOption(ec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ec.AllDatabases {
|
||||
return nil
|
||||
}
|
||||
if err := validateSourceInfo(ec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// check if migration ops are supported for the database
|
||||
if !migrate.IsMigrationsSupported(ec.Source.Kind) {
|
||||
return fmt.Errorf("migrations on source %s of kind %s is not supported", ec.Source.Name, ec.Source.Kind)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateConfigV3Prechecks(cmd *cobra.Command, ec *cli.ExecutionContext) error {
|
||||
// for project using config older than v3, use PG source kind
|
||||
if ec.Config.Version < cli.V3 {
|
||||
ec.Source.Kind = hasura.SourceKindPG
|
||||
@ -127,34 +181,16 @@ func validateConfigV3Flags(cmd *cobra.Command, ec *cli.ExecutionContext) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// if --all-databases flag is present, ignore --database-name and showing UI prompt for choosing a single database
|
||||
if cmd.Flags().Changed("all-databases") {
|
||||
return nil
|
||||
}
|
||||
|
||||
// In case of single database, just choose the source automatically
|
||||
sources, err := metadatautil.GetSources(ec.APIClient.V1Metadata.ExportMetadata)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get available databases: %w", err)
|
||||
}
|
||||
if !cmd.Flags().Changed("database-name") && len(sources) == 1 {
|
||||
ec.Source.Name = sources[0]
|
||||
}
|
||||
// for project using config equal to or greater than v3
|
||||
// database-name flag is required when running in non-terminal mode
|
||||
if (!ec.IsTerminal || ec.Config.DisableInteractive) && ec.Source.Name == "" {
|
||||
if (!ec.IsTerminal || ec.Config.DisableInteractive) && !cmd.Flags().Changed("all-databases") && !cmd.Flags().Changed("database-name") {
|
||||
return errDatabaseNameNotSet
|
||||
}
|
||||
|
||||
// prompt UI for choosing database if source name is not set
|
||||
if ec.Source.Name == "" {
|
||||
databaseName, err := metadatautil.DatabaseChooserUI(ec.APIClient.V1Metadata.ExportMetadata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ec.Source.Name = databaseName
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateSourceInfo(ec *cli.ExecutionContext) error {
|
||||
// find out the database kind by making a API call to server
|
||||
// and update ec to include the database name and kind
|
||||
sourceKind, err := metadatautil.GetSourceKind(ec.APIClient.V1Metadata.ExportMetadata, ec.Source.Name)
|
||||
@ -165,10 +201,33 @@ func validateConfigV3Flags(cmd *cobra.Command, ec *cli.ExecutionContext) error {
|
||||
return fmt.Errorf("%w: error determining database kind for %s, check if database exists on hasura", errDatabaseNotFound, ec.Source.Name)
|
||||
}
|
||||
ec.Source.Kind = *sourceKind
|
||||
return nil
|
||||
}
|
||||
|
||||
// check if migration ops are supported for the database
|
||||
if !migrate.IsMigrationsSupported(*sourceKind) {
|
||||
return fmt.Errorf("migrations on source %s of kind %s is not supported", ec.Source.Name, *sourceKind)
|
||||
func databaseChooser(ec *cli.ExecutionContext) error {
|
||||
// prompt UI for choosing database if source name is not set
|
||||
if ec.Source.Name == "" {
|
||||
databaseName, err := metadatautil.DatabaseChooserUI(ec.APIClient.V1Metadata.ExportMetadata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ec.Source.Name = databaseName
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func databaseChooserWithAllOption(ec *cli.ExecutionContext) error {
|
||||
// prompt UI for choosing database if source name is not set
|
||||
if ec.Source.Name == "" {
|
||||
databaseName, err := metadatautil.DatabaseChooserUIWithAll(ec.APIClient.V1Metadata.ExportMetadata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if databaseName == metadatautil.ChooseAllDatabases {
|
||||
ec.AllDatabases = true
|
||||
return nil
|
||||
}
|
||||
ec.Source.Name = databaseName
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ func newMigrateApplyCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
hasura migrate apply --down all`,
|
||||
SilenceUsage: true,
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return validateConfigV3Flags(cmd, ec)
|
||||
return validateConfigV3FlagsWithAll(cmd, ec)
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return opts.Run()
|
||||
@ -85,7 +85,7 @@ func newMigrateApplyCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
f.StringVar(&opts.MigrationType, "type", "up", "type of migration (up, down) to be used with version flag")
|
||||
|
||||
f.BoolVar(&opts.DryRun, "dry-run", false, "print the names of migrations which are going to be applied")
|
||||
f.BoolVar(&opts.AllDatabases, "all-databases", false, "set this flag to attempt to apply migrations on all databases present on server")
|
||||
f.BoolVar(&opts.EC.AllDatabases, "all-databases", false, "set this flag to attempt to apply migrations on all databases present on server")
|
||||
f.BoolVar(&opts.ProgressBarLogs, "progressbar-logs", false, "print the logs of progressbar")
|
||||
if err := f.MarkHidden("progressbar-logs"); err != nil {
|
||||
ec.Logger.WithError(err).Errorf("error while using a dependency library")
|
||||
@ -105,7 +105,6 @@ type MigrateApplyOptions struct {
|
||||
SkipExecution bool
|
||||
DryRun bool
|
||||
Source cli.Source
|
||||
AllDatabases bool
|
||||
ProgressBarLogs bool
|
||||
}
|
||||
|
||||
@ -118,15 +117,15 @@ func (o *MigrateApplyOptions) Validate() error {
|
||||
if o.DryRun && o.SkipExecution {
|
||||
return errors.New("both --skip-execution and --dry-run flags cannot be used together")
|
||||
}
|
||||
if o.DryRun && o.AllDatabases {
|
||||
if o.DryRun && o.EC.AllDatabases {
|
||||
return errors.New("both --all-databases and --dry-run flags cannot be used together")
|
||||
}
|
||||
|
||||
if o.EC.Config.Version >= cli.V3 {
|
||||
if !o.AllDatabases && len(o.Source.Name) == 0 {
|
||||
if !o.EC.AllDatabases && len(o.Source.Name) == 0 {
|
||||
return fmt.Errorf("unable to determine database on which migration should be applied")
|
||||
}
|
||||
if !o.AllDatabases {
|
||||
if !o.EC.AllDatabases {
|
||||
if len(o.Source.Name) == 0 {
|
||||
return fmt.Errorf("empty database name")
|
||||
}
|
||||
@ -203,13 +202,13 @@ func (o *MigrateApplyOptions) Apply() (chan MigrateApplyResult, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
if len(o.Source.Name) == 0 {
|
||||
if len(o.Source.Name) == 0 && !o.EC.AllDatabases {
|
||||
o.Source = o.EC.Source
|
||||
}
|
||||
if err := o.Validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if o.AllDatabases && o.EC.Config.Version >= cli.V3 {
|
||||
if o.EC.AllDatabases && o.EC.Config.Version >= cli.V3 {
|
||||
o.EC.Spin("getting lists of databases from server ")
|
||||
sourcesAndKind, err := metadatautil.GetSourcesAndKind(o.EC.APIClient.V1Metadata.ExportMetadata)
|
||||
o.EC.Spinner.Stop()
|
||||
@ -264,7 +263,7 @@ func (o *MigrateApplyOptions) Exec() error {
|
||||
return &errDatabaseMigrationDirectoryNotFound{fmt.Sprintf("expected to find a migrations directory for database %s in %s, but encountered error: %s", o.Source.Name, o.EC.MigrationDir, err.Error())}
|
||||
}
|
||||
}
|
||||
if o.AllDatabases && (len(o.GotoVersion) > 0 || len(o.VersionMigration) > 0) {
|
||||
if o.EC.AllDatabases && (len(o.GotoVersion) > 0 || len(o.VersionMigration) > 0) {
|
||||
return fmt.Errorf("cannot use --goto or --version in conjunction with --all-databases")
|
||||
}
|
||||
migrationType, step, err := getMigrationTypeAndStep(o.UpMigration, o.DownMigration, o.VersionMigration, o.MigrationType, o.GotoVersion, o.SkipExecution)
|
||||
|
@ -7,7 +7,6 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/Pallinder/go-randomdata"
|
||||
"golang.org/x/term"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/testutil"
|
||||
. "github.com/onsi/ginkgo"
|
||||
@ -218,11 +217,7 @@ var testProgressBar = func(projectDirectory string) {
|
||||
WorkingDirectory: projectDirectory,
|
||||
})
|
||||
|
||||
if !term.IsTerminal(int(os.Stdout.Fd())) {
|
||||
Eventually(session.Err, 60*40).ShouldNot(Say(progressBar))
|
||||
} else {
|
||||
Eventually(session.Err, 60*40).Should(Say(progressBar))
|
||||
}
|
||||
Eventually(session, 60*40).Should(Exit(0))
|
||||
})
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"strconv"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2"
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
|
||||
"github.com/hasura/graphql-engine/cli/v2/migrate"
|
||||
mig "github.com/hasura/graphql-engine/cli/v2/migrate/cmd"
|
||||
"github.com/hasura/graphql-engine/cli/v2/util"
|
||||
@ -28,7 +29,7 @@ func newMigrateDeleteCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
SilenceUsage: true,
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
ec.Logger.Warn("[PREVIEW] this command is in preview. usage may change in future\n")
|
||||
if err := validateConfigV3Flags(cmd, ec); err != nil {
|
||||
if err := validateConfigV3FlagsWithAll(cmd, ec); err != nil {
|
||||
return err
|
||||
}
|
||||
if !cmd.Flags().Changed("all") && !cmd.Flags().Changed("version") {
|
||||
@ -52,21 +53,17 @@ func newMigrateDeleteCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
}
|
||||
}
|
||||
|
||||
opts.Source = ec.Source
|
||||
if ec.Config.Version >= cli.V3 {
|
||||
var err error
|
||||
opts.EC.Spin("Removing migrations")
|
||||
err = opts.Run()
|
||||
opts.EC.Spinner.Stop()
|
||||
if ec.AllDatabases && !opts.force {
|
||||
confirmation, err := util.GetYesNoPrompt("clear all mentioned migrations of all databases and it's history on the server?")
|
||||
if err != nil {
|
||||
return fmt.Errorf("operation failed: %w", err)
|
||||
return fmt.Errorf("error getting user input: %w", err)
|
||||
}
|
||||
return err
|
||||
if !confirmation {
|
||||
return nil
|
||||
}
|
||||
opts.EC.Spin("Removing migrations")
|
||||
err := opts.Run()
|
||||
opts.EC.Spinner.Stop()
|
||||
if err != nil {
|
||||
}
|
||||
|
||||
if err := opts.Run(); err != nil {
|
||||
return fmt.Errorf("operation failed: %w", err)
|
||||
}
|
||||
return nil
|
||||
@ -93,6 +90,27 @@ type MigrateDeleteOptions struct {
|
||||
}
|
||||
|
||||
func (o *MigrateDeleteOptions) Run() error {
|
||||
o.EC.Spin("Removing migrations")
|
||||
defer o.EC.Spinner.Stop()
|
||||
if ec.AllDatabases {
|
||||
sourcesAndKind, err := metadatautil.GetSourcesAndKind(o.EC.APIClient.V1Metadata.ExportMetadata)
|
||||
if err != nil {
|
||||
return fmt.Errorf("got error while getting the sources list : %v", err)
|
||||
}
|
||||
for _, source := range sourcesAndKind {
|
||||
o.Source = cli.Source(source)
|
||||
err := o.RunOnSource()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error while deleting status for database %s: %v", o.Source.Name, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
o.Source = ec.Source
|
||||
return o.RunOnSource()
|
||||
}
|
||||
|
||||
func (o *MigrateDeleteOptions) RunOnSource() error {
|
||||
o.EC.Spin("Deleting migration...")
|
||||
|
||||
migrateDrv, err := migrate.NewMigrate(o.EC, true, o.Source.Name, o.Source.Kind)
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/hasura"
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/util"
|
||||
|
||||
@ -18,6 +19,7 @@ import (
|
||||
func newMigrateStatusCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
opts := &MigrateStatusOptions{
|
||||
EC: ec,
|
||||
StatusOpts: make(StatusOptions),
|
||||
}
|
||||
migrateStatusCmd := &cobra.Command{
|
||||
Use: "status",
|
||||
@ -29,17 +31,13 @@ func newMigrateStatusCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
hasura migrate status --endpoint "<endpoint>"`,
|
||||
SilenceUsage: true,
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return validateConfigV3Flags(cmd, ec)
|
||||
return validateConfigV3FlagsWithAll(cmd, ec)
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
opts.EC.Spin("Fetching migration status...")
|
||||
opts.Source = ec.Source
|
||||
status, err := opts.Run()
|
||||
opts.EC.Spinner.Stop()
|
||||
if err != nil {
|
||||
if err := opts.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
buf := printStatus(status)
|
||||
buf := printStatus(opts.StatusOpts)
|
||||
fmt.Fprintf(ec.Stdout, "%s", buf)
|
||||
return nil
|
||||
},
|
||||
@ -47,12 +45,41 @@ func newMigrateStatusCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
return migrateStatusCmd
|
||||
}
|
||||
|
||||
func (o *MigrateStatusOptions) Run() error {
|
||||
o.EC.Spin("Fetching migration status...")
|
||||
defer o.EC.Spinner.Stop()
|
||||
if ec.AllDatabases {
|
||||
sourcesAndKind, err := metadatautil.GetSourcesAndKind(o.EC.APIClient.V1Metadata.ExportMetadata)
|
||||
if err != nil {
|
||||
return fmt.Errorf("got error while getting the sources list : %v", err)
|
||||
}
|
||||
for _, source := range sourcesAndKind {
|
||||
o.Source = cli.Source(source)
|
||||
status, err := o.RunOnSource()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting status for database %s: %v", o.Source.Name, err)
|
||||
}
|
||||
o.StatusOpts[o.Source] = status
|
||||
}
|
||||
return err
|
||||
}
|
||||
o.Source = ec.Source
|
||||
status, err := o.RunOnSource()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting status for database %s: %v", o.Source.Name, err)
|
||||
}
|
||||
o.StatusOpts[o.Source] = status
|
||||
return err
|
||||
}
|
||||
|
||||
type StatusOptions map[cli.Source]*migrate.Status
|
||||
type MigrateStatusOptions struct {
|
||||
EC *cli.ExecutionContext
|
||||
Source cli.Source
|
||||
StatusOpts StatusOptions
|
||||
}
|
||||
|
||||
func (o *MigrateStatusOptions) Run() (*migrate.Status, error) {
|
||||
func (o *MigrateStatusOptions) RunOnSource() (*migrate.Status, error) {
|
||||
if o.EC.Config.Version <= cli.V2 {
|
||||
o.Source.Name = ""
|
||||
o.Source.Kind = hasura.SourceKindPG
|
||||
@ -68,11 +95,15 @@ func (o *MigrateStatusOptions) Run() (*migrate.Status, error) {
|
||||
return status, nil
|
||||
}
|
||||
|
||||
func printStatus(status *migrate.Status) *bytes.Buffer {
|
||||
func printStatus(statusOpts StatusOptions) *bytes.Buffer {
|
||||
out := new(tabwriter.Writer)
|
||||
buf := &bytes.Buffer{}
|
||||
out.Init(buf, 0, 8, 2, ' ', 0)
|
||||
w := util.NewPrefixWriter(out)
|
||||
for source, status := range statusOpts {
|
||||
if source.Name != "" {
|
||||
w.Write(util.LEVEL_0, fmt.Sprintf("\nDatabase: %s\n", source.Name))
|
||||
}
|
||||
w.Write(util.LEVEL_0, "VERSION\tNAME\tSOURCE STATUS\tDATABASE STATUS\n")
|
||||
for _, version := range status.Index {
|
||||
w.Write(util.LEVEL_0, "%d\t%s\t%s\t%s\n",
|
||||
@ -82,6 +113,7 @@ func printStatus(status *migrate.Status) *bytes.Buffer {
|
||||
convertBool(status.Migrations[version].IsApplied),
|
||||
)
|
||||
}
|
||||
}
|
||||
out.Flush()
|
||||
return buf
|
||||
}
|
||||
|
@ -1,16 +1,10 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2/seed"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2"
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/hasura"
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/scripts"
|
||||
"github.com/hasura/graphql-engine/cli/v2/util"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
@ -32,44 +26,6 @@ func NewSeedCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
if err := ec.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
// for project using config older than v3, use PG source kind
|
||||
if ec.Config.Version < cli.V3 {
|
||||
ec.Source.Kind = hasura.SourceKindPG
|
||||
if err := scripts.CheckIfUpdateToConfigV3IsRequired(ec); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// for project using config equal to or greater than v3
|
||||
// database-name flag is required when running in non-terminal mode
|
||||
if (!ec.IsTerminal || ec.Config.DisableInteractive) && !cmd.Flags().Changed("database-name") {
|
||||
return errors.New("--database-name flag is required")
|
||||
}
|
||||
|
||||
// prompt UI for choosing database if source name is not set
|
||||
if ec.Source.Name == "" {
|
||||
databaseName, err := metadatautil.DatabaseChooserUI(ec.APIClient.V1Metadata.ExportMetadata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ec.Source.Name = databaseName
|
||||
}
|
||||
|
||||
sourceKind, err := metadatautil.GetSourceKind(ec.APIClient.V1Metadata.ExportMetadata, ec.Source.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sourceKind == nil {
|
||||
return fmt.Errorf("cannot determine source kind for %v", ec.Source.Name)
|
||||
}
|
||||
ec.Source.Kind = *sourceKind
|
||||
|
||||
// check if seed ops are supported for the database
|
||||
if !seed.IsSeedsSupported(*sourceKind) {
|
||||
return fmt.Errorf("seed operations on database %s of kind %s is not supported", ec.Source.Name, *sourceKind)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/hasura/graphql-engine/cli/v2"
|
||||
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
|
||||
"github.com/hasura/graphql-engine/cli/v2/seed"
|
||||
)
|
||||
|
||||
@ -33,15 +34,33 @@ func newSeedApplyCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
hasura seed apply --file seeds/1234_add_some_seed_data.sql`,
|
||||
SilenceUsage: false,
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return ec.Validate()
|
||||
if err := validateConfigV3Prechecks(cmd, ec); err != nil {
|
||||
return err
|
||||
}
|
||||
if ec.Config.Version < cli.V3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := databaseChooserWithAllOption(ec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if ec.AllDatabases {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := validateSourceInfo(ec); err != nil {
|
||||
return err
|
||||
}
|
||||
// check if seed ops are supported for the database
|
||||
if !seed.IsSeedsSupported(ec.Source.Kind) {
|
||||
return fmt.Errorf("seed operations on database %s of kind %s is not supported", ec.Source.Name, ec.Source.Kind)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
opts.Driver = getSeedDriver(ec.Config.Version)
|
||||
opts.EC.Spin("Applying seeds...")
|
||||
opts.Source = ec.Source
|
||||
err := opts.Run()
|
||||
opts.EC.Spinner.Stop()
|
||||
if err != nil {
|
||||
if err := opts.Run(); err != nil {
|
||||
return fmt.Errorf("operation failed \n%w", err)
|
||||
}
|
||||
opts.EC.Logger.Info("Seeds planted")
|
||||
@ -53,6 +72,27 @@ func newSeedApplyCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
}
|
||||
|
||||
func (o *SeedApplyOptions) Run() error {
|
||||
fs := afero.NewOsFs()
|
||||
return o.Driver.ApplySeedsToDatabase(fs, o.EC.SeedsDirectory, o.FileNames, o.EC.Source)
|
||||
o.EC.Spin("Applying seeds...")
|
||||
defer o.EC.Spinner.Stop()
|
||||
if o.EC.AllDatabases {
|
||||
sourcesAndKind, err := metadatautil.GetSourcesAndKind(o.EC.APIClient.V1Metadata.ExportMetadata)
|
||||
if err != nil {
|
||||
return fmt.Errorf("got error while getting the sources list : %v", err)
|
||||
}
|
||||
for _, source := range sourcesAndKind {
|
||||
o.Source = cli.Source(source)
|
||||
err := o.ApplyOnSource()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error while applying seeds for database %s: %v", o.Source.Name, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
o.Source = o.EC.Source
|
||||
return o.ApplyOnSource()
|
||||
}
|
||||
|
||||
func (o *SeedApplyOptions) ApplyOnSource() error {
|
||||
fs := afero.NewOsFs()
|
||||
return o.Driver.ApplySeedsToDatabase(fs, o.EC.SeedsDirectory, o.FileNames, o.Source)
|
||||
}
|
||||
|
@ -50,7 +50,25 @@ func newSeedCreateCmd(ec *cli.ExecutionContext) *cobra.Command {
|
||||
Args: cobra.ExactArgs(1),
|
||||
SilenceUsage: false,
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
return ec.Validate()
|
||||
if err := validateConfigV3Prechecks(cmd, ec); err != nil {
|
||||
return err
|
||||
}
|
||||
if ec.Config.Version < cli.V3 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := databaseChooser(ec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validateSourceInfo(ec); err != nil {
|
||||
return err
|
||||
}
|
||||
// check if seed ops are supported for the database
|
||||
if !seed.IsSeedsSupported(ec.Source.Kind) {
|
||||
return fmt.Errorf("seed operations on database %s of kind %s is not supported", ec.Source.Name, ec.Source.Kind)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
opts.SeedName = args[0]
|
||||
|
@ -187,7 +187,7 @@ func TestMigrateCmd(t *testing.T, ec *cli.ExecutionContext) {
|
||||
EC: ec,
|
||||
Source: cli.Source{Name: "", Kind: hasura.SourceKindPG},
|
||||
}
|
||||
actualStatus, err := statusOpts.Run()
|
||||
actualStatus, err := statusOpts.RunOnSource()
|
||||
if err != nil {
|
||||
t.Fatalf("%s: unable to fetch migrate status, got %v", tc.name, err)
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ func TestDeployCmd(t *testing.T, ec *cli.ExecutionContext) {
|
||||
EC: ec,
|
||||
Source: cli.Source{Name: "default", Kind: hasura.SourceKindPG},
|
||||
}
|
||||
actualStatus, err := statusOpts.Run()
|
||||
actualStatus, err := statusOpts.RunOnSource()
|
||||
if err != nil {
|
||||
t.Fatalf("%s: unable to fetch migrate status, got %v", tc.name, err)
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ func TestMigrateCmd(t *testing.T, ec *cli.ExecutionContext) {
|
||||
EC: ec,
|
||||
Source: cli.Source{Name: "default", Kind: hasura.SourceKindPG},
|
||||
}
|
||||
actualStatus, err := statusOpts.Run()
|
||||
actualStatus, err := statusOpts.RunOnSource()
|
||||
if err != nil {
|
||||
t.Fatalf("%s: unable to fetch migrate status, got %v", tc.name, err)
|
||||
}
|
||||
|
@ -139,3 +139,22 @@ func DatabaseChooserUI(exportMetadata func() (io.Reader, error)) (string, error)
|
||||
|
||||
return databaseName, nil
|
||||
}
|
||||
|
||||
const ChooseAllDatabases = "All (all available databases)"
|
||||
|
||||
func DatabaseChooserUIWithAll(exportMetadata func() (io.Reader, error)) (string, error) {
|
||||
sources, err := GetSources(exportMetadata)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to get available databases: %w", err)
|
||||
}
|
||||
if len(sources) == 0 {
|
||||
return "", errors.New("no connected databases found in the server")
|
||||
}
|
||||
sources = append([]string{ChooseAllDatabases}, sources...)
|
||||
databaseName, err := util.GetSelectPrompt("Select a database to use", sources)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error in selecting a database to use: %w", err)
|
||||
}
|
||||
|
||||
return databaseName, nil
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ type ProjectMigrationApplierOption func(applier *projectMigrationsApplier)
|
||||
|
||||
func ApplyOnAllDatabases() ProjectMigrationApplierOption {
|
||||
return func(p *projectMigrationsApplier) {
|
||||
p.opts.AllDatabases = true
|
||||
p.opts.EC.AllDatabases = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) (
|
||||
Kind: source.Kind,
|
||||
},
|
||||
}
|
||||
status, err := opts.Run()
|
||||
status, err := opts.RunOnSource()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user