[GSoC RFC PATCH v3 2/5] repo-info: add the --format flag

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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)





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux