Message ID | 20240516154117.2306789-4-jmeng@redhat.com |
---|---|
State | Changes Requested |
Delegated to: | Ilya Maximets |
Headers | show |
Series | [ovs-dev,v12,1/6] Add global option for JSON output to ovs-appctl. | expand |
Context | Check | Description |
---|---|---|
ovsrobot/apply-robot | warning | apply and check: warning |
ovsrobot/github-robot-_Build_and_Test | success | github build: passed |
ovsrobot/intel-ovs-compilation | success | test: success |
Bleep bloop. Greetings Jakob Meng, I am a robot and I have tried out your patch. Thanks for your contribution. I encountered some error that I wasn't expecting. See the details below. checkpatch: WARNING: Line lacks whitespace around operator WARNING: Line lacks whitespace around operator #113 FILE: utilities/ovs-appctl.c:157: Requires: --format=json.\n\ Lines checked: 196, Warnings: 2, Errors: 0 Please check this out. If you feel there has been an error, please email aconole@redhat.com Thanks, 0-day Robot
On 5/16/24 17:41, jmeng@redhat.com wrote: > From: Jakob Meng <code@jakobmeng.de> > > With the '--pretty' option, ovs-appctl will now print JSON output in a > more readable fashion, i.e. with additional line breaks, spaces and > sorted dictionary keys. > > Signed-off-by: Jakob Meng <code@jakobmeng.de> > --- > Documentation/ref/ovs-appctl.8.rst | 7 ++++++ > NEWS | 1 + > tests/ovs-vswitchd.at | 5 +++++ > utilities/ovs-appctl.c | 34 ++++++++++++++++++++++++------ > 4 files changed, 40 insertions(+), 7 deletions(-) > > diff --git a/Documentation/ref/ovs-appctl.8.rst b/Documentation/ref/ovs-appctl.8.rst > index 9619c1226..db6c52b42 100644 > --- a/Documentation/ref/ovs-appctl.8.rst > +++ b/Documentation/ref/ovs-appctl.8.rst > @@ -79,6 +79,13 @@ In normal use only a single option is accepted: > > ``{"reply-format":"plain","reply":"$PLAIN_TEXT_HERE"}`` > > +* ``--pretty`` Not mentioned at the very top. > + > + By default, JSON output is printed as compactly as possible. This option > + causes JSON in output to be printed in a more readable fashion. For example, > + members of objects and elements of arrays are printed one per line, with > + indentation. Requires ``--format=json``. Double spaces between sentences. > + > Common Commands > =============== > > diff --git a/NEWS b/NEWS > index 7076939c5..0d41061d3 100644 > --- a/NEWS > +++ b/NEWS > @@ -3,6 +3,7 @@ Post-v3.3.0 > - ovs-appctl: > * Added new option [-f|--format] to choose the output format, e.g. 'json' > or 'text' (by default). > + * Added new option [--pretty] to print JSON output in a readable fashion. > - Python: > * Added support for different output formats like 'json' to appctl.py and > Python's unixctl classes. > diff --git a/tests/ovs-vswitchd.at b/tests/ovs-vswitchd.at > index 1ae7fcc32..2db8138f1 100644 > --- a/tests/ovs-vswitchd.at > +++ b/tests/ovs-vswitchd.at > @@ -275,4 +275,9 @@ ovs_version=$(ovs-appctl version) > AT_CHECK_UNQUOTED([ovs-appctl --format json version], [0], [dnl > {"reply":"$ovs_version","reply-format":"plain"}]) > > +AT_CHECK_UNQUOTED([ovs-appctl --format json --pretty version], [0], [dnl > +{ > + "reply": "$ovs_version", > + "reply-format": "plain"}]) > + > AT_CLEANUP > diff --git a/utilities/ovs-appctl.c b/utilities/ovs-appctl.c > index 0e99259e8..3b76740ea 100644 > --- a/utilities/ovs-appctl.c > +++ b/utilities/ovs-appctl.c > @@ -40,13 +40,15 @@ static void usage(void); > /* Parsed command line args. */ > struct cmdl_args { > enum unixctl_output_fmt format; > + unsigned int format_flags; > char *target; > }; > > static struct cmdl_args *cmdl_args_create(void); > static struct cmdl_args *parse_command_line(int argc, char *argv[]); > static struct jsonrpc *connect_to_target(const char *target); > -static char * reply_to_string(struct json *reply, enum unixctl_output_fmt fmt); > +static char * reply_to_string(struct json *reply, enum unixctl_output_fmt fmt, > + unsigned int fmt_flags); static char *reply_to_string > > int > main(int argc, char *argv[]) > @@ -84,7 +86,7 @@ main(int argc, char *argv[]) > > if (cmd_error) { > jsonrpc_close(client); > - msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT); > + msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT, 0); > fputs(msg, stderr); > free(msg); > ovs_error(0, "%s: server returned an error", args->target); > @@ -108,13 +110,13 @@ main(int argc, char *argv[]) > > if (cmd_error) { > jsonrpc_close(client); > - msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT); > + msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT, 0); > fputs(msg, stderr); > free(msg); > ovs_error(0, "%s: server returned an error", args->target); > exit(2); > } else if (cmd_result) { > - msg = reply_to_string(cmd_result, args->format); > + msg = reply_to_string(cmd_result, args->format, args->format_flags); > fputs(msg, stdout); > free(msg); > } else { > @@ -151,6 +153,8 @@ Other options:\n\ > --timeout=SECS wait at most SECS seconds for a response\n\ > -f, --format=FMT Output format. One of: 'json', or 'text'\n\ > (default: text)\n\ > + --pretty Format the output in a more readable fashion.\n\ > + Requires: --format=json.\n\ > -h, --help Print this helpful information\n\ > -V, --version Display ovs-appctl version information\n", > program_name, program_name); > @@ -163,6 +167,7 @@ cmdl_args_create(void) > struct cmdl_args *args = xmalloc(sizeof *args); > > args->format = UNIXCTL_OUTPUT_FMT_TEXT; > + args->format_flags = 0; > args->target = NULL; > > return args; > @@ -173,7 +178,8 @@ parse_command_line(int argc, char *argv[]) > { > enum { > OPT_START = UCHAR_MAX + 1, > - VLOG_OPTION_ENUMS > + OPT_PRETTY, > + VLOG_OPTION_ENUMS, > }; > static const struct option long_options[] = { > {"target", required_argument, NULL, 't'}, > @@ -181,6 +187,7 @@ parse_command_line(int argc, char *argv[]) > {"format", required_argument, NULL, 'f'}, > {"help", no_argument, NULL, 'h'}, > {"option", no_argument, NULL, 'o'}, > + {"pretty", no_argument, NULL, OPT_PRETTY}, > {"version", no_argument, NULL, 'V'}, > {"timeout", required_argument, NULL, 'T'}, > VLOG_LONG_OPTIONS, > @@ -190,6 +197,7 @@ parse_command_line(int argc, char *argv[]) > char *short_options = xasprintf("+%s", short_options_); > struct cmdl_args *args = cmdl_args_create(); > unsigned int timeout = 0; > + bool pretty = false; > int e_options; > > e_options = 0; > @@ -232,6 +240,10 @@ parse_command_line(int argc, char *argv[]) > ovs_cmdl_print_options(long_options); > exit(EXIT_SUCCESS); > > + case OPT_PRETTY: > + pretty = true; > + break; > + > case 'T': > if (!str_to_uint(optarg, 10, &timeout) || !timeout) { > ovs_fatal(0, "value %s on -T or --timeout is invalid", optarg); > @@ -261,6 +273,13 @@ parse_command_line(int argc, char *argv[]) > "(use --help for help)"); > } > > + if (pretty) { > + if (args->format != UNIXCTL_OUTPUT_FMT_JSON) { > + ovs_fatal(0, "--pretty is supported with --format json only"); > + } > + args->format_flags |= JSSF_PRETTY; > + } > + > if (!args->target) { > args->target = "ovs-vswitchd"; > } > @@ -309,7 +328,8 @@ connect_to_target(const char *target) > /* The caller is responsible for freeing the returned string, with free(), when > * it is no longer needed. */ > static char * > -reply_to_string(struct json *reply, enum unixctl_output_fmt fmt) > +reply_to_string(struct json *reply, enum unixctl_output_fmt fmt, > + unsigned int fmt_flags) > { > ovs_assert(reply); > > @@ -328,5 +348,5 @@ reply_to_string(struct json *reply, enum unixctl_output_fmt fmt) > json_type_to_string(reply->type)); > } > > - return json_to_string(reply, JSSF_SORT); > + return json_to_string(reply, JSSF_SORT | fmt_flags); > }
diff --git a/Documentation/ref/ovs-appctl.8.rst b/Documentation/ref/ovs-appctl.8.rst index 9619c1226..db6c52b42 100644 --- a/Documentation/ref/ovs-appctl.8.rst +++ b/Documentation/ref/ovs-appctl.8.rst @@ -79,6 +79,13 @@ In normal use only a single option is accepted: ``{"reply-format":"plain","reply":"$PLAIN_TEXT_HERE"}`` +* ``--pretty`` + + By default, JSON output is printed as compactly as possible. This option + causes JSON in output to be printed in a more readable fashion. For example, + members of objects and elements of arrays are printed one per line, with + indentation. Requires ``--format=json``. + Common Commands =============== diff --git a/NEWS b/NEWS index 7076939c5..0d41061d3 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,7 @@ Post-v3.3.0 - ovs-appctl: * Added new option [-f|--format] to choose the output format, e.g. 'json' or 'text' (by default). + * Added new option [--pretty] to print JSON output in a readable fashion. - Python: * Added support for different output formats like 'json' to appctl.py and Python's unixctl classes. diff --git a/tests/ovs-vswitchd.at b/tests/ovs-vswitchd.at index 1ae7fcc32..2db8138f1 100644 --- a/tests/ovs-vswitchd.at +++ b/tests/ovs-vswitchd.at @@ -275,4 +275,9 @@ ovs_version=$(ovs-appctl version) AT_CHECK_UNQUOTED([ovs-appctl --format json version], [0], [dnl {"reply":"$ovs_version","reply-format":"plain"}]) +AT_CHECK_UNQUOTED([ovs-appctl --format json --pretty version], [0], [dnl +{ + "reply": "$ovs_version", + "reply-format": "plain"}]) + AT_CLEANUP diff --git a/utilities/ovs-appctl.c b/utilities/ovs-appctl.c index 0e99259e8..3b76740ea 100644 --- a/utilities/ovs-appctl.c +++ b/utilities/ovs-appctl.c @@ -40,13 +40,15 @@ static void usage(void); /* Parsed command line args. */ struct cmdl_args { enum unixctl_output_fmt format; + unsigned int format_flags; char *target; }; static struct cmdl_args *cmdl_args_create(void); static struct cmdl_args *parse_command_line(int argc, char *argv[]); static struct jsonrpc *connect_to_target(const char *target); -static char * reply_to_string(struct json *reply, enum unixctl_output_fmt fmt); +static char * reply_to_string(struct json *reply, enum unixctl_output_fmt fmt, + unsigned int fmt_flags); int main(int argc, char *argv[]) @@ -84,7 +86,7 @@ main(int argc, char *argv[]) if (cmd_error) { jsonrpc_close(client); - msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT); + msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT, 0); fputs(msg, stderr); free(msg); ovs_error(0, "%s: server returned an error", args->target); @@ -108,13 +110,13 @@ main(int argc, char *argv[]) if (cmd_error) { jsonrpc_close(client); - msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT); + msg = reply_to_string(cmd_error, UNIXCTL_OUTPUT_FMT_TEXT, 0); fputs(msg, stderr); free(msg); ovs_error(0, "%s: server returned an error", args->target); exit(2); } else if (cmd_result) { - msg = reply_to_string(cmd_result, args->format); + msg = reply_to_string(cmd_result, args->format, args->format_flags); fputs(msg, stdout); free(msg); } else { @@ -151,6 +153,8 @@ Other options:\n\ --timeout=SECS wait at most SECS seconds for a response\n\ -f, --format=FMT Output format. One of: 'json', or 'text'\n\ (default: text)\n\ + --pretty Format the output in a more readable fashion.\n\ + Requires: --format=json.\n\ -h, --help Print this helpful information\n\ -V, --version Display ovs-appctl version information\n", program_name, program_name); @@ -163,6 +167,7 @@ cmdl_args_create(void) struct cmdl_args *args = xmalloc(sizeof *args); args->format = UNIXCTL_OUTPUT_FMT_TEXT; + args->format_flags = 0; args->target = NULL; return args; @@ -173,7 +178,8 @@ parse_command_line(int argc, char *argv[]) { enum { OPT_START = UCHAR_MAX + 1, - VLOG_OPTION_ENUMS + OPT_PRETTY, + VLOG_OPTION_ENUMS, }; static const struct option long_options[] = { {"target", required_argument, NULL, 't'}, @@ -181,6 +187,7 @@ parse_command_line(int argc, char *argv[]) {"format", required_argument, NULL, 'f'}, {"help", no_argument, NULL, 'h'}, {"option", no_argument, NULL, 'o'}, + {"pretty", no_argument, NULL, OPT_PRETTY}, {"version", no_argument, NULL, 'V'}, {"timeout", required_argument, NULL, 'T'}, VLOG_LONG_OPTIONS, @@ -190,6 +197,7 @@ parse_command_line(int argc, char *argv[]) char *short_options = xasprintf("+%s", short_options_); struct cmdl_args *args = cmdl_args_create(); unsigned int timeout = 0; + bool pretty = false; int e_options; e_options = 0; @@ -232,6 +240,10 @@ parse_command_line(int argc, char *argv[]) ovs_cmdl_print_options(long_options); exit(EXIT_SUCCESS); + case OPT_PRETTY: + pretty = true; + break; + case 'T': if (!str_to_uint(optarg, 10, &timeout) || !timeout) { ovs_fatal(0, "value %s on -T or --timeout is invalid", optarg); @@ -261,6 +273,13 @@ parse_command_line(int argc, char *argv[]) "(use --help for help)"); } + if (pretty) { + if (args->format != UNIXCTL_OUTPUT_FMT_JSON) { + ovs_fatal(0, "--pretty is supported with --format json only"); + } + args->format_flags |= JSSF_PRETTY; + } + if (!args->target) { args->target = "ovs-vswitchd"; } @@ -309,7 +328,8 @@ connect_to_target(const char *target) /* The caller is responsible for freeing the returned string, with free(), when * it is no longer needed. */ static char * -reply_to_string(struct json *reply, enum unixctl_output_fmt fmt) +reply_to_string(struct json *reply, enum unixctl_output_fmt fmt, + unsigned int fmt_flags) { ovs_assert(reply); @@ -328,5 +348,5 @@ reply_to_string(struct json *reply, enum unixctl_output_fmt fmt) json_type_to_string(reply->type)); } - return json_to_string(reply, JSSF_SORT); + return json_to_string(reply, JSSF_SORT | fmt_flags); }