#!/usr/bin/env python
#
# svnmerge-migrate-history-remotely.py: Remotely migrate merge history from
#     svnmerge.py's format to Subversion 1.5's format.
#
# ====================================================================
# Copyright (c) 2008 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/.
# ====================================================================

# $HeadURL$
# $Date$
# $Author$
# $Rev$


### THE SVNMERGE HISTORY MIGRATION ALGORITHM EMPLOYED HEREIN
###
### 1. Fetch properties for PATH, looking specifically for
###    'svnmerge-blocked', and 'svnmerge-integrated'.
###
### 2. Convert properties into real mergeinfo.  NOTE: svnmerge-*
###    properties have a slightly different and more flexible syntax.
###
### 3. Combine mergeinfos together.
###
### 4. [non-naive] Subtract natural history of the merge target from
###    its own mergeinfo.
###
### 5. [non-naive] Filter mergeinfo by merge source natural history
###    (so that mergeinfo only reflects real locations).
###
### 6. Convert mergeinfo back into a property value.  If it reflects
###    a change over the previously existing mergeinfo, or there were
###    some svnmerge-* properties to delete, then write the new
###    mergeinfo and delete the svnmerge-* properties.


import sys
import os
import urllib
import getopt
try:
    my_getopt = getopt.gnu_getopt
except AttributeError:
    my_getopt = getopt.getopt
try:
    from svn import client, ra, core
    svn_version = (core.SVN_VER_MAJOR, core.SVN_VER_MINOR, core.SVN_VER_PATCH)
    if svn_version < (1, 5, 0):
        raise ImportError
except ImportError:
    raise Exception, \
          "Subversion Python bindings version 1.5.0 or newer required."

### -------------------------------------------------------------------------

def errput(msg, only_a_warning=False):
    """Output MSG to stderr, possibly decorating it as an error
    instead of just a warning as determined by ONLY_A_WARNING."""

    if not only_a_warning:
        sys.stderr.write("ERROR: ")
    sys.stderr.write(msg + "\n")

def make_optrev(rev):
    """Return an svn_opt_revision_t build from revision specifier REV.
    REV maybe be an integer value or one of the following string
    specifiers: 'HEAD', 'BASE'."""

    try:
        revnum = int(rev)
        kind = core.svn_opt_revision_number
    except ValueError:
        revnum = -1
        if rev == 'HEAD':
            kind = core.svn_opt_revision_head
        elif rev == 'BASE':
            kind = core.svn_opt_revision_base
        else:
            raise Exception("Unsupported revision specified '%s'" % str(rev))
    optrev = core.svn_opt_revision_t()
    optrev.kind = kind
    optrev.value.number = revnum
    return optrev

def svnmerge_prop_to_mergeinfo(svnmerge_prop_val):
    """Parse svnmerge-* property value SVNMERGE_PROP_VAL (which uses
    any whitespace for delimiting sources and stores source paths
    URI-encoded) into Subversion mergeinfo."""

    if svnmerge_prop_val is None:
        return None

    # First we convert the svnmerge prop value into an svn:mergeinfo
    # prop value, then we parse it into mergeinfo.
    sources = svnmerge_prop_val.split()
    svnmerge_prop_val = ''
    for source in sources:
        pieces = source.split(':')
        if not (len(pieces) == 2 and pieces[1]):
            continue
        pieces[0] = urllib.unquote(pieces[0])
        svnmerge_prop_val = svnmerge_prop_val + '%s\n' % (':'.join(pieces))
    return core.svn_mergeinfo_parse(svnmerge_prop_val or '')

def mergeinfo_merge(mergeinfo1, mergeinfo2):
    """Like svn.core.svn_mergeinfo_merge(), but preserves None-ness."""

    if mergeinfo1 is None and mergeinfo2 is None:
        return None
    if mergeinfo1 is None:
        return mergeinfo2
    if mergeinfo2 is None:
        return mergeinfo1
    return core.svn_mergeinfo_merge(mergeinfo1, mergeinfo2)

def relative_path_from_urls(root_url, url, leading_slash=False):
    """Return the relative path (not URI-encoded) created by
    subtracting from URL the ROOT_URL.  Add a LEADING_SLASH if
    requested."""

    if root_url == url:
        return leading_slash and '/' or ''
    assert url.startswith(root_url)
    if leading_slash:
        return urllib.unquote(url[len(root_url):])
    else:
        return urllib.unquote(url[len(root_url)+1:])

