subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stef...@apache.org
Subject svn commit: r1767186 - in /subversion/trunk/subversion: include/svn_client.h libsvn_client/deprecated.c libsvn_client/list.c svn/list-cmd.c svn/svn.c tests/cmdline/list_tests.py
Date Sun, 30 Oct 2016 21:42:02 GMT
Author: stefan2
Date: Sun Oct 30 21:42:01 2016
New Revision: 1767186

URL: http://svn.apache.org/viewvc?rev=1767186&view=rev
Log:
Add support for the "--search" option to the 'list' command down to the
svn_client level.  Provide a simple test for it.

* subversion/include/svn_client.h
  (svn_client_list4): Rev API, adding the PATTERNS parameter.
  (svn_client_list3): Deprecate.

* subversion/libsvn_client/deprecated.c
  (svn_client_list3): Implement the deprecated API in terms of the new one.

* subversion/libsvn_client/list.c
  (match_patterns): New utility function handling the pattern matching.
  (get_dir_contents,
   list_internal): Add PATTERNS parameter and filter outout accordingly.
  (list_external_items,
   list_externals): Add PATTERNS parameter and pass it along.
  (svn_client_list4): Bump signature and pass parameters on.

* subversion/svn/list-cmd.c
  (svn_cl__list): Gather the --search patterns and pass them to the rev'ed
                  client API.

* subversion/svn/svn.c
  (svn_cl__cmd_table): Enabled the '--search' option for 'list'.

* subversion/tests/cmdline/list_tests.py
  (list_filtered): New test.
  (test_list): Register the new test.

Modified:
    subversion/trunk/subversion/include/svn_client.h
    subversion/trunk/subversion/libsvn_client/deprecated.c
    subversion/trunk/subversion/libsvn_client/list.c
    subversion/trunk/subversion/svn/list-cmd.c
    subversion/trunk/subversion/svn/svn.c
    subversion/trunk/subversion/tests/cmdline/list_tests.py

