Author: hwright
Date: Tue Apr 19 20:33:21 2011
New Revision: 1095195

URL: http://svn.apache.org/viewvc?rev=1095195&view=rev
Log:
Make the libsvn_client propset API operate on an array of targets, rather than
just one.

Note: This will probably choke the JavaHL bindings.

* subversion/svn/propdel-cmd.c
  (svn_cl__propdel): Don't iterate over the targets, just pass 'em down.

* subversion/svn/propset-cmd.c
  (svn_cl__propset): Same.

* subversion/svn/propedit-cmd.c
  (svn_cl__propedit): Wrap the single target in an array.

* subversion/libsvn_client/deprecated.c
  (svn_client_propset3): Same.

* subversion/include/svn_client.h
  (svn_client_propset4): Update targets param to be an array.  Update docs.

* subversion/libsvn_client/prop_commands.c
  (svn_client_propset4): Take an array of targets, and verify they are
    homogeneous.  Loop over them for either ra or working copy mods.

Modified:
    subversion/trunk/subversion/include/svn_client.h
    subversion/trunk/subversion/libsvn_client/deprecated.c
    subversion/trunk/subversion/libsvn_client/prop_commands.c
    subversion/trunk/subversion/svn/propdel-cmd.c
    subversion/trunk/subversion/svn/propedit-cmd.c
    subversion/trunk/subversion/svn/propset-cmd.c

Modified: subversion/trunk/subversion/include/svn_client.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Tue Apr 19 20:33:21 2011
@@ -4115,20 +4115,21 @@ svn_client_move(svn_client_commit_info_t
 
 
 /**
- * Set @a propname to @a propval on @a target.
+ * Set @a propname to @a propval on @a targets.
  * A @a propval of @c NULL will delete the property.
  *
- * If @a depth is #svn_depth_empty, set the property on @a target
- * only; if #svn_depth_files, set it on @a target and its file
- * children (if any); if #svn_depth_immediates, on @a target and all
- * of its immediate children (both files and directories); if
- * #svn_depth_infinity, on @a target and everything beneath it.
+ * If @a depth is #svn_depth_empty, set the property on each member of
+ * @a targets only; if #svn_depth_files, set it on @a targets and their file
+ * children (if any); if #svn_depth_immediates, on @a targets and all
+ * of their immediate children (both files and directories); if
+ * #svn_depth_infinity, on @a targets and everything beneath them.
  *
- * The @a target may only be an URL if @a base_revision_for_url is not
+ * Targets must either be all working copy paths or URLs.  The @a targets may
+ * only be an URL if @a base_revision_for_url is not
  * #SVN_INVALID_REVNUM; in this case, the property will only be set
  * if it has not changed since revision @a base_revision_for_url.
- * @a base_revision_for_url must be #SVN_INVALID_REVNUM if @a target
- * is not an URL.  @a depth deeper than #svn_depth_empty is not
+ * @a base_revision_for_url must be #SVN_INVALID_REVNUM if @a targets
+ * are not URLs.  @a depth deeper than #svn_depth_empty is not
  * supported on URLs.  The authentication baton in @a ctx and @a
  * ctx->log_msg_func3/@a ctx->log_msg_baton3 will be used to
  * immediately attempt to commit the property change in the
@@ -4140,8 +4141,8 @@ svn_client_move(svn_client_commit_info_t
  *
  * If @a skip_checks is TRUE, do no validity checking.  But if @a
  * skip_checks is FALSE, and @a propname is not a valid property for @a
- * target, return an error, either #SVN_ERR_ILLEGAL_TARGET (if the
- * property is not appropriate for @a target), or
+ * targets, return an error, either #SVN_ERR_ILLEGAL_TARGET (if the
+ * property is not appropriate for @a targets), or
  * #SVN_ERR_BAD_MIME_TYPE (if @a propname is "svn:mime-type", but @a
  * propval is not a valid mime-type).
  *
@@ -4171,7 +4172,7 @@ svn_client_move(svn_client_commit_info_t
 svn_error_t *
 svn_client_propset4(const char *propname,
                     const svn_string_t *propval,
-                    const char *target,
+                    const apr_array_header_t *targets,
                     svn_depth_t depth,
                     svn_boolean_t skip_checks,
                     svn_revnum_t base_revision_for_url,

Modified: subversion/trunk/subversion/libsvn_client/deprecated.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/deprecated.c?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_client/deprecated.c Tue Apr 19 20:33:21 
2011
@@ -1536,11 +1536,14 @@ svn_client_propset3(svn_commit_info_t **
                     apr_pool_t *pool)
 {
   struct capture_baton_t cb;
+  apr_array_header_t *targets = apr_array_make(pool, 1, sizeof(const char *));
+
+  APR_ARRAY_PUSH(targets, const char *) = target;
 
   cb.info = commit_info_p;
   cb.pool = pool;
 
-  return svn_client_propset4(propname, propval, target, depth, skip_checks,
+  return svn_client_propset4(propname, propval, targets, depth, skip_checks,
                              base_revision_for_url, changelists, revprop_table,
                              capture_commit_info, &cb, ctx, pool);
 }

Modified: subversion/trunk/subversion/libsvn_client/prop_commands.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/prop_commands.c?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/prop_commands.c (original)
+++ subversion/trunk/subversion/libsvn_client/prop_commands.c Tue Apr 19 
20:33:21 2011
@@ -343,7 +343,7 @@ set_props_cb(void *baton,
 svn_error_t *
 svn_client_propset4(const char *propname,
                     const svn_string_t *propval,
-                    const char *target,
+                    const apr_array_header_t *targets,
                     svn_depth_t depth,
                     svn_boolean_t skip_checks,
                     svn_revnum_t base_revision_for_url,
@@ -354,6 +354,23 @@ svn_client_propset4(const char *propname
                     svn_client_ctx_t *ctx,
                     apr_pool_t *pool)
 {
+  svn_boolean_t targets_are_urls;
+  int i;
+
+  if (targets->nelts == 0)
+    return SVN_NO_ERROR;
+
+  /* Check for homogeneity among our targets. */
+  targets_are_urls = svn_path_is_url(APR_ARRAY_IDX(targets, 0, const char *));
+  for (i = 1; i < targets->nelts; i++)
+    {
+      const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+      if (svn_path_is_url(target) != targets_are_urls)
+        return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                 _("Cannot mix repository and working copy paths"));
+    }
+
   /* Since Subversion controls the "svn:" property namespace, we
      don't honor the 'skip_checks' flag here.  Unusual property
      combinations, like svn:eol-style with a non-text svn:mime-type,
@@ -370,21 +387,21 @@ svn_client_propset4(const char *propname
     return svn_error_createf(SVN_ERR_CLIENT_PROPERTY_NAME, NULL,
                              _("Bad property name: '%s'"), propname);
 
-  if (svn_path_is_url(target))
+  if (targets_are_urls)
     {
       /* The rationale for requiring the base_revision_for_url
          argument is that without it, it's too easy to possibly
          overwrite someone else's change without noticing.  (See also
          tools/examples/svnput.c). */
       if (! SVN_IS_VALID_REVNUM(base_revision_for_url))
