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

Re: [PATCH] svn command - ls - Multiple targets

From: Noorul Islam K M <noorul_at_collab.net>
Date: Thu, 10 Feb 2011 16:50:39 +0530

Noorul Islam K M <noorul_at_collab.net> writes:

> Noorul Islam K M <noorul_at_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;
 }
Received on 2011-02-10 12:21:27 CET

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