def pretty_print_mergeinfo(mergeinfo, indent=0):
    """Print MERGEINFO hash, one source per line, with a given INDENT."""

    mstr = core.svn_mergeinfo_to_string(mergeinfo)
    sys.stdout.write('\n'.join(map(lambda x: indent * ' ' + x,
                                   filter(None, mstr.split('\n')))) + '\n')


### -------------------------------------------------------------------------

class SvnClient:
    """Subversion client operation abstraction."""

    def __init__(self, config_dir=None):
        core.svn_config_ensure(config_dir)
        self.ctx = client.ctx_t()
        self.ctx.auth_baton = core.svn_auth_open([
            client.get_simple_provider(),
            client.get_username_provider(),
            client.get_ssl_server_trust_file_provider(),
            client.get_ssl_client_cert_file_provider(),
            client.get_ssl_client_cert_pw_file_provider(),
            ])
        self.ctx.config = core.svn_config_get_config(config_dir)
        if config_dir is not None:
            core.svn_auth_set_parameter(self.ctx.auth_baton,
                                        core.SVN_AUTH_PARAM_CONFIG_DIR,
                                        config_dir)
        self.ra_callbacks = ra.callbacks_t()
        self.ra_callbacks.auth_baton = self.ctx.auth_baton
        self.base_optrev = make_optrev('BASE')

    def get_path_urls(self, path):
        """Return a 2-tuple containing the repository URL associated
        with the versioned working file or directory located at
        PATH and the repository URL for the same."""

        infos = []
        def _info_cb(infopath, info, pool, retval=infos):
          infos.append(info)
        client.svn_client_info(path, self.base_optrev, self.base_optrev,
                               _info_cb, 0, self.ctx)
        assert len(infos) == 1
        return infos[0].URL, infos[0].repos_root_URL

    def get_path_revision(self, path):
        """Return the current base revision of versioned file or
        directory PATH."""

        infos = []
        def _info_cb(infopath, info, pool, retval=infos):
          infos.append(info)
        client.svn_client_info(path, self.base_optrev, self.base_optrev,
                               _info_cb, 0, self.ctx)
        assert len(infos) == 1
        return infos[0].rev

    def get_path_mergeinfo(self, path, root_url=None):
        mergeinfo = client.mergeinfo_get_merged(path, self.base_optrev,
                                                self.ctx)
        if not mergeinfo:
            return mergeinfo
        if not root_url:
            path_url, root_url = self.get_path_urls(path)
            if not root_url:
                ras = self.cc.open_ra_session(url)
                root_url = ra.get_repos_root(ras)
        assert root_url
        new_mergeinfo = {}
        for key, value in mergeinfo.items():
            new_key = relative_path_from_urls(root_url, key, True)
            new_mergeinfo[new_key] = value
        return new_mergeinfo

    def get_path_property(self, path, propname):
        rev = self.base_optrev
        prophash, revnum = client.propget3(propname, path, rev, rev,
                                           core.svn_depth_empty, None,
                                           self.ctx)
        return prophash.get(path, None)

    def set_path_property(self, path, propname, propval):
        client.propset3(propname, propval, path, core.svn_depth_empty,
                        0, core.SVN_INVALID_REVNUM, None, None, self.ctx)

    def get_history_as_mergeinfo(self, ra_session, rel_path, rev,
                                 oldest_rev=core.SVN_INVALID_REVNUM):
        """Return the natural history of REL_PATH in REV, between OLDEST_REV
        and REV, as mergeinfo.  If OLDEST_REV is core.SVN_INVALID_REVNUM,
        all of PATH's history prior to REV will be returned.  REL_PATH is
        relative to the session URL of RA_SESSION.
        (Adapted from Subversion's svn_client__get_history_as_mergeinfo().)"""

        # Fetch the location segments in the history.
        location_segments = []
        def _segment_receiver(segment, pool):
            location_segments.append(segment)
        ra.get_location_segments(ra_session, rel_path, rev, rev,
                                 oldest_rev, _segment_receiver)

        # Location segments come in youngest to oldest.  But we rather
        # need oldest-to-youngest for proper revision range ordering.
        location_segments.sort(lambda a, b: cmp(a.range_start, b.range_start))

        # Transform location segments into merge sources and ranges.
        mergeinfo = {}
        for segment in location_segments:
            if segment.path is None:
                continue
            source_path = '/' + segment.path
            path_ranges = mergeinfo.get(source_path, [])
            range = core.svn_merge_range_t()
            range.start = max(segment.range_start - 1, 0)
            range.end = segment.range_end
            range.inheritable = 1
            path_ranges.append(range)
            mergeinfo[source_path] = path_ranges
        return mergeinfo

    def open_ra_session(self, session_url):
        return ra.open(session_url, self.ra_callbacks, None, self.ctx.config)

