Noorul Islam K M <noo...@collab.net> writes:

> Noorul Islam K M <noo...@collab.net> writes:
>
>> This patch is a followup of the following thread. All tests pass with
>> this patch.
>>
>> http://svn.haxx.se/dev/archive-2011-01/0210.shtml
>>
>> Log
>> [[[
>>
>> Make 'svn ls' continue processing targets after printing warning if one
>> or more of the targets is a non-existent URL or wc-entry. Also return a
>> non-zero error code and print an error message at the end in those
>> situations.
>>
>> * subversion/svn/list-cmd.c
>>   (svn_cl__list): If one of the targets is a non-existent URL or
>>     wc-entry, don't bail out.  Just warn and move on to the next
>>     target. Also return a non-zero error code and print an error message
>>     at the end in those situations.
>>
>> * subversion/tests/cmdline/basic_tests.py
>>   (ls_non_existent_wc_target, ls_non_existent_url_target, 
>>    ls_multiple_wc_targets, ls_multiple_url_targets): New tests.
>>   (test_list): Add reference to new tests.
>>
>> Patch by: Noorul Islam K M <noorul{_AT_}collab.net>
>> ]]]
>>
>> Index: subversion/tests/cmdline/basic_tests.py
>> ===================================================================
>> --- subversion/tests/cmdline/basic_tests.py  (revision 1069209)
>> +++ subversion/tests/cmdline/basic_tests.py  (working copy)
>> @@ -2690,6 +2690,84 @@
>>                                         [], 'ls',
>>                                         url)
>>  
>> +def ls_non_existent_wc_target(sbox):
>> +  "ls a non-existent wc target"
>> +
>> +  sbox.build()
>> +  wc_dir = sbox.wc_dir
>> +
>> +  non_existent_path = os.path.join(wc_dir, 'non-existent')
>> +  expected_err = "svn: warning: W155010: The node '" + \
>> +      os.path.abspath(non_existent_path) + "' was not found"
>> +
>> +  svntest.actions.run_and_verify_svn2(None, None, expected_err,
>> +                                      1, 'ls', non_existent_path)
>> +
>> +def ls_non_existent_url_target(sbox):
>> +  "ls a non-existent url target"
>> +
>> +  sbox.build()
>> +
>> +  non_existent_url = sbox.repo_url + '/non-existent'
>> +  expected_err = "svn: warning: W160013: .*"
>> +
>> +  svntest.actions.run_and_verify_svn2(None, None, expected_err,
>> +                                      1, 'ls', non_existent_url)
>> +
>> +def ls_multiple_wc_targets(sbox):
>> +  "ls multiple wc targets"
>> +
>> +  sbox.build()
>> +  wc_dir = sbox.wc_dir
>> +
>> +  alpha = os.path.join(wc_dir, 'A/B/E/alpha')
>> +  beta = os.path.join(wc_dir, 'A/B/E/beta')
>> +  non_existent_path = os.path.join(wc_dir, 'non-existent')
>> +
>> +  # All targets are existing
>> +  svntest.actions.run_and_verify_svn2(None, None, [],
>> +                                      0, 'ls', alpha, beta)
>> +
>> +  # One non-existing target
>> +  expected_err = "svn: warning: W155010: The node '" + \
>> +      os.path.abspath(non_existent_path) + "' was not found.\n" + \
>> +      ".*\nsvn: E200000: A problem occurred; see other errors for details\n"
>> +  expected_err_re = re.compile(expected_err)
>> +
>> +  exit_code, output, error = svntest.main.run_svn(1, 'ls', alpha, 
>> +                                                  non_existent_path, beta)
>> +
>> +  # Verify error
>> +  if not expected_err_re.match("".join(error)):
>> +    raise svntest.Failure('Cat failed: expected error "%s", but received '
>> +                          '"%s"' % (expected_err, "".join(error)))
>> +
>> +def ls_multiple_url_targets(sbox):
>> +  "ls multiple url targets"
>> +
>> +  sbox.build()
>> +
>> +  alpha = sbox.repo_url +  '/A/B/E/alpha'
>> +  beta = sbox.repo_url +  '/A/B/E/beta'
>> +  non_existent_url = sbox.repo_url +  '/non-existent'
>> +
>> +  # All targets are existing
>> +  svntest.actions.run_and_verify_svn2(None, None, [],
>> +                                      0, 'ls', alpha, beta)
>> +
>> +  # One non-existing target
>> +  expected_err = "svn: warning: W160013: .*\n" + \
>> +      ".*\nsvn: E200000: A problem occurred; see other errors for details\n"
>> +  expected_err_re = re.compile(expected_err)
>> +
>> +  exit_code, output, error = svntest.main.run_svn(1, 'ls', alpha, 
>> +                                                  non_existent_url, beta)
>> +
>> +  # Verify error
>> +  if not expected_err_re.match("".join(error)):
>> +    raise svntest.Failure('Cat failed: expected error "%s", but received 
>> "%s"' % \
>> +                          (expected_err, "".join(error)))
>> +
>>  ########################################################################
>>  # Run the tests
>>  
>> @@ -2751,6 +2829,10 @@
>>                basic_relocate,
>>                delete_urls_with_spaces,
>>                ls_url_special_characters,
>> +              ls_non_existent_wc_target,
>> +              ls_non_existent_url_target,
>> +              ls_multiple_wc_targets,
>> +              ls_multiple_url_targets,
>>               ]
>>  
>>  if __name__ == '__main__':
>> Index: subversion/svn/list-cmd.c
>> ===================================================================
>> --- subversion/svn/list-cmd.c        (revision 1069209)
>> +++ subversion/svn/list-cmd.c        (working copy)
>> @@ -215,6 +215,8 @@
>>    apr_pool_t *subpool = svn_pool_create(pool);
>>    apr_uint32_t dirent_fields;
>>    struct print_baton pb;
>> +  svn_boolean_t saw_a_problem = FALSE;
>> +  svn_error_t *err;
>>  
>>    SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
>>                                                        opt_state->targets,
>> @@ -280,14 +282,29 @@
>>            SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
>>          }
>>  
>> -      SVN_ERR(svn_client_list2(truepath, &peg_revision,
>> -                               &(opt_state->start_revision),
>> -                               opt_state->depth,
>> -                               dirent_fields,
>> -                               (opt_state->xml || opt_state->verbose),
>> -                               opt_state->xml ? print_dirent_xml : 
>> print_dirent,
>> -                               &pb, ctx, subpool));
>> +      err = svn_client_list2(truepath, &peg_revision,
>> +                             &(opt_state->start_revision),
>> +                             opt_state->depth,
>> +                             dirent_fields,
>> +                             (opt_state->xml || opt_state->verbose),
>> +                             opt_state->xml ? print_dirent_xml : 
>> print_dirent,
>> +                             &pb, ctx, subpool);
>>  
>> +      if (err)
>> +        {
>> +          /* If one of the targets is a non-existent URL or wc-entry,
>> +             don't bail out.  Just warn and move on to the next target. */
>> +          if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND ||
>> +              err->apr_err == SVN_ERR_FS_NOT_FOUND)
>> +              svn_handle_warning2(stderr, err, "svn: ");
>> +          else
>> +              return svn_error_return(err);
>> +
>> +          svn_error_clear(err);
>> +          err = NULL;
>> +          saw_a_problem = TRUE;
>> +        }
>> +
>>        if (opt_state->xml)
>>          {
>>            svn_stringbuf_t *sb = svn_stringbuf_create("", pool);
>> @@ -301,5 +318,8 @@
>>    if (opt_state->xml && ! opt_state->incremental)
>>      SVN_ERR(svn_cl__xml_print_footer("lists", pool));
>>  
>> -  return SVN_NO_ERROR;
>> +  if (saw_a_problem)
>> +    return svn_error_create(SVN_ERR_BASE, NULL, NULL);
>> +  else
>> +    return SVN_NO_ERROR;
>>  }
>
> A slightly modified patch is attached. This one escapes windows path
> separator '\' in regex so that test would pass on windows build.
>
> Thanks and Regards
> Noorul
>
> Index: subversion/tests/cmdline/basic_tests.py
> ===================================================================
> --- subversion/tests/cmdline/basic_tests.py   (revision 1069209)
> +++ subversion/tests/cmdline/basic_tests.py   (working copy)
> @@ -25,7 +25,7 @@
>  ######################################################################
>  
>  # General modules
> -import shutil, stat, re, os
> +import shutil, stat, re, os, sys
>  
>  # Our testing module
>  import svntest
> @@ -2690,6 +2690,91 @@
>                                         [], 'ls',
>                                         url)
>  
> +def ls_non_existent_wc_target(sbox):
> +  "ls a non-existent wc target"
> +
> +  sbox.build()
> +  wc_dir = sbox.wc_dir
> +
> +  non_existent_path = os.path.join(wc_dir, 'non-existent')
> +
> +  if sys.platform == 'win32':
> +    non_existent_path = non_existent_path.replace("\\", "\\\\")
> +
> +  expected_err = "svn: warning: W155010: The node '" + \
> +      os.path.abspath(non_existent_path) + "' was not found"
> +
> +  svntest.actions.run_and_verify_svn2(None, None, expected_err,
> +                                      1, 'ls', non_existent_path)
> +
> +def ls_non_existent_url_target(sbox):
> +  "ls a non-existent url target"
> +
> +  sbox.build()
> +
> +  non_existent_url = sbox.repo_url + '/non-existent'
> +  expected_err = "svn: warning: W160013: .*"
> +
> +  svntest.actions.run_and_verify_svn2(None, None, expected_err,
> +                                      1, 'ls', non_existent_url)
> +
> +def ls_multiple_wc_targets(sbox):
> +  "ls multiple wc targets"
> +
> +  sbox.build()
> +  wc_dir = sbox.wc_dir
> +
> +  alpha = os.path.join(wc_dir, 'A/B/E/alpha')
> +  beta = os.path.join(wc_dir, 'A/B/E/beta')
> +  non_existent_path = os.path.join(wc_dir, 'non-existent')
> +
> +  if sys.platform == 'win32':
> +    non_existent_path = non_existent_path.replace("\\", "\\\\")
> +
> +  # All targets are existing
> +  svntest.actions.run_and_verify_svn2(None, None, [],
> +                                      0, 'ls', alpha, beta)
> +
> +  # One non-existing target
> +  expected_err = "svn: warning: W155010: The node '" + \
> +      os.path.abspath(non_existent_path) + "' was not found.\n" + \
> +      ".*\nsvn: E200000: A problem occurred; see other errors for details\n"
> +  expected_err_re = re.compile(expected_err)
> +
> +  exit_code, output, error = svntest.main.run_svn(1, 'ls', alpha, 
> +                                                  non_existent_path, beta)
> +
> +  # Verify error
> +  if not expected_err_re.match("".join(error)):
> +    raise svntest.Failure('Cat failed: expected error "%s", but received '
> +                          '"%s"' % (expected_err, "".join(error)))
> +
> +def ls_multiple_url_targets(sbox):
> +  "ls multiple url targets"
> +
> +  sbox.build()
> +
> +  alpha = sbox.repo_url +  '/A/B/E/alpha'
> +  beta = sbox.repo_url +  '/A/B/E/beta'
> +  non_existent_url = sbox.repo_url +  '/non-existent'
> +
> +  # All targets are existing
> +  svntest.actions.run_and_verify_svn2(None, None, [],
> +                                      0, 'ls', alpha, beta)
> +
> +  # One non-existing target
> +  expected_err = "svn: warning: W160013: .*\n" + \
> +      ".*\nsvn: E200000: A problem occurred; see other errors for details\n"
> +  expected_err_re = re.compile(expected_err)
> +
> +  exit_code, output, error = svntest.main.run_svn(1, 'ls', alpha, 
> +                                                  non_existent_url, beta)
> +
> +  # Verify error
> +  if not expected_err_re.match("".join(error)):
> +    raise svntest.Failure('Cat failed: expected error "%s", but received 
> "%s"' % \
> +                          (expected_err, "".join(error)))
> +
>  ########################################################################
>  # Run the tests
>  
> @@ -2751,6 +2836,10 @@
>                basic_relocate,
>                delete_urls_with_spaces,
>                ls_url_special_characters,
> +              ls_non_existent_wc_target,
> +              ls_non_existent_url_target,
> +              ls_multiple_wc_targets,
> +              ls_multiple_url_targets,
>               ]
>  
>  if __name__ == '__main__':
> Index: subversion/svn/list-cmd.c
> ===================================================================
> --- subversion/svn/list-cmd.c (revision 1069209)
> +++ subversion/svn/list-cmd.c (working copy)
> @@ -215,6 +215,8 @@
>    apr_pool_t *subpool = svn_pool_create(pool);
>    apr_uint32_t dirent_fields;
>    struct print_baton pb;
> +  svn_boolean_t saw_a_problem = FALSE;
> +  svn_error_t *err;
>  
>    SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
>                                                        opt_state->targets,
> @@ -280,14 +282,29 @@
>            SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
>          }
>  
> -      SVN_ERR(svn_client_list2(truepath, &peg_revision,
> -                               &(opt_state->start_revision),
> -                               opt_state->depth,
> -                               dirent_fields,
> -                               (opt_state->xml || opt_state->verbose),
> -                               opt_state->xml ? print_dirent_xml : 
> print_dirent,
> -                               &pb, ctx, subpool));
> +      err = svn_client_list2(truepath, &peg_revision,
> +                             &(opt_state->start_revision),
> +                             opt_state->depth,
> +                             dirent_fields,
> +                             (opt_state->xml || opt_state->verbose),
> +                             opt_state->xml ? print_dirent_xml : 
> print_dirent,
> +                             &pb, ctx, subpool);
>  
> +      if (err)
> +        {
> +          /* If one of the targets is a non-existent URL or wc-entry,
> +             don't bail out.  Just warn and move on to the next target. */
> +          if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND ||
> +              err->apr_err == SVN_ERR_FS_NOT_FOUND)
> +              svn_handle_warning2(stderr, err, "svn: ");
> +          else
> +              return svn_error_return(err);
> +
> +          svn_error_clear(err);
> +          err = NULL;
> +          saw_a_problem = TRUE;
> +        }
> +
>        if (opt_state->xml)
>          {
>            svn_stringbuf_t *sb = svn_stringbuf_create("", pool);
> @@ -301,5 +318,8 @@
>    if (opt_state->xml && ! opt_state->incremental)
>      SVN_ERR(svn_cl__xml_print_footer("lists", pool));
>  
> -  return SVN_NO_ERROR;
> +  if (saw_a_problem)
> +    return svn_error_create(SVN_ERR_BASE, NULL, NULL);
> +  else
> +    return SVN_NO_ERROR;
>  }

