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

Re: svn info not setting exit status.

From: Karl Fogel <kfogel_at_red-bean.com>
Date: Tue, 20 May 2008 12:55:46 -0400

[I'm cross-posting this to dev@, because the behavior might be a bug.]

"Mark E. Hamilton" <mhamilt_at_sandia.gov> writes:
> I'm trying to check to see if a path exists in my repository or
> not. However, when I use 'svn info' on an invalid URL it does not set
> the exit status to a non-zero value as I expected. It also prints what
> seems to be an extra blank line to stderr, as shown below.
>
> $ svn info file:///svnroot/test_repos/boogers >/dev/null ; echo $?
> file:///svnroot/test_repos/boogers: (Not a valid URL)
>
> 0
> $
>
> When I use 'svn checkout' on the same URL is reports that it doesn't
> exist and sets the exit status to '1'.
>
> $ svn checkout file:///svnroot/test_repos/boogers >/dev/null ; echo $?
> svn: URL 'file:///svnroot/test_repos/boogers' doesn't exist
> 1
> $
>
> I'm using 1.5.0rc4.
>
> Am I incorrect in expecting 'svn info' to set the exit status if the
> URL doesn't exist? If so, what is the correct way to (silently) check
> to see if something exists in the repository? I don't want to have to
> parse stderr (or stdout, for that matter, which is why I'm redirecting
> it to /dev/null.) All I want is a simple True/False (0/1 in the shell)
> response as to whether the URL exists.

Your question is complex. First, note that the user might run 'svn
info' on multiple targets in one command, like:

   $ svn info URL1 URL2 ... -or-
   $ svn info PATH1 PATH2 ... -or even-
   $ svn info URL1 PATH1 URL2 PATH2 ...

(The multi-target behavior was implemented in r13123, with trivial
bugfix followups in r13124 and r14688; URLs were added in r13144.)

In order to make the multi-target behavior work, we decided that a
non-existent target shouldn't cause svn to bail out, but should instead
print a warning and then continue to the next target. See this code
from subversion/svn/info-cmd.c:svn_cl__info():

   for (i = 0; i < targets->nelts; i++)
     {
 
       [...]
 
       err = svn_client_info2(truepath,
                              &peg_revision, &(opt_state->start_revision),
                              receiver, NULL, opt_state->depth,
                              opt_state->changelists, ctx, subpool);
 
       /* 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 && err->apr_err == SVN_ERR_UNVERSIONED_RESOURCE)
         {
           svn_error_clear(err);
           SVN_ERR(svn_cmdline_fprintf
                   (stderr, subpool,
                    _("%s: (Not a versioned resource)\n\n"),
                    svn_path_local_style(target, pool)));
           continue;
         }
       else if (err && err->apr_err == SVN_ERR_RA_ILLEGAL_URL)
         {
           svn_error_clear(err);
           SVN_ERR(svn_cmdline_fprintf
                   (stderr, subpool,
                    _("%s: (Not a valid URL)\n\n"),
                    svn_path_local_style(target, pool)));
           continue;
         }
       else if (err)
         return err;
 
     }
   svn_pool_destroy(subpool);
 
   if (opt_state->xml && (! opt_state->incremental))
     SVN_ERR(svn_cl__xml_print_footer("info", pool));
 
   return SVN_NO_ERROR;

That's the end of the function at the bottom there -- we just return
SVN_NO_ERROR unconditionally.

In passing, let me note a stylistic problem here so I won't forgt: if
we're going to svn_error_clear(err), then we ought to set err = NULL as
well, even though due to the current code flow it's not strictly
necessary. Yes, err will get reassigned from svn_client_info2() on the
next iteration of the loop, but that won't happen on the last iteration,
which that means that if the last target is non-existent, we'll have a
dangling error that we simply happen not to check. That's likely to be
a bug source someday: someone may add a check for 'err' for some other
reason, not realizing the subtleties of the loop's logic.

Okay, on to the real question:

We definitely should continue the loop even in case of error, so we try
every target. But when we do exit, should it be a non-zero exit code if
any target received an error? Currently, we exit with zero.

There may be precedents for this sort of situation, and if there are,
Subversion should follow them. But I don't know what they are. Does
anyone else?

-Karl

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe_at_subversion.tigris.org
For additional commands, e-mail: dev-help_at_subversion.tigris.org
Received on 2008-05-20 18:56:05 CEST

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