view svnrepo.py @ 330:5f8f2fd4fd54

hg_delta_editor: simplify repository instantiation.
author Dan Villiom Podlaski Christiansen <danchr@gmail.com>
date Sat, 09 May 2009 14:46:12 +0200
parents 48ec2d62dc29
children 75f082b5897e
line wrap: on
line source

from mercurial import node
from mercurial import util as hgutil
import mercurial.repo

import hg_delta_editor
import util
import wrappers

def generate_repo_class(ui, repo):
    def localsvn(fn):
        '''
        Filter for instance methods which only apply to local Subversion
        repositories.
        '''
        if util.is_svn_repo(repo):
            return fn
        else:
            original = repo.__getattribute__(fn.__name__)
            return original

    def remotesvn(fn):
        '''
        Filter for instance methods which require the first argument
        to be a remote Subversion repository instance.
        '''
        original = repo.__getattribute__(fn.__name__)
        def wrapper(self, *args, **opts):
            if not isinstance(args[0], svnremoterepo):
                return original(*args, **opts)
            else:
                return fn(self, *args, **opts)
        wrapper.__name__ = fn.__name__ + '_wrapper'
        wrapper.__doc__ = fn.__doc__
        return wrapper

    class svnlocalrepo(repo.__class__):
        @remotesvn
        def pull(self, remote, heads=None, force=False):
            try:
                lock = self.wlock()
                wrappers.pull(None, self.ui, self, source=remote.path,
                              svn=True, rev=heads, force=force)
            except KeyboardInterrupt:
                pass
            finally:
                lock.release()

        @localsvn
        def tags(self):
            tags = super(svnlocalrepo, self).tags()
            hg_editor = hg_delta_editor.HgChangeReceiver(repo=self)
            for tag, source in hg_editor.tags.iteritems():
                target = hg_editor.get_parent_revision(source[1]+1, source[0])
                tags['tag/%s' % tag] = node.hex(target)
            return tags

    repo.__class__ = svnlocalrepo

class svnremoterepo(mercurial.repo.repository):
    def __init__(self, ui, path):
        self.ui = ui
        self.path = path
        self.capabilities = set(['lookup'])

    def url(self):
        return self.path

    def lookup(self, key):
        return key

    def cancopy(self):
        return False

    def heads(self, *args, **opts):
        """
        Whenever this function is hit, we abort. The traceback is useful for
        figuring out where to intercept the functionality.
        """
        raise hgutil.Abort('command unavailable for Subversion repositories')

def instance(ui, url, create):
    if create:
        raise hgutil.Abort('cannot create new remote Subversion repository')

    if url.startswith('svn+') and not url.startswith('svn+ssh:'):
        url = url[4:]
    return svnremoterepo(ui, util.normalize_url(url))