Skip to content

Commit

Permalink
atlasexec: handle output as JSON
Browse files Browse the repository at this point in the history
  • Loading branch information
giautm committed Aug 18, 2024
1 parent cc893f9 commit cdcb030
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 50 deletions.
80 changes: 44 additions & 36 deletions atlasexec/atlas_schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ type (
Env string
Vars VarArgs
Context *Context
Format string
DevURL string

From, To []string
Expand All @@ -67,7 +66,6 @@ type (
Env string
Vars VarArgs
Context *Context
Format string
DevURL string

From, To []string
Expand All @@ -81,7 +79,6 @@ type (
Env string
Vars VarArgs
Context *Context
Format string
DevURL string

From, To []string
Expand Down Expand Up @@ -142,6 +139,25 @@ type (
Stmt string `json:"Stmt,omitempty"` // SQL statement that failed.
Text string `json:"Text,omitempty"` // Error message as returned by the database.
}
// SchemaPlan is the result of a 'schema plan' command.
SchemaPlan struct {
Env Env `json:"Env,omitempty"` // Environment info.
Repo string `json:"Repo,omitempty"` // Repository name.
Lint *SummaryReport `json:"Lint,omitempty"` // Lint report.
File *SchemaPlanFile `json:"File,omitempty"` // Plan file.
Error string `json:"Error,omitempty"` // Any error occurred during planning.
}
// SchemaPlanFile is a JSON representation of a schema plan file.
SchemaPlanFile struct {
Name string `json:"Name,omitempty"` // Name of the plan.
FromHash string `json:"FromHash,omitempty"` // Hash of the 'from' realm.
ToHash string `json:"ToHash,omitempty"` // Hash of the 'to' realm.
Migration string `json:"Migration,omitempty"` // Migration SQL.
// registry only fields.
URL string `json:"URL,omitempty"` // URL of the plan in Atlas format.
Link string `json:"Link,omitempty"` // Link to the plan in the registry.
Status string `json:"Status,omitempty"` // Status of the plan in the registry.
}
)

// SchemaApply runs the 'schema apply' command.
Expand Down Expand Up @@ -245,8 +261,8 @@ func (c *Client) SchemaTest(ctx context.Context, params *SchemaTestParams) (stri
}

// SchemaPlan runs the `schema plan` command.
func (c *Client) SchemaPlan(ctx context.Context, params *SchemaPlanParams) (string, error) {
args := []string{"schema", "plan"}
func (c *Client) SchemaPlan(ctx context.Context, params *SchemaPlanParams) (*SchemaPlan, error) {
args := []string{"schema", "plan", "--format", "{{ json . }}"}
// Global flags
if params.ConfigURL != "" {
args = append(args, "--config", params.ConfigURL)
Expand All @@ -261,14 +277,11 @@ func (c *Client) SchemaPlan(ctx context.Context, params *SchemaPlanParams) (stri
if params.Context != nil {
buf, err := json.Marshal(params.Context)
if err != nil {
return "", err
return nil, err
}
args = append(args, "--context", string(buf))
}
// Flags of the 'schema plan' sub-commands
if params.Format != "" {
args = append(args, "--format", params.Format)
}
if params.DevURL != "" {
args = append(args, "--dev-url", params.DevURL)
}
Expand All @@ -287,28 +300,29 @@ func (c *Client) SchemaPlan(ctx context.Context, params *SchemaPlanParams) (stri
switch {
case params.Save:
if params.Push || params.DryRun {
return "", &InvalidParamsError{"schema plan", "can not use --save with --push or --dry-run"}
return nil, &InvalidParamsError{"schema plan", "can not use --save with --push or --dry-run"}
}
args = append(args, "--save")
case params.Push:
if params.Save || params.DryRun {
return "", &InvalidParamsError{"schema plan", "can not use --push with --save or --dry-run"}
return nil, &InvalidParamsError{"schema plan", "can not use --push with --save or --dry-run"}
}
args = append(args, "--push")
case params.DryRun:
if params.Save || params.Push {
return "", &InvalidParamsError{"schema plan", "can not use --dry-run with --save or --push"}
return nil, &InvalidParamsError{"schema plan", "can not use --dry-run with --save or --push"}
}
args = append(args, "--dry-run")
default:
args = append(args, "--auto-approve")
}
return stringVal(c.runCommand(ctx, args))
// NOTE: This command only support one result.
return firstResult(jsonDecode[SchemaPlan](c.runCommand(ctx, args)))
}

// SchemaPlanPush runs the `schema plan push` command.
func (c *Client) SchemaPlanPush(ctx context.Context, params *SchemaPlanPushParams) (string, error) {
args := []string{"schema", "plan", "push"}
args := []string{"schema", "plan", "push", "--format", "{{ json . }}"}
// Global flags
if params.ConfigURL != "" {
args = append(args, "--config", params.ConfigURL)
Expand All @@ -328,9 +342,6 @@ func (c *Client) SchemaPlanPush(ctx context.Context, params *SchemaPlanPushParam
args = append(args, "--context", string(buf))
}
// Flags of the 'schema plan push' sub-commands
if params.Format != "" {
args = append(args, "--format", params.Format)
}
if params.DevURL != "" {
args = append(args, "--dev-url", params.DevURL)
}
Expand All @@ -357,8 +368,8 @@ func (c *Client) SchemaPlanPush(ctx context.Context, params *SchemaPlanPushParam
}

// SchemaPlanLint runs the `schema plan lint` command.
func (c *Client) SchemaPlanLint(ctx context.Context, params *SchemaPlanLintParams) (string, error) {
args := []string{"schema", "plan", "lint"}
func (c *Client) SchemaPlanLint(ctx context.Context, params *SchemaPlanLintParams) (*SchemaPlan, error) {
args := []string{"schema", "plan", "lint", "--format", "{{ json . }}"}
// Global flags
if params.ConfigURL != "" {
args = append(args, "--config", params.ConfigURL)
Expand All @@ -373,14 +384,11 @@ func (c *Client) SchemaPlanLint(ctx context.Context, params *SchemaPlanLintParam
if params.Context != nil {
buf, err := json.Marshal(params.Context)
if err != nil {
return "", err
return nil, err
}
args = append(args, "--context", string(buf))
}
// Flags of the 'schema plan lint' sub-commands
if params.Format != "" {
args = append(args, "--format", params.Format)
}
if params.DevURL != "" {
args = append(args, "--dev-url", params.DevURL)
}
Expand All @@ -393,7 +401,7 @@ func (c *Client) SchemaPlanLint(ctx context.Context, params *SchemaPlanLintParam
if params.File != "" {
args = append(args, "--file", params.File)
} else {
return "", &InvalidParamsError{"schema plan lint", "missing required flag --file"}
return nil, &InvalidParamsError{"schema plan lint", "missing required flag --file"}
}
if params.Name != "" {
args = append(args, "--name", params.Name)
Expand All @@ -402,11 +410,12 @@ func (c *Client) SchemaPlanLint(ctx context.Context, params *SchemaPlanLintParam
args = append(args, "--repo", params.Repo)
}
args = append(args, "--auto-approve")
return stringVal(c.runCommand(ctx, args))
// NOTE: This command only support one result.
return firstResult(jsonDecode[SchemaPlan](c.runCommand(ctx, args)))
}

// SchemaPlanValidate runs the `schema plan validate` command.
func (c *Client) SchemaPlanValidate(ctx context.Context, params *SchemaPlanValidateParams) (string, error) {
func (c *Client) SchemaPlanValidate(ctx context.Context, params *SchemaPlanValidateParams) error {
args := []string{"schema", "plan", "validate"}
// Global flags
if params.ConfigURL != "" {
Expand All @@ -422,7 +431,7 @@ func (c *Client) SchemaPlanValidate(ctx context.Context, params *SchemaPlanValid
if params.Context != nil {
buf, err := json.Marshal(params.Context)
if err != nil {
return "", err
return err
}
args = append(args, "--context", string(buf))
}
Expand All @@ -442,7 +451,7 @@ func (c *Client) SchemaPlanValidate(ctx context.Context, params *SchemaPlanValid
if params.File != "" {
args = append(args, "--file", params.File)
} else {
return "", &InvalidParamsError{"schema plan validate", "missing required flag --file"}
return &InvalidParamsError{"schema plan validate", "missing required flag --file"}
}
if params.Name != "" {
args = append(args, "--name", params.Name)
Expand All @@ -451,12 +460,13 @@ func (c *Client) SchemaPlanValidate(ctx context.Context, params *SchemaPlanValid
args = append(args, "--repo", params.Repo)
}
args = append(args, "--auto-approve")
return stringVal(c.runCommand(ctx, args))
_, err := stringVal(c.runCommand(ctx, args))
return err
}

// SchemaPlanApprove runs the `schema plan approve` command.
func (c *Client) SchemaPlanApprove(ctx context.Context, params *SchemaPlanApproveParams) (string, error) {
args := []string{"schema", "plan", "approve"}
func (c *Client) SchemaPlanApprove(ctx context.Context, params *SchemaPlanApproveParams) (*SchemaPlan, error) {
args := []string{"schema", "plan", "approve", "--format", "{{ json . }}"}
// Global flags
if params.ConfigURL != "" {
args = append(args, "--config", params.ConfigURL)
Expand All @@ -468,15 +478,13 @@ func (c *Client) SchemaPlanApprove(ctx context.Context, params *SchemaPlanApprov
args = append(args, params.Vars.AsArgs()...)
}
// Flags of the 'schema plan approve' sub-commands
if params.Format != "" {
args = append(args, "--format", params.Format)
}
if params.URL != "" {
args = append(args, "--url", params.URL)
} else {
return "", &InvalidParamsError{"schema plan approve", "missing required flag --url"}
return nil, &InvalidParamsError{"schema plan approve", "missing required flag --url"}
}
return stringVal(c.runCommand(ctx, args))
// NOTE: This command only support one result.
return firstResult(jsonDecode[SchemaPlan](c.runCommand(ctx, args)))
}

func newSchemaApplyError(r []*SchemaApply) error {
Expand Down
28 changes: 14 additions & 14 deletions atlasexec/atlas_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,65 +26,65 @@ func TestSchemaPlan(t *testing.T) {
{
name: "no params",
params: &atlasexec.SchemaPlanParams{},
expect: "schema plan --auto-approve",
expect: "schema plan --format {{ json . }} --auto-approve",
},
{
name: "with env",
params: &atlasexec.SchemaPlanParams{
Env: "test",
},
expect: "schema plan --env test --auto-approve",
expect: "schema plan --format {{ json . }} --env test --auto-approve",
},
{
name: "with from to",
params: &atlasexec.SchemaPlanParams{
From: []string{"1", "2"},
To: []string{"2", "3"},
},
expect: `schema plan --from 1,2 --to 2,3 --auto-approve`,
expect: `schema plan --format {{ json . }} --from 1,2 --to 2,3 --auto-approve`,
},
{
name: "with config",
params: &atlasexec.SchemaPlanParams{
ConfigURL: "file://config.hcl",
},
expect: "schema plan --config file://config.hcl --auto-approve",
expect: "schema plan --format {{ json . }} --config file://config.hcl --auto-approve",
},
{
name: "with dev-url",
params: &atlasexec.SchemaPlanParams{
DevURL: "sqlite://file?_fk=1&cache=shared&mode=memory",
},
expect: "schema plan --dev-url sqlite://file?_fk=1&cache=shared&mode=memory --auto-approve",
expect: "schema plan --format {{ json . }} --dev-url sqlite://file?_fk=1&cache=shared&mode=memory --auto-approve",
},
{
name: "with name",
params: &atlasexec.SchemaPlanParams{
Name: "example",
},
expect: "schema plan --name example --auto-approve",
expect: "schema plan --format {{ json . }} --name example --auto-approve",
},
{
name: "with dry-run",
params: &atlasexec.SchemaPlanParams{
DryRun: true,
},
expect: "schema plan --dry-run",
expect: "schema plan --format {{ json . }} --dry-run",
},
{
name: "with save",
params: &atlasexec.SchemaPlanParams{
Save: true,
},
expect: "schema plan --save",
expect: "schema plan --format {{ json . }} --save",
},
{
name: "with push",
params: &atlasexec.SchemaPlanParams{
Repo: "testing-repo",
Push: true,
},
expect: "schema plan --repo testing-repo --push",
expect: "schema plan --format {{ json . }} --repo testing-repo --push",
},
}
for _, tt := range testCases {
Expand Down Expand Up @@ -118,15 +118,15 @@ func TestSchemaPlanPush(t *testing.T) {
Repo: "testing-repo",
File: "file://plan.hcl",
},
expect: "schema plan push --file file://plan.hcl --repo testing-repo --auto-approve",
expect: "schema plan push --format {{ json . }} --file file://plan.hcl --repo testing-repo --auto-approve",
},
{
name: "with pending status",
params: &atlasexec.SchemaPlanPushParams{
Pending: true,
File: "file://plan.hcl",
},
expect: "schema plan push --file file://plan.hcl --pending",
expect: "schema plan push --format {{ json . }} --file file://plan.hcl --pending",
},
}
for _, tt := range testCases {
Expand Down Expand Up @@ -160,14 +160,14 @@ func TestSchemaPlanLint(t *testing.T) {
Repo: "testing-repo",
File: "file://plan.hcl",
},
expect: "schema plan lint --file file://plan.hcl --repo testing-repo --auto-approve",
expect: "schema plan lint --format {{ json . }} --file file://plan.hcl --repo testing-repo --auto-approve",
},
{
name: "with file only",
params: &atlasexec.SchemaPlanLintParams{
File: "file://plan.hcl",
},
expect: "schema plan lint --file file://plan.hcl --auto-approve",
expect: "schema plan lint --format {{ json . }} --file file://plan.hcl --auto-approve",
},
}
for _, tt := range testCases {
Expand Down Expand Up @@ -213,7 +213,7 @@ func TestSchemaPlanValidate(t *testing.T) {
}
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
_, err := c.SchemaPlanValidate(context.Background(), tt.params)
err := c.SchemaPlanValidate(context.Background(), tt.params)
require.Error(t, err)
// The script mock-args.sh exit with an error code.
// So, our atlasexec.SchemaTest should return a Error.
Expand Down

0 comments on commit cdcb030

Please sign in to comment.