-        return svn_error_createf(SVN_ERR_CLIENT_BAD_REVISION, NULL,
-                                 _("Setting property on non-local target '%s' "
-                                   "needs a base revision"), target);
+        return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL,
+                                _("Setting property on non-local targets "
+                                  "needs a base revision"));
 
       if (depth > svn_depth_empty)
-        return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                                 _("Setting property recursively on non-local "
-                                   "target '%s' is not supported"), target);
+        return svn_error_create(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
+                                _("Setting property recursively on non-local "
+                                  "targets is not supported"));
 
       /* ### When you set svn:eol-style or svn:keywords on a wc file,
          ### Subversion sends a textdelta at commit time to properly
@@ -398,54 +415,81 @@ svn_client_propset4(const char *propname
       if ((strcmp(propname, SVN_PROP_EOL_STYLE) == 0) ||
           (strcmp(propname, SVN_PROP_KEYWORDS) == 0))
         return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
-                                 _("Setting property '%s' on non-local target "
-                                   "'%s' is not supported"), propname, target);
+                                 _("Setting property '%s' on non-local "
+                                   "targets is not supported"), propname);
+
+      for (i = 0; i < targets->nelts; i++)
+        {
+          const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+          SVN_ERR(propset_on_url(propname, propval, target, skip_checks,
+                                 base_revision_for_url, revprop_table,
+                                 commit_callback, commit_baton, ctx, pool));
+        }
 
-      return propset_on_url(propname, propval, target, skip_checks,
-                            base_revision_for_url, revprop_table,
-                            commit_callback, commit_baton, ctx, pool);
+      return SVN_NO_ERROR;
     }
   else
     {
-      svn_node_kind_t kind;
       apr_hash_t *changelist_hash = NULL;
-      const char *target_abspath;
-      svn_error_t *err;
-      struct set_props_baton baton;
-
-      SVN_ERR(svn_dirent_get_absolute(&target_abspath, target, pool));
+      apr_pool_t *iterpool = svn_pool_create(pool);
 
       if (changelists && changelists->nelts)
         SVN_ERR(svn_hash_from_cstring_keys(&changelist_hash,
                                            changelists, pool));
 
-      err = svn_wc_read_kind(&kind, ctx->wc_ctx, target_abspath, FALSE, pool);
-
-      if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
-          || kind == svn_node_unknown || kind == svn_node_none)
+      for (i = 0; i < targets->nelts; i++)
         {
-          /* svn uses SVN_ERR_UNVERSIONED_RESOURCE as warning only
-             for this function. */
-          return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, err,
-                                   _("'%s' is not under version control"),
-                                   svn_dirent_local_style(target_abspath,
-                                                          pool));
-        }
-      else
-        SVN_ERR(err);
+          svn_node_kind_t kind;
+          const char *target_abspath;
+          svn_error_t *err;
+          struct set_props_baton baton;
+          const char *target = APR_ARRAY_IDX(targets, i, const char *);
+
+          svn_pool_clear(iterpool);
+
+          /* Check for cancellation */
+          if (ctx->cancel_func)
+            SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
 
