-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add JSON output support to pg-schema-diff plan. #175
Conversation
4b4fdd6
to
4b855ac
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really solid! A couple tiny nits. Thanks for implementing this :)
cmd/pg-schema-diff/plan_cmd.go
Outdated
*e = outputFormat(v) | ||
return nil | ||
default: | ||
return errors.New(`must be one of "pretty" or "json"`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: include the unknown value the user used. Also let's group with the other plan flag structs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like Cobra prepends this. I added the value the user used and it came out like this:
Error: invalid argument "test" for "--output-format" flag: must be one of "pretty" or "json", value passed in was "test"
I'm going to leave it out, but if you think it's useful because the error might be used outside of Cobra let me know and I can add it back in.
Here's how it looks by default:
Error: invalid argument "test" for "--output-format" flag: must be one of "pretty" or "json"
@@ -139,6 +172,8 @@ func createPlanFlags(cmd *cobra.Command) *planFlags { | |||
), | |||
) | |||
|
|||
cmd.Flags().Var(&flags.outputFormat, "output-format", "Change the output format for what is printed. Defaults to pretty-printed human-readable output. (options: pretty, json)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: set default value to pretty and make a required param
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a default value now, but it has to be on the struct itself, when using Var
there is no way to set a default.
I also didn't mark it as required because when it's marked as required via MarkFlagRequired
the CLI will always require something to be passed in, even though the struct instance already has it set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense!
cmd/pg-schema-diff/plan_cmd.go
Outdated
fmt.Printf("\n%s\n", header("Generated plan")) | ||
fmt.Println(planToPrettyS(plan)) | ||
|
||
if planFlags.outputFormat == "" || planFlags.outputFormat == outputFormatPretty { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not support an empty string for output format (once the param is default and required). Let's also error out if the enum value is not known, i.e., if neither if condition matches, then return an error.
Alternatively (up to you!), you could add to the output format type an additional property called print
:
{
name string
print func(plan)
}
....
...
planFlags.outputFormat.print(plan)
Then we wouldn't need any sort of conditional switchhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I reworked this as suggested - now each output format has a function to convert the plan to an output string.
Thanks for the suggestion, it's definitely much cleaner.
@bplunkett-stripe I think I addressed everything - apologies if something is off, just let me know and I can sort it out. Also thanks for jumping on this, much appreciated. |
@@ -78,6 +77,11 @@ type ( | |||
targetDatabaseDSN string | |||
} | |||
|
|||
outputFormat struct { | |||
identifier string | |||
convertToOutputString func(diff.Plan) string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice
@@ -139,6 +172,8 @@ func createPlanFlags(cmd *cobra.Command) *planFlags { | |||
), | |||
) | |||
|
|||
cmd.Flags().Var(&flags.outputFormat, "output-format", "Change the output format for what is printed. Defaults to pretty-printed human-readable output. (options: pretty, json)") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense!
@tonycosentini before merging, could you paste some example outputs of a "pretty" plan and a "json" plan. Just want to make sure those look okay! (Currently CLI tests are just by-hand right now, so the current practice to just to include some example runs in your PR)! |
@bplunkett-stripe here are some examples Normal output without specifying any format (defaults to pretty):
Passing pretty as output format:
JSON output:
Invalid output format:
|
Sorry I hit the merge button for you! You don't have write permissions on the repo, so you can't hit the merge button unfortunately. The commit is authored by you though! 🎉 This is a very nice improvement to the repo! Thanks for making it. |
Add JSON output support to pg-schema-diff plan.
This is exactly what I needed. Thanks @tonycosentini! |
Description
This adds support for different output formats when running the
plan
subcommand. Currently it only supports pretty printing (which is what already exists today) or JSON.I rarely/never write golang so this PR was more or less a first attempt to get a discussion going, happy to refactor as needed.
Motivation
I'm working on a tool written in Python that is using the pg-schema-diff to generate schema plans. It would be great to have a structured output option so I can just parse the output in Python.
Alternatively I can build some kind of bindings for this library, that would require waaay more overhead than just being able to parse the JSON output.
I think this would make the tool much more versatile.
Testing
Just manual testing. I'm happy to add test coverage, but I didn't see any other CLI tests (besides some options parsing tests) so I wasn't really sure where to start.