コード例 #1
0
def install(args):
    """Install the given requirements without linking them into an environment.
    This is a low-level command, and is generally unused.

    Examples:

        # Install a single package.
        vee install [email protected]:westernx/sgmock

        # Install multiple packages.
        vee install [email protected]:westernx/sgmock [email protected]:westernx/sgsession \\
            http:/example.org/path/to/tarball.tgz --make-install

        # Install from a requirement set.
        vee install path/to/requirements.txt

    """

    home = args.assert_home()

    if not args.requirements:
        raise ValueError('please provide requirements to install')

    reqs = Requirements(args.requirements, home=home)
    pkgs = PackageSet(home=home)

    # TODO: Resolve everything at once like upgrade does.
    for req in reqs.iter_packages():
        pkg = pkgs.resolve(req, check_existing=not args.force)
        try:
            pkgs.install(pkg.name, reinstall=args.force)
        except AlreadyInstalled:
            print style('Already installed', 'blue', bold=True), style(str(pkg.freeze()), bold=True)
コード例 #2
0
    def test_local_envvars(self):
        reqs = Requirements()
        reqs.parse_file('''
            url -e KEY=VALUE
        '''.strip().splitlines())

        flat = ''.join(reqs.iter_dump()).strip()
        self.assertEqual(flat, 'file:url --environ=KEY=VALUE')
コード例 #3
0
 def test_global_envvars(self):
     req_set = Requirements()
     req_set.parse_file('''
         first
         KEY=VALUE1
         second
         KEY=VALUE2
         third
     '''.strip().splitlines())
     reqs = list(req_set.iter_packages())
     self.assertEqual(reqs[0].base_environ, {})
     self.assertEqual(reqs[1].base_environ, {'KEY': 'VALUE1'})
     self.assertEqual(reqs[2].base_environ, {'KEY': 'VALUE2'})
コード例 #4
0
 def test_else(self):
     reqs = Requirements()
     reqs.parse_file('''
         % if 0:
             zero
         % elif 0:
             one
         % else:
             two
         % endif
     '''.strip().splitlines())
     pkgs = list(reqs.iter_packages())
     self.assertEqual(len(pkgs), 1)
     self.assertEqual(pkgs[0].name, 'two')
コード例 #5
0
ファイル: test_package_sets.py プロジェクト: westernx/vee
    def test_prefix_function(self):

        home = self.home()

        reqs = Requirements()
        reqs.parse_file('''

            first --revision 1.0
            second -e "FIRST=$(prefix first)"

        '''.strip().splitlines())

        pkgs = PackageSet(home=home)
        pkgs.resolve_set(reqs)

        first = pkgs['first']
        first.install_path = '/path/to/first'

        second = pkgs['second']
        env = second.fresh_environ()

        self.assertEqual(env['FIRST'], '/path/to/first')
コード例 #6
0
    def test_platforms(self):
        req_set = Requirements()
        req_set.parse_file('''

            before
            % if MACOS:
                macos
            % elif LINUX:
                linux
            % endif
            after

        '''.strip().splitlines())

        print req_set

        reqs = list(req_set.iter_packages())
        self.assertEqual(reqs[0].name, 'before')
        if sys.platform == 'darwin':
            self.assertEqual(reqs[1].name, 'macos')
        elif sys.platform == 'linux2':
            self.assertEqual(reqs[1].name, 'linux')
        self.assertEqual(reqs[2].name, 'after')
コード例 #7
0
 def load_requirements(self, revision=None):
     reqs = Requirements(env_repo=self, home=self.home)
     if revision is not None:
         contents = self.show(revision, 'requirements.txt')
         if contents:
             reqs.parse_file(contents.splitlines())
     else:
         if os.path.exists(self._req_path):
             reqs.parse_file(self._req_path)
     return reqs