### -------------------------------------------------------------------------

class SvnmergeHistoryMigrator:
    """svnmerge.py tracking data conversion class."""

    def __init__(self, client_context, verbose=False, naive=False):
        self.cc = client_context
        self.verbose = verbose
        self.naive = naive

    def migrate_path(self, path):
        sys.stdout.write("Searching for merge tracking information...\n")

        # Get svnmerge-integrated property for PATH, as Subversion mergeinfo.
        integrated_mergeinfo = svnmerge_prop_to_mergeinfo(
            self.cc.get_path_property(path, 'svnmerge-integrated'))
        if integrated_mergeinfo and self.verbose:
            sys.stdout.write("Found svnmerge-integrated:\n")
            pretty_print_mergeinfo(integrated_mergeinfo, 3)

        # Get svnmerge-blocked property for PATH, as Subversion mergeinfo.
        blocked_mergeinfo = svnmerge_prop_to_mergeinfo(
            self.cc.get_path_property(path, 'svnmerge-blocked'))
        if blocked_mergeinfo and self.verbose:
            sys.stdout.write("Found svnmerge-blocked:\n")
            pretty_print_mergeinfo(blocked_mergeinfo, 3)

        # No svnmerge tracking data?  Nothing to do.
        if not (integrated_mergeinfo or blocked_mergeinfo):
            errput("No svnmerge.py tracking data found for '%s'." % (path),
                   True)
            return

        # Fetch Subversion mergeinfo for PATH.  Hopefully there is
        # none, but if there is, we'll assume folks want to keep it.
        orig_mergeinfo = self.cc.get_path_mergeinfo(path)
        if orig_mergeinfo and self.verbose:
            sys.stdout.write("Found Subversion mergeinfo:\n")
            pretty_print_mergeinfo(orig_mergeinfo, 3)

        # Merge all our mergeinfos together.
        new_mergeinfo = mergeinfo_merge(orig_mergeinfo, integrated_mergeinfo)
        new_mergeinfo = mergeinfo_merge(new_mergeinfo, blocked_mergeinfo)

        # Unless we're doing a naive migration (or we've no, or only
        # empty, mergeinfo anyway), start trying to cleanup after
        # svnmerge.py's history-ignorant initialization.
        if not self.naive and new_mergeinfo:

            sys.stdout.write("Sanitizing mergeinfo (this can take a "
                             "while)...\n")

            # What we need:
            #    - the relative path in the repository for PATH
            #    - repository root URL and an RA session rooted thereat
            #    - the base revision of PATH
            path_url, root_url = self.cc.get_path_urls(path)
            if root_url:
                ras = self.cc.open_ra_session(root_url)
            else:
                ras = self.cc.open_ra_session(path_url)
                root_url = ra.get_repos_root(ras)
                ra.reparent(ras, root_url)
            assert path_url.startswith(root_url)
            rel_path = relative_path_from_urls(root_url, path_url)
            path_rev = self.cc.get_path_revision(path)

            # We begin by subtracting the natural history of the merge
            # target from its own mergeinfo.
            implicit_mergeinfo = \
                self.cc.get_history_as_mergeinfo(ras, rel_path, path_rev)
            if self.verbose:
                sys.stdout.write("   subtracting natural history:\n")
                pretty_print_mergeinfo(implicit_mergeinfo, 6)
            new_mergeinfo = core.svn_mergeinfo_remove(implicit_mergeinfo,
                                                      new_mergeinfo)
            if self.verbose:
                sys.stdout.write("   remaining mergeinfo to be filtered:\n")
                pretty_print_mergeinfo(new_mergeinfo, 6)

            # Unfortunately, svnmerge.py tends to initialize using
            # oft-bogus revision ranges like 1-SOMETHING when the
            # merge source didn't even exist in r1.  So if the natural
            # history of a branch begins in some revision other than
            # r1, there's still going to be cruft revisions left in
            # NEW_MERGEINFO after subtracting the natural history.
            # So, we also examine the natural history of the merge
            # sources, and use that as a filter for the explicit
            # mergeinfo we've calculated so far.
            mergeinfo_so_far = new_mergeinfo
            new_mergeinfo = {}
            for source_path, ranges in mergeinfo_so_far.items():

                # If by some chance it is the case that /path:RANGE1
                # and /path:RANGE2 a) represent different lines of
                # history, and b) were combined into
                # /path:RANGE1+RANGE2 (due to the ranges being
                # contiguous), we'll foul this up.  But the chances
                # are preeeeeeeetty slim.
                for range in ranges:
                    try:
                        history = self.cc.get_history_as_mergeinfo(
                            ras, source_path[1:], range.end, range.start + 1)
                        if self.verbose:
                            sys.stdout.write("   new sanitized chunk:\n")
                            pretty_print_mergeinfo(history, 6)
                        new_mergeinfo = mergeinfo_merge(new_mergeinfo, history)
                    except core.SubversionException as e:
                        if not (e.apr_err == core.SVN_ERR_FS_NOT_FOUND
                                or e.apr_err == core.SVN_ERR_FS_NO_SUCH_REVISION):
                            raise

        if self.verbose:
            sys.stdout.write("New converted mergeinfo:\n")
            pretty_print_mergeinfo(new_mergeinfo, 3)

        sys.stdout.write("Locally removing svnmerge properties and setting "
                         "new svn:mergeinfo property.\n")
        self.cc.set_path_property(path, 'svnmerge-integrated', None)
        self.cc.set_path_property(path, 'svnmerge-blocked', None)
        self.cc.set_path_property(path, 'svn:mergeinfo',
                                  core.svn_mergeinfo_to_string(new_mergeinfo))


