git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [RFC/PATCH 0/3] JSON/XML output for scripting interface

From
Julian Phillips <julian@quantumfyre.co.uk>
Date
Apr 11, 2010, 17:30 UTC
Message-ID
<cb4ed5763e71bd84b4e80109923494ca@212.159.54.234>
In-Reply-To
<k2pfabb9a1e1004110848u15859465qf14e3d40eb4ba877@mail.gmail.com>

On Sun, 11 Apr 2010 17:48:28 +0200, Sverre Rabbelier <srabbelier@gmail.com> wrote:

> Heya,
> 
> On Sun, Apr 11, 2010 at 13:37, Julian Phillips
<julian@quantumfyre.co.uk>
Show 6 quoted lines
> wrote:
>> Here is an attempt at making a format agnostic structured output
>> library.  The
>> idea being that the command doing the output doesn't have to care what
>> the
>> actual output format is, it just uses the abstract notion of objects
and
Show 6 quoted lines
>> arrays.
> 
> How easy is it to add support for this to other commands using the
> infrastructure this command adds? I assume that we'd want to do this
> for all/most plumbing commands, so I think it's important that we make
> sure it's easy to add for other commands other than 'git status', no?

It's intended to be easy, as the intention was to make the structured output available from all plumbing commands (and maybe even some porcelain commands, if they are often scripted?). Easy is in the eye of the beholder though. I've done ls-tree as an example below (I expect my MUA will probably mangle the patch - sorry). I didn't think it was too hard, but that's not really surprising since I wrote the API ... you'll have to tell me what you think.

diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index dc86b0d..7b5a5e8 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -10,6 +10,7 @@
 #include "quote.h"
 #include "builtin.h"
 #include "parse-options.h"
+#include "output.h"
 
 static int line_termination = '\n';
 #define LS_RECURSIVE 1
@@ -22,6 +23,7 @@ static int ls_options;
 static const char **pathspec;
 static int chomp_prefix;
 static const char *ls_tree_prefix;
+static struct output_context *oc;
 
 static const  char * const ls_tree_usage[] = {
 	"git ls-tree [<options>] <tree-ish> [path...]",
@@ -90,6 +92,25 @@ static int show_tree(const unsigned char *sha1, const
char *base, int baselen,
 	    (baselen < chomp_prefix || memcmp(ls_tree_prefix, base,
chomp_prefix)))
 		return 0;
 
+	if (oc != NULL) {
+		output_start_object(oc, "entry");
+		output_strf(oc, "path", "%s%s", base + chomp_prefix, pathname);
+		if (!(ls_options & LS_NAME_ONLY)) {
+			output_strf(oc, "mode", "%06o", mode);
+			output_str(oc, "type", type);
+			output_str(oc, "hash", sha1_to_hex(sha1));
+			if ((ls_options & LS_SHOW_SIZE) && !strcmp(type, blob_type)) {
+				unsigned long size;
+				if (sha1_object_info(sha1, &size) == OBJ_BAD)
+					output_str(oc, "size", "bad");
+				else
+					output_uint(oc, "size", size);
+			}
+		}
+		output_end_current(oc);
+		return retval;
+	}
+
 	if (!(ls_options & LS_NAME_ONLY)) {
 		if (ls_options & LS_SHOW_SIZE) {
 			char size_text[24];
@@ -119,6 +140,8 @@ int cmd_ls_tree(int argc, const char **argv, const
char *prefix)
 	unsigned char sha1[20];
 	struct tree *tree;
 	int full_tree = 0;
+	char *structured_output_arg = NULL;
+	enum output_style output_style;
 	const struct option ls_tree_options[] = {
 		OPT_BIT('d', NULL, &ls_options, "only show trees",
 			LS_TREE_ONLY),
@@ -140,6 +163,7 @@ int cmd_ls_tree(int argc, const char **argv, const
char *prefix)
 			    "list entire tree; not just current directory "
 			    "(implies --full-name)"),
 		OPT__ABBREV(&abbrev),
+		OPT_OUTPUT(0, "structured-output", &structured_output_arg),
 		OPT_END()
 	};
 
@@ -159,6 +183,8 @@ int cmd_ls_tree(int argc, const char **argv, const
char *prefix)
 	    ((LS_TREE_ONLY|LS_RECURSIVE) & ls_options))
 		ls_options |= LS_SHOW_TREES;
 
+	output_style = handle_output_arg(structured_output_arg);
+
 	if (argc < 1)
 		usage_with_options(ls_tree_usage, ls_tree_options);
 	if (get_sha1(argv[0], sha1))
@@ -168,7 +194,16 @@ int cmd_ls_tree(int argc, const char **argv, const
char *prefix)
 	tree = parse_tree_indirect(sha1);
 	if (!tree)
 		die("not a tree object");
+
+	if (output_style != OUTPUT_NORMAL) {
+		oc = output_start(output_style);
+		output_start_array(oc, "entries");
+	}
+
 	read_tree_recursive(tree, "", 0, 0, pathspec, show_tree, NULL);
 
+	if (output_style != OUTPUT_NORMAL)
+		output_end(oc);
+
 	return 0;
 }
-- 
Julian
Previous: Sverre RabbelierNext: Sverre Rabbelier
Message 17 of 24 in “JSON/XML output for scripting interface”
  1. 0/3 JSON/XML output for scripting interfaceJulian Phillips, Apr 11, 2010
  2. 1/3 strbuf: Add strbuf_vaddf functionJulian Phillips, Apr 11, 2010
  3. Erik Faye-LundApr 11, 2010
  4. Julian PhillipsApr 11, 2010
  5. 2/3 add a library of code for producing structured outputJulian Phillips, Apr 11, 2010
  6. Erik Faye-LundApr 11, 2010
  7. Julian PhillipsApr 11, 2010
  8. Jakub NarebskiApr 11, 2010
  9. Junio C HamanoApr 11, 2010
  10. Sverre RabbelierApr 11, 2010
  11. Julian PhillipsApr 11, 2010
  12. Jakub NarebskiApr 11, 2010
  13. Julian PhillipsApr 11, 2010
  14. Eric RaymondApr 11, 2010
  15. 3/3 status: add support for structured outputJulian Phillips, Apr 11, 2010
  16. Sverre RabbelierApr 11, 2010
  17. Julian PhillipsApr 11, 2010
  18. Sverre RabbelierApr 11, 2010
  19. Julian PhillipsApr 11, 2010
  20. Sverre RabbelierApr 11, 2010
  21. Jon SeymourApr 11, 2010
  22. Eric RaymondApr 11, 2010
  23. Jon SeymourApr 11, 2010
  24. Julian PhillipsApr 11, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.