コード例 #8
0
ファイル: exec_.py プロジェクト: westernx/vee
def exec_(args):
    """Construct an environment, and either export it or run a command in it.
    e.g.::

        # Run in the default repository.
        $ vee exec $command

        # Run within a given repository.
        $ vee exec --repo named_repo $command

        # Run within a named environment.
        $ vee exec -e named_environ $command

        # Run within a constructed runtime for a set of requirements.
        $ vee exec -r requirements.txt $command

        # Export the default environment.
        $ vee exec --export
        export LD_LIBRARY_PATH="/usr/local/vee/lib:$LD_LIBRARY_PATH"
        export PATH="/usr/local/vee/bin:$PATH"
        export PYTHONPATH="/usr/local/vee/lib/python2.7/site-packages"

    """

    home = args.assert_home()

    # TODO: seed these with the current values.
    repo_names = []
    env_names = []

    environ_diff = {}

    if args.bootstrap:
        bootstrap = os.environ['VEE_EXEC_ARGS'].split() if os.environ.get(
            'VEE_EXEC_ARGS') else []
        # This is gross, but easier than building another parser. It does mean
        # that we expect this variable must be set by ourselves.
        while bootstrap:
            arg = bootstrap.pop(0)
            if arg in ('--dev', ):
                setattr(args, arg[2:], True)
            elif arg in ('--requirements', '--repo', '--environment'):
                v = getattr(args, arg[2:], None) or []
                v.append(bootstrap.pop(0))
                setattr(args, arg[2:], v)
            else:
                print >> sys.stderr, 'cannot bootstrap', arg

    if args.dev:
        # Store the original flags as provided so that --bootstrap can pick it back up.
        bootstrap = os.environ['VEE_EXEC_ARGS'].split() if os.environ.get(
            'VEE_EXEC_ARGS') else []
        if '--dev' not in bootstrap:
            bootstrap.append('--dev')
        for attr in 'requirements', 'repo', 'environment':
            for value in getattr(args, attr, None) or ():
                bootstrap.append('--' + attr)
                bootstrap.append(value)
        environ_diff['VEE_EXEC_ARGS'] = ' '.join(bootstrap)

    if not (args.export or args.command or args.prefix):
        raise ValueError(
            'Must either --prefix, --export, or provide a command')

    # Default to the default repo.
    if not (args.requirements or args.environment or args.repos):
        args.repos = [None]

    paths = []

    # Named (or default) repos.
    for name in args.repos or ():
        repo = home.get_env_repo(name or None)  # Allow '' to be the default.
        args.environment = args.environment or []
        args.environment.append('%s/%s' % (repo.name, repo.branch_name))
        repo_names.append(repo.name)

    # Requirements and requirement sets.
    req_args = []
    for arg in args.requirements or ():
        req_args.extend(arg.split(','))
    req_set = Requirements(home=home)
    req_set.parse_args(req_args)
    pkg_set = PackageSet(home=home)
    for req in req_set.iter_packages():
        pkg = pkg_set.resolve(req)
        pkg._assert_paths(install=True)
        if not pkg.installed:
            raise NotInstalled(pkg.install_path)
        paths.append(pkg.install_path)

    # Named environments.
    for name in args.environment or ():
        env = Environment(name, home=home)
        paths.append(env.path)
        env_names.append(name)

    if args.prefix:
        for path in paths:
            print path
        return

    environ_diff.update(guess_envvars(paths))

    if args.dev:
        for pkg in home.iter_development_packages(exists=True, search=True):
            if pkg.environ:
                environ_diff.update(
                    render_envvars(pkg.environ, pkg.work_tree, environ_diff))

    # Add the current virtualenv.
    venv = os.environ.get('VIRTUAL_ENV')
    if venv:
        environ_diff['PYTHONPATH'] = '%s:%s' % (
            os.path.join(venv, 'lib', 'python%d.%d' % sys.version_info[:2],
                         'site-packages'),
            environ_diff.get('PYTHONPATH', ''),  # This is sloppy.
        )

    # More environment variables.
    command = args.command or []
    while command and re.match(r'^\w+=', command[0]):
        k, v = command.pop(0).split('=', 1)
        environ_diff[k] = v

    # Make sure setuptools is bootstrapped.
    bootstrap_environ(environ_diff)

    environ_diff['VEE_EXEC_PATH'] = ':'.join(paths)
    environ_diff['VEE_EXEC_REPO'] = ','.join(repo_names)
    environ_diff['VEE_EXEC_ENV'] = ','.join(env_names)
    environ_diff['VEE_EXEC_PREFIX'] = paths[0]

    # Print it out instead of running it.
    if args.export:
        for k, v in sorted(environ_diff.iteritems()):
            existing = os.environ.get(k)

            # Since we modify os.environ in __init__ to bootstrap the vendored
            # packages, swaping out the original values will not include the
            # bootstrap. So we are tricking the code so that it still includes it.
            if k == 'PYTHONPATH' and existing.endswith(vendor_path):
                existing += (':' if existing else '') + vendor_path

            if existing is not None and not k.startswith('VEE_EXEC'):
                v = v.replace(existing, '$' + k)
            print 'export %s="%s"' % (k, v)
        return

    environ = os.environ.copy()
    environ.update(environ_diff)
    os.execvpe(args.command[0], args.command, environ)
コード例 #9
0
ファイル: repo.py プロジェクト: westernx/vee
    def add_requirements(self, raw, insert=False, commit=True):

        old = Requirements(home=self.home)
        path = os.path.join(self.path, 'requirements.txt')
        if os.path.exists(path):
            old.parse_file(path)

        new = Requirements(home=self.home, file=StringIO(raw))

        new_urls = set()
        new_names = set()
        for req in new.iter_packages():
            new_names.add(req.name or guess_name(req.url))
            new_urls.add(req.url)

        for prefix, element, postfix in old:
            if (not isinstance(element, Package) or
                (element.name or guess_name(element.url)) not in new_names
                    or element.url not in new_urls):
                if insert:
                    new.append((prefix, element, postfix))
                else:
                    new.insert(0, (prefix, element, postfix))

        with open(path, 'wb') as fh:
            for line in new.iter_dump():
                fh.write(line)

        if commit:
            self.commit('add requirements')
