Exemplo n.º 1
0
        def callback_target():
            
            try:
                fh = os.fdopen(prfd)
            except:
                os.close(prfd)
                raise

            while True:
                arg_count = fh.readline().strip()
                if not arg_count:
                    break
                arg_count = int(arg_count)
                args = []
                for arg_i in range(arg_count):
                    arg_len = int(fh.readline())
                    args.append(fh.read(arg_len))
                name = args[0]
                if name in callbacks:
                    try:
                        res = callbacks[name](*args[1:])
                    except Exception as e:
                        log.exception('exception in callback %s: %s' % (name, e))
                        res = None
                else:
                    log.warning('no callback %s' % name)
                    res = None
                if res is None:
                    os.write(pwfd, '0\n')
                else:
                    res = str(res)
                    os.write(pwfd, '%s\n' % len(res))
                    os.write(pwfd, res)
Exemplo n.º 2
0
    def rewrite_shebang(self, old_path, new_path):

        # Only care if it is at all executable.
        stat = os.stat(old_path)
        if not (stat.st_mode & 0o111):
            return

        # If it starts with a Python shebang, rewrite it.
        with open(old_path, 'rb') as old_fh:
            old_shebang = old_fh.readline()
            m = re.match(r'#!(|\S+/)([^\s/]+)', old_shebang)
            if not m:
                return

            new_bin = os.path.join(self.path, 'bin', m.group(2))
            if not os.path.exists(new_bin):
                return

            new_shebang = '#!%s%s' % (new_bin, old_shebang[m.end(2):])
            log.info('Rewriting shebang of %s' % old_path, verbosity=1)
            log.debug('New shebang: %s' % new_shebang.strip(), verbosity=1)

            self._assert_real_dir(os.path.dirname(new_path))

            # Due to the way the _assert_real_dir works, we may have already
            # created a symlink in the location of the new_path which points to
            # the old_path. If we don't delete it first, then we will be
            # reading and writing to the same time, and will only get the
            # shebang + 1024 bytes (the buffer size on my machine).
            if os.path.lexists(new_path):
                os.unlink(new_path)

            with open(new_path, 'wb') as new_fh:
                new_fh.write(new_shebang)
                new_fh.writelines(old_fh)
            try:
                shutil.copystat(old_path, new_path)
            except OSError as e:
                # These often come up when you are not the owner
                # of the file.
                log.exception('Could not copystat to %s' % new_path)
                if e.errno != errno.EPERM:
                    raise

            return True
Exemplo n.º 3
0
    def install(self,
                names=None,
                link_env=None,
                reinstall=False,
                relink=False,
                no_deps=False):

        # I'd love to split this method into an "install" and "link" step, but
        # then we'd need to reimplement the dependency resolution. That would
        # be a good idea to do anyways, but... meh.

        if isinstance(names, str):
            names = [names]
        names = list(names if names else self.keys())

        for name in names:
            if name not in self:
                raise KeyError(name)

        if not isinstance(reinstall, set):
            reinstall = set(
                names if no_deps else self.keys()) if reinstall else set()
        if not isinstance(relink, set):
            relink = set(
                names if no_deps else self.keys()) if relink else set()

        while names:
            name = names.pop(0)

            self._parent_names.setdefault(name, None)

            parent_chain = []
            tip = name
            while tip and tip not in parent_chain:
                parent_chain.append(tip)
                tip = self._parent_names.get(tip)
            parent_chain = parent_chain[1:]

            print(
                '==>', style(name, 'blue'),
                style('(%s)' % ' < '.join(parent_chain), faint=True)
                if parent_chain else '')

            with log.indent():

                # Avoid infinite error loops.
                if name in self._errored:
                    log.warning('Skipping due to previous error.')
                    continue

                try:
                    self._install_one(names, name, link_env, reinstall, relink,
                                      no_deps)
                except PipelineError as e:
                    self._errored.add(name)
                    log.error(str(e))
                    continue
                except Exception as e:
                    self._errored.add(name)
                    print_cli_exc(e, verbose=True)
                    log.exception('Exception while processing %s' % name)
                    continue

        if self._errored:
            log.warning('There were errors in: %s' %
                        ', '.join(sorted(self._errored)))
Exemplo n.º 4
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]:vfxetc/sgmock

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

        # Install and link from a requirement set.
        $ vee link path/to/manifest.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:
        repo = home.get_repo(args.repo)
        env = Environment('%s/%s' % (repo.name, repo.branch_name), home=home)

    if args.raw:
        for dir_ in args.requirements:
            log.info(style_note('Linking', dir_))
            env.link_directory(dir_)
        return

    manifest = Manifest(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(manifest)

    for req in manifest.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