On Sun, 11 Apr 2010 17:48:28 +0200, Sverre Rabbelier <srabbelier@xxxxxxxxx> wrote: > Heya, > > On Sun, Apr 11, 2010 at 13:37, Julian Phillips <julian@xxxxxxxxxxxxxxxxx> > 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 >> 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html