[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] Improve error checking for rev-prop commands (incl. issue #2364)

From: Julian Foad <julianfoad_at_btopenworld.com>
Date: 2005-07-31 18:33:10 CEST

Julian Foad wrote:
[...]
> 1. It was never intended that a working copy item should be specified as
> the target for operating on a revision property. It is accepted, but
> the documentation doesn't mention it: the help says "[URL]". Therefore
> there is no reason why a revision should be able to be specified
> relative to a WC target. However, the error message for such an attempt
> was inappropriate:
>
> $ svn proplist --revprop -r BASE
> svn: A path under version control is needed for this operation
>
> The new error message with this patch is:
>
> $ svn proplist --revprop -r BASE
> svn: Must specify revision explicitly, and not relative to a WC item,
> when operating on a revision property
>
[...]
>
> The attached patch fixes that error message and does some more besides.
> I'll leave point 2 for now. Reviews or thoughts, please.

... and, this time, the patch is attached.

- Julian

Improve the error checking for commands operating on revision properties.

- Give a more appropriate error when a WC-relative revision like "BASE" is
  specified. (Issue #2364.)
- Give an error if multiple targets are specified, rather than ignoring them.
- Ensure that error messages are marked for localisation (they weren't for
  "propget").
- Factor out duplicated code.

* subversion/clients/cmdline/cl.h,
  subversion/clients/cmdline/props.c
  (svn_cl__revprop_no_rev_error): Remove.
  (svn_cl__revprop_prepare): New function.

* subversion/clients/cmdline/propdel-cmd.c (svn_cl__propdel),
  subversion/clients/cmdline/propedit-cmd.c (svn_cl__propedit),
  subversion/clients/cmdline/propget-cmd.c (svn_cl__propget),
  subversion/clients/cmdline/proplist-cmd.c (svn_cl__proplist),
  subversion/clients/cmdline/propset-cmd.c (svn_cl__propset):
    Replace duplicated code with a call to svn_cl__revprop_prepare().

Index: subversion/clients/cmdline/cl.h
===================================================================
--- subversion/clients/cmdline/cl.h (revision 15510)
+++ subversion/clients/cmdline/cl.h (working copy)
@@ -270,10 +270,17 @@ svn_cl__print_prop_hash (apr_hash_t *pro
                          svn_boolean_t names_only,
                          apr_pool_t *pool);
 
-/* Return a SVN_ERR_CL_ARG_PARSING_ERROR error, with a message stating
- that one must give an explicit revision when operating on a
- revision property. */
-svn_error_t *svn_cl__revprop_no_rev_error (apr_pool_t *pool);
+/* Do the following things that are commonly required before accessing revision
+ properties. Ensure that REVISION is specified explicitly and is not
+ relative to a working-copy item. Ensure that exactly one target is
+ specified in TARGETS. Set *URL to the URL of the target. Return an
+ appropriate error if any of those checks or operations fail.
+ */
+svn_error_t *
+svn_cl__revprop_prepare (const svn_opt_revision_t *revision,
+ apr_array_header_t *targets,
+ const char **URL,
+ apr_pool_t *pool);
 
 /* Search for a text editor command in standard environment variables,
    and invoke it to edit CONTENTS (using a temporary file created in
Index: subversion/clients/cmdline/propdel-cmd.c
===================================================================
--- subversion/clients/cmdline/propdel-cmd.c (revision 15510)
+++ subversion/clients/cmdline/propdel-cmd.c (working copy)
@@ -62,26 +62,10 @@ svn_cl__propdel (apr_getopt_t *os,
   if (opt_state->revprop) /* operate on a revprop */
     {
       svn_revnum_t rev;
- const char *URL, *target;
+ const char *URL;
 
- /* All property commands insist on a specific revision when
- operating on a revprop. */
- if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
- return svn_cl__revprop_no_rev_error (pool);
-
- /* Else some revision was specified, so proceed. */
-
- /* Either we have a URL target, or an implicit wc-path ('.')
- which needs to be converted to a URL. */
- if (targets->nelts <= 0)
- return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
- _("No URL target available"));
- target = ((const char **) (targets->elts))[0];
- SVN_ERR (svn_client_url_from_path (&URL, target, pool));
- if (URL == NULL)
- return svn_error_create
- (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
- _("Either a URL or versioned item is required"));
+ SVN_ERR (svn_cl__revprop_prepare (&opt_state->start_revision, targets,
+ &URL, pool));
 
       /* Let libsvn_client do the real work. */
       SVN_ERR (svn_client_revprop_set (pname_utf8, NULL,
Index: subversion/clients/cmdline/propedit-cmd.c
===================================================================
--- subversion/clients/cmdline/propedit-cmd.c (revision 15510)
+++ subversion/clients/cmdline/propedit-cmd.c (working copy)
@@ -63,32 +63,16 @@ svn_cl__propedit (apr_getopt_t *os,
   if (opt_state->revprop) /* operate on a revprop */
     {
       svn_revnum_t rev;
- const char *URL, *target;
+ const char *URL;
       svn_string_t *propval;
       const char *temp_dir;
 
- /* All property commands insist on a specific revision when
- operating on a revprop. */
- if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
- return svn_cl__revprop_no_rev_error (pool);
-
- /* Else some revision was specified, so proceed. */
-
       /* Implicit "." is okay for revision properties; it just helps
          us find the right repository. */
       svn_opt_push_implicit_dot_target (targets, pool);
 
- /* Either we have a URL target, or an implicit wc-path ('.')
- which needs to be converted to a URL. */
- if (targets->nelts <= 0)
- return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
- _("No URL target available"));
- target = ((const char **) (targets->elts))[0];
- SVN_ERR (svn_client_url_from_path (&URL, target, pool));
- if (URL == NULL)
- return svn_error_create
- (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
- _("Either a URL or versioned item is required"));
+ SVN_ERR (svn_cl__revprop_prepare (&opt_state->start_revision, targets,
+ &URL, pool));
 
       /* Fetch the current property. */
       SVN_ERR (svn_client_revprop_get (pname_utf8, &propval,
Index: subversion/clients/cmdline/propget-cmd.c
===================================================================
--- subversion/clients/cmdline/propget-cmd.c (revision 15510)
+++ subversion/clients/cmdline/propget-cmd.c (working copy)
@@ -86,26 +86,11 @@ svn_cl__propget (apr_getopt_t *os,
   if (opt_state->revprop) /* operate on a revprop */
     {
       svn_revnum_t rev;
- const char *URL, *target;
+ const char *URL;
       svn_string_t *propval;
 
- /* All property commands insist on a specific revision when
- operating on a revprop. */
- if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
- return svn_cl__revprop_no_rev_error (pool);
-
- /* Else some revision was specified, so proceed. */
-
- /* Either we have a URL target, or an implicit wc-path ('.')
- which needs to be converted to a URL. */
- if (targets->nelts <= 0)
- return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
- "No URL target available");
- target = ((const char **) (targets->elts))[0];
- SVN_ERR (svn_client_url_from_path (&URL, target, pool));
- if (URL == NULL)
- return svn_error_create(SVN_ERR_UNVERSIONED_RESOURCE, NULL,
- "Either a URL or versioned item is required");
+ SVN_ERR (svn_cl__revprop_prepare (&opt_state->start_revision, targets,
+ &URL, pool));
       
       /* Let libsvn_client do the real work. */
       SVN_ERR (svn_client_revprop_get (pname_utf8, &propval,
Index: subversion/clients/cmdline/proplist-cmd.c
===================================================================
--- subversion/clients/cmdline/proplist-cmd.c (revision 15510)
+++ subversion/clients/cmdline/proplist-cmd.c (working copy)
@@ -55,27 +55,11 @@ svn_cl__proplist (apr_getopt_t *os,
   if (opt_state->revprop) /* operate on revprops */
     {
       svn_revnum_t rev;
- const char *URL, *target;
+ const char *URL;
       apr_hash_t *proplist;
 
- /* All property commands insist on a specific revision when
- operating on revprops. */
- if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
- return svn_cl__revprop_no_rev_error (pool);
-
- /* Else some revision was specified, so proceed. */
-
- /* Either we have a URL target, or an implicit wc-path ('.')
- which needs to be converted to a URL. */
- if (targets->nelts <= 0)
- return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
- _("No URL target available"));
- target = ((const char **) (targets->elts))[0];
- SVN_ERR (svn_client_url_from_path (&URL, target, pool));
- if (URL == NULL)
- return svn_error_create
- (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
- _("Either a URL or versioned item is required"));
+ SVN_ERR (svn_cl__revprop_prepare (&opt_state->start_revision, targets,
+ &URL, pool));
 
       /* Let libsvn_client do the real work. */
       SVN_ERR (svn_client_revprop_list (&proplist,
Index: subversion/clients/cmdline/props.c
===================================================================
--- subversion/clients/cmdline/props.c (revision 15510)
+++ subversion/clients/cmdline/props.c (working copy)
@@ -28,6 +28,7 @@
 #include "svn_error.h"
 #include "svn_subst.h"
 #include "svn_props.h"
+#include "svn_opt.h"
 #include "cl.h"
 
 #include "svn_private_config.h"
@@ -35,12 +36,37 @@
 
 
 svn_error_t *
-svn_cl__revprop_no_rev_error (apr_pool_t *pool)
+svn_cl__revprop_prepare (const svn_opt_revision_t *revision,
+ apr_array_header_t *targets,
+ const char **URL,
+ apr_pool_t *pool)
 {
- return svn_error_create
- (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
- _("Must specify revision explicitly when operating on a "
- "revision property"));
+ const char *target;
+
+ if (revision->kind != svn_opt_revision_number
+ && revision->kind != svn_opt_revision_date
+ && revision->kind != svn_opt_revision_head)
+ return svn_error_create
+ (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Must specify revision explicitly, and not relative to a WC item, "
+ "when operating on a revision property"));
+
+ /* There must be exactly one target at this point. If it was optional and
+ unspecified by the user, the caller has already added the implicit '.'. */
+ if (targets->nelts != 1)
+ return svn_error_create (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+ _("Wrong number of targets specified"));
+
+ /* (The docs say the target must be either a URL or implicit '.', but
+ explicit WC targets are also accepted.) */
+ target = ((const char **) (targets->elts))[0];
+ SVN_ERR (svn_client_url_from_path (URL, target, pool));
+ if (*URL == NULL)
+ return svn_error_create
+ (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
+ _("Either a URL or versioned item is required"));
+
+ return SVN_NO_ERROR;
 }
 
 
Index: subversion/clients/cmdline/propset-cmd.c
===================================================================
--- subversion/clients/cmdline/propset-cmd.c (revision 15510)
+++ subversion/clients/cmdline/propset-cmd.c (working copy)
@@ -91,30 +91,14 @@ svn_cl__propset (apr_getopt_t *os,
   if (opt_state->revprop) /* operate on a revprop */
     {
       svn_revnum_t rev;
- const char *URL, *target;
-
- /* All property commands insist on a specific revision when
- operating on a revprop. */
- if (opt_state->start_revision.kind == svn_opt_revision_unspecified)
- return svn_cl__revprop_no_rev_error (pool);
-
- /* Else some revision was specified, so proceed. */
+ const char *URL;
 
       /* Implicit "." is okay for revision properties; it just helps
          us find the right repository. */
       svn_opt_push_implicit_dot_target (targets, pool);
 
- /* Either we have a URL target, or an implicit wc-path ('.')
- which needs to be converted to a URL. */
- if (targets->nelts <= 0)
- return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL,
- _("No URL target available"));
- target = ((const char **) (targets->elts))[0];
- SVN_ERR (svn_client_url_from_path (&URL, target, pool));
- if (URL == NULL)
- return svn_error_create (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
- _("Either a URL or versioned item is"
- " required"));
+ SVN_ERR (svn_cl__revprop_prepare (&opt_state->start_revision, targets,
+ &URL, pool));
 
       /* Let libsvn_client do the real work. */
       SVN_ERR (svn_client_revprop_set (pname_utf8, propval,

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sun Jul 31 18:33:56 2005

This is an archived mail posted to the Subversion Dev mailing list.