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

Re: new experimental branch: dir-auto-props (issue 1989)

From: Ph. Marek <philipp.marek_at_bmlv.gv.at>
Date: 2005-03-23 07:53:35 CET

On Tuesday 22 March 2005 16:20, Philip Martin wrote:
> Julian Foad <julianfoad@btopenworld.com> writes:
> > Ph. Marek wrote:
> >> Well, here it is.
> >
> > Could you post it with a log message, please?
Here you are.

> I remember one other problem that came up when directory auto-props
> were last discussed, svn:ignore takes values that span multiple lines
> and the config parser doesn't support that (or didn't the last time I
> tried).
>
> I'm not sure what to do to make svn:ignore work, a parser change,
> different properties, some sort of newline escaping, etc. but I think
> providing directory auto-props without proper svn:ignore support is a
> bit of a mistake.
Well, there you're right. That might be a problem.
I'll have a look at the code and post my comments.

First thoughts: how about having multiple matching properties in [auto-props]
concatenated?
Example:
 [dir-auto-props]
 * = svn:ignore=*.o
 * = svn:ignore=*.tmp
 * = svn:ignore=*~
That's not the most prettiest thing, but could be handy for other properties
too.

How about the easy solution - make \r, \n, and maybe \x??, \??? available? Do
we fear that such things are already used in some config file? If not, that's
an easy first solution. (But what about unicode characters? Do we need them
here??)

Regards,

Phil

[[[

Issue 1989: automatic directory properties

* subversion/include/svn_config.h
  (SVN_CONFIG_SECTION_DIR_AUTO_PROPS): Definition of new string

* subversion/libsvn_client/client.h
  (svn_client__get_dir_auto_props): definition of new function

* subversion/libsvn_client/add.c
  (svn_client__get_dir_auto_props): new function
  (add): call svn_client__get_dir_auto_props for directories
  (svn_client__get_auto_props): changed code to match documentation

* subversion/libsvn_client/commit.c
  (import_dir): call svn_client__get_dir_auto_props to fetch
  automatic properties

* subversion/tests/clients/cmdline/autoprop_tests.py:
  Added tests for dir-auto-props

]]]

=== subversion/include/svn_config.h
==================================================================
--- subversion/include/svn_config.h  (revision 231)
+++ subversion/include/svn_config.h  (local)
@@ -83,6 +83,7 @@
 #define SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS         "enable-auto-props"
 #define SVN_CONFIG_SECTION_TUNNELS              "tunnels"
 #define SVN_CONFIG_SECTION_AUTO_PROPS           "auto-props"
+#define SVN_CONFIG_SECTION_DIR_AUTO_PROPS           "dir-auto-props"

 /* For repository svnserve.conf files */
 #define SVN_CONFIG_SECTION_GENERAL              "general"
=== subversion/libsvn_client/add.c
==================================================================
--- subversion/libsvn_client/add.c  (revision 231)
+++ subversion/libsvn_client/add.c  (local)
@@ -171,6 +171,8 @@
   if (use_autoprops)
     svn_config_enumerate (cfg, SVN_CONFIG_SECTION_AUTO_PROPS,
                           auto_props_enumerator, &autoprops);
+  else
+    *properties = NULL;

   /* if mimetype has not been set check the file */
   if (! autoprops.mimetype)
@@ -197,6 +199,41 @@
   return SVN_NO_ERROR;
 }

