You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ju...@apache.org on 2015/03/05 17:03:52 UTC

svn commit: r1664385 - /subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c

Author: julianfoad
Date: Thu Mar  5 16:03:52 2015
New Revision: 1664385

URL: http://svn.apache.org/r1664385
Log:
On the 'move-tracking-2' branch: Make 'svnmover' display the usage message for
the subcommand when too few arguments are given.

* subversion/svnmove/svnmover.c
  (action_defn_t): Add help text fields.
  (help_for_subcommand): New.
  (action_defn): Move the help text to here...
  (usage): ... from here.
  (insufficient): Add help for the subcommand into the error message.
  (parse_actions): Adjust the calls to 'insufficient'.

Modified:
    subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c

Modified: subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c
URL: http://svn.apache.org/viewvc/subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c?rev=1664385&r1=1664384&r2=1664385&view=diff
==============================================================================
--- subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c (original)
+++ subversion/branches/move-tracking-2/subversion/svnmover/svnmover.c Thu Mar  5 16:03:52 2015
@@ -249,25 +249,48 @@ typedef struct action_defn_t {
   enum action_code_t code;
   const char *name;
   int num_args;
+  const char *args_help;
+  const char *help;
 } action_defn_t;
 
+#define NL "\n                           "
 static const action_defn_t action_defn[] =
 {
-  {ACTION_DIFF,             "diff", 2},
-  {ACTION_DIFF_E,           "diff-e", 2},
-  {ACTION_LOG,              "log", 2},
-  {ACTION_LIST_BRANCHES,    "branches", 1},
-  {ACTION_LIST_BRANCHES_R,  "ls-br-r", 0},
-  {ACTION_BRANCH,           "branch", 2},
-  {ACTION_MKBRANCH,         "mkbranch", 1},
-  {ACTION_BRANCHIFY,        "branchify", 1},
-  {ACTION_DISSOLVE,         "dissolve", 1},
-  {ACTION_MERGE,            "merge", 3},
-  {ACTION_MV,               "mv", 2},
-  {ACTION_MKDIR,            "mkdir", 1},
-  {ACTION_PUT_FILE,         "put", 2},
-  {ACTION_CP,               "cp", 2},
-  {ACTION_RM,               "rm", 1},
+  {ACTION_LIST_BRANCHES,    "branches", 1, "PATH",
+    "list all branches in the same family as that at PATH"},
+  {ACTION_LIST_BRANCHES_R,  "ls-br-r", 0, "",
+    "list all branches, recursively"},
+  {ACTION_LOG,              "log", 2, "FROM@REV TO@REV",
+    "show per-revision diffs between FROM and TO"},
+  {ACTION_BRANCH,           "branch", 2, "SRC DST",
+    "branch the branch-root or branch-subtree at SRC" NL
+    "to make a new branch at DST"},
+  {ACTION_MKBRANCH,         "mkbranch", 1, "ROOT",
+    "make a directory that's the root of a new branch" NL
+    "in a new branching family; like mkdir+branchify"},
+  {ACTION_BRANCHIFY,        "branchify", 1, "ROOT",
+    "change the existing simple subtree at ROOT into" NL
+    "a sub-branch (presently, in a new branch family)"},
+  {ACTION_DISSOLVE,         "dissolve", 1, "ROOT",
+    "change the existing sub-branch at ROOT into a" NL
+    "simple sub-tree of its parent branch"},
+  {ACTION_DIFF,             "diff", 2, "LEFT RIGHT",
+    "diff LEFT to RIGHT"},
+  {ACTION_DIFF_E,           "diff-e", 2, "LEFT RIGHT",
+    "diff LEFT to RIGHT (element-focused output)"},
+  {ACTION_MERGE,            "merge", 3, "FROM TO YCA@REV",
+    "merge changes YCA->FROM and YCA->TO into TO"},
+  {ACTION_CP,               "cp", 2, "REV SRC DST",
+    "copy SRC@REV to DST"},
+  {ACTION_MV,               "mv", 2, "SRC DST",
+    "move SRC to DST"},
+  {ACTION_RM,               "rm", 1, "PATH",
+    "delete PATH"},
+  {ACTION_MKDIR,            "mkdir", 1, "PATH",
+    "create new directory PATH"},
+  {ACTION_PUT_FILE,         "put", 2, "LOCAL_FILE PATH",
+    "add or modify file PATH with text copied from" NL
+    "LOCAL_FILE (use \"-\" to read from standard input)"},
 };
 
 typedef struct action_t {
@@ -1764,10 +1787,21 @@ sanitize_url(const char *url,
   return svn_uri_canonicalize(url, pool);
 }
 
+static const char *
+help_for_subcommand(const action_defn_t *action, apr_pool_t *pool)
+{
+  const char *cmd = apr_psprintf(pool, "%s %s",
+                                 action->name, action->args_help);
+
+  return apr_psprintf(pool, "  %-22s : %s\n", cmd, action->help);
+}
+
 /* Print a usage message on STREAM. */
 static void
 usage(FILE *stream, apr_pool_t *pool)
 {
+  int i;
+
   svn_error_clear(svn_cmdline_fputs(
     _("usage: svnmover -U REPO_URL [ACTION...]\n"
       "A client for experimenting with move tracking.\n"
@@ -1780,28 +1814,14 @@ usage(FILE *stream, apr_pool_t *pool)
       "\n"
       "  Store move tracking metadata either in local files or in revprops.\n"
       "\n"
-      "Actions:\n"
-      "  branches PATH          : list all branches in the same family as that at PATH\n"
-      "  ls-br-r                : list all branches, recursively\n"
-      "  log FROM@REV TO@REV    : show per-revision diffs between FROM and TO\n"
-      "  branch SRC DST         : branch the branch-root or branch-subtree at SRC\n"
-      "                           to make a new branch at DST\n"
-      "  mkbranch ROOT          : make a directory that's the root of a new branch\n"
-      "                           in a new branching family; like mkdir+branchify\n"
-      "  branchify ROOT         : change the existing simple subtree at ROOT into\n"
-      "                           a sub-branch (presently, in a new branch family)\n"
-      "  dissolve ROOT          : change the existing sub-branch at ROOT into a\n"
-      "                           simple sub-tree of its parent branch\n"
-      "  diff LEFT RIGHT        : diff LEFT to RIGHT\n"
-      "  diff-e LEFT RIGHT      : diff LEFT to RIGHT (element-focused output)\n"
-      "  merge FROM TO YCA@REV  : merge changes YCA->FROM and YCA->TO into TO\n"
-      "  cp REV SRC DST         : copy SRC@REV to DST\n"
-      "  mv SRC DST             : move SRC to DST\n"
-      "  rm PATH                : delete PATH\n"
-      "  mkdir PATH             : create new directory PATH\n"
-      "  put LOCAL_FILE PATH    : add or modify file PATH with text copied from\n"
-      "                           LOCAL_FILE (use \"-\" to read from standard input)\n"
-      "\n"
+      "Actions:\n"),
+                  stream, pool));
+  for (i = 0; i < sizeof (action_defn) / sizeof (action_defn[0]); i++)
+    svn_error_clear(svn_cmdline_fputs(
+                      help_for_subcommand(&action_defn[i], pool),
+                      stream, pool));
+  svn_error_clear(svn_cmdline_fputs(
+    _("\n"
       "Valid options:\n"
       "  -h, -? [--help]        : display this text\n"
       "  -v [--verbose]         : display debugging messages\n"
@@ -1831,10 +1851,12 @@ usage(FILE *stream, apr_pool_t *pool)
 }
 
 static svn_error_t *
-insufficient(void)
+insufficient(int i, apr_pool_t *pool)
 {
-  return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
-                          "insufficient arguments");
+  return svn_error_createf(SVN_ERR_INCORRECT_PARAMS, NULL,
+                           "insufficient arguments:\n"
+                           "%s",
+                           help_for_subcommand(&action_defn[i], pool));
 }
 
 static svn_error_t *
@@ -1963,7 +1985,7 @@ parse_actions(apr_array_header_t **actio
 
   for (i = 0; i < action_args->nelts; ++i)
     {
-      int j, num_url_args;
+      int j, k, num_url_args;
       const char *action_string = APR_ARRAY_IDX(action_args, i, const char *);
       action_t *action = apr_pcalloc(pool, sizeof(*action));
       const char *cp_from_rev = NULL;
@@ -1993,25 +2015,25 @@ parse_actions(apr_array_header_t **actio
         {
           /* next argument is the copy source revision */
           if (++i == action_args->nelts)
-            return svn_error_trace(insufficient());
+            return svn_error_trace(insufficient(j, pool));
           cp_from_rev = APR_ARRAY_IDX(action_args, i, const char *);
         }
 
       /* Parse the required number of URLs. */
-      for (j = 0; j < num_url_args; ++j)
+      for (k = 0; k < num_url_args; ++k)
         {
           const char *path;
 
           if (++i == action_args->nelts)
-            return svn_error_trace(insufficient());
+            return svn_error_trace(insufficient(j, pool));
           path = APR_ARRAY_IDX(action_args, i, const char *);
 
-          if (cp_from_rev && j == 0)
+          if (cp_from_rev && k == 0)
             {
               path = apr_psprintf(pool, "%s@%s", path, cp_from_rev);
             }
 
-          SVN_ERR(svn_opt_parse_path(&action->rev_spec[j], &path, path, pool));
+          SVN_ERR(svn_opt_parse_path(&action->rev_spec[k], &path, path, pool));
 
           /* If there's an ANCHOR_URL, we expect URL to be a path
              relative to ANCHOR_URL (and we build a full url from the