-      baton.ctx = ctx;
-      baton.local_abspath = target_abspath;
-      baton.depth = depth;
-      baton.kind = kind;
-      baton.propname = propname;
-      baton.propval = propval;
-      baton.skip_checks = skip_checks;
-      baton.changelist_hash = changelist_hash;
-
-      SVN_ERR(svn_wc__call_with_write_lock(set_props_cb, &baton,
-                                           ctx->wc_ctx, target_abspath, FALSE,
-                                           pool, pool));
+          SVN_ERR(svn_dirent_get_absolute(&target_abspath, target, iterpool));
+
+          err = svn_wc_read_kind(&kind, ctx->wc_ctx, target_abspath, FALSE,
+                                 iterpool);
+
+          if ((err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND)
+              || kind == svn_node_unknown || kind == svn_node_none)
+            {
+              if (ctx->notify_func2)
+                {
+                  svn_wc_notify_t *notify = svn_wc_create_notify(
+                                                    target_abspath,
+                                                    svn_wc_notify_warning,
+                                                    iterpool);
+
+                  notify->err = err;
+                  ctx->notify_func2(ctx->notify_baton2, notify, iterpool);
+                }
+
+              svn_error_clear(err);
+            }
+          else
+            SVN_ERR(err);
+
+          baton.ctx = ctx;
+          baton.local_abspath = target_abspath;
+          baton.depth = depth;
+          baton.kind = kind;
+          baton.propname = propname;
+          baton.propval = propval;
+          baton.skip_checks = skip_checks;
+          baton.changelist_hash = changelist_hash;
+
+          SVN_ERR(svn_wc__call_with_write_lock(set_props_cb, &baton,
+                                               ctx->wc_ctx, target_abspath,
+                                               FALSE, iterpool, iterpool));
+        }
+      svn_pool_destroy(iterpool);
 
       return SVN_NO_ERROR;
     }

Modified: subversion/trunk/subversion/svn/propdel-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/propdel-cmd.c?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/propdel-cmd.c (original)
+++ subversion/trunk/subversion/svn/propdel-cmd.c Tue Apr 19 20:33:21 2011
@@ -90,36 +90,17 @@ svn_cl__propdel(apr_getopt_t *os,
     }
   else  /* operate on a normal, versioned property (not a revprop) */
     {
-      apr_pool_t *subpool = svn_pool_create(pool);
-      int i;
-
       if (opt_state->depth == svn_depth_unknown)
         opt_state->depth = svn_depth_empty;
 
       /* For each target, remove the property PNAME. */
-      for (i = 0; i < targets->nelts; i++)
-        {
-          const char *target = APR_ARRAY_IDX(targets, i, const char *);
-
-          svn_pool_clear(subpool);
-          SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
-
-          /* Pass FALSE for 'skip_checks' because it doesn't matter here,
-             and opt_state->force doesn't apply to this command anyway. */
-          SVN_ERR(svn_cl__try(svn_client_propset4(
-                               pname_utf8,
-                               NULL, target,
-                               opt_state->depth,
-                               FALSE, SVN_INVALID_REVNUM,
-                               opt_state->changelists, NULL,
-                               svn_cl__print_commit_info, NULL,
-                               ctx, subpool),
-                              NULL, opt_state->quiet,
-                              SVN_ERR_UNVERSIONED_RESOURCE,
-                              SVN_ERR_ENTRY_NOT_FOUND,
-                              SVN_NO_ERROR));
-        }
-      svn_pool_destroy(subpool);
+      SVN_ERR(svn_client_propset4(pname_utf8,
+                                  NULL, targets,
+                                  opt_state->depth,
+                                  FALSE, SVN_INVALID_REVNUM,
+                                  opt_state->changelists, NULL,
+                                  svn_cl__print_commit_info, NULL,
+                                  ctx, pool));
     }
 
   return SVN_NO_ERROR;

