From d08619f0952d4ec472d0ce6dcd90cfac7f62dce6 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Thu, 3 Mar 2022 20:15:06 +0300 Subject: Add support for --stdout-format to bdep-config-list command --- bdep/config.cli | 60 +++++++++++++++++++++++++++++++++++- bdep/config.cxx | 82 ++++++++++++++++++++++++++++++++++++++++++++++--- tests/config.testscript | 48 ++++++++++++++++++++++++++++- 3 files changed, 183 insertions(+), 7 deletions(-) diff --git a/bdep/config.cli b/bdep/config.cli index ac67a54..b5b7225 100644 --- a/bdep/config.cli +++ b/bdep/config.cli @@ -133,7 +133,65 @@ namespace bdep associated with the project. Unless one or more configurations are specified explicitly, \cb{list} prints all the associate configurations. Note that the output is written to \cb{stdout}, not - \cb{stderr}.| + \cb{stderr}. + + If the output format is \cb{json} (see the \cb{--stdout-format} + common option), then the output is a JSON array of objects which are + the serialized representation of the following C++ \cb{struct} + \cb{configuration}: + + \ + struct package + { + string name; + }; + + struct configuration + { + uint64_t id; + string path; + optional name; + string type; + bool default; + bool forward; + bool auto_sync; + vector packages; + }; + \ + + For example: + + \ + [ + { + \"id\": 1, + \"path\": \"/tmp/hello-gcc\", + \"name\": \"gcc\", + \"type\": \"target\", + \"default\": true, + \"forward\": true, + \"auto_sync\": true, + \"packages\": [ + { + \"name\": \"hello\" + } + ] + } + ] + \ + + See the JSON OUTPUT section in \l{bdep-common-options(1)} for details + on the overall properties of this format and the semantics of the + \cb{struct} serialization. + + The \cb{id} member is a numeric configuration id that can be used to + identify the configuration instead of the name or path (see the + \cb{--config-id} option). The \cb{path} member is an absolute path to + the configuration directory. The \cb{packages} member contains the + array of packages belonging to this project that have been + initialized in this configuration. See the \cb{create} subcommand for + the meaning of other members (\cb{name}, \cb{type}, \cb{default}, + etc).| \li|\cb{move} diff --git a/bdep/config.cxx b/bdep/config.cxx index edc8ccd..c8a8529 100644 --- a/bdep/config.cxx +++ b/bdep/config.cxx @@ -5,6 +5,8 @@ #include // cout +#include + #include #include #include @@ -780,6 +782,70 @@ namespace bdep return 0; } + static void + cmd_config_list_lines (const configurations& cfgs) + { + for (const shared_ptr& c: cfgs) + { + //@@ TODO: use tabular layout facility when ready. + + print_configuration (cout, c); + cout << endl; + } + } + + static void + cmd_config_list_json (const configurations& cfgs) + { + butl::json::stream_serializer ss (cout); + + ss.begin_array (); + + for (const shared_ptr& c: cfgs) + { + ss.begin_object (); + + ss.member ("id", *c->id); + ss.member ("path", c->path.string ()); + + if (c->name) + ss.member ("name", *c->name); + + ss.member ("type", c->type); + + if (c->default_) + ss.member ("default", c->default_); + + if (c->forward) + ss.member ("forward", c->forward); + + if (c->auto_sync) + ss.member ("auto-sync", c->auto_sync); + + if (!c->packages.empty ()) + { + ss.member_name ("packages"); + + ss.begin_array (); + + for (const package_state& s: c->packages) + { + ss.begin_object (); + ss.member ("name", s.name.string (), false /* check */); + ss.end_object (); + } + + ss.end_array (); + } + + ss.end_object (); + } + + ss.end_array (); + + cout << endl; + } + static int cmd_config_list (const cmd_config_options& o, cli::scanner&) { @@ -819,12 +885,18 @@ namespace bdep t.commit (); - for (const shared_ptr& c: cfgs) + switch (o.stdout_format ()) { - //@@ TODO: use tabular layout facility when ready. - - print_configuration (cout, c); - cout << endl; + case stdout_format::lines: + { + cmd_config_list_lines (cfgs); + break; + } + case stdout_format::json: + { + cmd_config_list_json (cfgs); + break; + } } return 0; diff --git a/tests/config.testscript b/tests/config.testscript index f4ce520..c08c3bf 100644 --- a/tests/config.testscript +++ b/tests/config.testscript @@ -39,6 +39,27 @@ deinit += -d prj @cfg $~/cfg-dir/ 1 target default,forwarded,auto-synchronized EOO + # While at it, test printing the configurations list in the JSON format. + # + $* list @cfg --stdout-format 'json' >>/~"%EOO%"; + [ + { + "id": 1, + "path": "$~/cfg-dir", + "name": "cfg", + "type": "target", + "default": true, + "forward": true, + "auto-sync": true, + "packages": [ + { + "name": "prj" + } + ] + } + ] + EOO + $update @cfg 2>>~%EOE%; %(mkdir|c\+\+|ld) .+%{3} EOE @@ -254,9 +275,34 @@ deinit += -d prj $* add @host-cfg 2>!; - $* add @cfg 2>>/"EOE" + $* add @cfg 2>>/"EOE"; added configuration @cfg $~/prj-cfg/ 5 target default,forwarded,auto-synchronized EOE + + # While at it, test printing the configurations list in the JSON format. + # + $* list --stdout-format 'json' >>/~"%EOO%" + [ + { + "id": 5, + "path": "$~/prj-cfg", + "name": "cfg", + "type": "target", + "default": true, + "forward": true, + "auto-sync": true + }, + { + "id": 4, + "path": "$~/prj-host-cfg", + "name": "host-cfg", + "type": "host", + "default": true, + "forward": true, + "auto-sync": true + } + ] + EOO } : move -- cgit v1.1