_apycotlib/repositories.py
author David Douard <david.douard@logilab.fr>
Fri, 14 Nov 2014 12:51:47 +0100
changeset 1740 f3137466457a
parent 1677 998cd9f5cbed
permissions -rw-r--r--
Big Refactoring (BR) of the test execution model Get rid of narval preprocessors in favor of Recipes - Each preprocessing recipe must be run from the "main" recipe (thus we add a ATest.exec_recipe() method that can be called from Recipe execution). - We add a (Repository, checkout_recipe, Recipe) relation, which is the Recipe that tells how to retrieve the code for a given Repository - Also add a (ProjectEnvironment, setup_recipe, Recip) dedicated to perform the installation for a project (compile and install) - Add implementations for these recipes for Python project - Rewrite the quick recipe using this new model

"""Some standard sources repositories, + factory function

:organization: Logilab
:copyright: 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
:license: General Public License version 2 - http://www.gnu.org/licenses
"""
__docformat__ = "restructuredtext en"

from os import path as osp, environ
from time import localtime

from logilab.common.textutils import split_url_or_path

from apycotlib import register, get_registered, ConfigError


def get_repository(**attrs):
    """factory method: return a repository implementation according to
    <attrs> (a dictionary)
    """
    repo_type = attrs['repository']['type']
    return get_registered('repository', repo_type)(attrs)

class VCSRepository(objet):
    """base class for clonable repository"""

    id = None
    default_branch = None

    def __init__(self, repository, changeset):
        self.repository = repository
        if not self.repository:
            raise ConfigError('Repository must be specified')
        self.cset = changeset
        if not self.ref_repo:
            raise ConfigError('Missing information to checkout repository %s'
                              % self.repository)

    def __eq__(self, other):
        return (isinstance(other, self.__class__) and
                self.repository == other.repository and
                self.path == other.path)

    def __ne__(self, other):
        return not self == other

    def __repr__(self):
        """get a string synthetizing the location"""
        myrepr = '%s:%s' % (self.id, self.ref_repo)
        myrepr += '@%s' % self.cset
        return myrepr

    @property
    def co_path(self):
        """return the path where the project will be located in the test
        environment
        """
        copath = split_url_or_path(self.ref_repo)[1]
        if self.path:
            copath = osp.join(copath, self.path)
        return osp.join(environ['APYCOT_ROOT'], copath)

    def co_command(self, quiet=True):
        """return a command that may be given to os.system to check out a given
        package
        """
        raise NotImplementedError()


class HGRepository(VCSRepository):
    """extract sources/information for a project from a Mercurial repository"""
    id = 'mercurial'

    @property
    def ref_repo(self):
        return self.repository['source_url']

    def co_command(self, quiet=True):
        """return a command that may be given to os.system to check out a given
        package
        """
        if quiet:
            return "hg clone -q %s && hg -R %s up '::. and public()'" % (self.ref_repo, self.co_path)
        return "hg clone %s && hg -R %s up '::. and public()'" % (self.ref_repo, self.co_path)


register('repository', HGRepository)