+svn_error_t *
+svn_client__get_dir_auto_props (apr_hash_t **properties,
+                                const char *path,
+                                svn_client_ctx_t *ctx,
+                                apr_pool_t *pool)
+{
+  svn_config_t *cfg;
+  svn_boolean_t use_autoprops;
+  auto_props_baton_t autoprops;
+
+  autoprops.properties = apr_hash_make (pool);
+  autoprops.filename = svn_path_basename (path, pool);
+  autoprops.pool = pool;
+  autoprops.mimetype = NULL;
+  autoprops.have_executable = FALSE;
+  *properties = autoprops.properties;
+
+  cfg = ctx->config ? apr_hash_get (ctx->config, SVN_CONFIG_CATEGORY_CONFIG,
+                                    APR_HASH_KEY_STRING) : NULL;
+
+  /* check that auto props is enabled */
+  SVN_ERR (svn_config_get_bool (cfg, &use_autoprops,
+                                SVN_CONFIG_SECTION_MISCELLANY,
+                                SVN_CONFIG_OPTION_ENABLE_AUTO_PROPS, FALSE));
+
+  /* search for directory auto props */
+  if (use_autoprops)
+    svn_config_enumerate (cfg, SVN_CONFIG_SECTION_DIR_AUTO_PROPS,
+                          auto_props_enumerator, &autoprops);
+  else
+    *properties = NULL;
+
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 add_file (const char *path,
           svn_client_ctx_t *ctx,
@@ -389,10 +426,12 @@
 {
   svn_node_kind_t kind;
   svn_error_t *err;
+  apr_hash_t* properties;
+  apr_hash_index_t *hi;

   SVN_ERR (svn_io_check_path (path, &kind, pool));
   if ((kind == svn_node_dir) && recursive)
-    err = add_dir_recursive (path, adm_access, force, ctx, pool);
+        err = add_dir_recursive (path, adm_access, force, ctx, pool);
   else if (kind == svn_node_file)
     err = add_file (path, ctx, adm_access, pool);
   else
@@ -400,6 +439,31 @@
                       ctx->cancel_func, ctx->cancel_baton,
                       ctx->notify_func, ctx->notify_baton, pool);

+  if (kind == svn_node_dir)
+    {
+      /* Now that the .svn-directories exist, do the directories auto-props
*/
+      SVN_ERR (svn_client__get_dir_auto_props (&properties, path, ctx,
+                                               pool));
+      if (properties)
+        {
+          /* loop through the hashtable and add the properties */
+          for (hi = apr_hash_first (pool, properties);
+               hi != NULL; hi = apr_hash_next (hi))
+            {
+              const void *pname;
+              void *pval;
+
+              apr_hash_this (hi, &pname, NULL, &pval);
+              /* It's probably best to pass 0 for force, so that if
+                 the autoprops say to set some weird combination,
+                 we just error and let the user sort it out. */
+              SVN_ERR (svn_wc_prop_set2 (pname, pval, path,
+                                         adm_access, FALSE, pool));
+            }
+        }
+    }
+
+
   /* Ignore SVN_ERR_ENTRY_EXISTS when FORCE is set.  */
   if (err && err->apr_err == SVN_ERR_ENTRY_EXISTS && force)
     {
=== subversion/libsvn_client/client.h
==================================================================
--- subversion/libsvn_client/client.h  (revision 231)
+++ subversion/libsvn_client/client.h  (local)
@@ -286,6 +286,18 @@
                                          const char *path,
                                          svn_client_ctx_t *ctx,
                                          apr_pool_t *pool);
+
+
+/* Read automatic properties matching PATH from CTX->config.
+   Set *PROPERTIES to a hash containing propname/value pairs
+   (const char * keys mapping to svn_string_t * values), or if
+   auto-props are disabled, set *PROPERTIES to NULL.
+   Allocate the hash table, keys, values, and mimetype in POOL. */
+svn_error_t *svn_client__get_dir_auto_props (apr_hash_t **properties,
+                                             const char *path,
+                                             svn_client_ctx_t *ctx,
+                                             apr_pool_t *pool);
+

 /* The main logic for client deletion from a working copy. Deletes PATH
=== subversion/libsvn_client/commit.c
==================================================================
--- subversion/libsvn_client/commit.c  (revision 231)
+++ subversion/libsvn_client/commit.c  (local)
@@ -277,11 +277,27 @@
   apr_hash_t *dirents;
   apr_hash_index_t *hi;
   apr_array_header_t *ignores;
+  apr_hash_t* properties;

   SVN_ERR (svn_path_check_valid (path, pool));

   SVN_ERR (svn_wc_get_default_ignores (&ignores, ctx->config, pool));

+  SVN_ERR (svn_client__get_dir_auto_props (&properties, path, ctx,
+                                       pool));
+  if (properties)
+    {
+      for (hi = apr_hash_first (pool, properties); hi; hi = apr_hash_next
(hi))
+        {
+          const void *pname;
+          void *pval;
+
+          apr_hash_this (hi, &pname, NULL, &pval);
+          SVN_ERR (editor->change_dir_prop (dir_baton, pname, pval, pool));
+        }
+    }
+
+
   SVN_ERR (svn_io_get_dirents (&dirents, path, pool));

   for (hi = apr_hash_first (pool, dirents); hi; hi = apr_hash_next (hi))
=== subversion/tests/clients/cmdline/autoprop_tests.py
==================================================================
--- subversion/tests/clients/cmdline/autoprop_tests.py  (revision 231)
+++ subversion/tests/clients/cmdline/autoprop_tests.py  (local)
@@ -77,6 +77,8 @@
   fd.write('foobar.lha = lhafile=da;lzhfile=niet\n')
   fd.write('spacetest = abc = def ; ghi = ; = j \n')
   fd.write('* = auto=oui\n')
+  fd.write('[dir-auto-props]\n')
+  fd.write('dir-with-auto-prop = auto-prop=ok\n')
   fd.write('\n')
   fd.close()

@@ -87,7 +89,14 @@

 #----------------------------------------------------------------------
+def create_test_dir(dir, name):
+  "create a test directory"
+  path = os.path.join(dir, name)
+  if not os.path.isdir(path):
+    os.makedirs(path)

+#----------------------------------------------------------------------
+
 def create_test_file(dir, name):
   "create a test file"

@@ -158,9 +167,14 @@
                'spacetest']
   for filename in filenames:
     create_test_file(files_dir, filename)
+  # create test directories
+  dirnames = ['no-props',
+             'dir-with-auto-prop']
+  for dirname in dirnames:
+    create_test_dir(files_dir, dirname)

   if len(subdir) == 0:
-    # add/import the files
+    # add/import the files/directories
     for filename in filenames:
       path = os.path.join(files_dir, filename)
       if cmd == 'import':
@@ -168,6 +182,13 @@
       else:
         tmp_params = parameters + [path]
       svntest.main.run_svn(None, *tmp_params)
+    for dirname in dirnames:
+      path = os.path.join(files_dir, dirname)
+      if cmd == 'import':
+        tmp_params = parameters + [path, repos_url + '/' + dirname]
+      else:
+        tmp_params = parameters + [path]
+      svntest.main.run_svn(None, *tmp_params)
   else:
     # add/import subdirectory
     if cmd == 'import':
@@ -194,9 +215,15 @@
     check_proplist(filename, ['auto : oui', 'lhafile : da', 'lzhfile :
niet'])
     filename = os.path.join(files_wc_dir, 'spacetest')
     check_proplist(filename, ['auto : oui', 'abc : def', 'ghi :'])
+    dirname = os.path.join(files_wc_dir, 'no-props')
+    check_proplist(dirname, [])
+    dirname = os.path.join(files_wc_dir, 'dir-with-auto-prop')
+    check_proplist(dirname, ['auto-prop : ok']);
   else:
     for filename in filenames:
       check_proplist(os.path.join(files_wc_dir, filename), [])
+    for dirname in dirnames:
+      check_proplist(os.path.join(files_wc_dir, dirname), [])

 #----------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Wed Mar 23 07:54:51 2005

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

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.