I got this hint from one of the recent commits. So even better way of
escaping '\'. Attached is the modified patch.

Thanks and Regards
Noorul

Index: subversion/tests/cmdline/basic_tests.py
===================================================================
--- subversion/tests/cmdline/basic_tests.py     (revision 1069209)
+++ subversion/tests/cmdline/basic_tests.py     (working copy)
@@ -2690,6 +2690,85 @@
                                        [], 'ls',
                                        url)
 
+def ls_non_existent_wc_target(sbox):
+  "ls a non-existent wc target"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  non_existent_path = os.path.join(wc_dir, 'non-existent')
+
+  expected_err = "svn: warning: W155010: The node '" + \
+      re.escape(os.path.abspath(non_existent_path)) + "' was not found"
+
+  svntest.actions.run_and_verify_svn2(None, None, expected_err,
+                                      1, 'ls', non_existent_path)
+
+def ls_non_existent_url_target(sbox):
+  "ls a non-existent url target"
+
+  sbox.build()
+
+  non_existent_url = sbox.repo_url + '/non-existent'
+  expected_err = "svn: warning: W160013: .*"
+
+  svntest.actions.run_and_verify_svn2(None, None, expected_err,
+                                      1, 'ls', non_existent_url)
+
+def ls_multiple_wc_targets(sbox):
+  "ls multiple wc targets"
+
+  sbox.build()
+  wc_dir = sbox.wc_dir
+
+  alpha = os.path.join(wc_dir, 'A/B/E/alpha')
+  beta = os.path.join(wc_dir, 'A/B/E/beta')
+  non_existent_path = os.path.join(wc_dir, 'non-existent')
+
+  # All targets are existing
+  svntest.actions.run_and_verify_svn2(None, None, [],
+                                      0, 'ls', alpha, beta)
+
+  # One non-existing target
+  expected_err = "svn: warning: W155010: The node '" + \
+      re.escape(os.path.abspath(non_existent_path)) + "' was not found.\n" + \
+      ".*\nsvn: E200000: A problem occurred; see other errors for details\n"
+  expected_err_re = re.compile(expected_err)
+
+  exit_code, output, error = svntest.main.run_svn(1, 'ls', alpha, 
+                                                  non_existent_path, beta)
+
+  # Verify error
+  if not expected_err_re.match("".join(error)):
+    raise svntest.Failure('Cat failed: expected error "%s", but received '
+                          '"%s"' % (expected_err, "".join(error)))
+
+def ls_multiple_url_targets(sbox):
+  "ls multiple url targets"
+
+  sbox.build()
+
+  alpha = sbox.repo_url +  '/A/B/E/alpha'
+  beta = sbox.repo_url +  '/A/B/E/beta'
+  non_existent_url = sbox.repo_url +  '/non-existent'
+
+  # All targets are existing
+  svntest.actions.run_and_verify_svn2(None, None, [],
+                                      0, 'ls', alpha, beta)
+
+  # One non-existing target
+  expected_err = "svn: warning: W160013: .*\n" + \
+      ".*\nsvn: E200000: A problem occurred; see other errors for details\n"
+  expected_err_re = re.compile(expected_err)
+
+  exit_code, output, error = svntest.main.run_svn(1, 'ls', alpha, 
+                                                  non_existent_url, beta)
+
+  # Verify error
+  if not expected_err_re.match("".join(error)):
+    raise svntest.Failure('Cat failed: expected error "%s", but received "%s"' 
% \
+                          (expected_err, "".join(error)))
+
 ########################################################################
 # Run the tests
 