Modified: subversion/trunk/subversion/svn/propedit-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/propedit-cmd.c?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/propedit-cmd.c (original)
+++ subversion/trunk/subversion/svn/propedit-cmd.c Tue Apr 19 20:33:21 2011
@@ -287,6 +287,8 @@ svn_cl__propedit(apr_getopt_t *os,
           if (edited_propval && !svn_string_compare(propval, edited_propval))
             {
               svn_error_t *err = SVN_NO_ERROR;
+              apr_array_header_t *targs = apr_array_make(subpool, 1,
+                                                sizeof(const char *));
 
               svn_cl__check_boolean_prop_val(pname_utf8, edited_propval->data,
                                              subpool);
@@ -296,7 +298,8 @@ svn_cl__propedit(apr_getopt_t *os,
                                                    opt_state, NULL, 
ctx->config,
                                                    subpool));
 
-              err = svn_client_propset4(pname_utf8, edited_propval, target,
+              APR_ARRAY_PUSH(targs, const char *) = target;
+              err = svn_client_propset4(pname_utf8, edited_propval, targs,
                                         svn_depth_empty, opt_state->force,
                                         base_rev, NULL, 
opt_state->revprop_table,
                                         commit_info_handler, &cib,

Modified: subversion/trunk/subversion/svn/propset-cmd.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/propset-cmd.c?rev=1095195&r1=1095194&r2=1095195&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/propset-cmd.c (original)
+++ subversion/trunk/subversion/svn/propset-cmd.c Tue Apr 19 20:33:21 2011
@@ -130,7 +130,6 @@ svn_cl__propset(apr_getopt_t *os,
     }
   else  /* operate on a normal, versioned property (not a revprop) */
     {
-      apr_pool_t *iterpool;
       int i;
 
       if (opt_state->depth == svn_depth_unknown)
@@ -172,43 +171,20 @@ svn_cl__propset(apr_getopt_t *os,
             }
         }
 
-      iterpool = svn_pool_create(scratch_pool);
+      SVN_ERR(svn_client_propset4(pname_utf8, propval, targets,
+                                  opt_state->depth, opt_state->force,
+                                  SVN_INVALID_REVNUM, opt_state->changelists,
+                                  NULL, svn_cl__print_commit_info, NULL, ctx,
+                                  scratch_pool));
+
       for (i = 0; i < targets->nelts; i++)
         {
           const char *target = APR_ARRAY_IDX(targets, i, const char *);
-          svn_error_t *err;
-
-          svn_pool_clear(iterpool);
-          SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
-
-          err = svn_client_propset4(
-                               pname_utf8, propval, target,
-                               opt_state->depth, opt_state->force,
-                               SVN_INVALID_REVNUM, opt_state->changelists,
-                               NULL, svn_cl__print_commit_info, NULL, ctx,
-                               iterpool);
-          if (err && (err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE
-                   || err->apr_err == SVN_ERR_ENTRY_NOT_FOUND) )
-            {
-              if (! opt_state->quiet)
-                {
-                  svn_wc_notify_t *notify = svn_wc_create_notify(NULL,
-                                                         svn_wc_notify_warning,
-                                                         iterpool);
-
-                  notify->err = err;
-                  ctx->notify_func2(ctx->notify_baton, notify, iterpool);
-                }
-
-              svn_error_clear(err);
-            }
-          else if (err)
-            return err;
 
           if (! opt_state->quiet)
-            svn_cl__check_boolean_prop_val(pname_utf8, propval->data, 
iterpool);
+            svn_cl__check_boolean_prop_val(pname_utf8, propval->data,
+                                           scratch_pool);
         }
-      svn_pool_destroy(iterpool);
     }
 
   return SVN_NO_ERROR;


Reply via email to