Пример #1
0
class Git:
    """Git interface for vamp."""
    __borg_state = {}

    GITHUB_API_URL = 'https://api.github.com'

    def __init__(self):
        self.__dict__ = self.__borg_state

        self.c = Config()

    def get_url(self, full_name):
        """Get a URL ready for cloning given a 'full_name'.

        'full_name' must be of the format 'user/repo'.

        Returns the clone-able URL or None if no URL was found.
        """
        api_url = "{0}/repos/{1}".format(self.GITHUB_API_URL, full_name)
        r = requests.get(api_url)
        if r.status_code == 200:
            j = r.json()
            return j.get('clone_url', None)
        else:
            return None

    def is_repo(self, url):
        """Given a url, will check if it points to a valid Git repo.

        'url' can be any URL that Git supports.
        """
        try:
            subprocess.check_output(['git', 'ls-remote', url],
                    stderr=subprocess.STDOUT)
            return True
        except CalledProcessError as e:
            if e.returncode != 128:
                # No clue what happened here
                print('Unexpected git error! Return code {0}'.format(
                    e.returncode))
                print(e.cmd)
                print(e.output)
                # I think an error message is sufficient, not sure we want
                # this to block
            return False

    def clone(self, url, dest):
        """Clones the git repo at 'url' to the path at 'dest'."""
        print("> Cloning from '{0}'...".format(url))
        r = subprocess.check_output(['git', 'clone', url, dest])
        if self.c.get('globals', 'verbose', False):
            print(r)

    def update(self, dest):
        """Updates the git repo at 'dest'."""
        print("> Updating '{0}'...".format(dest))
        r = subprocess.check_output(['git', '-C', dest, 'pull'])
        if self.c.get('globals', 'verbose', False):
            print(r)
Пример #2
0
    def __init__(self, force=False):
        self.__dict__ = self.__borg_state

        self.c = Config()
        self.force = force
        self.b = Bank()
        self.m = Manifest()
        self.cache = {}
        self._installed = {}
        self._working_dirs = set()
Пример #3
0
def command_init():
    """Initializes various systems ('all' if none specified)"""
    sub_systems = {
            'config' : False,
            'bank' : False,
            'paths' : False
        }

    if args.option in sub_systems:
        sub_systems[args.option] = True
    elif args.option is None:
        for k in sub_systems:
            sub_systems[k] = True
    else:
        print("Error! Invalid sub-system!")
        print("See help for 'init' to see valid sub-sustems!")
        sys.exit(1)

    print("Initializing vamp...\n")

    if sub_systems['config']:
        print("> Initializing configuration file...")
        c = Config()
        if args.force:
            print(">> Forcing default values for configuration file...")
            c.set_defaults()
            c.save()

    if sub_systems['paths']:
        print("> Initializing system paths...")
        c = Config()
        if 'paths' not in c.config:
            print("Error! Configuration file is missing 'paths' section!")
            print("Did you forget to init the config sub-system?")
            sys.exit(1)

        for p in c.config['paths']:
            print(">> Initializing '{0}'...".format(p))
            ensure_path(c.config['paths'][p])

    if sub_systems['bank']:
        print("> Initializing blood bank...")
        b = Bank()
        b.init_bank(bank=None, force=args.force)
Пример #4
0
    def __init__(self):
        self.__dict__ = self.__borg_state

        self.c = Config()