コード例 #10
0
def init(args, do_clone=False, do_install=False, do_add=False, is_find=False):

    do_init = not (do_clone or do_install or do_add)

    name = args.name
    home = args.assert_home()

    con = home.db.connect()

    # Make sure there are no other packages already, and clear out old ones
    # which no longer exist.
    for row in con.execute('SELECT * FROM development_packages WHERE name = ?',
                           [name]):
        if not args.force and os.path.exists(os.path.join(row['path'],
                                                          '.git')):
            if is_find:
                print style_note('"%s" already exists:' % name, row['path'])
                return
            else:
                print style_error('"%s" already exists:' % name, row['path'])
                return 1
        else:
            con.execute('DELETE FROM development_packages WHERE id = ?',
                        [row['id']])

    path = os.path.abspath(args.path or os.path.join(home.dev_root, name))

    dev_repo = GitRepo(path)

    if do_init:
        print style_note('Initing %s' % dev_repo.work_tree)
        makedirs(dev_repo.work_tree)
        dev_repo.git('init')

    elif do_clone:
        print style_note('Cloning %s' % args.url)
        makedirs(dev_repo.work_tree)
        dev_repo.clone_if_not_exists(args.url)

    elif do_install:
        # Find an existing tool.
        # TODO: put more of this into EnvironmentRepo or Requirements
        env_repo = home.get_env_repo(args.repo)
        req_path = os.path.join(env_repo.work_tree, 'requirements.txt')
        reqs = Requirements(req_path, home=home)
        for req in reqs.iter_packages():
            if req.name.lower() == name.lower():
                # Make sure it is a Git package.
                url = normalize_git_url(req.url, prefix=False)
                if url:
                    break
        else:
            print style_error('Could not find git-based "%s" in "%s" repo.' %
                              (name, env_repo.name))
            return 2
        print style_note('Found %s in %s' % (name, env_repo.name), str(req))
        makedirs(dev_repo.work_tree)
        dev_repo.clone_if_not_exists(url, shallow=False)

    elif do_add:
        print style_note('Adding %s from %s' % (name, path))

    if not os.path.exists(path):
        log.error('%s does not exist' % path)
        return 1

    package = Package([path], home=home, dev=True)
    try:
        package.pipeline.run_to('develop')
    except Exception as e:
        print_cli_exc(e)
        return 1

    print style_note('Linking dev package', name, path)
    con.execute(
        'INSERT INTO development_packages (name, path, environ) VALUES (?, ?, ?)',
        [name, path, json.dumps(package.environ)])

    dev_pkg = DevPackage(
        {
            'name': name,
            'path': path,
            'environ': package.environ
        }, home=home)
    dev_pkg.save_tag()
コード例 #11
0
def link(args):
    """Link the given requirement or requirements into the given environment,
    e.g.::
        
        # Install and link a single package.
        $ vee link [email protected]:westernx/sgmock

        # Install and link multiple packages.
        $ vee link [email protected]:westernx/sgmock [email protected]:westernx/sgsession \\
            http:/example.org/path/to/tarball.tgz --make-install

        # Install and link from a requirement set.
        $ vee link path/to/requirements.txt

    """

    if args.no_install and args.re_install:
        raise ValueError(
            'please use only one of --no-install and --re-install')

    home = args.assert_home()

    if sum(
            int(bool(x))
            for x in (args.repo, args.environment, args.directory)) > 1:
        raise ValueError(
            'use only one of --repo, --environment, or --directory')

    if args.environment:
        env = Environment(args.environment, home=home)
    elif args.directory:
        env = Environment(os.path.abspath(args.directory), home=home)
    else:
        env_repo = home.get_env_repo(args.repo)
        env = Environment('%s/%s' % (env_repo.name, env_repo.branch_name),
                          home=home)

    if args.raw:
        for dir_ in args.requirements:
            print style('Linking', 'blue', bold=True), style(dir_, bold=True)
            env.link_directory(dir_)
        return

    req_set = Requirements(args.requirements, home=home)
    pkg_set = PackageSet(env=env, home=home)

    # Register the whole set, so that dependencies are pulled from here instead
    # of weakly resolved from installed packages.
    pkg_set.resolve_set(req_set)

    for req in req_set.iter_packages():

        # Skip if it wasn't requested.
        if args.subset and req.name not in args.subset:
            continue

        log.info(style('==> %s' % req.name, 'blue'))

        pkg = pkg_set.resolve(req, check_existing=not args.reinstall)

        if args.no_install and not pkg.installed:
            raise CliError('not installed: %s' % req)

        try:
            with log.indent():
                pkg_set.install(pkg.name,
                                link_env=env,
                                reinstall=args.reinstall,
                                relink=args.force)
        except AlreadyInstalled:
            pass
        except AlreadyLinked as e:
            log.info(style('Already linked ', 'blue') + str(req), verbosity=1)
        except Exception as e:
            print_cli_exc(e, verbose=True)
            log.exception('Failed to link %s' % req)
            continue