cli: port pkg/migrate to use internal/errors

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/6491
Co-authored-by: Mohd Bilal <24944223+m-Bilal@users.noreply.github.com>
GitOrigin-RevId: 37640b3f888f6ca68df6894fa1d0f9a5368136b6
This commit is contained in:
Aravind K P 2022-10-27 21:46:07 +05:30 committed by hasura-bot
parent a649967d40
commit 283866526f
4 changed files with 125 additions and 64 deletions

View File

@ -3,6 +3,7 @@ package migrate
import (
"github.com/hasura/graphql-engine/cli/v2"
"github.com/hasura/graphql-engine/cli/v2/commands"
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
)
type projectMigrationsApplier struct {
@ -48,13 +49,14 @@ func ApplyVersion(version string, direction MigrationDirection) ProjectMigration
}
func (p *projectMigrationsApplier) apply(opts ...ProjectMigrationApplierOption) ([]ApplyResult, error) {
var op errors.Op = "migrate.projectMigrationsApplier.apply"
for _, opt := range opts {
opt(p)
}
var results []ApplyResult
resultChan, err := p.opts.Apply()
if err != nil {
return nil, err
return nil, errors.E(op, err)
}
for v := range resultChan {
results = append(results, ApplyResult(v))

View File

@ -5,6 +5,7 @@ import (
"io"
"github.com/hasura/graphql-engine/cli/v2/commands"
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
"github.com/hasura/graphql-engine/cli/v2"
"github.com/spf13/viper"
@ -15,29 +16,45 @@ type ProjectMigrate struct {
}
func (p *ProjectMigrate) status(opts ...ProjectMigrationStatusOption) ([]databaseMigration, error) {
var op errors.Op = "migrate.ProjectMigrate.status"
lister := newProjectMigrationsStatus(p.ec)
if len(opts) == 0 {
opts = append(opts, StatusAllDatabases())
}
return lister.Status(opts...)
dms, err := lister.Status(opts...)
if err != nil {
return nil, errors.E(op, err)
}
return dms, nil
}
func (p *ProjectMigrate) StatusJSON(opts ...ProjectMigrationStatusOption) (io.Reader, error) {
var op errors.Op = "migrate.ProjectMigrate.StatusJSON"
lister := newProjectMigrationsStatus(p.ec)
if len(opts) == 0 {
opts = append(opts, StatusAllDatabases())
}
return lister.StatusJSON(opts...)
r, err := lister.StatusJSON(opts...)
if err != nil {
return nil, errors.E(op, err)
}
return r, nil
}
type ApplyResult commands.MigrateApplyResult
func (p *ProjectMigrate) Apply(opts ...ProjectMigrationApplierOption) ([]ApplyResult, error) {
var op errors.Op = "migrate.ProjectMigrate.Apply"
applier := newProjectMigrationsApplier(p.ec)
return applier.apply(opts...)
r, err := applier.apply(opts...)
if err != nil {
return nil, errors.E(op, err)
}
return r, nil
}
func NewProjectMigrate(projectDirectory string, opts ...ProjectMigrateOption) (*ProjectMigrate, error) {
var op errors.Op = "migrate.NewProjectMigrate"
p := &ProjectMigrate{}
ec := cli.NewExecutionContext()
ec.ExecutionDirectory = projectDirectory
@ -47,17 +64,17 @@ func NewProjectMigrate(projectDirectory string, opts ...ProjectMigrateOption) (*
ec.Stderr = io.Discard
ec.Stdout = io.Discard
if err := ec.Prepare(); err != nil {
return nil, err
return nil, errors.E(op, err)
}
p.ec = ec
for _, opt := range opts {
opt(p)
}
if err := ec.Validate(); err != nil {
return nil, err
return nil, errors.E(op, err)
}
if ec.Config.Version <= cli.V1 {
return nil, fmt.Errorf("config %v is not supported", ec.Config.Version)
return nil, errors.E(op, fmt.Errorf("config %v is not supported", ec.Config.Version))
}
return p, nil
}

View File

@ -10,6 +10,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
"github.com/hasura/graphql-engine/cli/v2/internal/testutil"
)
@ -34,11 +35,12 @@ func TestProjectMigrate_ApplyConfig_v3(t *testing.T) {
opts []ProjectMigrationApplierOption
}
tests := []struct {
name string
fields fields
args args
want []ApplyResult
wantErr bool
name string
fields fields
args args
want []ApplyResult
wantErr bool
assertErr require.ErrorAssertionFunc
}{
{
"can apply migrations in config v3 project",
@ -62,6 +64,7 @@ func TestProjectMigrate_ApplyConfig_v3(t *testing.T) {
},
},
false,
require.NoError,
},
{
"can apply a version in config v3 project",
@ -80,6 +83,7 @@ func TestProjectMigrate_ApplyConfig_v3(t *testing.T) {
},
},
false,
require.NoError,
},
{
"can apply a version in config v3 project",
@ -98,6 +102,7 @@ func TestProjectMigrate_ApplyConfig_v3(t *testing.T) {
},
},
false,
require.NoError,
},
}
for _, tt := range tests {
@ -105,12 +110,12 @@ func TestProjectMigrate_ApplyConfig_v3(t *testing.T) {
p, err := NewProjectMigrate(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString))
require.NoError(t, err)
got, err := p.Apply(tt.args.opts...)
tt.assertErr(t, err)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Equal(t, tt.want, got)
return
}
require.NoError(t, err)
require.Equal(t, tt.want, got)
})
}
}
@ -128,11 +133,12 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) {
opts []ProjectMigrationApplierOption
}
tests := []struct {
name string
fields fields
args args
want []ApplyResult
wantErr bool
name string
fields fields
args args
want []ApplyResult
wantErr bool
assertErr require.ErrorAssertionFunc
}{
{
"can apply migrations in config v2 project",
@ -150,6 +156,7 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) {
},
},
false,
require.NoError,
},
{
"can apply down migration on a version in config v2 project",
@ -167,6 +174,7 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) {
},
},
false,
require.NoError,
},
{
"throws error when trying to do a down migration which is not applied",
@ -184,6 +192,7 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) {
},
},
false,
require.NoError,
},
{
"can apply up migrations of a version on a config v2 project",
@ -201,6 +210,7 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) {
},
},
false,
require.NoError,
},
}
for _, tt := range tests {
@ -208,20 +218,19 @@ func TestProjectMigrate_Apply_Configv2(t *testing.T) {
p, err := NewProjectMigrate(tt.fields.projectDirectory, WithAdminSecret(testutil.TestAdminSecret), WithEndpoint(tt.fields.endpointString))
require.NoError(t, err)
got, err := p.Apply(tt.args.opts...)
tt.assertErr(t, err)
if tt.wantErr {
require.Error(t, err)
} else {
require.NoError(t, err)
for idx, want := range tt.want {
if idx >= len(got) {
t.Errorf("expected to got to have equal number of elements: want %v got %v", len(tt.want), len(got))
}
if len(want.Message) > 0 {
assert.Equal(t, want.Message, got[idx].Message)
}
if want.Error != nil {
assert.Equal(t, want.Error.Error(), got[idx].Error.Error())
}
return
}
for idx, want := range tt.want {
if idx >= len(got) {
t.Errorf("expected to got to have equal number of elements: want %v got %v", len(tt.want), len(got))
}
if len(want.Message) > 0 {
assert.Equal(t, want.Message, got[idx].Message)
}
if want.Error != nil {
assert.Equal(t, want.Error.Error(), got[idx].Error.Error())
}
}
})
@ -241,12 +250,13 @@ func TestProjectMigrate_Status_ConfigV2(t *testing.T) {
opts []ProjectMigrationStatusOption
}
tests := []struct {
name string
fields fields
args args
want string
wantErr bool
before func(t *testing.T, p *ProjectMigrate)
name string
fields fields
args args
want string
wantErr bool
assertErr require.ErrorAssertionFunc
before func(t *testing.T, p *ProjectMigrate)
}{
{
"can get status of migrations",
@ -296,6 +306,7 @@ func TestProjectMigrate_Status_ConfigV2(t *testing.T) {
}
]`,
false,
require.NoError,
func(t *testing.T, p *ProjectMigrate) {},
},
{
@ -346,6 +357,7 @@ func TestProjectMigrate_Status_ConfigV2(t *testing.T) {
}
]`,
false,
require.NoError,
func(t *testing.T, p *ProjectMigrate) {
_, err := p.Apply(ApplyOnAllDatabases())
assert.NoError(t, err)
@ -360,8 +372,9 @@ func TestProjectMigrate_Status_ConfigV2(t *testing.T) {
require.NoError(t, err)
tt.before(t, applier)
got, err := p.status(tt.args.opts...)
tt.assertErr(t, err)
if tt.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
gotJSON, err := json.Marshal(got)
@ -403,6 +416,7 @@ func TestProjectMigrate_Status_ConfigV3(t *testing.T) {
args args
want string
wantErr bool
assertErr require.ErrorAssertionFunc
testSetup func() (hgeEndpoint string, teardown func())
before func(t *testing.T, p *ProjectMigrate)
}{
@ -486,6 +500,7 @@ func TestProjectMigrate_Status_ConfigV3(t *testing.T) {
}
]`,
false,
require.NoError,
func() (string, func()) { return hgeEndpoint, func() {} },
func(t *testing.T, p *ProjectMigrate) {},
},
@ -570,6 +585,7 @@ func TestProjectMigrate_Status_ConfigV3(t *testing.T) {
}
]`,
false,
require.NoError,
func() (string, func()) { return hgeEndpoint, func() {} },
func(t *testing.T, p *ProjectMigrate) {
_, err := p.Apply(ApplyOnAllDatabases())
@ -587,6 +603,11 @@ func TestProjectMigrate_Status_ConfigV3(t *testing.T) {
},
``,
true,
func(tt require.TestingT, err error, i ...interface{}) {
require.IsType(t, &errors.Error{}, err)
e := err.(*errors.Error)
require.Equal(t, errors.Op("migrate.ProjectMigrate.status"), e.Op)
},
func() (string, func()) {
port, teardown := testutil.StartHasuraWithMetadataDatabase(t, testutil.HasuraDockerImage)
return fmt.Sprintf("http://%s:%s", testutil.Hostname, port), teardown
@ -607,19 +628,19 @@ func TestProjectMigrate_Status_ConfigV3(t *testing.T) {
require.NoError(t, err)
tt.before(t, applier)
got, err := p.status(tt.args.opts...)
tt.assertErr(t, err)
if tt.wantErr {
require.Error(t, err)
} else {
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))
return
}
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))
})
}
}
@ -643,9 +664,11 @@ func TestProjectMigrate_SkipExecution_Configv3(t *testing.T) {
opts []ProjectMigrationApplierOption
}
tests := []struct {
name string
args args
want string
name string
args args
want string
wantErr bool
assertErr require.ErrorAssertionFunc
}{
{
"mark migration as unapplied",
@ -692,6 +715,8 @@ func TestProjectMigrate_SkipExecution_Configv3(t *testing.T) {
}
]
`,
false,
require.NoError,
},
{
"mark migration as applied",
@ -738,6 +763,8 @@ func TestProjectMigrate_SkipExecution_Configv3(t *testing.T) {
}
]
`,
false,
require.NoError,
},
}
@ -749,7 +776,10 @@ func TestProjectMigrate_SkipExecution_Configv3(t *testing.T) {
require.NoError(t, err)
status, err := p.StatusJSON()
assert.NoError(t, err)
tt.assertErr(t, err)
if tt.wantErr {
return
}
statusJsonb, err := ioutil.ReadAll(status)
assert.NoError(t, err)
@ -772,9 +802,11 @@ func TestProjectMigrate_SkipExecution_Configv2(t *testing.T) {
opts []ProjectMigrationApplierOption
}
tests := []struct {
name string
args args
want string
name string
args args
want string
wantErr bool
assertErr require.ErrorAssertionFunc
}{
{
"mark migration as unapplied",
@ -821,6 +853,8 @@ func TestProjectMigrate_SkipExecution_Configv2(t *testing.T) {
}
]
`,
false,
require.NoError,
},
{
"mark migration as applied",
@ -867,6 +901,8 @@ func TestProjectMigrate_SkipExecution_Configv2(t *testing.T) {
}
]
`,
false,
require.NoError,
},
}
@ -878,7 +914,10 @@ func TestProjectMigrate_SkipExecution_Configv2(t *testing.T) {
require.NoError(t, err)
status, err := p1.StatusJSON()
assert.NoError(t, err)
tt.assertErr(t, err)
if tt.wantErr {
return
}
statusJsonb, err := ioutil.ReadAll(status)
assert.NoError(t, err)

View File

@ -8,6 +8,7 @@ import (
"github.com/hasura/graphql-engine/cli/v2"
"github.com/hasura/graphql-engine/cli/v2/commands"
"github.com/hasura/graphql-engine/cli/v2/internal/errors"
"github.com/hasura/graphql-engine/cli/v2/internal/metadatautil"
"github.com/hasura/graphql-engine/cli/v2/migrate"
)
@ -23,6 +24,7 @@ type projectMigrationsStatus struct {
}
func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) ([]databaseMigration, error) {
var op errors.Op = "migrate.projectMigrationsStatus.Status"
var migrateStatus []databaseMigration
for _, opt := range opts {
opt(p)
@ -31,7 +33,7 @@ func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) (
metadataOps := cli.GetCommonMetadataOps(p.ec)
sources, err := metadatautil.GetSourcesAndKindStrict(metadataOps.ExportMetadata)
if err != nil {
return nil, err
return nil, errors.E(op, err)
}
for _, source := range sources {
opts := commands.MigrateStatusOptions{
@ -43,7 +45,7 @@ func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) (
}
status, err := opts.RunOnSource()
if err != nil {
return nil, err
return nil, errors.E(op, err)
}
migrateStatus = append(
migrateStatus,
@ -58,13 +60,14 @@ func (p *projectMigrationsStatus) Status(opts ...ProjectMigrationStatusOption) (
}
func (p *projectMigrationsStatus) StatusJSON(opts ...ProjectMigrationStatusOption) (io.Reader, error) {
var op errors.Op = "migrate.projectMigrationsStatus.StatusJSON"
d, err := p.Status(opts...)
b := new(bytes.Buffer)
if err != nil {
return nil, err
return nil, errors.E(op, err)
}
if err := json.NewEncoder(b).Encode(d); err != nil {
return nil, fmt.Errorf("error encoding migration status as json: %w", err)
return nil, errors.E(op, fmt.Errorf("error encoding migration status as json: %w", err))
}
return b, nil
}