Пример #5
0
class PackageHandler:
    __borg_state = {}

    def __init__(self, force=False):
        self.__dict__ = self.__borg_state

        self.c = Config()
        self.force = force
        self.b = Bank()
        self.m = Manifest()
        self.cache = {}
        self._installed = {}
        self._working_dirs = set()

    def _check_deps(self, pkg):
        """Checks that the dependencies are installed for a package."""
        all_deps = True
        for dep in pkg.requires:
            if dep not in self.m.get('PackageHandler', 'installed'):
                print("!! Error, dependency '{0}' not found for package" +
                " '{1}'!".format(dep, pkg.name))
                all_deps = False

        if not pkg.check_system_requirements():
            print("!! Error, system requirements not satisfied for" +
            " '{0}'!".format(pkg.name))
            all_deps = False

        return all_deps

    def _get_package(self, package):
        """Returns a package object, either loading as needed or from cache."""
        if package in self.cache:
            return self.cache[package]
        else:
            p = self.b.get_package(package)
            self.cache[package] = p
            return p

    def _cleanup(self, directory):
        """Given a directory, clean it up without prejudice.

        Will only clean up directries in the vamp infrastructure."""
        if directory in self._working_dirs:
            shutil.rmtree(directory)
            self._working_dirs.remove(directory)
        else:
            raise OSError("Error! Attempt to remove directory outside of vamp" + \
                    "infrastructure! '{0}'".format(directory))

    def _get_workdir(self, package):
        """Given a package name, get a working directory for it."""
        wdir = tempfile.mkdtemp(prefix=package)
        self._working_dirs.add(wdir)
        ensure_path(wdir)
        return wdir

    def _get_installdir(self, package):
        """Given a package name, get the installation directory for it."""
        indir = "{0}/{1}".format(self.c.get('paths', 'install', True), package)
        self._working_dirs.add(indir)
        ensure_path(indir)
        return indir

    def _install(self, package):
        """Installs a package."""
        pkg = self._get_package(package)
        if pkg is None:
            print("Error! Unable to find package '{0}'!".format(package))
            sys.exit(1)

        if self._check_deps(pkg):
            print("> Installing '{0}'...".format(pkg.name))
            working_dir = self._get_workdir(package)
            install_dir = self._get_installdir(package)
            bins = pkg.install(working_dir, install_dir, self.c.get('globals',
                'verbose'))
            if bins is None:
                print("!! Error installing package '{0}'!".format(package))
                print("!! No binaries specified!")
                self._cleanup(working_dir)
                self._cleanup(install_dir)
            else:
                self._cleanup(working_dir)
        else:
            print("!! Error installing package '{0}'".format(package) + \
                    ", problem with dependencies!")
            sys.exit(1)

    def _find_build_deps(self, pkg):
        """Internal, recursive, function for finding the build deps of a
        package."""
        deps = []
        deps.append(pkg.package_name)
        for req in pkg.requires:
            if req not in self._installed:
                deppkg = self._get_package(req)
                deps.extend(self._find_build_deps(deppkg))
        return deps

    def build_deps(self, package):
        """Given a package, build the dependencies needed to install it."""
        pkg = self._get_package(package)
        # Pre-cache the installed packages
        self._installed = self.m.get('PackageHandler', 'installed')
        return list(set(self._find_build_deps(pkg)))

    def install(self, packages):
        """Given a list of packages, install them.

        If the list is not dependency resolved, you will probably get errors
        on install."""
        for p in packages:
            self._install(p)
Пример #6
0
    def __init__(self):
        self.__dict__ = self.__borg_state

        self.c = Config()
        self.g = Git()
        self.m = Manifest()
Пример #7
0
class Bank:
    __borg_state = {}
    BLOODBANK = ".bloodbank"
    GITHUBBANK = ".github"

    def __init__(self):
        self.__dict__ = self.__borg_state

        self.c = Config()
        self.g = Git()
        self.m = Manifest()

    def init_bank(self, bank=None, force=False):
        """Initializes a bank.

        'bank' should be a string of the format 'user/repo'.

        If 'bank' is not specified, will init the main bloodbank.
        """
        clone_to = None
        url = None
        if bank is None:
            url = self.c.get("urls", "bloodbank")
            clone_to = "{0}/{1}".format(self.c.get("paths", "bank"), self.BLOODBANK)
        else:
            url = self.g.get_url(bank)
            clone_to = "{0}/{1}/{2}".format(self.c.get("paths", "bank"), self.GITHUBBANK, bank)

        if url is None:
            print("Error! No valid URL found for '{0}'!".format(bank))
            sys.exit(1)

        if os.path.isdir(clone_to):
            if force:
                print("!! Bank directory exists, but overwriting because " + "of --force")
                shutil.rmtree(clone_to)
                self.g.clone(url, clone_to)
            else:
                print("!! Bank directory exists, using existing")
        else:
            self.g.clone(url, clone_to)

        self.m.set("bank", "repos", {bank: {"url": url, "dir": clone_to, "lastup": time.time()}})

    def get_package(self, package):
        """Given a package name, import the package object and return it."""
        # We have to run through a number of sources to get the package
        filename = "{0}/{1}/.bank/{2}.py".format(self.c.get("paths", "bank", True), self.BLOODBANK, package)
        if os.path.isfile(filename):
            return kitten_importer(filename, package)
        else:
            if self.g.get_url(package) is not None:
                appname = package.split("/")[-1]
                self.init_bank(package)
                filename = "{0}/{1}/.bank/{2}.py".format(self.c.get("paths", "bank", True), self.GITHUBBANK, appname)
                if os.path.isfile(filename):
                    return kitten_importer(filename, appname)
        return None

    def update(self, bank=None):
        """Update a bank.

        'bank' should be a string of the format 'user/repo'.

        If 'bank' is none, will update all repos.
        """
        repos = self.m.get("bank", "repos", {})
        if bank is None:
            for repo in repos:
                if os.path.isdir(repos[repo]["dir"]):
                    self.g.update(repos[repo]["dir"])
                else:
                    print(
                        "Error! No bank found at '{0}', yet manifest " + "reports one there!".format(repos[repo]["dir"])
                    )
                    # FIXME : Would be nice to suggest a way to fix this
                    sys.exit(1)
        else:
            if bank in repos:
                repo = repos[bank]
                if os.path.isdir(repo["dir"]):
                    self.g.update(repo["dir"])
                else:
                    print("Error! No bank found at '{0}, yet manifest " + "reports one there!".format(repo["dir"]))
                    # FIXME : Same as above
                    sys.exit(1)
            else:
                print("Error! Bank '{0}' not found in manifest!".format(bank))