@@ -2751,6 +2830,10 @@
               basic_relocate,
               delete_urls_with_spaces,
               ls_url_special_characters,
+              ls_non_existent_wc_target,
+              ls_non_existent_url_target,
+              ls_multiple_wc_targets,
+              ls_multiple_url_targets,
              ]
 
 if __name__ == '__main__':
Index: subversion/svn/list-cmd.c
===================================================================
--- subversion/svn/list-cmd.c   (revision 1069209)
+++ subversion/svn/list-cmd.c   (working copy)
@@ -215,6 +215,8 @@
   apr_pool_t *subpool = svn_pool_create(pool);
   apr_uint32_t dirent_fields;
   struct print_baton pb;
+  svn_boolean_t saw_a_problem = FALSE;
+  svn_error_t *err;
 
   SVN_ERR(svn_cl__args_to_target_array_print_reserved(&targets, os,
                                                       opt_state->targets,
@@ -280,14 +282,29 @@
           SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout));
         }
 
-      SVN_ERR(svn_client_list2(truepath, &peg_revision,
-                               &(opt_state->start_revision),
-                               opt_state->depth,
-                               dirent_fields,
-                               (opt_state->xml || opt_state->verbose),
-                               opt_state->xml ? print_dirent_xml : 
print_dirent,
-                               &pb, ctx, subpool));
+      err = svn_client_list2(truepath, &peg_revision,
+                             &(opt_state->start_revision),
+                             opt_state->depth,
+                             dirent_fields,
+                             (opt_state->xml || opt_state->verbose),
+                             opt_state->xml ? print_dirent_xml : print_dirent,
+                             &pb, ctx, subpool);
 
+      if (err)
+        {
+          /* If one of the targets is a non-existent URL or wc-entry,
+             don't bail out.  Just warn and move on to the next target. */
+          if (err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND ||
+              err->apr_err == SVN_ERR_FS_NOT_FOUND)
+              svn_handle_warning2(stderr, err, "svn: ");
+          else
+              return svn_error_return(err);
+
+          svn_error_clear(err);
+          err = NULL;
+          saw_a_problem = TRUE;
+        }
+
       if (opt_state->xml)
         {
           svn_stringbuf_t *sb = svn_stringbuf_create("", pool);
@@ -301,5 +318,8 @@
   if (opt_state->xml && ! opt_state->incremental)
     SVN_ERR(svn_cl__xml_print_footer("lists", pool));
 
-  return SVN_NO_ERROR;
+  if (saw_a_problem)
+    return svn_error_create(SVN_ERR_BASE, NULL, NULL);
+  else
+    return SVN_NO_ERROR;
 }

Reply via email to