From c7ac1ede3f13fdea6a715a029beede94a57bea94 Mon Sep 17 00:00:00 2001 From: Aravind K P Date: Fri, 18 Jun 2021 11:54:16 +0530 Subject: [PATCH] cli: add `migrate` and `metadata` packages > ### Description > This PR adds two new packages which implement the CLI requirements specified in RFC:https://github.com/hasura/lux/blob/cloud/docs/rfcs/20210614_github_integration.md 1. `pkg/metadata` ![image](https://user-images.githubusercontent.com/8335904/122384828-b4757d80-cf89-11eb-9e21-ef116fb928e9.png) 2. `pkg/migrate` ![image](https://user-images.githubusercontent.com/8335904/122510554-68771700-d023-11eb-9f5d-046d2c0cf18a.png) ### Changelog - [x] `CHANGELOG.md` is updated with user-facing content relevant to this PR. If no changelog is required, then add the `no-changelog-required` label. ### Affected components - [x] CLI https://github.com/hasura/graphql-engine-mono/pull/1598 GitOrigin-RevId: 0e2bce498386c5aae68dbca0fe383a6afff9d1a9 --- cli/cli.go | 13 +- cli/commands/metadata_apply.go | 2 +- cli/commands/metadata_diff.go | 65 ++- cli/commands/metadata_reload.go | 2 +- cli/commands/migrate_apply.go | 202 ++++--- cli/commands/migrate_status.go | 6 + cli/go.mod | 1 - cli/go.sum | 39 -- cli/integration_test/v2/migrate.go | 2 +- cli/integration_test/v3/migrate.go | 3 +- .../{ => default}/1591867862409_test.sql | 0 .../{ => default}/1591867862419_test2.sql | 0 cli/internal/metadataobject/handler.go | 16 +- cli/internal/testutil/vars.go | 2 + cli/logger_hook.go | 8 +- cli/pkg/metadata/project_metadata.go | 113 ++++ cli/pkg/metadata/project_metadata_test.go | 206 +++++++ .../metadata_diff_test/config_v2_diff | 17 + .../metadata_diff_test/config_v3_diff | 17 + .../metadata_parse_test/config-v2.golden.json | 29 + .../metadata_parse_test/config-v3.golden.json | 50 ++ .../metadata/testdata/projectv2/config.yaml | 6 + .../projectv2/metadata/actions.graphql | 0 .../testdata/projectv2/metadata/actions.yaml | 6 + .../projectv2/metadata/allow_list.yaml | 1 + .../projectv2/metadata/cron_triggers.yaml | 1 + .../projectv2/metadata/functions.yaml | 1 + .../projectv2/metadata/query_collections.yaml | 1 + .../projectv2/metadata/remote_schemas.yaml | 1 + .../testdata/projectv2/metadata/tables.yaml | 12 + .../testdata/projectv2/metadata/version.yaml | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../1623842069725_create_schema_pub/down.sql | 1 + .../1623842069725_create_schema_pub/up.sql | 1 + .../down.sql | 1 + .../1623842076537_create_table_pub_t3/up.sql | 1 + .../down.sql | 1 + .../1623842087940_create_table_pub_t4/up.sql | 1 + .../metadata/testdata/projectv3/config.yaml | 6 + .../projectv3/metadata/actions.graphql | 0 .../testdata/projectv3/metadata/actions.yaml | 6 + .../projectv3/metadata/allow_list.yaml | 1 + .../projectv3/metadata/cron_triggers.yaml | 1 + .../metadata/databases/databases.yaml | 14 + .../databases/default/tables/pub_t3.yaml | 3 + .../databases/default/tables/pub_t4.yaml | 3 + .../databases/default/tables/public_t1.yaml | 3 + .../databases/default/tables/public_t2.yaml | 3 + .../databases/default/tables/tables.yaml | 4 + .../projectv3/metadata/query_collections.yaml | 1 + .../projectv3/metadata/remote_schemas.yaml | 1 + .../projectv3/metadata/rest_endpoints.yaml | 1 + .../testdata/projectv3/metadata/version.yaml | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../1623841492743_create_schema_pub/down.sql | 1 + .../1623841492743_create_schema_pub/up.sql | 1 + .../down.sql | 1 + .../1623841500466_create_table_pub_t3/up.sql | 1 + .../down.sql | 1 + .../1623841510619_create_table_pub_t4/up.sql | 1 + cli/pkg/migrate/apply.go | 49 ++ cli/pkg/migrate/project_migrate.go | 72 +++ cli/pkg/migrate/project_migrate_test.go | 541 ++++++++++++++++++ cli/pkg/migrate/status.go | 82 +++ .../migrate/testdata/projectv2/config.yaml | 6 + .../projectv2/metadata/actions.graphql | 0 .../testdata/projectv2/metadata/actions.yaml | 6 + .../projectv2/metadata/allow_list.yaml | 1 + .../projectv2/metadata/cron_triggers.yaml | 1 + .../projectv2/metadata/functions.yaml | 1 + .../projectv2/metadata/query_collections.yaml | 1 + .../projectv2/metadata/remote_schemas.yaml | 1 + .../testdata/projectv2/metadata/tables.yaml | 12 + .../testdata/projectv2/metadata/version.yaml | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../1623842069725_create_schema_pub/down.sql | 1 + .../1623842069725_create_schema_pub/up.sql | 1 + .../down.sql | 1 + .../1623842076537_create_table_pub_t3/up.sql | 1 + .../down.sql | 1 + .../1623842087940_create_table_pub_t4/up.sql | 1 + .../migrate/testdata/projectv3/config.yaml | 6 + .../projectv3/metadata/actions.graphql | 0 .../testdata/projectv3/metadata/actions.yaml | 6 + .../projectv3/metadata/allow_list.yaml | 1 + .../projectv3/metadata/cron_triggers.yaml | 1 + .../metadata/databases/databases.yaml | 14 + .../databases/default/tables/pub_t3.yaml | 3 + .../databases/default/tables/pub_t4.yaml | 3 + .../databases/default/tables/public_t1.yaml | 3 + .../databases/default/tables/public_t2.yaml | 3 + .../databases/default/tables/tables.yaml | 4 + .../projectv3/metadata/query_collections.yaml | 1 + .../projectv3/metadata/remote_schemas.yaml | 1 + .../projectv3/metadata/rest_endpoints.yaml | 1 + .../testdata/projectv3/metadata/version.yaml | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../1623841492743_create_schema_pub/down.sql | 1 + .../s1/1623841492743_create_schema_pub/up.sql | 1 + .../down.sql | 1 + .../1623841500466_create_table_pub_t3/up.sql | 1 + .../down.sql | 1 + .../1623841510619_create_table_pub_t4/up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../1623841492743_create_schema_pub/down.sql | 1 + .../s2/1623841492743_create_schema_pub/up.sql | 1 + .../down.sql | 1 + .../1623841500466_create_table_pub_t3/up.sql | 1 + .../down.sql | 1 + .../1623841510619_create_table_pub_t4/up.sql | 1 + 125 files changed, 1576 insertions(+), 167 deletions(-) rename cli/integration_test/v3/seeds/{ => default}/1591867862409_test.sql (100%) rename cli/integration_test/v3/seeds/{ => default}/1591867862419_test2.sql (100%) create mode 100644 cli/pkg/metadata/project_metadata.go create mode 100644 cli/pkg/metadata/project_metadata_test.go create mode 100644 cli/pkg/metadata/testdata/metadata_diff_test/config_v2_diff create mode 100644 cli/pkg/metadata/testdata/metadata_diff_test/config_v3_diff create mode 100644 cli/pkg/metadata/testdata/metadata_parse_test/config-v2.golden.json create mode 100644 cli/pkg/metadata/testdata/metadata_parse_test/config-v3.golden.json create mode 100644 cli/pkg/metadata/testdata/projectv2/config.yaml create mode 100644 cli/pkg/metadata/testdata/projectv2/metadata/actions.graphql create mode 100644 cli/pkg/metadata/testdata/projectv2/metadata/actions.yaml create mode 100644 cli/pkg/metadata/testdata/projectv2/metadata/allow_list.yaml create mode 100644 cli/pkg/metadata/testdata/projectv2/metadata/cron_triggers.yaml create mode 100644 cli/pkg/metadata/testdata/projectv2/metadata/functions.yaml create mode 100644 cli/pkg/metadata/testdata/projectv2/metadata/query_collections.yaml create mode 100644 cli/pkg/metadata/testdata/projectv2/metadata/remote_schemas.yaml create mode 100644 cli/pkg/metadata/testdata/projectv2/metadata/tables.yaml create mode 100644 cli/pkg/metadata/testdata/projectv2/metadata/version.yaml create mode 100644 cli/pkg/metadata/testdata/projectv2/migrations/1623842054907_create_table_public_t1/down.sql create mode 100644 cli/pkg/metadata/testdata/projectv2/migrations/1623842054907_create_table_public_t1/up.sql create mode 100644 cli/pkg/metadata/testdata/projectv2/migrations/1623842062104_create_table_public_t2/down.sql create mode 100644 cli/pkg/metadata/testdata/projectv2/migrations/1623842062104_create_table_public_t2/up.sql create mode 100644 cli/pkg/metadata/testdata/projectv2/migrations/1623842069725_create_schema_pub/down.sql create mode 100644 cli/pkg/metadata/testdata/projectv2/migrations/1623842069725_create_schema_pub/up.sql create mode 100644 cli/pkg/metadata/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/down.sql create mode 100644 cli/pkg/metadata/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/up.sql create mode 100644 cli/pkg/metadata/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/down.sql create mode 100644 cli/pkg/metadata/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/up.sql create mode 100644 cli/pkg/metadata/testdata/projectv3/config.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/actions.graphql create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/actions.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/allow_list.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/cron_triggers.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/databases/databases.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/pub_t3.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/pub_t4.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/public_t1.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/public_t2.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/tables.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/query_collections.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/remote_schemas.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/rest_endpoints.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/metadata/version.yaml create mode 100644 cli/pkg/metadata/testdata/projectv3/migrations/default/1623841477474_create_table_public_t1/down.sql create mode 100644 cli/pkg/metadata/testdata/projectv3/migrations/default/1623841477474_create_table_public_t1/up.sql create mode 100644 cli/pkg/metadata/testdata/projectv3/migrations/default/1623841485323_create_table_public_t2/down.sql create mode 100644 cli/pkg/metadata/testdata/projectv3/migrations/default/1623841485323_create_table_public_t2/up.sql create mode 100644 cli/pkg/metadata/testdata/projectv3/migrations/default/1623841492743_create_schema_pub/down.sql create mode 100644 cli/pkg/metadata/testdata/projectv3/migrations/default/1623841492743_create_schema_pub/up.sql create mode 100644 cli/pkg/metadata/testdata/projectv3/migrations/default/1623841500466_create_table_pub_t3/down.sql create mode 100644 cli/pkg/metadata/testdata/projectv3/migrations/default/1623841500466_create_table_pub_t3/up.sql create mode 100644 cli/pkg/metadata/testdata/projectv3/migrations/default/1623841510619_create_table_pub_t4/down.sql create mode 100644 cli/pkg/metadata/testdata/projectv3/migrations/default/1623841510619_create_table_pub_t4/up.sql create mode 100644 cli/pkg/migrate/apply.go create mode 100644 cli/pkg/migrate/project_migrate.go create mode 100644 cli/pkg/migrate/project_migrate_test.go create mode 100644 cli/pkg/migrate/status.go create mode 100644 cli/pkg/migrate/testdata/projectv2/config.yaml create mode 100644 cli/pkg/migrate/testdata/projectv2/metadata/actions.graphql create mode 100644 cli/pkg/migrate/testdata/projectv2/metadata/actions.yaml create mode 100644 cli/pkg/migrate/testdata/projectv2/metadata/allow_list.yaml create mode 100644 cli/pkg/migrate/testdata/projectv2/metadata/cron_triggers.yaml create mode 100644 cli/pkg/migrate/testdata/projectv2/metadata/functions.yaml create mode 100644 cli/pkg/migrate/testdata/projectv2/metadata/query_collections.yaml create mode 100644 cli/pkg/migrate/testdata/projectv2/metadata/remote_schemas.yaml create mode 100644 cli/pkg/migrate/testdata/projectv2/metadata/tables.yaml create mode 100644 cli/pkg/migrate/testdata/projectv2/metadata/version.yaml create mode 100644 cli/pkg/migrate/testdata/projectv2/migrations/1623842054907_create_table_public_t1/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv2/migrations/1623842054907_create_table_public_t1/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv2/migrations/1623842062104_create_table_public_t2/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv2/migrations/1623842062104_create_table_public_t2/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv2/migrations/1623842069725_create_schema_pub/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv2/migrations/1623842069725_create_schema_pub/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/config.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/actions.graphql create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/actions.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/allow_list.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/cron_triggers.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/databases/databases.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/pub_t3.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/pub_t4.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/public_t1.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/public_t2.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/tables.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/query_collections.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/remote_schemas.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/rest_endpoints.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/metadata/version.yaml create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841477474_create_table_public_t1/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841477474_create_table_public_t1/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841485323_create_table_public_t2/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841485323_create_table_public_t2/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841492743_create_schema_pub/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841492743_create_schema_pub/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841500466_create_table_pub_t3/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841500466_create_table_pub_t3/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841510619_create_table_pub_t4/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841510619_create_table_pub_t4/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841477474_create_table_public_t1/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841477474_create_table_public_t1/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841485323_create_table_public_t2/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841485323_create_table_public_t2/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841492743_create_schema_pub/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841492743_create_schema_pub/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841500466_create_table_pub_t3/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841500466_create_table_pub_t3/up.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841510619_create_table_pub_t4/down.sql create mode 100644 cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841510619_create_table_pub_t4/up.sql diff --git a/cli/cli.go b/cli/cli.go index e7ada678202..f39a0ec6919 100644 --- a/cli/cli.go +++ b/cli/cli.go @@ -12,6 +12,7 @@ import ( "crypto/x509" "encoding/json" "fmt" + "io" "io/ioutil" "net/http" "net/url" @@ -354,7 +355,8 @@ type Config struct { type ExecutionContext struct { // CMDName is the name of CMD (os.Args[0]). To be filled in later to // correctly render example strings etc. - CMDName string + CMDName string + Stderr, Stdout io.Writer // ID is a unique ID for this Execution ID string @@ -456,7 +458,10 @@ type Source struct { // NewExecutionContext returns a new instance of execution context func NewExecutionContext() *ExecutionContext { - ec := &ExecutionContext{} + ec := &ExecutionContext{ + Stderr: os.Stderr, + Stdout: os.Stdout, + } ec.Telemetry = telemetry.BuildEvent() ec.Telemetry.Version = version.BuildVersion return ec @@ -880,7 +885,7 @@ func (ec *ExecutionContext) readConfig() error { func (ec *ExecutionContext) setupSpinner() { if ec.Spinner == nil { spnr := spinner.New(spinner.CharSets[7], 100*time.Millisecond) - spnr.Writer = os.Stderr + spnr.Writer = ec.Stderr ec.Spinner = spnr } } @@ -920,7 +925,7 @@ func (ec *ExecutionContext) setupLogger() { if ec.Logger == nil { logger := logrus.New() ec.Logger = logger - ec.Logger.SetOutput(os.Stderr) + ec.Logger.SetOutput(ec.Stderr) } if ec.LogLevel != "" { diff --git a/cli/commands/metadata_apply.go b/cli/commands/metadata_apply.go index e97c369a6ee..76dcdb38342 100644 --- a/cli/commands/metadata_apply.go +++ b/cli/commands/metadata_apply.go @@ -62,7 +62,7 @@ func (o *MetadataApplyOptions) Run() error { if !o.DryRun { o.EC.Spin("Applying metadata...") if o.EC.Config.Version == cli.V2 { - err := metadataHandler.V1ApplyMetadata() + _, err := metadataHandler.V1ApplyMetadata() o.EC.Spinner.Stop() if err != nil { return errorApplyingMetadata(err) diff --git a/cli/commands/metadata_diff.go b/cli/commands/metadata_diff.go index 9b5bfabe7af..c1ff169b26b 100644 --- a/cli/commands/metadata_diff.go +++ b/cli/commands/metadata_diff.go @@ -2,12 +2,13 @@ package commands import ( "fmt" - "github.com/aryann/difflib" - "io" + "io" "io/ioutil" "os" "strings" + "github.com/aryann/difflib" + "github.com/hasura/graphql-engine/cli/v2/internal/metadataobject" "github.com/hasura/graphql-engine/cli/v2" @@ -21,10 +22,11 @@ import ( ) type MetadataDiffOptions struct { - EC *cli.ExecutionContext - Output io.Writer - Args []string - DiffType string + EC *cli.ExecutionContext + Output io.Writer + Args []string + DiffType string + DisableColor bool // two Metadata to diff, 2nd is server if it's empty Metadata [2]string } @@ -146,9 +148,9 @@ func (o *MetadataDiffOptions) runv2(args []string) error { } if o.Metadata[1] != "" { - err = printDiff(string(oldYaml), string(newYaml), o.Metadata[0], o.Metadata[1], o.Output, o.DiffType) + err = printDiff(string(oldYaml), string(newYaml), o.Metadata[0], o.Metadata[1], o.Output, o.DiffType, o.DisableColor) } else { - err = printDiff(string(oldYaml), string(newYaml), o.Metadata[0], "server", o.Output, o.DiffType) + err = printDiff(string(oldYaml), string(newYaml), o.Metadata[0], "server", o.Output, o.DiffType, o.DisableColor) } if err != nil { @@ -164,35 +166,42 @@ func (o *MetadataDiffOptions) Run() error { return fmt.Errorf("metadata diff for config %d not supported", o.EC.Config.Version) } } + type Difftype string + const DifftypeUnifiedCommon Difftype = "unified-common" -func printDiff(before, after, firstArg, SecondArg string, to io.Writer, difftype string) error { - diffType := Difftype(difftype) +func printDiff(before, after, firstArg, SecondArg string, to io.Writer, difftype string, disableColor bool) error { + diffType := Difftype(difftype) switch diffType { case DifftypeUnifiedCommon: - printDiffv1(before, after, to) + printDiffv1(before, after, to) default: - return printDiffv2(before, after, firstArg, SecondArg, to) + return printDiffv2(before, after, firstArg, SecondArg, to, disableColor) } return nil } -func printDiffv2(before, after, firstArg, SecondArg string, to io.Writer) error { +func printDiffv2(before, after, firstArg, SecondArg string, to io.Writer, disableColor bool) error { edits := myers.ComputeEdits(span.URIFromPath("a.txt"), before, after) text := fmt.Sprint(gotextdiff.ToUnified(firstArg, SecondArg, before, edits)) - + makeDiffLine := func(line, color string) string { + if disableColor { + return line + } + return ansi.Color(line, color) + } lines := strings.Split(text, "\n") for _, line := range lines { if line == "" { break } if (string)(line[0]) == "-" { - fmt.Fprintf(to, "%s\n", ansi.Color(line, "red")) + fmt.Fprintf(to, "%s\n", makeDiffLine(line, "red")) } else if (string)(line[0]) == "+" { - fmt.Fprintf(to, "%s\n", ansi.Color(line, "yellow")) + fmt.Fprintf(to, "%s\n", makeDiffLine(line, "yellow")) } else if (string)(line[0]) == "@" { - fmt.Fprintf(to, "%s\n", ansi.Color(line, "cyan")) + fmt.Fprintf(to, "%s\n", makeDiffLine(line, "cyan")) } } @@ -200,19 +209,19 @@ func printDiffv2(before, after, firstArg, SecondArg string, to io.Writer) error } func printDiffv1(before, after string, to io.Writer) { - diffs := difflib.Diff(strings.Split(before, "\n"), strings.Split(after, "\n")) + diffs := difflib.Diff(strings.Split(before, "\n"), strings.Split(after, "\n")) - for _, diff := range diffs { - text := diff.Payload - switch diff.Delta { - case difflib.RightOnly: - fmt.Fprintf(to, "%s\n", ansi.Color(text, "green")) - case difflib.LeftOnly: - fmt.Fprintf(to, "%s\n", ansi.Color(text, "red")) - case difflib.Common: - fmt.Fprintf(to, "%s\n", text) + for _, diff := range diffs { + text := diff.Payload + switch diff.Delta { + case difflib.RightOnly: + fmt.Fprintf(to, "%s\n", ansi.Color(text, "green")) + case difflib.LeftOnly: + fmt.Fprintf(to, "%s\n", ansi.Color(text, "red")) + case difflib.Common: + fmt.Fprintf(to, "%s\n", text) + } } - } } func checkDir(path string) error { diff --git a/cli/commands/metadata_reload.go b/cli/commands/metadata_reload.go index 3d41b2fddb3..e2ca654108e 100644 --- a/cli/commands/metadata_reload.go +++ b/cli/commands/metadata_reload.go @@ -47,7 +47,7 @@ func (o *metadataReloadOptions) run() error { var err error metadataHandler := metadataobject.NewHandlerFromEC(ec) - err = metadataHandler.ReloadMetadata() + _, err = metadataHandler.ReloadMetadata() if err != nil { return errors.Wrap(err, "Cannot reload metadata") } diff --git a/cli/commands/migrate_apply.go b/cli/commands/migrate_apply.go index b7286cabc9d..866ed3db684 100644 --- a/cli/commands/migrate_apply.go +++ b/cli/commands/migrate_apply.go @@ -6,6 +6,8 @@ import ( "path/filepath" "strconv" + "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" @@ -61,80 +63,7 @@ func newMigrateApplyCmd(ec *cli.ExecutionContext) *cobra.Command { return validateConfigV3Flags(cmd, ec) }, RunE: func(cmd *cobra.Command, args []string) error { - opts.Source = ec.Source - if opts.dryRun && opts.SkipExecution { - return errors.New("both --skip-execution and --dry-run flags cannot be used together") - } - if opts.allDatabases { - opts.EC.Spin("getting lists of databases from server ") - sourcesAndKind, err := metadatautil.GetSourcesAndKind(ec.APIClient.V1Metadata.ExportMetadata) - opts.EC.Spinner.Stop() - if err != nil { - return fmt.Errorf("determing list of connected sources and kind: %w", err) - } - for _, source := range sourcesAndKind { - opts.Source.Kind = source.Kind - opts.Source.Name = source.Name - if !opts.dryRun { - opts.EC.Spin(fmt.Sprintf("Applying migrations on database: %s ", opts.Source.Name)) - } - err := opts.Run() - opts.EC.Spinner.Stop() - if err != nil { - if err == migrate.ErrNoChange { - opts.EC.Logger.Infof("nothing to apply on database: %s", opts.Source.Name) - continue - } - if e, ok := err.(*os.PathError); ok { - // If Op is first, then log No migrations to apply - if e.Op == "first" { - opts.EC.Logger.Infof("nothing to apply on database: %s", opts.Source.Name) - continue - } - } - // check if the returned error is a directory not found error - // ie might be because a migrations/ directory is not found - // if so skip this - if e, ok := err.(*errDatabaseMigrationDirectoryNotFound); ok { - opts.EC.Logger.Errorf("skipping applying migrations for database %s, encountered: \n%s", opts.Source.Name, e.Error()) - continue - } - opts.EC.Logger.Errorf("skipping applying migrations for database %s, encountered: \n%v", opts.Source.Name, err) - continue - } - opts.EC.Logger.Infof("applied migrations on database: %s", opts.Source.Name) - } - } else { - if !opts.dryRun { - opts.EC.Spin("Applying migrations...") - } - err := opts.Run() - opts.EC.Spinner.Stop() - if err != nil { - if err == migrate.ErrNoChange { - opts.EC.Logger.Info("nothing to apply") - return nil - } - // check if the returned error is a directory not found error - // ie might be because a migrations/ directory is not found - // if so skip this - if e, ok := err.(*errDatabaseMigrationDirectoryNotFound); ok { - return fmt.Errorf("applying migrations on database %s: %w", opts.Source.Name, e) - } - if e, ok := err.(*os.PathError); ok { - // If Op is first, then log No migrations to apply - if e.Op == "first" { - opts.EC.Logger.Info("nothing to apply") - return nil - } - } - return fmt.Errorf("apply failed\n%w", err) - } - if !opts.dryRun { - opts.EC.Logger.Info("migrations applied") - } - } - return nil + return opts.Run() }, } f := migrateApplyCmd.Flags() @@ -148,8 +77,8 @@ func newMigrateApplyCmd(ec *cli.ExecutionContext) *cobra.Command { f.BoolVar(&opts.SkipExecution, "skip-execution", false, "skip executing the migration action, but mark them as applied") 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.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") return migrateApplyCmd } @@ -163,10 +92,42 @@ type MigrateApplyOptions struct { // version up to which migration chain has to be applied GotoVersion string SkipExecution bool - dryRun bool + DryRun bool Source cli.Source - allDatabases bool + AllDatabases bool } + +func (o *MigrateApplyOptions) Validate() error { + if o.EC.Config.Version == cli.V2 { + o.Source.Kind = hasura.SourceKindPG + o.Source.Name = "" + } + + if o.EC.Config.Version >= cli.V3 { + if !o.AllDatabases && len(o.Source.Name) == 0 { + return fmt.Errorf("unable to determine database on which migration should be applied") + } + if !o.AllDatabases { + if len(o.Source.Name) == 0 { + return fmt.Errorf("empty database name") + } + if len(o.Source.Kind) == 0 { + // 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(o.EC.APIClient.V1Metadata.ExportMetadata, o.Source.Name) + if err != nil { + return fmt.Errorf("determining database kind of %s: %w", o.Source.Name, err) + } + if sourceKind == nil { + return fmt.Errorf("error determining database kind for %s, check if database exists on hasura", o.Source.Name) + } + o.Source.Kind = *sourceKind + } + } + } + return nil +} + type errDatabaseMigrationDirectoryNotFound struct { message string } @@ -175,6 +136,87 @@ func (e *errDatabaseMigrationDirectoryNotFound) Error() string { return e.message } func (o *MigrateApplyOptions) Run() error { + if len(o.Source.Name) == 0 { + o.Source = o.EC.Source + } + if err := o.Validate(); err != nil { + return err + } + if o.DryRun && o.SkipExecution { + return errors.New("both --skip-execution and --dry-run flags cannot be used together") + } + if o.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() + if err != nil { + return fmt.Errorf("determing list of connected sources and kind: %w", err) + } + for _, source := range sourcesAndKind { + o.Source.Kind = source.Kind + o.Source.Name = source.Name + if !o.DryRun { + o.EC.Spin(fmt.Sprintf("Applying migrations on database: %s ", o.Source.Name)) + } + err := o.Exec() + o.EC.Spinner.Stop() + if err != nil { + if err == migrate.ErrNoChange { + o.EC.Logger.Infof("nothing to apply on database: %s", o.Source.Name) + continue + } + if e, ok := err.(*os.PathError); ok { + // If Op is first, then log No migrations to apply + if e.Op == "first" { + o.EC.Logger.Infof("nothing to apply on database: %s", o.Source.Name) + continue + } + } + // check if the returned error is a directory not found error + // ie might be because a migrations/ directory is not found + // if so skip this + if e, ok := err.(*errDatabaseMigrationDirectoryNotFound); ok { + o.EC.Logger.Errorf("skipping applying migrations for database %s, encountered: \n%s", o.Source.Name, e.Error()) + continue + } + o.EC.Logger.Errorf("skipping applying migrations for database %s, encountered: \n%v", o.Source.Name, err) + continue + } + o.EC.Logger.Infof("applied migrations on database: %s", o.Source.Name) + } + } else { + if !o.DryRun { + o.EC.Spin("Applying migrations...") + } + err := o.Exec() + o.EC.Spinner.Stop() + if err != nil { + if err == migrate.ErrNoChange { + o.EC.Logger.Info("nothing to apply") + return nil + } + // check if the returned error is a directory not found error + // ie might be because a migrations/ directory is not found + // if so skip this + if e, ok := err.(*errDatabaseMigrationDirectoryNotFound); ok { + return fmt.Errorf("applying migrations on database %s: %w", o.Source.Name, e) + } + if e, ok := err.(*os.PathError); ok { + // If Op is first, then log No migrations to apply + if e.Op == "first" { + o.EC.Logger.Info("nothing to apply") + return nil + } + } + return fmt.Errorf("apply failed\n%w", err) + } + if !o.DryRun { + o.EC.Logger.Info("migrations applied") + } + } + return nil +} +func (o *MigrateApplyOptions) Exec() error { if o.EC.Config.Version >= cli.V3 { // check if a migrations directory exists for source in project migrationDirectory := filepath.Join(o.EC.MigrationDir, o.Source.Name) @@ -182,7 +224,7 @@ func (o *MigrateApplyOptions) Run() 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.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) @@ -195,7 +237,7 @@ func (o *MigrateApplyOptions) Run() error { return err } migrateDrv.SkipExecution = o.SkipExecution - migrateDrv.DryRun = o.dryRun + migrateDrv.DryRun = o.DryRun return ExecuteMigration(migrationType, migrateDrv, step) } diff --git a/cli/commands/migrate_status.go b/cli/commands/migrate_status.go index d024d395182..e0538ed3eda 100644 --- a/cli/commands/migrate_status.go +++ b/cli/commands/migrate_status.go @@ -6,6 +6,8 @@ import ( "os" "text/tabwriter" + "github.com/hasura/graphql-engine/cli/v2/internal/hasura" + "github.com/hasura/graphql-engine/cli/v2/util" "github.com/hasura/graphql-engine/cli/v2" @@ -52,6 +54,10 @@ type MigrateStatusOptions struct { } func (o *MigrateStatusOptions) Run() (*migrate.Status, error) { + if o.EC.Config.Version <= cli.V2 { + o.Source.Name = "" + o.Source.Kind = hasura.SourceKindPG + } migrateDrv, err := migrate.NewMigrate(o.EC, true, o.Source.Name, o.Source.Kind) if err != nil { return nil, err diff --git a/cli/go.mod b/cli/go.mod index cf1276145e4..4936c2ddfe8 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -46,7 +46,6 @@ require ( github.com/ory/dockertest/v3 v3.6.3 github.com/parnurzeal/gorequest v0.2.16 github.com/pkg/errors v0.9.1 - github.com/pmezard/go-difflib v1.0.0 github.com/qor/admin v0.0.0-20191205023516-9032e7fec172 // indirect github.com/qor/assetfs v0.0.0-20170713023933-ff57fdc13a14 // indirect github.com/qor/audited v0.0.0-20171228121055-b52c9c2f0571 // indirect diff --git a/cli/go.sum b/cli/go.sum index 53ea4f50629..c900bc8da5e 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -176,8 +176,6 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gobuffalo/here v0.6.0 h1:hYrd0a6gDmWxBM4TnrGw8mQg24iSVoIkHEk7FodQcBI= -github.com/gobuffalo/here v0.6.0/go.mod h1:wAG085dHOYqUpf+Ap+WOdrPTp5IYcDAs/x7PLa8Y5fM= github.com/goccy/go-yaml v1.8.8 h1:MGfRB1GeSn/hWXYWS2Pt67iC2GJNnebdIro01ddyucA= github.com/goccy/go-yaml v1.8.8/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -313,7 +311,6 @@ github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd h1:Coekwdh0v github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -379,7 +376,6 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -414,8 +410,6 @@ github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtb github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -472,17 +466,13 @@ github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYe github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -549,12 +539,8 @@ github.com/yosssi/gohtml v0.0.0-20190915184251-7ff6f235ecaf h1:VA200mPTYh9FWY8zK github.com/yosssi/gohtml v0.0.0-20190915184251-7ff6f235ecaf/go.mod h1:+ccdNT0xMY1dtc5XBxumbYfOUhmduiGudqaDgD2rVRE= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -622,7 +608,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191003171128-d98b1b443823/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -667,11 +652,8 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -725,7 +707,6 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= @@ -751,13 +732,9 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -771,12 +748,8 @@ google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -800,12 +773,8 @@ google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -827,7 +796,6 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= @@ -852,11 +820,8 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= @@ -869,13 +834,9 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= -moul.io/http2curl v1.0.0 h1:6XwpyZOYsgZJrU8exnG87ncVkU1FVCcTRpwzOkTDUi8= moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= -moul.io/http2curl v1.0.0/go.mod h1:f6cULg+e4Md/oW1cYmwW4IWQOVl2lGbmCNGOHvzX2kE= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/cli/integration_test/v2/migrate.go b/cli/integration_test/v2/migrate.go index 8615b17cbfd..f78524c31cf 100644 --- a/cli/integration_test/v2/migrate.go +++ b/cli/integration_test/v2/migrate.go @@ -27,7 +27,7 @@ func TestMigrateCmd(t *testing.T, ec *cli.ExecutionContext) { if err != nil { t.Fatalf("unable to copy migrations directory %v", err) } - + ec.Source.Kind = hasura.SourceKindPG tt := []struct { name string opts migrateInterface diff --git a/cli/integration_test/v3/migrate.go b/cli/integration_test/v3/migrate.go index 2dde85e2d96..88b4a6e60fe 100644 --- a/cli/integration_test/v3/migrate.go +++ b/cli/integration_test/v3/migrate.go @@ -27,7 +27,8 @@ func TestMigrateCmd(t *testing.T, ec *cli.ExecutionContext) { if err != nil { t.Fatalf("unable to copy migrations directory %v", err) } - + ec.Source.Name = "default" + ec.Source.Kind = hasura.SourceKindPG tt := []struct { name string opts migrateInterface diff --git a/cli/integration_test/v3/seeds/1591867862409_test.sql b/cli/integration_test/v3/seeds/default/1591867862409_test.sql similarity index 100% rename from cli/integration_test/v3/seeds/1591867862409_test.sql rename to cli/integration_test/v3/seeds/default/1591867862409_test.sql diff --git a/cli/integration_test/v3/seeds/1591867862419_test2.sql b/cli/integration_test/v3/seeds/default/1591867862419_test2.sql similarity index 100% rename from cli/integration_test/v3/seeds/1591867862419_test2.sql rename to cli/integration_test/v3/seeds/default/1591867862419_test2.sql diff --git a/cli/internal/metadataobject/handler.go b/cli/internal/metadataobject/handler.go index 5335543675a..09c3492f757 100644 --- a/cli/internal/metadataobject/handler.go +++ b/cli/internal/metadataobject/handler.go @@ -88,10 +88,10 @@ func (h *Handler) ResetMetadata() error { } // ReloadMetadata - Reload Hasura GraphQL Engine metadata on the database -func (h *Handler) ReloadMetadata() error { +func (h *Handler) ReloadMetadata() (io.Reader, error) { var err error - _, err = h.v1MetadataOps.ReloadMetadata() - return err + r, err := h.v1MetadataOps.ReloadMetadata() + return r, err } func (h *Handler) BuildMetadata() (yaml.MapSlice, error) { @@ -125,16 +125,16 @@ func (h *Handler) MakeJSONMetadata() ([]byte, error) { return jbyt, nil } -func (h *Handler) V1ApplyMetadata() error { +func (h *Handler) V1ApplyMetadata() (io.Reader, error) { jbyt, err := h.MakeJSONMetadata() if err != nil { - return err + return nil, err } - _, err = h.v1MetadataOps.ReplaceMetadata(bytes.NewReader(jbyt)) + r, err := h.v1MetadataOps.ReplaceMetadata(bytes.NewReader(jbyt)) if err != nil { - return err + return nil, err } - return nil + return r, nil } func (h *Handler) V2ApplyMetadata() (*hasura.V2ReplaceMetadataResponse, error) { diff --git a/cli/internal/testutil/vars.go b/cli/internal/testutil/vars.go index 2038375e163..b298b1ff616 100644 --- a/cli/internal/testutil/vars.go +++ b/cli/internal/testutil/vars.go @@ -16,6 +16,8 @@ var ( return "" }() + TestAdminSecret = os.Getenv("HASURA_GRAPHQL_TEST_ADMIN_SECRET") + DockerSwitchIP = func() string { switch runtime.GOOS { case "darwin", "windows": diff --git a/cli/logger_hook.go b/cli/logger_hook.go index 7b2158aaf33..350fabadf9a 100644 --- a/cli/logger_hook.go +++ b/cli/logger_hook.go @@ -1,10 +1,11 @@ package cli import ( + "io" + "github.com/briandowns/spinner" "github.com/mattn/go-colorable" "github.com/sirupsen/logrus" - "io/ioutil" ) type spinnerHook struct { @@ -14,7 +15,8 @@ type spinnerHook struct { func newSpinnerHandlerHook(parent *logrus.Logger, spinner *spinner.Spinner, isTerminal, noColor bool) *spinnerHook { logger := logrus.New() - if parent.Out != ioutil.Discard { + logger.Out = parent.Out + if parent.Out != io.Discard { if isTerminal { if noColor { logger.Formatter = &logrus.TextFormatter{ @@ -27,12 +29,12 @@ func newSpinnerHandlerHook(parent *logrus.Logger, spinner *spinner.Spinner, isTe DisableTimestamp: true, } } + logger.Out = colorable.NewColorableStderr() } else { logger.Formatter = &logrus.JSONFormatter{ PrettyPrint: false, } } - logger.Out = colorable.NewColorableStderr() logger.Level = parent.GetLevel() } return &spinnerHook{ diff --git a/cli/pkg/metadata/project_metadata.go b/cli/pkg/metadata/project_metadata.go new file mode 100644 index 00000000000..a6bd017ea33 --- /dev/null +++ b/cli/pkg/metadata/project_metadata.go @@ -0,0 +1,113 @@ +package metadata + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + + "github.com/hasura/graphql-engine/cli/v2/commands" + + "github.com/hasura/graphql-engine/cli/v2/internal/metadataobject" + + "github.com/spf13/viper" + + "github.com/hasura/graphql-engine/cli/v2" +) + +type ProjectMetadata struct { + ec *cli.ExecutionContext +} + +// Parse metadata in project as JSON +func (p *ProjectMetadata) Parse() (io.Reader, error) { + metadataHandler := metadataobject.NewHandlerFromEC(p.ec) + jsonMetadata, err := metadataHandler.MakeJSONMetadata() + if err != nil { + return nil, fmt.Errorf("parsing project metadata to json failed: %w", err) + } + return bytes.NewReader(jsonMetadata), nil +} + +// Apply metadata from in the project and provide raw response from hge server +func (p *ProjectMetadata) Apply() (io.Reader, error) { + metadataHandler := metadataobject.NewHandlerFromEC(p.ec) + if p.ec.Config.Version == cli.V2 { + r, err := metadataHandler.V1ApplyMetadata() + if err != nil { + return nil, err + } + return r, nil + } + if p.ec.Config.Version >= cli.V3 { + replaceMetadataResponse, err := metadataHandler.V2ApplyMetadata() + if err != nil { + return nil, err + } + b := new(bytes.Buffer) + if err := json.NewEncoder(b).Encode(replaceMetadataResponse); err != nil { + return nil, fmt.Errorf("encoding json reponse from server: %w", err) + } + return b, nil + } + return nil, nil +} + +// Reload metadata on hge server and provides raw response from hge server +func (p *ProjectMetadata) Reload() (io.Reader, error) { + metadataHandler := metadataobject.NewHandlerFromEC(p.ec) + return metadataHandler.ReloadMetadata() +} + +// Diff will return the differences between metadata in the project (in JSON) and on the server +func (p *ProjectMetadata) Diff() (io.Reader, error) { + w := new(bytes.Buffer) + opts := &commands.MetadataDiffOptions{ + EC: p.ec, + Output: w, + DisableColor: true, + } + if err := opts.Run(); err != nil { + return nil, err + } + return w, nil +} + +type ProjectMetadataOption func(*ProjectMetadata) + +func WithAdminSecret(adminSecret string) ProjectMetadataOption { + return func(m *ProjectMetadata) { + m.ec.Viper.Set("admin_secret", adminSecret) + } +} + +func WithEndpoint(endpoint string) ProjectMetadataOption { + return func(m *ProjectMetadata) { + m.ec.Viper.Set("endpoint", endpoint) + } +} + +func NewProjectMetadata(projectDirectory string, opts ...ProjectMetadataOption) (*ProjectMetadata, error) { + ec := cli.NewExecutionContext() + ec.ExecutionDirectory = projectDirectory + ec.Viper = viper.New() + ec.IsTerminal = false + ec.Stdout = io.Discard + ec.Stderr = io.Discard + + if err := ec.Prepare(); err != nil { + return nil, err + } + p := &ProjectMetadata{ec} + for _, opt := range opts { + opt(p) + } + + if err := ec.Validate(); err != nil { + return nil, err + } + if ec.Config.Version <= cli.V1 { + return nil, fmt.Errorf("config %v is not supported", ec.Config.Version) + } + return p, nil +} diff --git a/cli/pkg/metadata/project_metadata_test.go b/cli/pkg/metadata/project_metadata_test.go new file mode 100644 index 00000000000..ae621701daf --- /dev/null +++ b/cli/pkg/metadata/project_metadata_test.go @@ -0,0 +1,206 @@ +package metadata + +import ( + "fmt" + "io/ioutil" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/hasura/graphql-engine/cli/v2/internal/testutil" +) + +func TestProjectMetadataOps_Apply(t *testing.T) { + port, teardown := testutil.StartHasura(t, testutil.HasuraDockerImage) + hgeEndpoint := fmt.Sprintf("http://localhost:%s", port) + defer teardown() + type fields struct { + projectDirectory string + endpointString string + } + tests := []struct { + name string + fields fields + want string + wantErr bool + }{ + { + "can apply metadata from config v3 project", + fields{ + projectDirectory: "testdata/projectv3", + endpointString: hgeEndpoint, + }, + `{"is_consistent":false,"inconsistent_objects":[{"definition":{"name":"t1","schema":"public"},"name":"table t1 in source default","reason":"Inconsistent object: no such table/view exists in source: \"t1\"","type":"table"},{"definition":{"name":"t2","schema":"public"},"name":"table t2 in source default","reason":"Inconsistent object: no such table/view exists in source: \"t2\"","type":"table"},{"definition":{"name":"t4","schema":"pub"},"name":"table pub.t4 in source default","reason":"Inconsistent object: no such table/view exists in source: \"pub.t4\"","type":"table"},{"definition":{"name":"t3","schema":"pub"},"name":"table pub.t3 in source default","reason":"Inconsistent object: no such table/view exists in source: \"pub.t3\"","type":"table"}]}`, + false, + }, + { + "can apply metadata from config v2 project", + fields{ + projectDirectory: "testdata/projectv2", + endpointString: hgeEndpoint, + }, + "", + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p, err := NewProjectMetadata(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString)) + require.NoError(t, err) + got, err := p.Apply() + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.NotNil(t, got) + + gotb, err := ioutil.ReadAll(got) + require.NoError(t, err) + require.JSONEq(t, tt.want, string(gotb)) + } + }) + } +} + +func TestProjectMetadataOps_Parse(t *testing.T) { + port, teardown := testutil.StartHasura(t, testutil.HasuraDockerImage) + hgeEndpoint := fmt.Sprintf("http://localhost:%s", port) + defer teardown() + type fields struct { + projectDirectory string + adminSecret string + endpointString string + } + tests := []struct { + name string + fields fields + wantGolden string + wantErr bool + }{ + { + "can generate json metadata from config v3 project", + fields{ + projectDirectory: "testdata/projectv3", + }, + "testdata/metadata_parse_test/config-v3.golden.json", + false, + }, + { + "can generate json metadata from config v2 project", + fields{ + projectDirectory: "testdata/projectv2", + }, + "testdata/metadata_parse_test/config-v2.golden.json", + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p, err := NewProjectMetadata(tt.fields.projectDirectory, WithEndpoint(hgeEndpoint), WithAdminSecret(testutil.TestAdminSecret)) + require.NoError(t, err) + got, err := p.Parse() + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.NotNil(t, got) + gotb, err := ioutil.ReadAll(got) + require.NoError(t, err) + wantb, err := ioutil.ReadFile(tt.wantGolden) + require.NoError(t, err) + + require.JSONEq(t, string(wantb), string(gotb)) + } + }) + } +} + +func TestProjectMetadataOps_Diff(t *testing.T) { + port, teardown := testutil.StartHasura(t, testutil.HasuraDockerImage) + hgeEndpoint := fmt.Sprintf("http://localhost:%s", port) + defer teardown() + type fields struct { + projectDirectory string + adminSecret string + endpointString string + } + tests := []struct { + name string + fields fields + wantGolden string + wantErr bool + }{ + { + "can generate diff on config v3 project", + fields{ + projectDirectory: "testdata/projectv3", + }, + "testdata/metadata_diff_test/config_v3_diff", + false, + }, + { + "can generate diff on config v2 project", + fields{ + projectDirectory: "testdata/projectv2", + }, + "testdata/metadata_diff_test/config_v2_diff", + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p, err := NewProjectMetadata(tt.fields.projectDirectory, WithEndpoint(hgeEndpoint), WithAdminSecret(testutil.TestAdminSecret)) + require.NoError(t, err) + got, err := p.Diff() + if tt.wantErr { + require.Error(t, err) + } + gotb, err := ioutil.ReadAll(got) + require.NoError(t, err) + wantb, err := ioutil.ReadFile(tt.wantGolden) + require.NoError(t, err) + require.Equal(t, string(wantb), string(gotb)) + }) + } +} + +func TestProjectMetadata_Reload(t *testing.T) { + port, teardown := testutil.StartHasura(t, testutil.HasuraDockerImage) + hgeEndpoint := fmt.Sprintf("http://localhost:%s", port) + defer teardown() + type fields struct { + projectDirectory string + adminSecret string + endpointString string + } + tests := []struct { + name string + fields fields + want string + wantErr bool + }{ + { + "can reload metadata", + fields{ + projectDirectory: "testdata/projectv3", + endpointString: hgeEndpoint, + }, + `{"message": "success"}`, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p, err := NewProjectMetadata(tt.fields.projectDirectory, WithEndpoint(hgeEndpoint), WithAdminSecret(testutil.TestAdminSecret)) + require.NoError(t, err) + got, err := p.Reload() + if tt.wantErr { + require.Error(t, err) + } + require.NoError(t, err) + gotb, err := ioutil.ReadAll(got) + require.NoError(t, err) + require.JSONEq(t, tt.want, string(gotb)) + }) + } +} diff --git a/cli/pkg/metadata/testdata/metadata_diff_test/config_v2_diff b/cli/pkg/metadata/testdata/metadata_diff_test/config_v2_diff new file mode 100644 index 00000000000..974fdaadf98 --- /dev/null +++ b/cli/pkg/metadata/testdata/metadata_diff_test/config_v2_diff @@ -0,0 +1,17 @@ +--- testdata/projectv2/metadata ++++ server +@@ -1,14 +1,2 @@ +-tables: +-- table: +- name: t3 +- schema: pub +-- table: +- name: t4 +- schema: pub +-- table: +- name: t1 +- schema: public +-- table: +- name: t2 +- schema: public ++tables: [] diff --git a/cli/pkg/metadata/testdata/metadata_diff_test/config_v3_diff b/cli/pkg/metadata/testdata/metadata_diff_test/config_v3_diff new file mode 100644 index 00000000000..e857f953381 --- /dev/null +++ b/cli/pkg/metadata/testdata/metadata_diff_test/config_v3_diff @@ -0,0 +1,17 @@ +--- testdata/projectv3/metadata ++++ server +@@ -13,16 +13,4 @@ +- tables: +- - table: +- name: t3 +- schema: pub +- - table: +- name: t4 +- schema: pub +- - table: +- name: t1 +- schema: public +- - table: +- name: t2 +- schema: public ++ tables: [] diff --git a/cli/pkg/metadata/testdata/metadata_parse_test/config-v2.golden.json b/cli/pkg/metadata/testdata/metadata_parse_test/config-v2.golden.json new file mode 100644 index 00000000000..bebc6208830 --- /dev/null +++ b/cli/pkg/metadata/testdata/metadata_parse_test/config-v2.golden.json @@ -0,0 +1,29 @@ +{ + "version": 2, + "tables": [ + { + "table": { + "name": "t3", + "schema": "pub" + } + }, + { + "table": { + "name": "t4", + "schema": "pub" + } + }, + { + "table": { + "name": "t1", + "schema": "public" + } + }, + { + "table": { + "name": "t2", + "schema": "public" + } + } + ] +} diff --git a/cli/pkg/metadata/testdata/metadata_parse_test/config-v3.golden.json b/cli/pkg/metadata/testdata/metadata_parse_test/config-v3.golden.json new file mode 100644 index 00000000000..cb22605fd95 --- /dev/null +++ b/cli/pkg/metadata/testdata/metadata_parse_test/config-v3.golden.json @@ -0,0 +1,50 @@ +{ + "version": 3, + "sources": [ + { + "configuration": { + "connection_info": { + "database_url": { + "from_env": "HASURA_GRAPHQL_DATABASE_URL" + }, + "isolation_level": "read-committed", + "pool_settings": { + "connection_lifetime": 600, + "idle_timeout": 180, + "max_connections": 50, + "retries": 1 + }, + "use_prepared_statements": true + } + }, + "kind": "postgres", + "name": "default", + "tables": [ + { + "table": { + "name": "t3", + "schema": "pub" + } + }, + { + "table": { + "name": "t4", + "schema": "pub" + } + }, + { + "table": { + "name": "t1", + "schema": "public" + } + }, + { + "table": { + "name": "t2", + "schema": "public" + } + } + ] + } + ] +} diff --git a/cli/pkg/metadata/testdata/projectv2/config.yaml b/cli/pkg/metadata/testdata/projectv2/config.yaml new file mode 100644 index 00000000000..6ddf586e53d --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/config.yaml @@ -0,0 +1,6 @@ +version: 2 +endpoint: http://localhost:8080 +metadata_directory: metadata +actions: + kind: synchronous + handler_webhook_baseurl: http://localhost:3000 diff --git a/cli/pkg/metadata/testdata/projectv2/metadata/actions.graphql b/cli/pkg/metadata/testdata/projectv2/metadata/actions.graphql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cli/pkg/metadata/testdata/projectv2/metadata/actions.yaml b/cli/pkg/metadata/testdata/projectv2/metadata/actions.yaml new file mode 100644 index 00000000000..1edb4c2ffc5 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/metadata/actions.yaml @@ -0,0 +1,6 @@ +actions: [] +custom_types: + enums: [] + input_objects: [] + objects: [] + scalars: [] diff --git a/cli/pkg/metadata/testdata/projectv2/metadata/allow_list.yaml b/cli/pkg/metadata/testdata/projectv2/metadata/allow_list.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/metadata/allow_list.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/metadata/testdata/projectv2/metadata/cron_triggers.yaml b/cli/pkg/metadata/testdata/projectv2/metadata/cron_triggers.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/metadata/cron_triggers.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/metadata/testdata/projectv2/metadata/functions.yaml b/cli/pkg/metadata/testdata/projectv2/metadata/functions.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/metadata/functions.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/metadata/testdata/projectv2/metadata/query_collections.yaml b/cli/pkg/metadata/testdata/projectv2/metadata/query_collections.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/metadata/query_collections.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/metadata/testdata/projectv2/metadata/remote_schemas.yaml b/cli/pkg/metadata/testdata/projectv2/metadata/remote_schemas.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/metadata/remote_schemas.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/metadata/testdata/projectv2/metadata/tables.yaml b/cli/pkg/metadata/testdata/projectv2/metadata/tables.yaml new file mode 100644 index 00000000000..46d71f1c64f --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/metadata/tables.yaml @@ -0,0 +1,12 @@ +- table: + schema: pub + name: t3 +- table: + schema: pub + name: t4 +- table: + schema: public + name: t1 +- table: + schema: public + name: t2 diff --git a/cli/pkg/metadata/testdata/projectv2/metadata/version.yaml b/cli/pkg/metadata/testdata/projectv2/metadata/version.yaml new file mode 100644 index 00000000000..22817d2a9c7 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/metadata/version.yaml @@ -0,0 +1 @@ +version: 2 diff --git a/cli/pkg/metadata/testdata/projectv2/migrations/1623842054907_create_table_public_t1/down.sql b/cli/pkg/metadata/testdata/projectv2/migrations/1623842054907_create_table_public_t1/down.sql new file mode 100644 index 00000000000..54b977c2b6b --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/migrations/1623842054907_create_table_public_t1/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."t1"; diff --git a/cli/pkg/metadata/testdata/projectv2/migrations/1623842054907_create_table_public_t1/up.sql b/cli/pkg/metadata/testdata/projectv2/migrations/1623842054907_create_table_public_t1/up.sql new file mode 100644 index 00000000000..61aedad2db3 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/migrations/1623842054907_create_table_public_t1/up.sql @@ -0,0 +1 @@ +CREATE TABLE "public"."t1" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/metadata/testdata/projectv2/migrations/1623842062104_create_table_public_t2/down.sql b/cli/pkg/metadata/testdata/projectv2/migrations/1623842062104_create_table_public_t2/down.sql new file mode 100644 index 00000000000..6a84b5b2ff2 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/migrations/1623842062104_create_table_public_t2/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."t2"; diff --git a/cli/pkg/metadata/testdata/projectv2/migrations/1623842062104_create_table_public_t2/up.sql b/cli/pkg/metadata/testdata/projectv2/migrations/1623842062104_create_table_public_t2/up.sql new file mode 100644 index 00000000000..19e05f2815e --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/migrations/1623842062104_create_table_public_t2/up.sql @@ -0,0 +1 @@ +CREATE TABLE "public"."t2" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/metadata/testdata/projectv2/migrations/1623842069725_create_schema_pub/down.sql b/cli/pkg/metadata/testdata/projectv2/migrations/1623842069725_create_schema_pub/down.sql new file mode 100644 index 00000000000..c2e1d74c3e9 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/migrations/1623842069725_create_schema_pub/down.sql @@ -0,0 +1 @@ +drop schema "pub" cascade; diff --git a/cli/pkg/metadata/testdata/projectv2/migrations/1623842069725_create_schema_pub/up.sql b/cli/pkg/metadata/testdata/projectv2/migrations/1623842069725_create_schema_pub/up.sql new file mode 100644 index 00000000000..64b99887b8d --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/migrations/1623842069725_create_schema_pub/up.sql @@ -0,0 +1 @@ +create schema "pub"; diff --git a/cli/pkg/metadata/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/down.sql b/cli/pkg/metadata/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/down.sql new file mode 100644 index 00000000000..a8b64773bf0 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/down.sql @@ -0,0 +1 @@ +DROP TABLE "pub"."t3"; diff --git a/cli/pkg/metadata/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/up.sql b/cli/pkg/metadata/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/up.sql new file mode 100644 index 00000000000..0575feb3a41 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/up.sql @@ -0,0 +1 @@ +CREATE TABLE "pub"."t3" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/metadata/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/down.sql b/cli/pkg/metadata/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/down.sql new file mode 100644 index 00000000000..35433c15285 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/down.sql @@ -0,0 +1 @@ +DROP TABLE "pub"."t4"; diff --git a/cli/pkg/metadata/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/up.sql b/cli/pkg/metadata/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/up.sql new file mode 100644 index 00000000000..4f409da7f7c --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/up.sql @@ -0,0 +1 @@ +CREATE TABLE "pub"."t4" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/metadata/testdata/projectv3/config.yaml b/cli/pkg/metadata/testdata/projectv3/config.yaml new file mode 100644 index 00000000000..725c8005e8d --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/config.yaml @@ -0,0 +1,6 @@ +version: 3 +endpoint: http://localhost:8080 +metadata_directory: metadata +actions: + kind: synchronous + handler_webhook_baseurl: http://localhost:3000 diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/actions.graphql b/cli/pkg/metadata/testdata/projectv3/metadata/actions.graphql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/actions.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/actions.yaml new file mode 100644 index 00000000000..1edb4c2ffc5 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/actions.yaml @@ -0,0 +1,6 @@ +actions: [] +custom_types: + enums: [] + input_objects: [] + objects: [] + scalars: [] diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/allow_list.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/allow_list.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/allow_list.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/cron_triggers.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/cron_triggers.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/cron_triggers.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/databases/databases.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/databases/databases.yaml new file mode 100644 index 00000000000..65a11b202ed --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/databases/databases.yaml @@ -0,0 +1,14 @@ +- name: default + kind: postgres + configuration: + connection_info: + database_url: + from_env: HASURA_GRAPHQL_DATABASE_URL + isolation_level: read-committed + pool_settings: + connection_lifetime: 600 + idle_timeout: 180 + max_connections: 50 + retries: 1 + use_prepared_statements: true + tables: "!include default/tables/tables.yaml" diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/pub_t3.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/pub_t3.yaml new file mode 100644 index 00000000000..51065134a6b --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/pub_t3.yaml @@ -0,0 +1,3 @@ +table: + name: t3 + schema: pub diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/pub_t4.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/pub_t4.yaml new file mode 100644 index 00000000000..c70fdc67359 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/pub_t4.yaml @@ -0,0 +1,3 @@ +table: + name: t4 + schema: pub diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/public_t1.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/public_t1.yaml new file mode 100644 index 00000000000..4c8eb5bb4ef --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/public_t1.yaml @@ -0,0 +1,3 @@ +table: + name: t1 + schema: public diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/public_t2.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/public_t2.yaml new file mode 100644 index 00000000000..1cba494e6b5 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/public_t2.yaml @@ -0,0 +1,3 @@ +table: + name: t2 + schema: public diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/tables.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/tables.yaml new file mode 100644 index 00000000000..c3ada35c0d8 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/databases/default/tables/tables.yaml @@ -0,0 +1,4 @@ +- "!include pub_t3.yaml" +- "!include pub_t4.yaml" +- "!include public_t1.yaml" +- "!include public_t2.yaml" diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/query_collections.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/query_collections.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/query_collections.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/remote_schemas.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/remote_schemas.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/remote_schemas.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/rest_endpoints.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/rest_endpoints.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/rest_endpoints.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/metadata/testdata/projectv3/metadata/version.yaml b/cli/pkg/metadata/testdata/projectv3/metadata/version.yaml new file mode 100644 index 00000000000..0a70affa4bd --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/metadata/version.yaml @@ -0,0 +1 @@ +version: 3 diff --git a/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841477474_create_table_public_t1/down.sql b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841477474_create_table_public_t1/down.sql new file mode 100644 index 00000000000..54b977c2b6b --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841477474_create_table_public_t1/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."t1"; diff --git a/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841477474_create_table_public_t1/up.sql b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841477474_create_table_public_t1/up.sql new file mode 100644 index 00000000000..61aedad2db3 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841477474_create_table_public_t1/up.sql @@ -0,0 +1 @@ +CREATE TABLE "public"."t1" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841485323_create_table_public_t2/down.sql b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841485323_create_table_public_t2/down.sql new file mode 100644 index 00000000000..6a84b5b2ff2 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841485323_create_table_public_t2/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."t2"; diff --git a/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841485323_create_table_public_t2/up.sql b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841485323_create_table_public_t2/up.sql new file mode 100644 index 00000000000..19e05f2815e --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841485323_create_table_public_t2/up.sql @@ -0,0 +1 @@ +CREATE TABLE "public"."t2" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841492743_create_schema_pub/down.sql b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841492743_create_schema_pub/down.sql new file mode 100644 index 00000000000..c2e1d74c3e9 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841492743_create_schema_pub/down.sql @@ -0,0 +1 @@ +drop schema "pub" cascade; diff --git a/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841492743_create_schema_pub/up.sql b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841492743_create_schema_pub/up.sql new file mode 100644 index 00000000000..64b99887b8d --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841492743_create_schema_pub/up.sql @@ -0,0 +1 @@ +create schema "pub"; diff --git a/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841500466_create_table_pub_t3/down.sql b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841500466_create_table_pub_t3/down.sql new file mode 100644 index 00000000000..a8b64773bf0 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841500466_create_table_pub_t3/down.sql @@ -0,0 +1 @@ +DROP TABLE "pub"."t3"; diff --git a/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841500466_create_table_pub_t3/up.sql b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841500466_create_table_pub_t3/up.sql new file mode 100644 index 00000000000..0575feb3a41 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841500466_create_table_pub_t3/up.sql @@ -0,0 +1 @@ +CREATE TABLE "pub"."t3" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841510619_create_table_pub_t4/down.sql b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841510619_create_table_pub_t4/down.sql new file mode 100644 index 00000000000..35433c15285 --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841510619_create_table_pub_t4/down.sql @@ -0,0 +1 @@ +DROP TABLE "pub"."t4"; diff --git a/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841510619_create_table_pub_t4/up.sql b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841510619_create_table_pub_t4/up.sql new file mode 100644 index 00000000000..4f409da7f7c --- /dev/null +++ b/cli/pkg/metadata/testdata/projectv3/migrations/default/1623841510619_create_table_pub_t4/up.sql @@ -0,0 +1 @@ +CREATE TABLE "pub"."t4" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/apply.go b/cli/pkg/migrate/apply.go new file mode 100644 index 00000000000..6d18242a3de --- /dev/null +++ b/cli/pkg/migrate/apply.go @@ -0,0 +1,49 @@ +package migrate + +import ( + "github.com/hasura/graphql-engine/cli/v2" + "github.com/hasura/graphql-engine/cli/v2/commands" +) + +type projectMigrationsApplier struct { + ec *cli.ExecutionContext + opts commands.MigrateApplyOptions +} + +func newProjectMigrationsApplier(ec *cli.ExecutionContext) *projectMigrationsApplier { + p := &projectMigrationsApplier{ec: ec, opts: commands.MigrateApplyOptions{EC: ec}} + return p +} + +type ProjectMigrationApplierOption func(applier *projectMigrationsApplier) + +func ApplyOnAllDatabases() ProjectMigrationApplierOption { + return func(p *projectMigrationsApplier) { + p.opts.AllDatabases = true + } +} + +func ApplyOnDatabaseName(databaseName string) ProjectMigrationApplierOption { + return func(p *projectMigrationsApplier) { + p.opts.Source.Name = databaseName + } +} + +type MigrationDirection string + +const MigrationDirectionUp MigrationDirection = "up" +const MigrationDirectionDown MigrationDirection = "down" + +func ApplyVersion(version string, direction MigrationDirection) ProjectMigrationApplierOption { + return func(p *projectMigrationsApplier) { + p.opts.VersionMigration = version + p.opts.MigrationType = string(direction) + } +} + +func (p *projectMigrationsApplier) Apply(opts ...ProjectMigrationApplierOption) error { + for _, opt := range opts { + opt(p) + } + return p.opts.Run() +} diff --git a/cli/pkg/migrate/project_migrate.go b/cli/pkg/migrate/project_migrate.go new file mode 100644 index 00000000000..a973c1aec58 --- /dev/null +++ b/cli/pkg/migrate/project_migrate.go @@ -0,0 +1,72 @@ +package migrate + +import ( + "fmt" + "io" + + "github.com/hasura/graphql-engine/cli/v2" + "github.com/spf13/viper" +) + +type ProjectMigrate struct { + ec *cli.ExecutionContext +} + +func (p *ProjectMigrate) status(opts ...ProjectMigrationStatusOption) ([]databaseMigration, error) { + lister := newProjectMigrationsStatus(p.ec) + if len(opts) == 0 { + opts = append(opts, StatusAllDatabases()) + } + return lister.Status(opts...) +} + +func (p *ProjectMigrate) StatusJSON(opts ...ProjectMigrationStatusOption) (io.Reader, error) { + lister := newProjectMigrationsStatus(p.ec) + if len(opts) == 0 { + opts = append(opts, StatusAllDatabases()) + } + return lister.StatusJSON(opts...) +} + +func (p *ProjectMigrate) Apply(opts ...ProjectMigrationApplierOption) error { + applier := newProjectMigrationsApplier(p.ec) + return applier.Apply(opts...) +} + +func NewProjectMigrate(projectDirectory string, opts ...ProjectMigrateOption) (*ProjectMigrate, error) { + p := &ProjectMigrate{} + ec := cli.NewExecutionContext() + ec.ExecutionDirectory = projectDirectory + ec.Viper = viper.New() + + ec.IsTerminal = false + ec.Stderr = io.Discard + ec.Stdout = io.Discard + if err := ec.Prepare(); err != nil { + return nil, err + } + p.ec = ec + for _, opt := range opts { + opt(p) + } + if err := ec.Validate(); err != nil { + return nil, err + } + if ec.Config.Version <= cli.V1 { + return nil, fmt.Errorf("config %v is not supported", ec.Config.Version) + } + return p, nil +} + +type ProjectMigrateOption func(*ProjectMigrate) + +func WithEndpoint(endpoint string) ProjectMigrateOption { + return func(m *ProjectMigrate) { + m.ec.Viper.Set("endpoint", endpoint) + } +} +func WithAdminSecret(adminSecret string) ProjectMigrateOption { + return func(m *ProjectMigrate) { + m.ec.Viper.Set("admin_secret", adminSecret) + } +} diff --git a/cli/pkg/migrate/project_migrate_test.go b/cli/pkg/migrate/project_migrate_test.go new file mode 100644 index 00000000000..92e8d976cf0 --- /dev/null +++ b/cli/pkg/migrate/project_migrate_test.go @@ -0,0 +1,541 @@ +package migrate + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/stretchr/testify/require" + + "github.com/hasura/graphql-engine/cli/v2/internal/testutil" +) + +func TestProjectMigrate_ApplyConfig_v3(t *testing.T) { + port, teardown := testutil.StartHasuraWithMetadataDatabase(t, testutil.HasuraDockerImage) + hasuraEndpoint := fmt.Sprintf("%s:%s", testutil.BaseURL, port) + connectionStringSource1, teardownPG1 := testutil.StartPGContainer(t) + connectionStringSource2, teardownPG2 := testutil.StartPGContainer(t) + testutil.AddPGSourceToHasura(t, hasuraEndpoint, connectionStringSource1, "s1") + testutil.AddPGSourceToHasura(t, hasuraEndpoint, connectionStringSource2, "s2") + defer func() { + teardownPG2() + teardownPG1() + teardown() + }() + hgeEndpoint := fmt.Sprintf("http://localhost:%s", port) + type fields struct { + projectDirectory string + endpointString string + } + type args struct { + opts []ProjectMigrationApplierOption + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + "can apply migrations in config v3 project", + fields{ + projectDirectory: "testdata/projectv3", + endpointString: hgeEndpoint, + }, + args{ + []ProjectMigrationApplierOption{ApplyOnAllDatabases()}, + }, + false, + }, + { + "can apply a version in config v3 project", + fields{ + projectDirectory: "testdata/projectv3", + endpointString: hgeEndpoint, + }, + args{ + []ProjectMigrationApplierOption{ApplyOnDatabaseName("s1"), ApplyVersion("1623841477474", MigrationDirectionDown)}, + }, + false, + }, + { + "can apply a version in config v3 project", + fields{ + projectDirectory: "testdata/projectv3", + endpointString: hgeEndpoint, + }, + args{ + []ProjectMigrationApplierOption{ApplyOnDatabaseName("s1"), ApplyVersion("1623841477474", MigrationDirectionUp)}, + }, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p, err := NewProjectMigrate(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString)) + require.NoError(t, err) + err = p.Apply(tt.args.opts...) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestProjectMigrate_Apply_Configv2(t *testing.T) { + port, teardown := testutil.StartHasura(t, testutil.HasuraDockerImage) + defer teardown() + hgeEndpoint := fmt.Sprintf("http://localhost:%s", port) + type fields struct { + projectDirectory string + adminSecret string + endpointString string + } + type args struct { + opts []ProjectMigrationApplierOption + } + tests := []struct { + name string + fields fields + args args + wantErr bool + }{ + { + "can apply migrations in config v2 project", + fields{ + projectDirectory: "testdata/projectv2", + adminSecret: "", + endpointString: hgeEndpoint, + }, + args{ + []ProjectMigrationApplierOption{ApplyOnAllDatabases()}, + }, + false, + }, + { + "can apply down migration on a version in config v2 project", + fields{ + projectDirectory: "testdata/projectv2", + adminSecret: "", + endpointString: hgeEndpoint, + }, + args{ + []ProjectMigrationApplierOption{ApplyVersion("1623842054907", MigrationDirectionDown)}, + }, + false, + }, + { + "throws error when trying to do a down migration which is not applied", + fields{ + projectDirectory: "testdata/projectv2", + adminSecret: "", + endpointString: hgeEndpoint, + }, + args{ + []ProjectMigrationApplierOption{ApplyVersion("1623842054907", MigrationDirectionDown)}, + }, + true, + }, + { + "can apply up migrations of a version on a config v2 project", + fields{ + projectDirectory: "testdata/projectv2", + adminSecret: "", + endpointString: hgeEndpoint, + }, + args{ + []ProjectMigrationApplierOption{ApplyVersion("1623842054907", MigrationDirectionUp)}, + }, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p, err := NewProjectMigrate(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString)) + require.NoError(t, err) + err = p.Apply(tt.args.opts...) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +func TestProjectMigrate_Status_ConfigV2(t *testing.T) { + port, teardown := testutil.StartHasura(t, testutil.HasuraDockerImage) + defer teardown() + hgeEndpoint := fmt.Sprintf("http://localhost:%s", port) + type fields struct { + projectDirectory string + adminSecret string + endpointString string + } + type args struct { + opts []ProjectMigrationStatusOption + } + tests := []struct { + name string + fields fields + args args + want string + wantErr bool + before func(t *testing.T, p *ProjectMigrate) + }{ + { + "can get status of migrations", + fields{ + projectDirectory: "testdata/projectv2", + adminSecret: "", + endpointString: hgeEndpoint, + }, + args{ + opts: []ProjectMigrationStatusOption{}, + }, + ` +[ + { + "databaseName": "default", + "status": { + "migrations": [ + 1623842054907, + 1623842062104, + 1623842069725, + 1623842076537, + 1623842087940 + ], + "status": { + "1623842054907": { + "database_status": false, + "source_status": true + }, + "1623842062104": { + "database_status": false, + "source_status": true + }, + "1623842069725": { + "database_status": false, + "source_status": true + }, + "1623842076537": { + "database_status": false, + "source_status": true + }, + "1623842087940": { + "database_status": false, + "source_status": true + } + } + } + } +]`, + false, + func(t *testing.T, p *ProjectMigrate) {}, + }, + { + "can get status of migrations", + fields{ + projectDirectory: "testdata/projectv2", + adminSecret: "", + endpointString: hgeEndpoint, + }, + args{ + opts: []ProjectMigrationStatusOption{}, + }, + ` +[ + { + "databaseName": "default", + "status": { + "migrations": [ + 1623842054907, + 1623842062104, + 1623842069725, + 1623842076537, + 1623842087940 + ], + "status": { + "1623842054907": { + "database_status": true, + "source_status": true + }, + "1623842062104": { + "database_status": true, + "source_status": true + }, + "1623842069725": { + "database_status": true, + "source_status": true + }, + "1623842076537": { + "database_status": true, + "source_status": true + }, + "1623842087940": { + "database_status": true, + "source_status": true + } + } + } + } +]`, + false, + func(t *testing.T, p *ProjectMigrate) { + assert.NoError(t, p.Apply(ApplyOnAllDatabases())) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p, err := NewProjectMigrate(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString)) + require.NoError(t, err) + applier, err := NewProjectMigrate(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString)) + require.NoError(t, err) + tt.before(t, applier) + got, err := p.status(tt.args.opts...) + if tt.wantErr { + require.Error(t, err) + } + require.NoError(t, err) + gotJSON, err := json.Marshal(got) + require.NoError(t, err) + require.JSONEq(t, tt.want, string(gotJSON)) + + statusJson, err := p.StatusJSON(tt.args.opts...) + require.NoError(t, err) + statusJsonb, err := ioutil.ReadAll(statusJson) + require.NoError(t, err) + require.JSONEq(t, tt.want, string(statusJsonb)) + }) + } +} + +func TestProjectMigrate_Status_ConfigV3(t *testing.T) { + port, teardown := testutil.StartHasuraWithMetadataDatabase(t, testutil.HasuraDockerImage) + hasuraEndpoint := fmt.Sprintf("%s:%s", testutil.BaseURL, port) + connectionStringSource1, teardownPG1 := testutil.StartPGContainer(t) + connectionStringSource2, teardownPG2 := testutil.StartPGContainer(t) + testutil.AddPGSourceToHasura(t, hasuraEndpoint, connectionStringSource1, "s1") + testutil.AddPGSourceToHasura(t, hasuraEndpoint, connectionStringSource2, "s2") + defer func() { + teardownPG2() + teardownPG1() + teardown() + }() + hgeEndpoint := fmt.Sprintf("http://localhost:%s", port) + type fields struct { + projectDirectory string + adminSecret string + endpointString string + } + type args struct { + opts []ProjectMigrationStatusOption + } + tests := []struct { + name string + fields fields + args args + want string + wantErr bool + before func(t *testing.T, p *ProjectMigrate) + }{ + { + "can get status of migrations", + fields{ + projectDirectory: "testdata/projectv3", + adminSecret: "", + endpointString: hgeEndpoint, + }, + args{ + opts: []ProjectMigrationStatusOption{}, + }, + `[ + { + "databaseName": "s1", + "status": { + "migrations": [ + 1623841477474, + 1623841485323, + 1623841492743, + 1623841500466, + 1623841510619 + ], + "status": { + "1623841477474": { + "database_status": false, + "source_status": true + }, + "1623841485323": { + "database_status": false, + "source_status": true + }, + "1623841492743": { + "database_status": false, + "source_status": true + }, + "1623841500466": { + "database_status": false, + "source_status": true + }, + "1623841510619": { + "database_status": false, + "source_status": true + } + } + } + }, + { + "databaseName": "s2", + "status": { + "migrations": [ + 1623841477474, + 1623841485323, + 1623841492743, + 1623841500466, + 1623841510619 + ], + "status": { + "1623841477474": { + "database_status": false, + "source_status": true + }, + "1623841485323": { + "database_status": false, + "source_status": true + }, + "1623841492743": { + "database_status": false, + "source_status": true + }, + "1623841500466": { + "database_status": false, + "source_status": true + }, + "1623841510619": { + "database_status": false, + "source_status": true + } + } + } + } +]`, + false, + func(t *testing.T, p *ProjectMigrate) {}, + }, + { + "can get status of migrations", + fields{ + projectDirectory: "testdata/projectv3", + adminSecret: "", + endpointString: hgeEndpoint, + }, + args{ + opts: []ProjectMigrationStatusOption{}, + }, + ` +[ + { + "databaseName": "s1", + "status": { + "migrations": [ + 1623841477474, + 1623841485323, + 1623841492743, + 1623841500466, + 1623841510619 + ], + "status": { + "1623841477474": { + "database_status": true, + "source_status": true + }, + "1623841485323": { + "database_status": true, + "source_status": true + }, + "1623841492743": { + "database_status": true, + "source_status": true + }, + "1623841500466": { + "database_status": true, + "source_status": true + }, + "1623841510619": { + "database_status": true, + "source_status": true + } + } + } + }, + { + "databaseName": "s2", + "status": { + "migrations": [ + 1623841477474, + 1623841485323, + 1623841492743, + 1623841500466, + 1623841510619 + ], + "status": { + "1623841477474": { + "database_status": true, + "source_status": true + }, + "1623841485323": { + "database_status": true, + "source_status": true + }, + "1623841492743": { + "database_status": true, + "source_status": true + }, + "1623841500466": { + "database_status": true, + "source_status": true + }, + "1623841510619": { + "database_status": true, + "source_status": true + } + } + } + } +]`, + false, + func(t *testing.T, p *ProjectMigrate) { + assert.NoError(t, p.Apply(ApplyOnAllDatabases())) + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + p, err := NewProjectMigrate(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString)) + require.NoError(t, err) + applier, err := NewProjectMigrate(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString)) + require.NoError(t, err) + tt.before(t, applier) + got, err := p.status(tt.args.opts...) + if tt.wantErr { + require.Error(t, err) + } + require.NoError(t, err) + gotJSON, err := json.Marshal(got) + require.NoError(t, err) + require.JSONEq(t, tt.want, string(gotJSON)) + + statusJson, err := p.StatusJSON(tt.args.opts...) + require.NoError(t, err) + statusJsonb, err := ioutil.ReadAll(statusJson) + require.NoError(t, err) + require.JSONEq(t, tt.want, string(statusJsonb)) + }) + } +} diff --git a/cli/pkg/migrate/status.go b/cli/pkg/migrate/status.go new file mode 100644 index 00000000000..3ad86d45226 --- /dev/null +++ b/cli/pkg/migrate/status.go @@ -0,0 +1,82 @@ +package migrate + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + + "github.com/hasura/graphql-engine/cli/v2" + "github.com/hasura/graphql-engine/cli/v2/commands" + "github.com/hasura/graphql-engine/cli/v2/internal/metadatautil" + "github.com/hasura/graphql-engine/cli/v2/migrate" +) + +type databaseMigration struct { + DatabaseName string `json:"databaseName"` + Status migrate.Status `json:"status"` +} + +type projectMigrationsStatus struct { + ec *cli.ExecutionContext + allDatabases bool +} + +func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) ([]databaseMigration, error) { + var migrateStatus []databaseMigration + for _, opt := range opts { + opt(p) + } + if p.allDatabases { + metadataOps := cli.GetCommonMetadataOps(p.ec) + sources, err := metadatautil.GetSourcesAndKind(metadataOps.ExportMetadata) + if err != nil { + return nil, err + } + for _, source := range sources { + opts := commands.MigrateStatusOptions{ + EC: p.ec, + Source: cli.Source{ + Name: source.Name, + Kind: source.Kind, + }, + } + status, err := opts.Run() + if err != nil { + return nil, err + } + migrateStatus = append( + migrateStatus, + databaseMigration{ + DatabaseName: source.Name, + Status: *status, + }, + ) + } + } + return migrateStatus, nil +} + +func (p *projectMigrationsStatus) StatusJSON(opts ...ProjectMigrationStatusOption) (io.Reader, error) { + d, err := p.Status(opts...) + b := new(bytes.Buffer) + if err != nil { + return nil, err + } + if err := json.NewEncoder(b).Encode(d); err != nil { + return nil, fmt.Errorf("error encoding migration status as json: %w", err) + } + return b, nil +} + +type ProjectMigrationStatusOption func(applier *projectMigrationsStatus) + +func newProjectMigrationsStatus(ec *cli.ExecutionContext) *projectMigrationsStatus { + p := &projectMigrationsStatus{ec: ec} + return p +} +func StatusAllDatabases() ProjectMigrationStatusOption { + return func(p *projectMigrationsStatus) { + p.allDatabases = true + } +} diff --git a/cli/pkg/migrate/testdata/projectv2/config.yaml b/cli/pkg/migrate/testdata/projectv2/config.yaml new file mode 100644 index 00000000000..6ddf586e53d --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/config.yaml @@ -0,0 +1,6 @@ +version: 2 +endpoint: http://localhost:8080 +metadata_directory: metadata +actions: + kind: synchronous + handler_webhook_baseurl: http://localhost:3000 diff --git a/cli/pkg/migrate/testdata/projectv2/metadata/actions.graphql b/cli/pkg/migrate/testdata/projectv2/metadata/actions.graphql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cli/pkg/migrate/testdata/projectv2/metadata/actions.yaml b/cli/pkg/migrate/testdata/projectv2/metadata/actions.yaml new file mode 100644 index 00000000000..1edb4c2ffc5 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/metadata/actions.yaml @@ -0,0 +1,6 @@ +actions: [] +custom_types: + enums: [] + input_objects: [] + objects: [] + scalars: [] diff --git a/cli/pkg/migrate/testdata/projectv2/metadata/allow_list.yaml b/cli/pkg/migrate/testdata/projectv2/metadata/allow_list.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/metadata/allow_list.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/migrate/testdata/projectv2/metadata/cron_triggers.yaml b/cli/pkg/migrate/testdata/projectv2/metadata/cron_triggers.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/metadata/cron_triggers.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/migrate/testdata/projectv2/metadata/functions.yaml b/cli/pkg/migrate/testdata/projectv2/metadata/functions.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/metadata/functions.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/migrate/testdata/projectv2/metadata/query_collections.yaml b/cli/pkg/migrate/testdata/projectv2/metadata/query_collections.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/metadata/query_collections.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/migrate/testdata/projectv2/metadata/remote_schemas.yaml b/cli/pkg/migrate/testdata/projectv2/metadata/remote_schemas.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/metadata/remote_schemas.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/migrate/testdata/projectv2/metadata/tables.yaml b/cli/pkg/migrate/testdata/projectv2/metadata/tables.yaml new file mode 100644 index 00000000000..46d71f1c64f --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/metadata/tables.yaml @@ -0,0 +1,12 @@ +- table: + schema: pub + name: t3 +- table: + schema: pub + name: t4 +- table: + schema: public + name: t1 +- table: + schema: public + name: t2 diff --git a/cli/pkg/migrate/testdata/projectv2/metadata/version.yaml b/cli/pkg/migrate/testdata/projectv2/metadata/version.yaml new file mode 100644 index 00000000000..22817d2a9c7 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/metadata/version.yaml @@ -0,0 +1 @@ +version: 2 diff --git a/cli/pkg/migrate/testdata/projectv2/migrations/1623842054907_create_table_public_t1/down.sql b/cli/pkg/migrate/testdata/projectv2/migrations/1623842054907_create_table_public_t1/down.sql new file mode 100644 index 00000000000..54b977c2b6b --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/migrations/1623842054907_create_table_public_t1/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."t1"; diff --git a/cli/pkg/migrate/testdata/projectv2/migrations/1623842054907_create_table_public_t1/up.sql b/cli/pkg/migrate/testdata/projectv2/migrations/1623842054907_create_table_public_t1/up.sql new file mode 100644 index 00000000000..61aedad2db3 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/migrations/1623842054907_create_table_public_t1/up.sql @@ -0,0 +1 @@ +CREATE TABLE "public"."t1" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv2/migrations/1623842062104_create_table_public_t2/down.sql b/cli/pkg/migrate/testdata/projectv2/migrations/1623842062104_create_table_public_t2/down.sql new file mode 100644 index 00000000000..6a84b5b2ff2 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/migrations/1623842062104_create_table_public_t2/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."t2"; diff --git a/cli/pkg/migrate/testdata/projectv2/migrations/1623842062104_create_table_public_t2/up.sql b/cli/pkg/migrate/testdata/projectv2/migrations/1623842062104_create_table_public_t2/up.sql new file mode 100644 index 00000000000..19e05f2815e --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/migrations/1623842062104_create_table_public_t2/up.sql @@ -0,0 +1 @@ +CREATE TABLE "public"."t2" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv2/migrations/1623842069725_create_schema_pub/down.sql b/cli/pkg/migrate/testdata/projectv2/migrations/1623842069725_create_schema_pub/down.sql new file mode 100644 index 00000000000..c2e1d74c3e9 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/migrations/1623842069725_create_schema_pub/down.sql @@ -0,0 +1 @@ +drop schema "pub" cascade; diff --git a/cli/pkg/migrate/testdata/projectv2/migrations/1623842069725_create_schema_pub/up.sql b/cli/pkg/migrate/testdata/projectv2/migrations/1623842069725_create_schema_pub/up.sql new file mode 100644 index 00000000000..64b99887b8d --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/migrations/1623842069725_create_schema_pub/up.sql @@ -0,0 +1 @@ +create schema "pub"; diff --git a/cli/pkg/migrate/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/down.sql b/cli/pkg/migrate/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/down.sql new file mode 100644 index 00000000000..a8b64773bf0 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/down.sql @@ -0,0 +1 @@ +DROP TABLE "pub"."t3"; diff --git a/cli/pkg/migrate/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/up.sql b/cli/pkg/migrate/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/up.sql new file mode 100644 index 00000000000..0575feb3a41 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/migrations/1623842076537_create_table_pub_t3/up.sql @@ -0,0 +1 @@ +CREATE TABLE "pub"."t3" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/down.sql b/cli/pkg/migrate/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/down.sql new file mode 100644 index 00000000000..35433c15285 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/down.sql @@ -0,0 +1 @@ +DROP TABLE "pub"."t4"; diff --git a/cli/pkg/migrate/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/up.sql b/cli/pkg/migrate/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/up.sql new file mode 100644 index 00000000000..4f409da7f7c --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv2/migrations/1623842087940_create_table_pub_t4/up.sql @@ -0,0 +1 @@ +CREATE TABLE "pub"."t4" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv3/config.yaml b/cli/pkg/migrate/testdata/projectv3/config.yaml new file mode 100644 index 00000000000..725c8005e8d --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/config.yaml @@ -0,0 +1,6 @@ +version: 3 +endpoint: http://localhost:8080 +metadata_directory: metadata +actions: + kind: synchronous + handler_webhook_baseurl: http://localhost:3000 diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/actions.graphql b/cli/pkg/migrate/testdata/projectv3/metadata/actions.graphql new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/actions.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/actions.yaml new file mode 100644 index 00000000000..1edb4c2ffc5 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/actions.yaml @@ -0,0 +1,6 @@ +actions: [] +custom_types: + enums: [] + input_objects: [] + objects: [] + scalars: [] diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/allow_list.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/allow_list.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/allow_list.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/cron_triggers.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/cron_triggers.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/cron_triggers.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/databases/databases.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/databases/databases.yaml new file mode 100644 index 00000000000..65a11b202ed --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/databases/databases.yaml @@ -0,0 +1,14 @@ +- name: default + kind: postgres + configuration: + connection_info: + database_url: + from_env: HASURA_GRAPHQL_DATABASE_URL + isolation_level: read-committed + pool_settings: + connection_lifetime: 600 + idle_timeout: 180 + max_connections: 50 + retries: 1 + use_prepared_statements: true + tables: "!include default/tables/tables.yaml" diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/pub_t3.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/pub_t3.yaml new file mode 100644 index 00000000000..51065134a6b --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/pub_t3.yaml @@ -0,0 +1,3 @@ +table: + name: t3 + schema: pub diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/pub_t4.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/pub_t4.yaml new file mode 100644 index 00000000000..c70fdc67359 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/pub_t4.yaml @@ -0,0 +1,3 @@ +table: + name: t4 + schema: pub diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/public_t1.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/public_t1.yaml new file mode 100644 index 00000000000..4c8eb5bb4ef --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/public_t1.yaml @@ -0,0 +1,3 @@ +table: + name: t1 + schema: public diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/public_t2.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/public_t2.yaml new file mode 100644 index 00000000000..1cba494e6b5 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/public_t2.yaml @@ -0,0 +1,3 @@ +table: + name: t2 + schema: public diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/tables.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/tables.yaml new file mode 100644 index 00000000000..c3ada35c0d8 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/databases/default/tables/tables.yaml @@ -0,0 +1,4 @@ +- "!include pub_t3.yaml" +- "!include pub_t4.yaml" +- "!include public_t1.yaml" +- "!include public_t2.yaml" diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/query_collections.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/query_collections.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/query_collections.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/remote_schemas.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/remote_schemas.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/remote_schemas.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/rest_endpoints.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/rest_endpoints.yaml new file mode 100644 index 00000000000..fe51488c706 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/rest_endpoints.yaml @@ -0,0 +1 @@ +[] diff --git a/cli/pkg/migrate/testdata/projectv3/metadata/version.yaml b/cli/pkg/migrate/testdata/projectv3/metadata/version.yaml new file mode 100644 index 00000000000..0a70affa4bd --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/metadata/version.yaml @@ -0,0 +1 @@ +version: 3 diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841477474_create_table_public_t1/down.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841477474_create_table_public_t1/down.sql new file mode 100644 index 00000000000..54b977c2b6b --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841477474_create_table_public_t1/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."t1"; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841477474_create_table_public_t1/up.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841477474_create_table_public_t1/up.sql new file mode 100644 index 00000000000..61aedad2db3 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841477474_create_table_public_t1/up.sql @@ -0,0 +1 @@ +CREATE TABLE "public"."t1" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841485323_create_table_public_t2/down.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841485323_create_table_public_t2/down.sql new file mode 100644 index 00000000000..6a84b5b2ff2 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841485323_create_table_public_t2/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."t2"; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841485323_create_table_public_t2/up.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841485323_create_table_public_t2/up.sql new file mode 100644 index 00000000000..19e05f2815e --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841485323_create_table_public_t2/up.sql @@ -0,0 +1 @@ +CREATE TABLE "public"."t2" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841492743_create_schema_pub/down.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841492743_create_schema_pub/down.sql new file mode 100644 index 00000000000..c2e1d74c3e9 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841492743_create_schema_pub/down.sql @@ -0,0 +1 @@ +drop schema "pub" cascade; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841492743_create_schema_pub/up.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841492743_create_schema_pub/up.sql new file mode 100644 index 00000000000..64b99887b8d --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841492743_create_schema_pub/up.sql @@ -0,0 +1 @@ +create schema "pub"; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841500466_create_table_pub_t3/down.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841500466_create_table_pub_t3/down.sql new file mode 100644 index 00000000000..a8b64773bf0 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841500466_create_table_pub_t3/down.sql @@ -0,0 +1 @@ +DROP TABLE "pub"."t3"; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841500466_create_table_pub_t3/up.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841500466_create_table_pub_t3/up.sql new file mode 100644 index 00000000000..0575feb3a41 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841500466_create_table_pub_t3/up.sql @@ -0,0 +1 @@ +CREATE TABLE "pub"."t3" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841510619_create_table_pub_t4/down.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841510619_create_table_pub_t4/down.sql new file mode 100644 index 00000000000..35433c15285 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841510619_create_table_pub_t4/down.sql @@ -0,0 +1 @@ +DROP TABLE "pub"."t4"; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841510619_create_table_pub_t4/up.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841510619_create_table_pub_t4/up.sql new file mode 100644 index 00000000000..4f409da7f7c --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s1/1623841510619_create_table_pub_t4/up.sql @@ -0,0 +1 @@ +CREATE TABLE "pub"."t4" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841477474_create_table_public_t1/down.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841477474_create_table_public_t1/down.sql new file mode 100644 index 00000000000..54b977c2b6b --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841477474_create_table_public_t1/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."t1"; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841477474_create_table_public_t1/up.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841477474_create_table_public_t1/up.sql new file mode 100644 index 00000000000..61aedad2db3 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841477474_create_table_public_t1/up.sql @@ -0,0 +1 @@ +CREATE TABLE "public"."t1" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841485323_create_table_public_t2/down.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841485323_create_table_public_t2/down.sql new file mode 100644 index 00000000000..6a84b5b2ff2 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841485323_create_table_public_t2/down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."t2"; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841485323_create_table_public_t2/up.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841485323_create_table_public_t2/up.sql new file mode 100644 index 00000000000..19e05f2815e --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841485323_create_table_public_t2/up.sql @@ -0,0 +1 @@ +CREATE TABLE "public"."t2" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841492743_create_schema_pub/down.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841492743_create_schema_pub/down.sql new file mode 100644 index 00000000000..c2e1d74c3e9 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841492743_create_schema_pub/down.sql @@ -0,0 +1 @@ +drop schema "pub" cascade; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841492743_create_schema_pub/up.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841492743_create_schema_pub/up.sql new file mode 100644 index 00000000000..64b99887b8d --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841492743_create_schema_pub/up.sql @@ -0,0 +1 @@ +create schema "pub"; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841500466_create_table_pub_t3/down.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841500466_create_table_pub_t3/down.sql new file mode 100644 index 00000000000..a8b64773bf0 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841500466_create_table_pub_t3/down.sql @@ -0,0 +1 @@ +DROP TABLE "pub"."t3"; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841500466_create_table_pub_t3/up.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841500466_create_table_pub_t3/up.sql new file mode 100644 index 00000000000..0575feb3a41 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841500466_create_table_pub_t3/up.sql @@ -0,0 +1 @@ +CREATE TABLE "pub"."t3" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841510619_create_table_pub_t4/down.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841510619_create_table_pub_t4/down.sql new file mode 100644 index 00000000000..35433c15285 --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841510619_create_table_pub_t4/down.sql @@ -0,0 +1 @@ +DROP TABLE "pub"."t4"; diff --git a/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841510619_create_table_pub_t4/up.sql b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841510619_create_table_pub_t4/up.sql new file mode 100644 index 00000000000..4f409da7f7c --- /dev/null +++ b/cli/pkg/migrate/testdata/projectv3/migrations/s2/1623841510619_create_table_pub_t4/up.sql @@ -0,0 +1 @@ +CREATE TABLE "pub"."t4" ("id" serial NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") );