### -------------------------------------------------------------------------

def usage_and_exit(errmsg=None):
    stream = errmsg and sys.stderr or sys.stdout
    stream.write("""Usage: %s [OPTIONS] BRANCH_PATH

Convert svnmerge.py tracking data found on the working copy
BRANCH_PATH into Subversion merge tracking data as a set of local
property modifications.  If BRANCH_PATH already has Subversion merge
tracking data, preserve it during the conversion process.  After this
script runs successfully, you can review and then commit the local
property modifications.  This script will *not* touch the contents of
any files at or under BRANCH_PATH -- it only effects property
modifications, which you can revert rather than commit if you so
desire.

NOTE: BRANCH_PATH need only be a depth-empty checkout of the branch
whose svnmerge.py tracking data you wish to convert.

NOTE: This script requires remote read access to the Subversion
repository whose working copy data you are trying to convert, but
currently does not implement prompting authentication providers.  You
must have valid cached credentials for this script to work.

Options:

   --help (-h, -?)      Show this usage message
   --verbose (-v)       Run in verbose mode
   --naive              Run a naive conversion (faster, but might generate
                           non-ideal results)
""" % (os.path.basename(sys.argv[0])))
    if errmsg:
        stream.write("\nERROR: %s\n" % (errmsg))
    sys.exit(errmsg and 1 or 0)

def main():
    try:
        opts, args = my_getopt(sys.argv[1:], "vh?",
                               ["verbose", "naive-mode", "help"])
    except:
        raise
        usage_and_exit("Unable to process arguments/options.")

    # Process arguments.
    if not args:
        usage_and_exit("No working copy path provided.")
    else:
        branch_path = core.svn_path_canonicalize(args[0])

    # Process options.
    verbose = naive_mode = False
    for opt, value in opts:
        if opt == "--help" or opt in ("-h", "-?"):
            usage_and_exit()
        elif opt == "--verbose" or opt == "-v":
            verbose = True
        elif opt == "--naive-mode":
            naive_mode = True
        else:
            usage_and_exit("Unknown option '%s'" % (opt))

    # Do the work.
    shm = SvnmergeHistoryMigrator(SvnClient(), verbose, naive_mode)
    shm.migrate_path(branch_path)

if __name__ == "__main__":
    main()
