Currently, git-rev-parse with the 'options for files' flags returns only the requested values (e.g. `git rev-parse --show-toplevel --show-ref-format` returns the top-level repository and the reference storage format), dumping them only separated by line feeds. However, from the perspective of a programmatic interface, this format is not a good choice as, for example: - it doesn't show the keys of the requested fields, meaning that the caller depends on the order of the requested fields for parsing them; - there's no guarantee that each line contains the value of one field, for example, the returned values may contain line feeds. This way, given that git-repo-info aims to produce a machine-readable output, it needs to follow other formats that are better suited for those means, for example: - JSON, which is widely used as a data exchange format; - null-terminated, composed zero or more <key><LF><value><NUL> entries. Add the --format flag to the repo-info command, allowing the user to choose between output formats. Add as options "json" and "null-terminated", and use "json" as the default format. Helped-by: Phillip Wood <phillip.wood@xxxxxxxxxxxxx> Helped-by: Junio C Hamano <gitster@xxxxxxxxx> Mentored-by: Karthik Nayak <karthik.188@xxxxxxxxx> Mentored-by: Patrick Steinhardt <ps@xxxxxx> Signed-off-by: Lucas Seiki Oshiro <lucasseikioshiro@xxxxxxxxx> --- Documentation/git-repo-info.adoc | 32 ++++++++++++++++- builtin/repo-info.c | 61 ++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/Documentation/git-repo-info.adoc b/Documentation/git-repo-info.adoc index d5f34fc46e..bf1d391482 100644 --- a/Documentation/git-repo-info.adoc +++ b/Documentation/git-repo-info.adoc @@ -8,7 +8,7 @@ git-repo-info - Retrieve information about a repository SYNOPSIS -------- [synopsis] -git repo-info +git repo-info [--format <format>] [<field>...] DESCRIPTION ----------- @@ -25,6 +25,36 @@ THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. OPTIONS ------- +`--format`:: +Specify the output format `<format>`. The valid values are: ++ +* `json`: output the data in JSON format, following this schema: ++ +---------------- +{ + "category1": { + "field1": value1, + "field2": value2, + ... + }, + "category2": { + "field3": value3, + ... + }, + ... +} +---------------- +* `null-terminated`: output the data in a null-terminated format, +following this syntax: ++ +---------------- +category1.field1<LF>value1<NUL> +category1.field2<LF>value2<NUL> +... +---------------- ++ +In this format, the fields will be returned in the same order they were +requested. `<key>`:: Key of the value that will be retrieved. It should be in the format diff --git a/builtin/repo-info.c b/builtin/repo-info.c index 0180c89908..cb4785169f 100644 --- a/builtin/repo-info.c +++ b/builtin/repo-info.c @@ -1,21 +1,78 @@ #include "builtin.h" +#include "json-writer.h" #include "parse-options.h" +enum output_format { + FORMAT_JSON, + FORMAT_NULL_TERMINATED, +}; + +struct repo_info { + struct repository *repo; + enum output_format format; +}; + +static void repo_info_init(struct repo_info *repo_info, + struct repository *repo, + const char *format) +{ + repo_info->repo = repo; + + if (!format || !strcmp(format, "json")) + repo_info->format = FORMAT_JSON; + else if (!strcmp(format, "null-terminated")) + repo_info->format = FORMAT_NULL_TERMINATED; + else + die("invalid format %s", format); +} + +static void repo_info_print_json(struct repo_info *repo_info UNUSED) +{ + struct json_writer jw; + + jw_init(&jw); + + jw_object_begin(&jw, 1); + jw_end(&jw); + + puts(jw.json.buf); + jw_release(&jw); +} + +static void repo_info_print(struct repo_info *repo_info) +{ + switch (repo_info->format) { + case FORMAT_JSON: + repo_info_print_json(repo_info); + break; + case FORMAT_NULL_TERMINATED: + break; + default: + BUG("%d: not a valid repo-info format", repo_info->format); + } +} + int cmd_repo_info(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { const char *const repo_info_usage[] = { - "git repo-info", + "git repo-info [--format <format>] [<field>...]", NULL }; + struct repo_info repo_info; + const char *format = NULL; struct option options[] = { + OPT_STRING(0, "format", &format, N_("format"), + N_("output format")), OPT_END() }; argc = parse_options(argc, argv, prefix, options, repo_info_usage, 0); + repo_info_init(&repo_info, repo, format); + repo_info_print(&repo_info); return 0; } -- 2.39.5 (Apple Git-154)