Branko Čibej wrote on Thu, Nov 07, 2019 at 17:28:35 +0100: > Not with a new option. Instead --show-item should accept a > comma-separated list of keywords.
You mean, like this? [[[ % subversion/svn/svn info wc/foo --show-item=kind,schedule,relative-url dir add ^/foo % ]]] That's not a mock-up: [[[ Index: subversion/svn/info-cmd.c =================================================================== --- subversion/svn/info-cmd.c (revision 1869499) +++ subversion/svn/info-cmd.c (working copy) @@ -411,8 +411,8 @@ typedef struct print_info_baton_t * The following fields are used by print_info_item(). */ - /* Which item to print. */ - info_item_t print_what; + /* Which items to print. */ + apr_array_header_t *print_whats; /* Do we expect to show info for multiple targets? */ svn_boolean_t multiple_targets; @@ -436,7 +436,7 @@ typedef struct print_info_baton_t * temporary allocation. */ static svn_error_t * -find_print_what(const char *keyword, +find_print_what(const char *keywords_from_argv, print_info_baton_t *receiver_baton, apr_pool_t *scratch_pool) { @@ -445,7 +445,9 @@ static svn_error_t * svn_cl__simcheck_t *kwbuf = apr_palloc( scratch_pool, info_item_map_len * sizeof(svn_cl__simcheck_t)); apr_size_t i; - + apr_array_header_t *whats; + + /* Initialize KEYWORDS and KWBUF. */ for (i = 0; i < info_item_map_len; ++i) { keywords[i] = &kwbuf[i]; @@ -454,9 +456,14 @@ static svn_error_t * kwbuf[i].data = &info_item_map[i]; } - switch (svn_cl__similarity_check(keyword, keywords, - info_item_map_len, scratch_pool)) + whats = svn_cstring_split(keywords_from_argv, ",", TRUE, scratch_pool); + for (i = 0; i < whats->nelts; i++) { + const char *keyword = APR_ARRAY_IDX(whats, i, const char *); + switch (svn_cl__similarity_check(keyword, keywords, + info_item_map_len, scratch_pool)) + /* TODO: indent this block */ + { const info_item_map_t *kw0; const info_item_map_t *kw1; const info_item_map_t *kw2; @@ -463,8 +470,9 @@ static svn_error_t * case 0: /* Exact match. */ kw0 = keywords[0]->data; - receiver_baton->print_what = kw0->print_what; - return SVN_NO_ERROR; + APR_ARRAY_PUSH(receiver_baton->print_whats, info_item_t) = + kw0->print_what; + break; case 1: /* The best alternative isn't good enough */ @@ -503,6 +511,13 @@ static svn_error_t * " did you mean '%s', '%s' or '%s'?"), keyword, kw0->keyword.data, kw1->keyword.data, kw2->keyword.data); } + } + + if (whats->nelts == 0) + return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL, + _("--show-item requires a non-empty argument")); + + return SVN_NO_ERROR; } /* A callback of type svn_client_info_receiver2_t. @@ -1125,12 +1140,18 @@ print_info_item(void *baton, receiver_baton->path_prefix, target, pool)); const char *const target_path = (receiver_baton->multiple_targets ? actual_target_path : NULL); + int i; if (receiver_baton->start_new_line) SVN_ERR(svn_cmdline_fputs("\n", stdout, pool)); - switch (receiver_baton->print_what) + for (i = 0; i < receiver_baton->print_whats->nelts; i++) { + if (i > 0) + SVN_ERR(svn_cmdline_fputs("\t", stdout, pool)); + switch (APR_ARRAY_IDX(receiver_baton->print_whats, i, info_item_t)) + /* TODO: indent this block */ + { case info_item_kind: SVN_ERR(print_info_item_string(svn_node_kind_to_word(info->kind), target_path, pool)); @@ -1235,6 +1256,7 @@ print_info_item(void *baton, default: SVN_ERR_MALFUNCTION(); } + } receiver_baton->start_new_line = TRUE; return SVN_NO_ERROR; @@ -1300,6 +1322,7 @@ svn_cl__info(apr_getopt_t *os, else if (opt_state->show_item) { receiver = print_info_item; + receiver_baton.print_whats = apr_array_make(pool, 1, sizeof(info_item_t)); if (opt_state->incremental) return svn_error_create( Index: subversion/svn/svn.c =================================================================== --- subversion/svn/svn.c (revision 1869499) +++ subversion/svn/svn.c (working copy) @@ -431,6 +431,7 @@ const apr_getopt_option_t svn_cl__options[] = " " "current revision (recommended when tagging)")}, {"show-item", opt_show_item, 1, + /* TODO: update docstring */ N_("print only the item identified by ARG:\n" " " " 'kind' node kind of TARGET\n" Index: subversion/tests/cmdline/info_tests.py =================================================================== --- subversion/tests/cmdline/info_tests.py (revision 1869499) +++ subversion/tests/cmdline/info_tests.py (working copy) @@ -644,6 +644,10 @@ def info_item_simple(sbox): ['1'], [], 'info', '--show-item=revision', '--no-newline', sbox.ospath('')) + svntest.actions.run_and_verify_svn( + ['1\tdir'], [], + 'info', '--show-item=revision,kind', '--no-newline', + sbox.ospath('')) def info_item_simple_multiple(sbox): ]]] In addition to those TODO comments there's also a function docstring that needs updating. > And we could add a catch-all keyword, e.g., 'all', as shorthand for 'print > all attributes as tab-separated values'. I suppose we could, but I don't see what a script might use --show-item=all for. Cheers, Daniel