/*
 * util.c:  Repository access utility routines.
 *
 * ====================================================================
 * Copyright (c) 2007 CollabNet.  All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.  The terms
 * are also available at http://subversion.tigris.org/license-1.html.
 * If newer versions of this license are posted there, you may use a
 * newer version instead, at your option.
 *
 * This software consists of voluntary contributions made by many
 * individuals.  For exact contribution history, see the revision
 * history and logs, available at http://subversion.tigris.org/.
 * ====================================================================
 */

/* ==================================================================== */

/*** Includes. ***/
#include <apr_pools.h>

#include "svn_types.h"
#include "svn_error.h"
#include "svn_error_codes.h"
#include "svn_ra.h"

#include "svn_private_config.h"


/* Return an error with code SVN_ERR_UNSUPPORTED_FEATURE, and an error
   message referencing PATH_OR_URL, if the "server" pointed to be
   RA_SESSION doesn't support Merge Tracking (e.g. is pre-1.5).
   Perform temporary allocations in POOL. */
svn_error_t *
svn_ra__assert_mergeinfo_capable_server(svn_ra_session_t *ra_session,
                                        const char *path_or_url,
                                        apr_pool_t *pool)
{
  svn_boolean_t mergeinfo_capable;
  SVN_ERR(svn_ra_has_capability(ra_session, &mergeinfo_capable,
                                SVN_RA_CAPABILITY_MERGEINFO, pool));
  if (! mergeinfo_capable)
    {
      if (path_or_url == NULL)
        {
          svn_error_t *err = svn_ra_get_session_url(ra_session, &path_or_url,
                                                    pool);
          if (err)
            {
              /* The SVN_ERR_UNSUPPORTED_FEATURE error is more important,
                 so dummy up the session's URL and chuck this error. */
              svn_error_clear(err);
              path_or_url = "<repository>";
            }
        }
      return svn_error_createf(SVN_ERR_UNSUPPORTED_FEATURE, NULL,
                               _("Retrieval of mergeinfo unsupported by '%s'"),
                               svn_path_local_style(path_or_url, pool));
    }
  return SVN_NO_ERROR;
}

Make 'svn mergeinfo' and its underlying APIs error out when talking to a pre-1.5 repository.
Make 'svn mergeinfo' and its underlying APIs error out when talking to
a pre-1.5 repository.

This change includes tests capable of being run against either a 1.4
or 1.5 server (and was run against both).

[ Note: All but subversion/libsvn_ra/util.c was committed in r28172. ]


* TODO-1.5-branch
  Remove TODO item completed by this commit.

* subversion/include/svn_client.h
  (svn_client_mergeinfo_get_merged, svn_client_mergeinfo_get_available):
   Document that an error with the code SVN_ERR_UNSUPPORTED_FEATURE is
   returned when the server doesn't support Merge Tracking.

* subversion/include/svn_ra.h
  (svn_ra_get_mergeinfo): Ditto, with note about inapplicability to
   ra_local.

* subversion/include/private/svn_ra_private.h
  Add new Subversion-private header file, which currently declares
  only the svn_ra__assert_mergeinfo_capable_server() API.

* subversion/libsvn_client/mergeinfo.h
  (svn_client__get_repos_mergeinfo): Add SQUELCH_INCAPABLE parameter, used
   to ignore a SVN_ERR_UNSUPPORTED_FEATURE returned by a server that
   doesn't support Merge Tracking.

* subversion/libsvn_client/mergeinfo.c
  Include private/svn_ra_private.h.
  (svn_client__get_repos_mergeinfo): Add SQUELCH_INCAPABLE parameter, used
   to ignore a SVN_ERR_UNSUPPORTED_FEATURE returned by a server that
   doesn't support Merge Tracking.
  (svn_client__get_wc_or_repos_mergeinfo): Adjust for
   svn_client__get_repos_mergeinfo() API change.
  (get_mergeinfo): Return an error if the server doesn't support Merge
   Tracking.  Improve APR pool usage.
  (svn_client_mergeinfo_get_available): Call get_mergeinfo() first to
   leverage its new server Merge Tracking capabilities check.

* subversion/libsvn_client/copy.c
  (calculate_target_mergeinfo): Adjust for svn_client__get_repos_mergeinfo()
   API change

* subversion/libsvn_client/merge.c
  (filter_reflected_revisions): Ditto.

* subversion/libsvn_ra/ra_loader.c
  Include private/svn_ra_private.h.
  (svn_ra_get_mergeinfo): Return an error if the server doesn't
   support Merge Tracking.

* subversion/libsvn_ra/util.c
  Add new Subversion-private header file, which currently defines
  only the svn_ra__assert_mergeinfo_capable_server() API.

* subversion/libsvn_ra_svn/client.c
  (ra_svn_get_mergeinfo): Remove SVN_RA_SVN_CAP_MERGEINFO capabilities
   check, which is now handled by ra_loader.c.

* subversion/libsvn_ra_neon/mergeinfo.c
  (svn_ra_neon__get_mergeinfo)))): Don't squelch a 501 HTTP status
   code (which is otherwise subsequently converted into an
   svn_error_t) encountered while making a mergeinfo REPORT request.

* subversion/libsvn_ra_serf/mergeinfo.c
  (svn_ra_serf__get_mergeinfo): Don't squelch an SVN_ERR_UNSUPPORTED_FEATURE
   error encountered while making a mergeinfo REPORT request.

* subversion/tests/cmdline/mergeinfo_tests.py
  Import the server_has_mergeinfo() function.
  (adjust_error_for_server_version): Add a new function that returns
   the expected error regexp appropriate for the server version used by
   the test suite.
  (no_mergeinfo): Leverage adjust_error_for_server_version(), and
   adjust for run_and_verify_mergeinfo() API changes.
  (mergeinfo): Provide a very basic implementation of the test.

* subversion/tests/cmdline/svntest/actions.py
  (run_and_verify_mergeinfo): Replace EXPECTED_PATHS, EXPECTED_SOURCE_PATHS,
   and EXPECTED_ELIGIBLE_REVS parameters with EXPECTED_OUTPUT, which is a
   dict of the format:
     { path : { source path : (merged ranges, eligible ranges) } }
   Correct/add parser expectations, adjust for parser API changes, and
   re-implement function accordingly.  Be sure to bail out early if a
   1.4 server is detected.

* subversion/tests/cmdline/svntest/parsers.py
  (MergeinfoReportParser): Add a comment showing some sample output.
  (MergeinfoReportParser.STATE_MERGED_RANGES,
   MergeinfoReportParser.STATE_ELIGIBLE_RANGES): Add new constants,
   the latter a replacement for STATE_ELIGIBLE_REVS.
  (MergeinfoReportParser.STATE_TRANSITIONS): Correct/add possible
   state transitions.
  (MergeinfoReportParser.STATE_TOKENS): Correct/add tokens present in
   the output.
  (MergeinfoReportParser.__init__): Replace "paths", "source_paths",
   and "eligible_revs" instance members with "report" dict.  Add
   "cur_target_path" and "cur_source_path" members to maintain some
   necessary parser state.  Replace "state_to_storage" dict with
   "parser_callbacks" dict of callback functions.
  (parsed_target_path, parsed_source_path, parsed_merged_ranges,
   parsed_eligible_ranges): Add parser callback functions invoked from
   the "parser_callbacks" dict.
  (parse): Replace use of "state_to_storage" with "parser_callbacks".


git-svn-id: f8a4e5e023278da1e04e203c7fe051e3c4285d88@868248 13f79535-47bb-0310-9956-ffa450edef68