Modified: subversion/trunk/subversion/include/svn_client.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=1767186&r1=1767185&r2=1767186&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Sun Oct 30 21:42:01 2016
@@ -6402,13 +6402,18 @@ typedef svn_error_t *(*svn_client_list_f
  * its children.  If @a path_or_url is non-existent, return
  * #SVN_ERR_FS_NOT_FOUND.
  *
+ * If the @a pattern array of <tt>const char *</tt> is not empty, only
+ * report paths whose last segment matches one of the specified glob
+ * patterns.  This does not affect the size of the tree nor the number of
+ * externals being covered.
+ *
  * If @a fetch_locks is TRUE, include locks when reporting directory entries.
  *
  * If @a include_externals is TRUE, also list all external items
  * reached by recursion. @a depth value passed to the original list target
  * applies for the externals also.
  *
- * Use @a pool for temporary allocations.
+ * Use @a scratch_pool for temporary allocations.
  *
  * Use authentication baton cached in @a ctx to authenticate against the
  * repository.
@@ -6424,8 +6429,29 @@ typedef svn_error_t *(*svn_client_list_f
  * otherwise simply bitwise OR together the combination of @c SVN_DIRENT_
  * fields you care about.
  *
+ * @since New in 1.10.
+ */
+svn_error_t *
+svn_client_list4(const char *path_or_url,
+                 const svn_opt_revision_t *peg_revision,
+                 const svn_opt_revision_t *revision,
+                 apr_array_header_t *patterns,
+                 svn_depth_t depth,
+                 apr_uint32_t dirent_fields,
+                 svn_boolean_t fetch_locks,
+                 svn_boolean_t include_externals,
+                 svn_client_list_func2_t list_func,
+                 void *baton,
+                 svn_client_ctx_t *ctx,
+                 apr_pool_t *scratch_pool);
+
+/** Similar to svn_client_list4(), but with @a patterm left empty.
+ *
  * @since New in 1.8.
+ *
+ * @deprecated Provided for backwards compatibility with the 1.9 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_client_list3(const char *path_or_url,
                  const svn_opt_revision_t *peg_revision,

Modified: subversion/trunk/subversion/libsvn_client/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/deprecated.c?rev=1767186&r1=1767185&r2=1767186&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_client/deprecated.c Sun Oct 30 21:42:01 2016
@@ -1330,6 +1330,27 @@ svn_client_export(svn_revnum_t *result_r
 
 /*** From list.c ***/
 
+svn_error_t *
+svn_client_list3(const char *path_or_url,
+                 const svn_opt_revision_t *peg_revision,
+                 const svn_opt_revision_t *revision,
+                 svn_depth_t depth,
+                 apr_uint32_t dirent_fields,
+                 svn_boolean_t fetch_locks,
+                 svn_boolean_t include_externals,
+                 svn_client_list_func2_t list_func,
+                 void *baton,
+                 svn_client_ctx_t *ctx,
+                 apr_pool_t *pool)
+{
+  apr_array_header_t *patterns = apr_array_make(pool, 0, sizeof(const char *));
+  return svn_error_trace(svn_client_list4(path_or_url, peg_revision,
+                                          revision, patterns, depth,
+                                          dirent_fields, fetch_locks,
+                                          include_externals,
+                                          list_func, baton, ctx, pool));
+}
+
 /* Baton for use with wrap_list_func */
 struct list_func_wrapper_baton {
     void *list_func1_baton;

Modified: subversion/trunk/subversion/libsvn_client/list.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/list.c?rev=1767186&r1=1767185&r2=1767186&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/list.c (original)
+++ subversion/trunk/subversion/libsvn_client/list.c Sun Oct 30 21:42:01 2016
@@ -21,6 +21,8 @@
  * ====================================================================
  */
 
+#include <apr_fnmatch.h>
+
 #include "svn_client.h"
 #include "svn_dirent_uri.h"
 #include "svn_hash.h"
@@ -41,6 +43,7 @@
 /* Prototypes for referencing before declaration */
 static svn_error_t *
 list_externals(apr_hash_t *externals,
+               apr_array_header_t *patterns,
                svn_depth_t depth,
                apr_uint32_t dirent_fields,
                svn_boolean_t fetch_locks,
@@ -53,6 +56,7 @@ static svn_error_t *
 list_internal(const char *path_or_url,
               const svn_opt_revision_t *peg_revision,
               const svn_opt_revision_t *revision,
+              apr_array_header_t *patterns,
               svn_depth_t depth,
               apr_uint32_t dirent_fields,
               svn_boolean_t fetch_locks,
@@ -64,6 +68,25 @@ list_internal(const char *path_or_url,
               svn_client_ctx_t *ctx,
               apr_pool_t *pool);
 
+/* Return TRUE if S matches any of the const char * in PATTERNS.
+ * Note that any S will match if PATTERNS is empty. */
+static svn_boolean_t
+match_patterns(const char *s,
+               apr_array_header_t *patterns)
+{
+  int i;
+  if (patterns->nelts == 0)
+    return TRUE;
+
+  for (i = 0; i < patterns->nelts; ++i)
+    {
+      const char *pattern = APR_ARRAY_IDX(patterns, i, const char *);
+      if (apr_fnmatch(pattern, s, APR_FNM_PERIOD) == APR_SUCCESS)
+        return TRUE;
+    }
+
+  return FALSE;
+}
 
 /* Get the directory entries of DIR at REV (relative to the root of
    RA_SESSION), getting at least the fields specified by DIRENT_FIELDS.
@@ -75,6 +98,10 @@ list_internal(const char *path_or_url,
    if svn_depth_infinity, invoke it on file and directory entries and
    recurse into the directory entries with the same depth.
 
+   If PATTERNS is not empty, the last path segments must match at least
+   one of const char * patterns in it or the respective dirent will not
+   be reported.
+
    LOCKS, if non-NULL, is a hash mapping const char * paths to svn_lock_t
    objects and FS_PATH is the absolute filesystem path of the RA session.
    Use SCRATCH_POOL for temporary allocations.
@@ -94,6 +121,7 @@ get_dir_contents(apr_uint32_t dirent_fie
                  svn_ra_session_t *ra_session,
                  apr_hash_t *locks,
                  const char *fs_path,
+                 apr_array_header_t *patterns,
                  svn_depth_t depth,
                  svn_client_ctx_t *ctx,
                  apr_hash_t *externals,
@@ -175,14 +203,15 @@ get_dir_contents(apr_uint32_t dirent_fie
       if (the_ent->kind == svn_node_file
           || depth == svn_depth_immediates
           || depth == svn_depth_infinity)
-        SVN_ERR(list_func(baton, path, the_ent, lock, fs_path,
-                          external_parent_url, external_target, iterpool));
+        if (match_patterns(item->key, patterns))
+          SVN_ERR(list_func(baton, path, the_ent, lock, fs_path,
+                            external_parent_url, external_target, iterpool));
 
       /* If externals is non-NULL, populate the externals hash table
          recursively for all directory entries. */
       if (depth == svn_depth_infinity && the_ent->kind == svn_node_dir)
-        SVN_ERR(get_dir_contents(dirent_fields, path, rev,
-                                 ra_session, locks, fs_path, depth, ctx,
+        SVN_ERR(get_dir_contents(dirent_fields, path, rev, ra_session,
+                                 locks, fs_path, patterns, depth, ctx,
                                  externals, external_parent_url,
                                  external_target, list_func, baton,
                                  result_pool, iterpool));
@@ -204,6 +233,10 @@ get_dir_contents(apr_uint32_t dirent_fie
    subdirectories (at svn_depth_empty).  Else if DEPTH is
    svn_depth_empty, just list PATH_OR_URL with none of its entries.
 
+   If PATTERNS is not empty, the last path segments must match at least
+   one of const char * patterns in it or the respective dirent will not
+   be reported.
+
    DIRENT_FIELDS controls which fields in the svn_dirent_t's are
    filled in.  To have them totally filled in use SVN_DIRENT_ALL,
    otherwise simply bitwise OR together the combination of SVN_DIRENT_*
@@ -230,6 +263,7 @@ static svn_error_t *
 list_internal(const char *path_or_url,
               const svn_opt_revision_t *peg_revision,
               const svn_opt_revision_t *revision,
+              apr_array_header_t *patterns,
               svn_depth_t depth,
               apr_uint32_t dirent_fields,
               svn_boolean_t fetch_locks,
@@ -291,17 +325,18 @@ list_internal(const char *path_or_url,
     locks = NULL;
 
   /* Report the dirent for the target. */
-  SVN_ERR(list_func(baton, "", dirent, locks
-                    ? (svn_hash_gets(locks, fs_path))
-                    : NULL, fs_path, external_parent_url,
-                    external_target, pool));
+  if (match_patterns(svn_dirent_dirname(fs_path, pool), patterns))
+    SVN_ERR(list_func(baton, "", dirent, locks
+                      ? (svn_hash_gets(locks, fs_path))
+                      : NULL, fs_path, external_parent_url,
+                      external_target, pool));
 
   if (dirent->kind == svn_node_dir
       && (depth == svn_depth_files
           || depth == svn_depth_immediates
           || depth == svn_depth_infinity))
     SVN_ERR(get_dir_contents(dirent_fields, "", loc->rev, ra_session, locks,
-                             fs_path, depth, ctx, externals,
+                             fs_path, patterns, depth, ctx, externals,
                              external_parent_url, external_target, list_func,
                              baton, pool, pool));
 
@@ -312,7 +347,7 @@ list_internal(const char *path_or_url,
     {
       /* The 'externals' hash populated by get_dir_contents() is processed
          here. */
-      SVN_ERR(list_externals(externals, depth, dirent_fields,
+      SVN_ERR(list_externals(externals, patterns, depth, dirent_fields,
                              fetch_locks, list_func, baton,
                              ctx, pool));
     }
@@ -349,6 +384,7 @@ wrap_list_error(const svn_client_ctx_t *
 static svn_error_t *
 list_external_items(apr_array_header_t *external_items,
                     const char *externals_parent_url,
+                    apr_array_header_t *patterns,
                     svn_depth_t depth,
                     apr_uint32_t dirent_fields,
                     svn_boolean_t fetch_locks,
@@ -389,6 +425,7 @@ list_external_items(apr_array_header_t *
                               list_internal(resolved_url,
                                             &item->peg_revision,
                                             &item->revision,
+                                            patterns,
                                             depth, dirent_fields,
                                             fetch_locks,
                                             TRUE,
@@ -411,6 +448,7 @@ list_external_items(apr_array_header_t *
    passed to svn_client_list(). */
 static svn_error_t *
 list_externals(apr_hash_t *externals,
+               apr_array_header_t *patterns,
                svn_depth_t depth,
                apr_uint32_t dirent_fields,
                svn_boolean_t fetch_locks,
@@ -440,9 +478,10 @@ list_externals(apr_hash_t *externals,
       if (! external_items->nelts)
         continue;
 
-      SVN_ERR(list_external_items(external_items, externals_parent_url, depth,
-                                  dirent_fields, fetch_locks, list_func,
-                                  baton, ctx, iterpool));
+      SVN_ERR(list_external_items(external_items, externals_parent_url,
+                                  patterns, depth, dirent_fields,
+                                  fetch_locks, list_func, baton, ctx,
+                                  iterpool));
 
     }
   svn_pool_destroy(iterpool);
@@ -452,9 +491,10 @@ list_externals(apr_hash_t *externals,
 
 
 svn_error_t *
-svn_client_list3(const char *path_or_url,
+svn_client_list4(const char *path_or_url,
                  const svn_opt_revision_t *peg_revision,
                  const svn_opt_revision_t *revision,
+                 apr_array_header_t *patterns,
                  svn_depth_t depth,
                  apr_uint32_t dirent_fields,
                  svn_boolean_t fetch_locks,
@@ -462,14 +502,14 @@ svn_client_list3(const char *path_or_url
                  svn_client_list_func2_t list_func,
                  void *baton,
                  svn_client_ctx_t *ctx,
-                 apr_pool_t *pool)
+                 apr_pool_t *scratch_pool)
 {
 
   return svn_error_trace(list_internal(path_or_url, peg_revision,
-                                       revision,
+                                       revision, patterns,
                                        depth, dirent_fields,
                                        fetch_locks,
                                        include_externals,
                                        NULL, NULL, list_func,
-                                       baton, ctx, pool));
+                                       baton, ctx, scratch_pool));
 }

Modified: subversion/trunk/subversion/svn/list-cmd.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/list-cmd.c?rev=1767186&r1=1767185&r2=1767186&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/list-cmd.c (original)
+++ subversion/trunk/subversion/svn/list-cmd.c Sun Oct 30 21:42:01 2016
@@ -351,6 +351,8 @@ svn_cl__list(apr_getopt_t *os,
       const char *target = APR_ARRAY_IDX(targets, i, const char *);
       const char *truepath;
       svn_opt_revision_t peg_revision;
+      apr_array_header_t *patterns;
+      int k;
 
       /* Initialize the following variables for
          every list target. */
@@ -360,6 +362,7 @@ svn_cl__list(apr_getopt_t *os,
 
       svn_pool_clear(subpool);
 
+      patterns = apr_array_make(subpool, 4, sizeof(const char *));
       SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton));
 
       /* Get peg revisions. */
@@ -375,8 +378,24 @@ svn_cl__list(apr_getopt_t *os,
           SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
         }
 
-      err = svn_client_list3(truepath, &peg_revision,
-                             &(opt_state->start_revision),
+      if (opt_state->search_patterns)
+        for (k = 0; k < opt_state->search_patterns->nelts; ++k)
+          {
+            apr_array_header_t *pattern_group
+              = APR_ARRAY_IDX(opt_state->search_patterns, k,
+                              apr_array_header_t *);
+
+            /* Should never fail but ... */
+            if (pattern_group->nelts != 1)
+              return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
+                                 _("'search-and' option is not supported"));
+
+            APR_ARRAY_PUSH(patterns, const char *)
+              = APR_ARRAY_IDX(pattern_group, 0, const char *);
+          }
+
+      err = svn_client_list4(truepath, &peg_revision,
+                             &(opt_state->start_revision), patterns,
                              opt_state->depth,
                              dirent_fields,
                              (opt_state->xml || opt_state->verbose),

Modified: subversion/trunk/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1767186&r1=1767185&r2=1767186&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/svn.c (original)
+++ subversion/trunk/subversion/svn/svn.c Sun Oct 30 21:42:01 2016
@@ -798,7 +798,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
      "    Size (in bytes)\n"
      "    Date and time of the last commit\n"),
     {'r', 'v', 'R', opt_depth, opt_incremental, opt_xml,
-     opt_include_externals}, },
+     opt_include_externals, opt_search}, },
 
   { "lock", svn_cl__lock, {0}, N_
     ("Lock working copy paths or URLs in the repository, so that\n"

Modified: subversion/trunk/subversion/tests/cmdline/list_tests.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/list_tests.py?rev=1767186&r1=1767185&r2=1767186&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/list_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/list_tests.py Sun Oct 30 21:42:01 2016
@@ -94,6 +94,20 @@ def list_verbose(sbox):
     expected, [], 'list', path, '--depth=infinity', "-v")
 
 
+def list_filtered(sbox):
+  "filtered list"
+
+  sbox.build(read_only=True)
+  path = sbox.repo_url + "/A/D"
+
+  # check plain info
+  expected = [ "H/omega\n",
+               "gamma\n" ]
+
+  exit_code, output, error = svntest.actions.run_and_verify_svn(
+    None, [], 'list', path, '--depth=infinity', '--search=*a')
+
+
 ########################################################################
 # Run the tests
 
@@ -101,6 +115,7 @@ def list_verbose(sbox):
 test_list = [ None,
               list_plain,
               list_verbose,
+              list_filtered,
              ]
 
 if __name__ == '__main__':



Mime
View raw message