コード例 #1
0
class PythonToolInstance:
    logger = logging.getLogger(__name__)

    def __init__(self, pex_path, interpreter):
        self._pex = PEX(pex_path, interpreter=interpreter)
        self._interpreter = interpreter

    @property
    def pex(self):
        return self._pex

    @property
    def interpreter(self):
        return self._interpreter

    def _pretty_cmdline(self, args):
        return safe_shlex_join(self._pex.cmdline(args))

    def output(self, args, stdin_payload=None, binary_mode=False, **kwargs):
        process = self._pex.run(args,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                with_chroot=False,
                                blocking=False,
                                **kwargs)
        if stdin_payload is not None:
            stdin_payload = ensure_binary(stdin_payload)
        (stdout, stderr) = process.communicate(input=stdin_payload)
        if not binary_mode:
            stdout = stdout.decode()
            stderr = stderr.decode()
        return (stdout, stderr, process.returncode, self._pretty_cmdline(args))

    @contextmanager
    def run_with(self, workunit_factory, args, **kwargs):
        # TODO(John Sirois): remove when we ingest a pex with a fix for:
        #  https://github.com/pantsbuild/pex/issues/707
        # Ensure we don't leak source files or undeclared 3rdparty requirements into the PEX
        # environment.
        supplied_env = kwargs.pop('env', None)
        env = (supplied_env or os.environ).copy()
        pythonpath = env.pop('PYTHONPATH', None)
        if pythonpath:
            self.logger.warning(
                'scrubbed PYTHONPATH={} from environment'.format(pythonpath))

        cmdline = self._pretty_cmdline(args)
        with workunit_factory(cmd=cmdline) as workunit:
            exit_code = self._pex.run(args,
                                      stdout=workunit.output('stdout'),
                                      stderr=workunit.output('stderr'),
                                      with_chroot=False,
                                      blocking=True,
                                      env=env,
                                      **kwargs)
            yield cmdline, exit_code, workunit

    def run(self, *args, **kwargs):
        with self.run_with(*args, **kwargs) as (cmdline, exit_code, _):
            return cmdline, exit_code
コード例 #2
0
ファイル: python_tool_prep_base.py プロジェクト: wiwa/pants
class PythonToolInstance:
    logger = logging.getLogger(__name__)

    def __init__(self, pex_path, interpreter):
        self._pex = PEX(pex_path, interpreter=interpreter)
        self._interpreter = interpreter

    @property
    def pex(self):
        return self._pex

    @property
    def interpreter(self):
        return self._interpreter

    def _pretty_cmdline(self, args):
        return safe_shlex_join(self._pex.cmdline(args))

    def output(self, args, stdin_payload=None, binary_mode=False, **kwargs):
        process = self._pex.run(
            args,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            with_chroot=False,
            blocking=False,
            **kwargs,
        )
        if stdin_payload is not None:
            stdin_payload = ensure_binary(stdin_payload)
        (stdout, stderr) = process.communicate(input=stdin_payload)
        if not binary_mode:
            stdout = stdout.decode()
            stderr = stderr.decode()
        return (stdout, stderr, process.returncode, self._pretty_cmdline(args))

    @contextmanager
    def run_with(self, workunit_factory, args, **kwargs):
        cmdline = self._pretty_cmdline(args)
        with workunit_factory(cmd=cmdline) as workunit:
            exit_code = self._pex.run(
                args,
                stdout=workunit.output("stdout"),
                stderr=workunit.output("stderr"),
                with_chroot=False,
                blocking=True,
                **kwargs,
            )
            yield cmdline, exit_code, workunit

    def run(self, *args, **kwargs):
        with self.run_with(*args, **kwargs) as (cmdline, exit_code, _):
            return cmdline, exit_code
コード例 #3
0
    def execute_codegen(self, target, results_dir):
        self.context.log.info("Processing target {}".format(target))

        requirements_pex = self.context.products.get_data(ResolveRequirements.REQUIREMENTS_PEX)

        interpreter = self.context.products.get_data(PythonInterpreter)
        pex_info = PexInfo.default(interpreter)
        pex_info.pex_path = requirements_pex.path()
        with temporary_dir() as source_pex_chroot:
            sources_pex_builder = PEXBuilder(
                path=source_pex_chroot,
                interpreter=interpreter,
                copy=True,
                pex_info=pex_info
            )
            pex_build_util.dump_sources(sources_pex_builder, target, self.context.log)
            sources_pex_builder.freeze()
            codegen_pex = PEX(sources_pex_builder.path(), interpreter)

            setup_py_paths = []
            for source in target.sources_relative_to_source_root():
                if os.path.basename(source) == 'setup.py':
                    setup_py_paths.append(source)
            if len(setup_py_paths) != 1:
                raise TaskError(
                    'Expected target {} to own exactly one setup.py, found {}'.format(
                        setup_py_paths,
                        len(setup_py_paths)
                    )
                )
            setup_py_path = setup_py_paths[0]

            result_code = codegen_pex.run(
                with_chroot=True,
                blocking=True,
                args=(setup_py_path, 'build_ext', '--inplace', '--verbose'),
                # Passing PATH helps cython find the correct c++ compiler
                env={'libraries': results_dir, 'PATH': os.getenv('PATH')}
            )

            if result_code != 0:
                raise TaskError(
                    'creating cython library failed',
                    exit_code=result_code,
                    failed_targets=[target]
                )

            library_source_path = os.path.join(
                sources_pex_builder.path(),
                os.path.dirname(setup_py_path),
                target.output
            )

            library_output = os.path.join(results_dir, target.output)
            safe_mkdir_for(library_output)
            shutil.move(library_source_path, library_output)

            self.context.log.info(
                'created library {}'.format(os.path.relpath(library_output, get_buildroot()))
            )
コード例 #4
0
    def execute(self):
        binary = self.require_single_root_target()
        if isinstance(binary, PythonBinary):
            # We can't throw if binary isn't a PythonBinary, because perhaps we were called on a
            # jvm_binary, in which case we have to no-op and let jvm_run do its thing.
            # TODO(benjy): Some more elegant way to coordinate how tasks claim targets.
            interpreter = self.select_interpreter_for_targets(
                self.context.targets())
            with self.temporary_pex_builder(
                    interpreter=interpreter,
                    pex_info=binary.pexinfo) as builder:
                chroot = PythonChroot(targets=[binary],
                                      builder=builder,
                                      platforms=binary.platforms,
                                      interpreter=interpreter,
                                      conn_timeout=self.conn_timeout)

                chroot.dump()
                builder.freeze()
                pex = PEX(builder.path(), interpreter=interpreter)
                self.context.lock.release()
                with self.context.new_workunit(name='run',
                                               labels=[WorkUnit.RUN]):
                    po = pex.run(blocking=False)
                    try:
                        return po.wait()
                    except KeyboardInterrupt:
                        po.send_signal(signal.SIGINT)
                        raise
コード例 #5
0
def main():
    parser = configure_clp()
    options, args = parser.parse_args()

    with TraceLogger.env_override(PEX_VERBOSE=options.verbosity):

        pex_builder = build_pex(args, options)

        if options.pex_name is not None:
            log('Saving PEX file to %s' % options.pex_name,
                v=options.verbosity)
            tmp_name = options.pex_name + '~'
            safe_delete(tmp_name)
            pex_builder.build(tmp_name)
            os.rename(tmp_name, options.pex_name)
            return 0

        if options.platform != Platform.current():
            log('WARNING: attempting to run PEX with differing platform!')

        pex_builder.freeze()

        log('Running PEX file at %s with args %s' % (pex_builder.path(), args),
            v=options.verbosity)
        pex = PEX(pex_builder.path(), interpreter=pex_builder.interpreter)
        return pex.run(args=list(args))
コード例 #6
0
ファイル: pex.py プロジェクト: 10fish/heron
def main():
  parser, resolver_options_builder = configure_clp()

  # split arguments early because optparse is dumb
  args = sys.argv[1:]
  try:
    separator = args.index('--')
    args, cmdline = args[:separator], args[separator + 1:]
  except ValueError:
    args, cmdline = args, []

  options, reqs = parser.parse_args(args=args)

  with ENV.patch(PEX_VERBOSE=str(options.verbosity)):
    with TRACER.timed('Building pex'):
      pex_builder = build_pex(reqs, options, resolver_options_builder)

    if options.pex_name is not None:
      log('Saving PEX file to %s' % options.pex_name, v=options.verbosity)
      tmp_name = options.pex_name + '~'
      safe_delete(tmp_name)
      pex_builder.build(tmp_name)
      os.rename(tmp_name, options.pex_name)
      return 0

    if options.platform != Platform.current():
      log('WARNING: attempting to run PEX with differing platform!')

    pex_builder.freeze()

    log('Running PEX file at %s with args %s' % (pex_builder.path(), cmdline), v=options.verbosity)
    pex = PEX(pex_builder.path(), interpreter=pex_builder.interpreter)
    sys.exit(pex.run(args=list(cmdline)))
コード例 #7
0
ファイル: pex.py プロジェクト: kamilchm/pex
def main():
  parser = configure_clp()
  options, args = parser.parse_args()
  verbosity = 5 if options.verbosity else -1

  with Tracer.env_override(PEX_VERBOSE=verbosity, PEX_HTTP=verbosity):

    pex_builder = build_pex(args, options)

    if options.pex_name is not None:
      log('Saving PEX file to %s' % options.pex_name, v=options.verbosity)
      tmp_name = options.pex_name + '~'
      safe_delete(tmp_name)
      pex_builder.build(tmp_name)
      os.rename(tmp_name, options.pex_name)
      return 0

    if options.platform != Platform.current():
      log('WARNING: attempting to run PEX with differing platform!')

    pex_builder.freeze()

    log('Running PEX file at %s with args %s' % (pex_builder.path(), args), v=options.verbosity)
    pex = PEX(pex_builder.path(), interpreter=pex_builder.interpreter)
    return pex.run(args=list(args))
コード例 #8
0
ファイル: python_repl.py プロジェクト: MathewJennings/pants
  def execute(self, **pex_run_kwargs):
    (accept_predicate, reject_predicate) = Target.lang_discriminator('python')
    targets = self.require_homogeneous_targets(accept_predicate, reject_predicate)
    if targets:
      # We can't throw if the target isn't a python target, because perhaps we were called on a
      # JVM target, in which case we have to no-op and let scala repl do its thing.
      # TODO(benjy): Some more elegant way to coordinate how tasks claim targets.
      interpreter = self.select_interpreter_for_targets(targets)

      extra_requirements = []
      if self.get_options().ipython:
        entry_point = self.get_options().ipython_entry_point
        for req in self.get_options().ipython_requirements:
          extra_requirements.append(PythonRequirement(req))
      else:
        entry_point = 'code:interact'

      with self.temporary_chroot(interpreter=interpreter, targets=targets,
                                 extra_requirements=extra_requirements,
                                 pre_freeze=lambda ch: ch.builder.set_entry_point(entry_point)) as chroot:
        pex = PEX(chroot.builder.path(), interpreter=interpreter)
        self.context.release_lock()
        with stty_utils.preserve_stty_settings():
          with self.context.new_workunit(name='run', labels=[WorkUnit.RUN]):
            po = pex.run(blocking=False, **pex_run_kwargs)
            try:
              return po.wait()
            except KeyboardInterrupt:
              pass
コード例 #9
0
ファイル: python_run.py プロジェクト: Yasumoto/pants
  def execute(self):
    binary = self.require_single_root_target()
    if isinstance(binary, PythonBinary):
      # We can't throw if binary isn't a PythonBinary, because perhaps we were called on a
      # jvm_binary, in which case we have to no-op and let jvm_run do its thing.
      # TODO(benjy): Some more elegant way to coordinate how tasks claim targets.
      interpreter = self.select_interpreter_for_targets(self.context.targets())
      with self.temporary_pex_builder(interpreter=interpreter, pex_info=binary.pexinfo) as builder:
        chroot = PythonChroot(
          targets=[binary],
          builder=builder,
          platforms=binary.platforms,
          interpreter=interpreter,
          conn_timeout=self.conn_timeout)

        chroot.dump()
        builder.freeze()
        pex = PEX(builder.path(), interpreter=interpreter)
        self.context.lock.release()
        with self.context.new_workunit(name='run', labels=[WorkUnit.RUN]):
          po = pex.run(blocking=False)
          try:
            return po.wait()
          except KeyboardInterrupt:
            po.send_signal(signal.SIGINT)
            raise
コード例 #10
0
ファイル: python_run.py プロジェクト: MathewJennings/pants
 def execute(self):
   binary = self.require_single_root_target()
   if isinstance(binary, PythonBinary):
     # We can't throw if binary isn't a PythonBinary, because perhaps we were called on a
     # jvm_binary, in which case we have to no-op and let jvm_run do its thing.
     # TODO(benjy): Some more elegant way to coordinate how tasks claim targets.
     interpreter = self.select_interpreter_for_targets(self.context.targets())
     with self.temporary_chroot(interpreter=interpreter, pex_info=binary.pexinfo, targets=[binary], platforms=binary.platforms) as chroot:
       pex = PEX(chroot.builder.path(), interpreter=interpreter)
       self.context.release_lock()
       with self.context.new_workunit(name='run', labels=[WorkUnit.RUN]):
         args = []
         for arg in self.get_options().args:
           args.extend(safe_shlex_split(arg))
         args += self.get_passthru_args()
         po = pex.run(blocking=False, args=args)
         try:
           result = po.wait()
           if result != 0:
             msg = '{interpreter} {entry_point} {args} ... exited non-zero ({code})'.format(
                       interpreter=interpreter.binary,
                       entry_point=binary.entry_point,
                       args=' '.join(args),
                       code=result)
             raise TaskError(msg, exit_code=result)
         except KeyboardInterrupt:
           po.send_signal(signal.SIGINT)
           raise
コード例 #11
0
ファイル: python_run.py プロジェクト: digideskio/pants
  def execute(self):
    binary = self.require_single_root_target()
    if isinstance(binary, PythonBinary):
      # We can't throw if binary isn't a PythonBinary, because perhaps we were called on a
      # jvm_binary, in which case we have to no-op and let jvm_run do its thing.
      # TODO(benjy): Some more elegant way to coordinate how tasks claim targets.
      interpreter = self.select_interpreter_for_targets(self.context.targets())
      with self.temporary_pex_builder(interpreter=interpreter, pex_info=binary.pexinfo) as builder:
        chroot = PythonChroot(
          targets=[binary],
          builder=builder,
          platforms=binary.platforms,
          interpreter=interpreter,
          conn_timeout=self.conn_timeout)

        chroot.dump()
        builder.freeze()
        pex = PEX(builder.path(), interpreter=interpreter)
        self.context.release_lock()
        with self.context.new_workunit(name='run', labels=[WorkUnit.RUN]):
          args = self.get_options().args + self.get_passthru_args()
          po = pex.run(blocking=False, args=args)
          try:
            result = po.wait()
            if result != 0:
              raise TaskError('python {args} ... exited non-zero ({code})' %
                              dict(args=args, code=result),
                              exit_code=result)
          except KeyboardInterrupt:
            po.send_signal(signal.SIGINT)
            raise
コード例 #12
0
ファイル: python_run.py プロジェクト: mccoysg/pants
    def execute(self):
        binary = self.require_single_root_target()
        if isinstance(binary, PythonBinary):
            # We can't throw if binary isn't a PythonBinary, because perhaps we were called on a
            # jvm_binary, in which case we have to no-op and let jvm_run do its thing.
            # TODO(benjy): Some more elegant way to coordinate how tasks claim targets.
            interpreter = self.select_interpreter_for_targets(
                self.context.targets())
            with self.temporary_pex_builder(
                    interpreter=interpreter,
                    pex_info=binary.pexinfo) as builder:
                chroot = PythonChroot(targets=[binary],
                                      builder=builder,
                                      platforms=binary.platforms,
                                      interpreter=interpreter)

                chroot.dump()
                builder.freeze()
                pex = PEX(builder.path(), interpreter=interpreter)
                self.context.release_lock()
                with self.context.new_workunit(name='run',
                                               labels=[WorkUnit.RUN]):
                    args = self.get_options().args + self.get_passthru_args()
                    po = pex.run(blocking=False, args=args)
                    try:
                        result = po.wait()
                        if result != 0:
                            raise TaskError(
                                'python {args} ... exited non-zero ({code})' %
                                dict(args=args, code=result),
                                exit_code=result)
                    except KeyboardInterrupt:
                        po.send_signal(signal.SIGINT)
                        raise
コード例 #13
0
ファイル: pip.py プロジェクト: slyphon/pex
    def _spawn_pip_isolated(self, args, cache=None, interpreter=None):
        pip_args = [
            '--disable-pip-version-check', '--isolated', '--exists-action', 'i'
        ]

        # The max pip verbosity is -vvv and for pex it's -vvvvvvvvv; so we scale down by a factor of 3.
        pex_verbosity = ENV.PEX_VERBOSE
        pip_verbosity = pex_verbosity // 3
        if pip_verbosity > 0:
            pip_args.append('-{}'.format('v' * pip_verbosity))
        else:
            pip_args.append('-q')

        if cache:
            pip_args.extend(['--cache-dir', cache])
        else:
            pip_args.append('--no-cache-dir')

        command = pip_args + args
        with ENV.strip().patch(PEX_ROOT=ENV.PEX_ROOT,
                               PEX_VERBOSE=str(pex_verbosity)) as env:
            from pex.pex import PEX
            pip = PEX(pex=self._pip_pex_path, interpreter=interpreter)
            return Job(command=pip.cmdline(command),
                       process=pip.run(args=command, env=env, blocking=False))
コード例 #14
0
class PythonToolInstance(object):
  def __init__(self, pex_path, interpreter):
    self._pex = PEX(pex_path, interpreter=interpreter)
    self._interpreter = interpreter

  @property
  def pex(self):
    return self._pex

  @property
  def interpreter(self):
    return self._interpreter

  def _pretty_cmdline(self, args):
    return safe_shlex_join(self._pex.cmdline(args))

  def output(self, args, stdin_payload=None, binary_mode=False, **kwargs):
    process = self._pex.run(args,
                            stdout=subprocess.PIPE,
                            stderr=subprocess.PIPE,
                            with_chroot=False,
                            blocking=False,
                            **kwargs)
    if stdin_payload is not None:
      stdin_payload = ensure_binary(stdin_payload)
    (stdout, stderr) = process.communicate(input=stdin_payload)
    if not binary_mode:
      stdout = stdout.decode('utf-8')
      stderr = stderr.decode('utf-8')
    return (stdout, stderr, process.returncode, self._pretty_cmdline(args))

  @contextmanager
  def run_with(self, workunit_factory, args, **kwargs):
    cmdline = self._pretty_cmdline(args)
    with workunit_factory(cmd=cmdline) as workunit:
      exit_code = self._pex.run(args,
                                stdout=workunit.output('stdout'),
                                stderr=workunit.output('stderr'),
                                with_chroot=False,
                                blocking=True,
                                **kwargs)
      yield cmdline, exit_code, workunit

  def run(self, *args, **kwargs):
    with self.run_with(*args, **kwargs) as (cmdline, exit_code, _):
      return cmdline, exit_code
コード例 #15
0
def test_osx_platform_intel_issue_523():
    def bad_interpreter(include_site_extras=True):
        return PythonInterpreter.from_binary(
            _KNOWN_BAD_APPLE_INTERPRETER,
            include_site_extras=include_site_extras)

    interpreter = bad_interpreter(include_site_extras=False)
    with temporary_dir() as cache:
        # We need to run the bad interpreter with a modern, non-Apple-Extras setuptools in order to
        # successfully install psutil.
        for requirement in (SETUPTOOLS_REQUIREMENT, WHEEL_REQUIREMENT):
            for resolved_dist in resolver.resolve(
                [requirement],
                    cache=cache,
                    # We can't use wheels since we're bootstrapping them.
                    precedence=(SourcePackage, EggPackage),
                    interpreter=interpreter):
                dist = resolved_dist.distribution
                interpreter = interpreter.with_extra(dist.key, dist.version,
                                                     dist.location)

        with nested(
                yield_pex_builder(installer_impl=WheelInstaller,
                                  interpreter=interpreter),
                temporary_filename()) as (pb, pex_file):
            for resolved_dist in resolver.resolve(['psutil==5.4.3'],
                                                  cache=cache,
                                                  precedence=(SourcePackage,
                                                              WheelPackage),
                                                  interpreter=interpreter):
                pb.add_dist_location(resolved_dist.distribution.location)
            pb.build(pex_file)

            # NB: We want PEX to find the bare bad interpreter at runtime.
            pex = PEX(pex_file, interpreter=bad_interpreter())
            args = [
                '-c',
                'import pkg_resources; print(pkg_resources.get_supported_platform())'
            ]
            env = os.environ.copy()
            env['PEX_VERBOSE'] = '1'
            process = pex.run(args=args,
                              env=env,
                              blocking=False,
                              stdout=subprocess.PIPE,
                              stderr=subprocess.PIPE)
            stdout, stderr = process.communicate()
            assert 0 == process.returncode, (
                'Process failed with exit code {} and stderr:\n{}'.format(
                    process.returncode, stderr))

            # Verify this all worked under the previously problematic pkg_resources-reported platform.
            release, _, _ = platform.mac_ver()
            major_minor = '.'.join(release.split('.')[:2])
            assert to_bytes(
                'macosx-{}-intel'.format(major_minor)) == stdout.strip()
コード例 #16
0
ファイル: py.py プロジェクト: rgbenson/pants
  def execute(self):
    if self.old_options.pex and self.old_options.ipython:
      self.error('Cannot specify both --pex and --ipython!')

    if self.old_options.entry_point and self.old_options.ipython:
      self.error('Cannot specify both --entry_point and --ipython!')

    if self.old_options.verbose:
      print('Build operating on targets: %s' % ' '.join(str(target) for target in self.targets))


    builder = PEXBuilder(tempfile.mkdtemp(), interpreter=self.interpreter,
                         pex_info=self.binary.pexinfo if self.binary else None)

    if self.old_options.entry_point:
      builder.set_entry_point(self.old_options.entry_point)

    if self.old_options.ipython:
      if not self.config.has_section('python-ipython'):
        self.error('No python-ipython sections defined in your pants.ini!')

      builder.info.entry_point = self.config.get('python-ipython', 'entry_point')
      if builder.info.entry_point is None:
        self.error('Must specify entry_point for IPython in the python-ipython section '
                   'of your pants.ini!')

      requirements = self.config.getlist('python-ipython', 'requirements', default=[])

      for requirement in requirements:
        self.extra_requirements.append(PythonRequirement(requirement))

    executor = PythonChroot(
        targets=self.targets,
        extra_requirements=self.extra_requirements,
        builder=builder,
        platforms=self.binary.platforms if self.binary else None,
        interpreter=self.interpreter,
        conn_timeout=self.old_options.conn_timeout)

    executor.dump()

    if self.old_options.pex:
      pex_name = self.binary.name if self.binary else Target.maybe_readable_identify(self.targets)
      pex_path = os.path.join(self.root_dir, 'dist', '%s.pex' % pex_name)
      builder.build(pex_path)
      print('Wrote %s' % pex_path)
      return 0
    else:
      builder.freeze()
      pex = PEX(builder.path(), interpreter=self.interpreter)
      po = pex.run(args=list(self.args), blocking=False)
      try:
        return po.wait()
      except KeyboardInterrupt:
        po.send_signal(signal.SIGINT)
        raise
コード例 #17
0
ファイル: testing.py プロジェクト: tdyas/pex
def run_simple_pex(pex, args=(), interpreter=None, stdin=None, **kwargs):
  p = PEX(pex, interpreter=interpreter)
  process = p.run(args=args,
                  blocking=False,
                  stdin=subprocess.PIPE,
                  stdout=subprocess.PIPE,
                  stderr=subprocess.STDOUT,
                  **kwargs)
  stdout, _ = process.communicate(input=stdin)
  return stdout.replace(b'\r', b''), process.returncode
コード例 #18
0
def main(args=None):
    args = args[:] if args else sys.argv[1:]
    args = [transform_legacy_arg(arg) for arg in args]
    parser = configure_clp()

    try:
        separator = args.index('--')
        args, cmdline = args[:separator], args[separator + 1:]
    except ValueError:
        args, cmdline = args, []

    options, reqs = parser.parse_args(args=args)
    if options.python and options.interpreter_constraint:
        die('The "--python" and "--interpreter-constraint" options cannot be used together.'
            )

    with ENV.patch(PEX_VERBOSE=str(options.verbosity),
                   PEX_ROOT=options.pex_root) as patched_env:

        # Don't alter cache if it is disabled.
        if options.cache_dir:
            options.cache_dir = make_relative_to_root(options.cache_dir)

        with TRACER.timed('Building pex'):
            pex_builder = build_pex(reqs, options)

        pex_builder.freeze(bytecode_compile=options.compile)
        pex = PEX(pex_builder.path(),
                  interpreter=pex_builder.interpreter,
                  verify_entry_point=options.validate_ep)

        if options.pex_name is not None:
            log('Saving PEX file to %s' % options.pex_name,
                V=options.verbosity)
            tmp_name = options.pex_name + '~'
            safe_delete(tmp_name)
            pex_builder.build(
                tmp_name,
                bytecode_compile=options.compile,
                deterministic_timestamp=not options.use_system_time)
            os.rename(tmp_name, options.pex_name)
        else:
            if not _compatible_with_current_platform(options.platforms):
                log('WARNING: attempting to run PEX with incompatible platforms!',
                    V=1)
                log('Running on platform {} but built for {}'.format(
                    Platform.current(), ', '.join(map(str,
                                                      options.platforms))),
                    V=1)

            log('Running PEX file at %s with args %s' %
                (pex_builder.path(), cmdline),
                V=options.verbosity)
            sys.exit(pex.run(args=list(cmdline), env=patched_env))
コード例 #19
0
ファイル: testing.py プロジェクト: jsirois/pex
def run_simple_pex(pex, args=(), interpreter=None, stdin=None, **kwargs):
  p = PEX(pex, interpreter=interpreter)
  process = p.run(args=args,
                  blocking=False,
                  stdin=subprocess.PIPE,
                  stdout=subprocess.PIPE,
                  stderr=subprocess.STDOUT,
                  **kwargs)
  stdout, _ = process.communicate(input=stdin)
  print(stdout.decode('utf-8') if PY3 else stdout)
  return stdout.replace(b'\r', b''), process.returncode
コード例 #20
0
def main(args=None):
    args = args[:] if args else sys.argv[1:]
    args = [transform_legacy_arg(arg) for arg in args]
    parser, resolver_options_builder = configure_clp()

    try:
        separator = args.index('--')
        args, cmdline = args[:separator], args[separator + 1:]
    except ValueError:
        args, cmdline = args, []

    options, reqs = parser.parse_args(args=args)
    if options.python and options.interpreter_constraint:
        die('The "--python" and "--interpreter-constraint" options cannot be used together.'
            )

    if options.pex_root:
        ENV.set('PEX_ROOT', options.pex_root)
    else:
        options.pex_root = ENV.PEX_ROOT  # If option not specified fallback to env variable.

    # Don't alter cache if it is disabled.
    if options.cache_dir:
        options.cache_dir = make_relative_to_root(options.cache_dir)
    options.interpreter_cache_dir = make_relative_to_root(
        options.interpreter_cache_dir)

    with ENV.patch(PEX_VERBOSE=str(options.verbosity)):
        with TRACER.timed('Building pex'):
            pex_builder = build_pex(reqs, options, resolver_options_builder)

        pex_builder.freeze()
        pex = PEX(pex_builder.path(),
                  interpreter=pex_builder.interpreter,
                  verify_entry_point=options.validate_ep)

        if options.pex_name is not None:
            log('Saving PEX file to %s' % options.pex_name,
                v=options.verbosity)
            tmp_name = options.pex_name + '~'
            safe_delete(tmp_name)
            pex_builder.build(tmp_name)
            os.rename(tmp_name, options.pex_name)
        else:
            if not _compatible_with_current_platform(options.platforms):
                log('WARNING: attempting to run PEX with incompatible platforms!'
                    )

            log('Running PEX file at %s with args %s' %
                (pex_builder.path(), cmdline),
                v=options.verbosity)
            sys.exit(pex.run(args=list(cmdline)))
コード例 #21
0
ファイル: mypy_task.py プロジェクト: lgirault/pants
  def _run_mypy(self, py3_interpreter, mypy_args, **kwargs):
    pex_info = PexInfo.default()
    pex_info.entry_point = 'mypy'
    mypy_version = self.get_options().mypy_version

    mypy_requirement_pex = self.resolve_requirement_strings(
      py3_interpreter, ['mypy=={}'.format(mypy_version)])

    path = os.path.realpath(os.path.join(self.workdir, str(py3_interpreter.identity), mypy_version))
    if not os.path.isdir(path):
      self.merge_pexes(path, pex_info, py3_interpreter, [mypy_requirement_pex])
    pex = PEX(path, py3_interpreter)
    return pex.run(mypy_args, **kwargs)
コード例 #22
0
ファイル: mypy_task.py プロジェクト: cosmicexplorer/pants
  def _run_mypy(self, py3_interpreter, mypy_args, **kwargs):
    pex_info = PexInfo.default()
    pex_info.entry_point = 'mypy'
    mypy_version = self.get_options().mypy_version

    mypy_requirement_pex = self.resolve_requirement_strings(
      py3_interpreter, ['mypy=={}'.format(mypy_version)])

    path = os.path.realpath(os.path.join(self.workdir, str(py3_interpreter.identity), mypy_version))
    if not os.path.isdir(path):
      self.merge_pexes(path, pex_info, py3_interpreter, [mypy_requirement_pex])
    pex = PEX(path, py3_interpreter)
    return pex.run(mypy_args, **kwargs)
コード例 #23
0
class PythonToolInstance(object):
    def __init__(self, pex_path, interpreter):
        self._pex = PEX(pex_path, interpreter=interpreter)

    def run(self, workunit_factory, args, **kwargs):
        cmdline = ' '.join(self._pex.cmdline(args))
        with workunit_factory(cmd=cmdline) as workunit:
            exit_code = self._pex.run(args,
                                      stdout=workunit.output('stdout'),
                                      stderr=workunit.output('stderr'),
                                      with_chroot=False,
                                      blocking=True,
                                      **kwargs)
            return cmdline, exit_code
コード例 #24
0
ファイル: python_run.py プロジェクト: Xaelias/pants
    def execute(self):
        binary = self.require_single_root_target()
        if isinstance(binary, PythonBinary):
            # We can't throw if binary isn't a PythonBinary, because perhaps we were called on a
            # jvm_binary, in which case we have to no-op and let jvm_run do its thing.
            # TODO(benjy): Use MutexTask to coordinate this.
            interpreter = self.context.products.get_data(PythonInterpreter)

            with temporary_dir() as tmpdir:
                # Create a wrapper pex to "merge" the other pexes into via PEX_PATH.
                builder = PEXBuilder(tmpdir,
                                     interpreter,
                                     pex_info=binary.pexinfo)
                builder.freeze()

                pexes = [
                    self.context.products.get_data(
                        ResolveRequirements.REQUIREMENTS_PEX),
                    self.context.products.get_data(
                        GatherSources.PYTHON_SOURCES)
                ]

                # TODO: Expose the path as a property in pex, instead of relying on
                # fishing it out of the cmdline.
                pex_path = os.pathsep.join([pex.cmdline()[1] for pex in pexes])

                pex = PEX(tmpdir, interpreter)

                self.context.release_lock()
                with self.context.new_workunit(name='run',
                                               labels=[WorkUnitLabel.RUN]):
                    args = []
                    for arg in self.get_options().args:
                        args.extend(safe_shlex_split(arg))
                    args += self.get_passthru_args()
                    po = pex.run(blocking=False,
                                 args=args,
                                 env={'PEX_PATH': pex_path})
                    try:
                        result = po.wait()
                        if result != 0:
                            msg = '{interpreter} {entry_point} {args} ... exited non-zero ({code})'.format(
                                interpreter=interpreter.binary,
                                entry_point=binary.entry_point,
                                args=' '.join(args),
                                code=result)
                            raise TaskError(msg, exit_code=result)
                    except KeyboardInterrupt:
                        po.send_signal(signal.SIGINT)
                        raise
コード例 #25
0
ファイル: pex.py プロジェクト: jsirois/pex
def main(args=None):
  args = args[:] if args else sys.argv[1:]
  args = [transform_legacy_arg(arg) for arg in args]
  parser, resolver_options_builder = configure_clp()

  try:
    separator = args.index('--')
    args, cmdline = args[:separator], args[separator + 1:]
  except ValueError:
    args, cmdline = args, []

  options, reqs = parser.parse_args(args=args)
  if options.python and options.interpreter_constraint:
    die('The "--python" and "--interpreter-constraint" options cannot be used together.')

  if options.pex_root:
    ENV.set('PEX_ROOT', options.pex_root)
  else:
    options.pex_root = ENV.PEX_ROOT  # If option not specified fallback to env variable.

  # Don't alter cache if it is disabled.
  if options.cache_dir:
    options.cache_dir = make_relative_to_root(options.cache_dir)

  with ENV.patch(PEX_VERBOSE=str(options.verbosity)):
    with TRACER.timed('Building pex'):
      pex_builder = build_pex(reqs, options, resolver_options_builder)

    pex_builder.freeze(bytecode_compile=options.compile)
    pex = PEX(pex_builder.path(),
              interpreter=pex_builder.interpreter,
              verify_entry_point=options.validate_ep)

    if options.pex_name is not None:
      log('Saving PEX file to %s' % options.pex_name, V=options.verbosity)
      tmp_name = options.pex_name + '~'
      safe_delete(tmp_name)
      pex_builder.build(
        tmp_name,
        bytecode_compile=options.compile,
        deterministic_timestamp=not options.use_system_time
      )
      os.rename(tmp_name, options.pex_name)
    else:
      if not _compatible_with_current_platform(options.platforms):
        log('WARNING: attempting to run PEX with incompatible platforms!')

      log('Running PEX file at %s with args %s' % (pex_builder.path(), cmdline),
          V=options.verbosity)
      sys.exit(pex.run(args=list(cmdline)))
コード例 #26
0
ファイル: python_repl.py プロジェクト: sheltowt/pants
    def execute(self):
        (accept_predicate,
         reject_predicate) = Target.lang_discriminator('python')
        targets = self.require_homogeneous_targets(accept_predicate,
                                                   reject_predicate)
        if targets:
            # We can't throw if the target isn't a python target, because perhaps we were called on a
            # JVM target, in which case we have to no-op and let scala repl do its thing.
            # TODO(benjy): Some more elegant way to coordinate how tasks claim targets.
            interpreter = self.select_interpreter_for_targets(targets)

            extra_requirements = []
            if self.context.options.python_repl_ipython:
                entry_point = self.context.config.get(
                    'python-ipython',
                    'entry_point',
                    default='IPython:start_ipython')
                ipython_requirements = self.context.config.getlist(
                    'python-ipython',
                    'requirements',
                    default=['ipython==1.0.0'])
                for req in ipython_requirements:
                    extra_requirements.append(PythonRequirement(req))
            else:
                entry_point = 'code:interact'

            with self.temporary_pex_builder(
                    interpreter=interpreter) as builder:
                builder.set_entry_point(entry_point)
                chroot = PythonChroot(targets=targets,
                                      extra_requirements=extra_requirements,
                                      builder=builder,
                                      interpreter=interpreter,
                                      conn_timeout=self.conn_timeout)

                chroot.dump()
                builder.freeze()
                pex = PEX(builder.path(), interpreter=interpreter)
                self.context.lock.release()
                with stty_utils.preserve_stty_settings():
                    with self.context.new_workunit(name='run',
                                                   labels=[WorkUnit.RUN]):
                        po = pex.run(blocking=False)
                        try:
                            return po.wait()
                        except KeyboardInterrupt:
                            pass
コード例 #27
0
    def _spawn_pip_isolated(self, args, cache=None, interpreter=None):
        pip_args = [
            # We vendor the version of pip we want so pip should never check for updates.
            "--disable-pip-version-check",
            # Don't read pip configuration files like `~/.config/pip/pip.conf`.
            "--isolated",
            # If we want to warn about a version of python we support, we should do it, not pip.
            "--no-python-version-warning",
            # If pip encounters a duplicate file path during its operations we don't want it to prompt
            # and we'd also like to know about this since it should never occur. We leverage the pip
            # global option:
            # --exists-action <action>
            #   Default action when a path already exists: (s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort.
            "--exists-action",
            "a",
        ]

        # The max pip verbosity is -vvv and for pex it's -vvvvvvvvv; so we scale down by a factor of 3.
        pex_verbosity = ENV.PEX_VERBOSE
        pip_verbosity = pex_verbosity // 3
        if pip_verbosity > 0:
            pip_args.append("-{}".format("v" * pip_verbosity))
        else:
            pip_args.append("-q")

        if cache:
            pip_args.extend(["--cache-dir", cache])
        else:
            pip_args.append("--no-cache-dir")

        command = pip_args + args
        with ENV.strip().patch(PEX_ROOT=cache or ENV.PEX_ROOT,
                               PEX_VERBOSE=str(pex_verbosity)) as env:
            # Guard against API calls from environment with ambient PYTHONPATH preventing pip PEX
            # bootstrapping. See: https://github.com/pantsbuild/pex/issues/892
            pythonpath = env.pop("PYTHONPATH", None)
            if pythonpath:
                TRACER.log(
                    "Scrubbed PYTHONPATH={} from the pip PEX environment.".
                    format(pythonpath),
                    V=3)

            from pex.pex import PEX

            pip = PEX(pex=self._pip_pex_path, interpreter=interpreter)
            return Job(command=pip.cmdline(command),
                       process=pip.run(args=command, env=env, blocking=False))
コード例 #28
0
def run_simple_pex(
        pex,  # type: str
        args=(),  # type: Iterable[str]
        interpreter=None,  # type: Optional[PythonInterpreter]
        stdin=None,  # type: Optional[bytes]
        **kwargs  # type: Any
):
    # type: (...) -> Tuple[bytes, int]
    p = PEX(pex, interpreter=interpreter)
    process = p.run(args=args,
                    blocking=False,
                    stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT,
                    **kwargs)
    stdout, _ = process.communicate(input=stdin)
    return stdout.replace(b"\r", b""), process.returncode
コード例 #29
0
ファイル: pex.py プロジェクト: t-cas/pex
def main(args=None):
    args = args or sys.argv[1:]
    parser, resolver_options_builder = configure_clp()

    try:
        separator = args.index('--')
        args, cmdline = args[:separator], args[separator + 1:]
    except ValueError:
        args, cmdline = args, []

    options, reqs = parser.parse_args(args=args)
    if options.pex_root:
        ENV.set('PEX_ROOT', options.pex_root)
    else:
        options.pex_root = ENV.PEX_ROOT  # If option not specified fallback to env variable.

    # Don't alter cache if it is disabled.
    if options.cache_dir:
        options.cache_dir = make_relative_to_root(options.cache_dir)
    options.interpreter_cache_dir = make_relative_to_root(
        options.interpreter_cache_dir)

    with ENV.patch(PEX_VERBOSE=str(options.verbosity)):
        with TRACER.timed('Building pex'):
            pex_builder = build_pex(reqs, options, resolver_options_builder)

        if options.pex_name is not None:
            log('Saving PEX file to %s' % options.pex_name,
                v=options.verbosity)
            tmp_name = options.pex_name + '~'
            safe_delete(tmp_name)
            pex_builder.build(tmp_name)
            os.rename(tmp_name, options.pex_name)
            return 0

        if options.platform and Platform.current() not in options.platform:
            log('WARNING: attempting to run PEX with incompatible platforms!')

        pex_builder.freeze()

        log('Running PEX file at %s with args %s' %
            (pex_builder.path(), cmdline),
            v=options.verbosity)
        pex = PEX(pex_builder.path(), interpreter=pex_builder.interpreter)
        sys.exit(pex.run(args=list(cmdline)))
コード例 #30
0
    def execute(self):
        binary = self.require_single_root_target()
        if isinstance(binary, PythonBinary):
            # We can't throw if binary isn't a PythonBinary, because perhaps we were called on a
            # jvm_binary, in which case we have to no-op and let jvm_run do its thing.
            # TODO(benjy): Use MutexTask to coordinate this.
            interpreter = self.context.products.get_data(PythonInterpreter)

            with temporary_dir() as tmpdir:
                # Create a wrapper pex to "merge" the other pexes into via PEX_PATH.
                builder = PEXBuilder(tmpdir, interpreter, pex_info=binary.pexinfo)
                builder.freeze()

                pexes = [
                    self.context.products.get_data(ResolveRequirements.REQUIREMENTS_PEX),
                    self.context.products.get_data(GatherSources.PYTHON_SOURCES),
                ]

                # TODO: Expose the path as a property in pex, instead of relying on
                # fishing it out of the cmdline.
                pex_path = os.pathsep.join([pex.cmdline()[1] for pex in pexes])

                pex = PEX(tmpdir, interpreter)

                self.context.release_lock()
                with self.context.new_workunit(name="run", labels=[WorkUnitLabel.RUN]):
                    args = []
                    for arg in self.get_options().args:
                        args.extend(safe_shlex_split(arg))
                    args += self.get_passthru_args()
                    po = pex.run(blocking=False, args=args, env={"PEX_PATH": pex_path})
                    try:
                        result = po.wait()
                        if result != 0:
                            msg = "{interpreter} {entry_point} {args} ... exited non-zero ({code})".format(
                                interpreter=interpreter.binary,
                                entry_point=binary.entry_point,
                                args=" ".join(args),
                                code=result,
                            )
                            raise TaskError(msg, exit_code=result)
                    except KeyboardInterrupt:
                        po.send_signal(signal.SIGINT)
                        raise
コード例 #31
0
    def _run_python_tests(self, targets, stdout, stderr):
        coverage_rc = None
        coverage_enabled = 'PANTS_PY_COVERAGE' in os.environ

        try:
            builder = PEXBuilder(interpreter=self.interpreter)
            builder.info.entry_point = 'pytest'
            chroot = PythonChroot(targets=targets,
                                  extra_requirements=self._TESTING_TARGETS,
                                  builder=builder,
                                  platforms=('current', ),
                                  interpreter=self.interpreter,
                                  conn_timeout=self._conn_timeout)
            builder = chroot.dump()
            builder.freeze()
            test_args = []
            test_args.extend(PythonTestBuilder.generate_junit_args(targets))
            test_args.extend(self.args)
            if coverage_enabled:
                coverage_rc, args = self.cov_setup(targets)
                test_args.extend(args)

            sources = list(
                itertools.chain(
                    *[t.sources_relative_to_buildroot() for t in targets]))
            pex = PEX(builder.path(), interpreter=self.interpreter)
            rc = pex.run(args=test_args + sources,
                         blocking=True,
                         setsid=True,
                         stdout=stdout,
                         stderr=stderr)
            # TODO(wickman): If coverage is enabled, write an intermediate .html that points to
            # each of the coverage reports generated and webbrowser.open to that page.
            rv = PythonTestResult.rc(rc)
        except Exception:
            import traceback
            print('Failed to run test!', file=stderr)
            traceback.print_exc()
            rv = PythonTestResult.exception()
        finally:
            if coverage_rc:
                os.unlink(coverage_rc)
        return rv
コード例 #32
0
ファイル: pip.py プロジェクト: smezouar/pex
  def _spawn_pip_isolated(self, args, cache=None, interpreter=None):
    pip_args = [
      # We vendor the version of pip we want so pip should never check for updates.
      '--disable-pip-version-check',

      # Don't read pip configuration files like `~/.config/pip/pip.conf`.
      '--isolated',

      # If we want to warn about a version of python we support, we should do it, not pip.
      '--no-python-version-warning'
    ]

    # The max pip verbosity is -vvv and for pex it's -vvvvvvvvv; so we scale down by a factor of 3.
    pex_verbosity = ENV.PEX_VERBOSE
    pip_verbosity = pex_verbosity // 3
    if pip_verbosity > 0:
      pip_args.append('-{}'.format('v' * pip_verbosity))
    else:
      pip_args.append('-q')

    if cache:
      pip_args.extend(['--cache-dir', cache])
    else:
      pip_args.append('--no-cache-dir')

    command = pip_args + args
    with ENV.strip().patch(PEX_ROOT=ENV.PEX_ROOT, PEX_VERBOSE=str(pex_verbosity)) as env:
      # Guard against API calls from environment with ambient PYTHONPATH preventing pip PEX
      # bootstrapping. See: https://github.com/pantsbuild/pex/issues/892
      pythonpath = env.pop('PYTHONPATH', None)
      if pythonpath:
        TRACER.log('Scrubbed PYTHONPATH={} from the pip PEX environment.'.format(pythonpath), V=3)

      from pex.pex import PEX
      pip = PEX(pex=self._pip_pex_path, interpreter=interpreter)
      return Job(
        command=pip.cmdline(command),
        process=pip.run(
          args=command,
          env=env,
          blocking=False
        )
      )
コード例 #33
0
def test_execute_interpreter_dashm_module():
    with temporary_dir() as pex_chroot:
        pex_builder = PEXBuilder(path=pex_chroot)
        pex_builder.add_source(None, 'foo/__init__.py')
        with tempfile.NamedTemporaryFile() as fp:
            fp.write(b'import sys; print(" ".join(sys.argv))')
            fp.flush()
            pex_builder.add_source(fp.name, 'foo/bar.py')
        pex_builder.freeze()
        pex = PEX(pex_chroot)
        process = pex.run(args=['-m', 'foo.bar', 'one', 'two'],
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          blocking=False)
        stdout, stderr = process.communicate()

        assert 0 == process.returncode
        assert b'foo.bar one two\n' == stdout
        assert b'' == stderr
コード例 #34
0
ファイル: pex.py プロジェクト: Houzz/pex
def main(args=None):
  args = args or sys.argv[1:]
  parser, resolver_options_builder = configure_clp()

  try:
    separator = args.index('--')
    args, cmdline = args[:separator], args[separator + 1:]
  except ValueError:
    args, cmdline = args, []

  options, reqs = parser.parse_args(args=args)
  if options.pex_root:
    ENV.set('PEX_ROOT', options.pex_root)
  else:
    options.pex_root = ENV.PEX_ROOT  # If option not specified fallback to env variable.

  # Don't alter cache if it is disabled.
  if options.cache_dir:
    options.cache_dir = make_relative_to_root(options.cache_dir)
  options.interpreter_cache_dir = make_relative_to_root(options.interpreter_cache_dir)

  with ENV.patch(PEX_VERBOSE=str(options.verbosity)):
    with TRACER.timed('Building pex'):
      pex_builder = build_pex(reqs, options, resolver_options_builder)

    if options.pex_name is not None:
      log('Saving PEX file to %s' % options.pex_name, v=options.verbosity)
      tmp_name = options.pex_name + '~'
      safe_delete(tmp_name)
      pex_builder.build(tmp_name)
      os.rename(tmp_name, options.pex_name)
      return 0

    if options.platform != Platform.current():
      log('WARNING: attempting to run PEX with differing platform!')

    pex_builder.freeze()

    log('Running PEX file at %s with args %s' % (pex_builder.path(), cmdline), v=options.verbosity)
    pex = PEX(pex_builder.path(), interpreter=pex_builder.interpreter)
    sys.exit(pex.run(args=list(cmdline)))
コード例 #35
0
def test_pex_builder_preamble():
    # type: () -> None
    with temporary_dir() as td:
        target = os.path.join(td, "foo.pex")
        should_create = os.path.join(td, "foo.1")

        tempfile_preamble = "\n".join(
            ["import sys", "open('{0}', 'w').close()".format(should_create), "sys.exit(3)"]
        )

        pb = PEXBuilder(preamble=tempfile_preamble)
        pb.build(target)

        assert not os.path.exists(should_create)

        pex = PEX(target, interpreter=pb.interpreter)
        process = pex.run(blocking=False)
        process.wait()

        assert process.returncode == 3
        assert os.path.exists(should_create)
コード例 #36
0
ファイル: python_repl.py プロジェクト: amedina/pants
  def execute(self):
    (accept_predicate, reject_predicate) = Target.lang_discriminator('python')
    targets = self.require_homogeneous_targets(accept_predicate, reject_predicate)
    if targets:
      # We can't throw if the target isn't a python target, because perhaps we were called on a
      # JVM target, in which case we have to no-op and let scala repl do its thing.
      # TODO(benjy): Some more elegant way to coordinate how tasks claim targets.
      interpreter = self.select_interpreter_for_targets(targets)

      extra_requirements = []
      if self.get_options().ipython:
        entry_point = self.context.config.get('python-ipython', 'entry_point',
                                              default='IPython:start_ipython')
        ipython_requirements = self.context.config.getlist('python-ipython', 'requirements',
                                                           default=['ipython==1.0.0'])
        for req in ipython_requirements:
          extra_requirements.append(PythonRequirement(req))
      else:
        entry_point = 'code:interact'

      with self.temporary_pex_builder(interpreter=interpreter) as builder:
        builder.set_entry_point(entry_point)
        chroot = PythonChroot(
          targets=targets,
          extra_requirements=extra_requirements,
          builder=builder,
          interpreter=interpreter,
          conn_timeout=self.conn_timeout)

        chroot.dump()
        builder.freeze()
        pex = PEX(builder.path(), interpreter=interpreter)
        self.context.lock.release()
        with stty_utils.preserve_stty_settings():
          with self.context.new_workunit(name='run', labels=[WorkUnit.RUN]):
            po = pex.run(blocking=False)
            try:
              return po.wait()
            except KeyboardInterrupt:
              pass
コード例 #37
0
def test_execute_interpreter_dashm_module():
    # type: () -> None
    with temporary_dir() as pex_chroot:
        pex_builder = PEXBuilder(path=pex_chroot)
        pex_builder.add_source(None, "foo/__init__.py")
        with tempfile.NamedTemporaryFile() as fp:
            fp.write(b'import sys; print(" ".join(sys.argv))')
            fp.flush()
            pex_builder.add_source(fp.name, "foo/bar.py")
        pex_builder.freeze()
        pex = PEX(pex_chroot)
        process = pex.run(
            args=["-m", "foo.bar", "one", "two"],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            blocking=False,
        )
        stdout, stderr = process.communicate()

        assert 0 == process.returncode
        assert b"foo.bar one two\n" == stdout
        assert b"" == stderr
コード例 #38
0
ファイル: test_builder.py プロジェクト: jmdcal/pants
  def _run_python_tests(self, targets, stdout, stderr):
    coverage_rc = None
    coverage_enabled = 'PANTS_PY_COVERAGE' in os.environ

    try:
      builder = PEXBuilder(interpreter=self.interpreter)
      builder.info.entry_point = 'pytest'
      chroot = PythonChroot(
          targets=targets,
          extra_requirements=self._TESTING_TARGETS,
          builder=builder,
          platforms=('current',),
          interpreter=self.interpreter,
          conn_timeout=self._conn_timeout)
      builder = chroot.dump()
      builder.freeze()
      test_args = []
      test_args.extend(PythonTestBuilder.generate_junit_args(targets))
      test_args.extend(self.args)
      if coverage_enabled:
        coverage_rc, args = self.cov_setup(targets)
        test_args.extend(args)

      sources = list(itertools.chain(*[t.sources_relative_to_buildroot() for t in targets]))
      pex = PEX(builder.path(), interpreter=self.interpreter)
      rc = pex.run(args=test_args + sources, blocking=True, setsid=True,
                   stdout=stdout, stderr=stderr)
      # TODO(wickman): If coverage is enabled, write an intermediate .html that points to
      # each of the coverage reports generated and webbrowser.open to that page.
      rv = PythonTestResult.rc(rc)
    except Exception:
      import traceback
      print('Failed to run test!', file=stderr)
      traceback.print_exc()
      rv = PythonTestResult.exception()
    finally:
      if coverage_rc:
        os.unlink(coverage_rc)
    return rv
コード例 #39
0
ファイル: test_pex_builder.py プロジェクト: jsirois/pex
def test_pex_builder_preamble():
  with temporary_dir() as td:
    target = os.path.join(td, 'foo.pex')
    should_create = os.path.join(td, 'foo.1')

    tempfile_preamble = "\n".join([
      "import sys",
      "open('{0}', 'w').close()".format(should_create),
      "sys.exit(3)"
    ])

    pb = PEXBuilder(preamble=tempfile_preamble)
    pb.build(target)

    assert not os.path.exists(should_create)

    pex = PEX(target, interpreter=pb.interpreter)
    process = pex.run(blocking=False)
    process.wait()

    assert process.returncode == 3
    assert os.path.exists(should_create)
コード例 #40
0
ファイル: pex.py プロジェクト: windie/heron
def main():
    parser, resolver_options_builder = configure_clp()

    # split arguments early because optparse is dumb
    args = sys.argv[1:]
    try:
        separator = args.index('--')
        args, cmdline = args[:separator], args[separator + 1:]
    except ValueError:
        args, cmdline = args, []

    options, reqs = parser.parse_args(args=args)

    with ENV.patch(PEX_VERBOSE=str(options.verbosity)):
        with TRACER.timed('Building pex'):
            pex_builder = build_pex(reqs, options, resolver_options_builder)

        if options.pex_name is not None:
            log('Saving PEX file to %s' % options.pex_name,
                v=options.verbosity)
            tmp_name = options.pex_name + '~'
            safe_delete(tmp_name)
            pex_builder.build(tmp_name)
            os.rename(tmp_name, options.pex_name)
            return 0

        if options.platform != Platform.current():
            log('WARNING: attempting to run PEX with differing platform!')

        pex_builder.freeze()

        log('Running PEX file at %s with args %s' %
            (pex_builder.path(), cmdline),
            v=options.verbosity)
        pex = PEX(pex_builder.path(), interpreter=pex_builder.interpreter)
        sys.exit(pex.run(args=list(cmdline)))
コード例 #41
0
def main(args=None):
    args = args[:] if args else sys.argv[1:]
    args = [transform_legacy_arg(arg) for arg in args]
    parser = configure_clp()

    try:
        separator = args.index("--")
        args, cmdline = args[:separator], args[separator + 1:]
    except ValueError:
        args, cmdline = args, []

    options = parser.parse_args(args=args)

    # Ensure the TMPDIR is an absolute path (So subprocesses that change CWD can find it) and
    # that it exists.
    tmpdir = os.path.realpath(options.tmpdir)
    if not os.path.exists(tmpdir):
        die("The specified --tmpdir does not exist: {}".format(tmpdir))
    if not os.path.isdir(tmpdir):
        die("The specified --tmpdir is not a directory: {}".format(tmpdir))
    tempfile.tempdir = os.environ["TMPDIR"] = tmpdir

    if options.cache_dir:
        pex_warnings.warn(
            "The --cache-dir option is deprecated, use --pex-root instead.")
        if options.pex_root and options.cache_dir != options.pex_root:
            die("Both --cache-dir and --pex-root were passed with conflicting values. "
                "Just set --pex-root.")

    if options.disable_cache:

        def warn_ignore_pex_root(set_via):
            pex_warnings.warn(
                "The pex root has been set via {via} but --disable-cache is also set. "
                "Ignoring {via} and disabling caches.".format(via=set_via))

        if options.cache_dir:
            warn_ignore_pex_root("--cache-dir")
        elif options.pex_root:
            warn_ignore_pex_root("--pex-root")
        elif os.environ.get("PEX_ROOT"):
            warn_ignore_pex_root("PEX_ROOT")

        pex_root = safe_mkdtemp()
    else:
        pex_root = options.cache_dir or options.pex_root or ENV.PEX_ROOT

    if options.python and options.interpreter_constraint:
        die('The "--python" and "--interpreter-constraint" options cannot be used together.'
            )

    if options.pex_repository and (options.indexes or options.find_links):
        die('The "--pex-repository" option cannot be used together with the "--index" or '
            '"--find-links" options.')

    with ENV.patch(PEX_VERBOSE=str(options.verbosity),
                   PEX_ROOT=pex_root,
                   TMPDIR=tmpdir) as patched_env:
        with TRACER.timed("Building pex"):
            pex_builder = build_pex(options.requirements,
                                    options,
                                    cache=ENV.PEX_ROOT)

        pex_builder.freeze(bytecode_compile=options.compile)
        interpreter = pex_builder.interpreter
        pex = PEX(pex_builder.path(),
                  interpreter=interpreter,
                  verify_entry_point=options.validate_ep)

        if options.pex_name is not None:
            log("Saving PEX file to %s" % options.pex_name,
                V=options.verbosity)
            pex_builder.build(
                options.pex_name,
                bytecode_compile=options.compile,
                deterministic_timestamp=not options.use_system_time,
            )
            if options.seed != Seed.NONE:
                seed_info = seed_cache(options,
                                       pex,
                                       verbose=options.seed == Seed.VERBOSE)
                print(seed_info)
        else:
            if not _compatible_with_current_platform(interpreter,
                                                     options.platforms):
                log("WARNING: attempting to run PEX with incompatible platforms!",
                    V=1)
                log(
                    "Running on platform {} but built for {}".format(
                        interpreter.platform,
                        ", ".join(map(str, options.platforms))),
                    V=1,
                )

            log(
                "Running PEX file at %s with args %s" %
                (pex_builder.path(), cmdline),
                V=options.verbosity,
            )
            sys.exit(pex.run(args=list(cmdline), env=patched_env))
コード例 #42
0
ファイル: python_eval.py プロジェクト: cosmicexplorer/pants
  def _compile_target(self, vt):
    """'Compiles' a python target.

    'Compiling' means forming an isolated chroot of its sources and transitive deps and then
    attempting to import each of the target's sources in the case of a python library or else the
    entry point in the case of a python binary.

    For a library with sources lib/core.py and lib/util.py a "compiler" main file would look like:

      if __name__ == '__main__':
        import lib.core
        import lib.util

    For a binary with entry point lib.bin:main the "compiler" main file would look like:

      if __name__ == '__main__':
        from lib.bin import main

    In either case the main file is executed within the target chroot to reveal missing BUILD
    dependencies.
    """
    target = vt.target
    with self.context.new_workunit(name=target.address.spec):
      modules = self._get_modules(target)
      if not modules:
        # Nothing to eval, so a trivial compile success.
        return 0

      interpreter = self._get_interpreter_for_target_closure(target)
      reqs_pex = self._resolve_requirements_for_versioned_target_closure(interpreter, vt)
      srcs_pex = self._source_pex_for_versioned_target_closure(interpreter, vt)

      # Create the executable pex.
      exec_pex_parent = os.path.join(self.workdir, 'executable_pex')
      executable_file_content = self._get_executable_file_content(exec_pex_parent, modules)

      hasher = hashlib.sha1()
      hasher.update(reqs_pex.path().encode('utf-8'))
      hasher.update(srcs_pex.path().encode('utf-8'))
      hasher.update(executable_file_content.encode('utf-8'))
      exec_file_hash = hasher.hexdigest()
      exec_pex_path = os.path.realpath(os.path.join(exec_pex_parent, exec_file_hash))
      if not os.path.isdir(exec_pex_path):
        with safe_concurrent_creation(exec_pex_path) as safe_path:
          # Write the entry point.
          safe_mkdir(safe_path)
          with open(os.path.join(safe_path, '{}.py'.format(self._EXEC_NAME)), 'w') as outfile:
            outfile.write(executable_file_content)
          pex_info = (target.pexinfo if isinstance(target, PythonBinary) else None) or PexInfo()
          # Override any user-specified entry point, under the assumption that the
          # executable_file_content does what the user intends (including, probably, calling that
          # underlying entry point).
          pex_info.entry_point = self._EXEC_NAME
          pex_info.pex_path = ':'.join(pex.path() for pex in (reqs_pex, srcs_pex) if pex)
          builder = PEXBuilder(safe_path, interpreter, pex_info=pex_info)
          builder.freeze()

      pex = PEX(exec_pex_path, interpreter)

      with self.context.new_workunit(name='eval',
                                     labels=[WorkUnitLabel.COMPILER, WorkUnitLabel.RUN,
                                             WorkUnitLabel.TOOL],
                                     cmd=' '.join(pex.cmdline())) as workunit:
        returncode = pex.run(stdout=workunit.output('stdout'), stderr=workunit.output('stderr'))
        workunit.set_outcome(WorkUnit.SUCCESS if returncode == 0 else WorkUnit.FAILURE)
        if returncode != 0:
          self.context.log.error('Failed to eval {}'.format(target.address.spec))
        return returncode
コード例 #43
0
    def _compile_target(self, target):
        # "Compiles" a target by forming an isolated chroot of its sources and transitive deps and then
        # attempting to import each of the target's sources in the case of a python library or else the
        # entry point in the case of a python binary.
        #
        # For a library with sources lib/core.py and lib/util.py a "compiler" main file would look like:
        #
        #   if __name__ == '__main__':
        #     import lib.core
        #     import lib.util
        #
        # For a binary with entry point lib.bin:main the "compiler" main file would look like:
        #
        #   if __name__ == '__main__':
        #     from lib.bin import main
        #
        # In either case the main file is executed within the target chroot to reveal missing BUILD
        # dependencies.

        with self.context.new_workunit(name=target.address.spec):
            modules = []
            if isinstance(target, PythonBinary):
                source = 'entry_point {}'.format(target.entry_point)
                components = target.entry_point.rsplit(':', 1)
                module = components[0]
                if len(components) == 2:
                    function = components[1]
                    data = TemplateData(
                        source=source,
                        import_statement='from {} import {}'.format(
                            module, function))
                else:
                    data = TemplateData(
                        source=source,
                        import_statement='import {}'.format(module))
                modules.append(data)
            else:
                for path in target.sources_relative_to_source_root():
                    if path.endswith('.py'):
                        if os.path.basename(path) == '__init__.py':
                            module_path = os.path.dirname(path)
                        else:
                            module_path, _ = os.path.splitext(path)
                        source = 'file {}'.format(
                            os.path.join(target.target_base, path))
                        module = module_path.replace(os.path.sep, '.')
                        data = TemplateData(
                            source=source,
                            import_statement='import {}'.format(module))
                        modules.append(data)

            if not modules:
                # Nothing to eval, so a trivial compile success.
                return 0

            interpreter = self.select_interpreter_for_targets([target])

            if isinstance(target, PythonBinary):
                pexinfo, platforms = target.pexinfo, target.platforms
            else:
                pexinfo, platforms = None, None

            with self.temporary_pex_builder(interpreter=interpreter,
                                            pex_info=pexinfo) as builder:
                with self.context.new_workunit(name='resolve'):
                    chroot = PythonChroot(context=self.context,
                                          targets=[target],
                                          builder=builder,
                                          platforms=platforms,
                                          interpreter=interpreter)

                    chroot.dump()

                with temporary_file() as imports_file:
                    generator = Generator(pkgutil.get_data(
                        __name__, self._EVAL_TEMPLATE_PATH),
                                          chroot=chroot.path(),
                                          modules=modules)
                    generator.write(imports_file)
                    imports_file.close()

                    builder.set_executable(imports_file.name,
                                           '__pants_python_eval__.py')

                    builder.freeze()
                    pex = PEX(builder.path(), interpreter=interpreter)

                    with self.context.new_workunit(
                            name='eval',
                            labels=[
                                WorkUnit.COMPILER, WorkUnit.RUN, WorkUnit.TOOL
                            ],
                            cmd=' '.join(pex.cmdline())) as workunit:
                        returncode = pex.run(stdout=workunit.output('stdout'),
                                             stderr=workunit.output('stderr'))
                        workunit.set_outcome(WorkUnit.SUCCESS if returncode ==
                                             0 else WorkUnit.FAILURE)
                        if returncode != 0:
                            self.context.log.error('Failed to eval {}'.format(
                                target.address.spec))
                        return returncode
コード例 #44
0
    def _spawn_pip_isolated(
        self,
        args,  # type: Iterable[str]
        package_index_configuration=None,  # type: Optional[PackageIndexConfiguration]
        cache=None,  # type: Optional[str]
        interpreter=None,  # type: Optional[PythonInterpreter]
    ):
        # type: (...) -> Job
        pip_args = [
            # We vendor the version of pip we want so pip should never check for updates.
            "--disable-pip-version-check",
            # If we want to warn about a version of python we support, we should do it, not pip.
            "--no-python-version-warning",
            # If pip encounters a duplicate file path during its operations we don't want it to
            # prompt and we'd also like to know about this since it should never occur. We leverage
            # the pip global option:
            # --exists-action <action>
            #   Default action when a path already exists: (s)witch, (i)gnore, (w)ipe, (b)ackup,
            #   (a)bort.
            "--exists-action",
            "a",
        ]
        if not package_index_configuration or package_index_configuration.isolated:
            # Don't read PIP_ environment variables or pip configuration files like
            # `~/.config/pip/pip.conf`.
            pip_args.append("--isolated")

        # The max pip verbosity is -vvv and for pex it's -vvvvvvvvv; so we scale down by a factor
        # of 3.
        pip_verbosity = ENV.PEX_VERBOSE // 3
        if pip_verbosity > 0:
            pip_args.append("-{}".format("v" * pip_verbosity))
        else:
            pip_args.append("-q")

        if cache:
            pip_args.extend(["--cache-dir", cache])
        else:
            pip_args.append("--no-cache-dir")

        command = pip_args + list(args)

        # N.B.: Package index options in Pep always have the same option names, but they are
        # registered as subcommand-specific, so we must append them here _after_ the pip subcommand
        # specified in `args`.
        if package_index_configuration:
            command.extend(package_index_configuration.args)

        env = package_index_configuration.env if package_index_configuration else {}
        with ENV.strip().patch(
            PEX_ROOT=cache or ENV.PEX_ROOT, PEX_VERBOSE=str(ENV.PEX_VERBOSE), **env
        ) as env:
            # Guard against API calls from environment with ambient PYTHONPATH preventing pip PEX
            # bootstrapping. See: https://github.com/pantsbuild/pex/issues/892
            pythonpath = env.pop("PYTHONPATH", None)
            if pythonpath:
                TRACER.log(
                    "Scrubbed PYTHONPATH={} from the pip PEX environment.".format(pythonpath), V=3
                )

            from pex.pex import PEX

            pip = PEX(pex=self._pip_pex_path, interpreter=interpreter)
            return Job(
                command=pip.cmdline(command), process=pip.run(args=command, env=env, blocking=False)
            )
コード例 #45
0
    def _compile_target(self, vt):
        """'Compiles' a python target.

    'Compiling' means forming an isolated chroot of its sources and transitive deps and then
    attempting to import each of the target's sources in the case of a python library or else the
    entry point in the case of a python binary.

    For a library with sources lib/core.py and lib/util.py a "compiler" main file would look like:

      if __name__ == '__main__':
        import lib.core
        import lib.util

    For a binary with entry point lib.bin:main the "compiler" main file would look like:

      if __name__ == '__main__':
        from lib.bin import main

    In either case the main file is executed within the target chroot to reveal missing BUILD
    dependencies.
    """
        target = vt.target
        with self.context.new_workunit(name=target.address.spec):
            modules = self._get_modules(target)
            if not modules:
                # Nothing to eval, so a trivial compile success.
                return 0

            interpreter = self._get_interpreter_for_target_closure(target)
            reqs_pex = self._resolve_requirements_for_versioned_target_closure(
                interpreter, vt)
            srcs_pex = self._source_pex_for_versioned_target_closure(
                interpreter, vt)

            # Create the executable pex.
            exec_pex_parent = os.path.join(self.workdir, 'executable_pex')
            executable_file_content = self._get_executable_file_content(
                exec_pex_parent, modules)

            hasher = hashlib.sha1()
            hasher.update(reqs_pex.path().encode('utf-8'))
            hasher.update(srcs_pex.path().encode('utf-8'))
            hasher.update(executable_file_content.encode('utf-8'))
            exec_file_hash = hasher.hexdigest()
            exec_pex_path = os.path.realpath(
                os.path.join(exec_pex_parent, exec_file_hash))
            if not os.path.isdir(exec_pex_path):
                with safe_concurrent_creation(exec_pex_path) as safe_path:
                    # Write the entry point.
                    safe_mkdir(safe_path)
                    with open(
                            os.path.join(safe_path,
                                         '{}.py'.format(self._EXEC_NAME)),
                            'w') as outfile:
                        outfile.write(executable_file_content)
                    pex_info = (target.pexinfo if isinstance(
                        target, PythonBinary) else None) or PexInfo()
                    # Override any user-specified entry point, under the assumption that the
                    # executable_file_content does what the user intends (including, probably, calling that
                    # underlying entry point).
                    pex_info.entry_point = self._EXEC_NAME
                    pex_info.pex_path = ':'.join(pex.path()
                                                 for pex in (reqs_pex,
                                                             srcs_pex) if pex)
                    builder = PEXBuilder(safe_path,
                                         interpreter,
                                         pex_info=pex_info)
                    builder.freeze()

            pex = PEX(exec_pex_path, interpreter)

            with self.context.new_workunit(
                    name='eval',
                    labels=[
                        WorkUnitLabel.COMPILER, WorkUnitLabel.RUN,
                        WorkUnitLabel.TOOL
                    ],
                    cmd=' '.join(pex.cmdline())) as workunit:
                returncode = pex.run(stdout=workunit.output('stdout'),
                                     stderr=workunit.output('stderr'))
                workunit.set_outcome(WorkUnit.SUCCESS if returncode ==
                                     0 else WorkUnit.FAILURE)
                if returncode != 0:
                    self.context.log.error('Failed to eval {}'.format(
                        target.address.spec))
                return returncode
コード例 #46
0
ファイル: pex.py プロジェクト: tdyas/pex
def main(args=None):
  args = args[:] if args else sys.argv[1:]
  args = [transform_legacy_arg(arg) for arg in args]
  parser = configure_clp()

  try:
    separator = args.index('--')
    args, cmdline = args[:separator], args[separator + 1:]
  except ValueError:
    args, cmdline = args, []

  options, reqs = parser.parse_args(args=args)

  if options.cache_dir:
    pex_warnings.warn('The --cache-dir option is deprecated, use --pex-root instead.')
    if options.pex_root and options.cache_dir != options.pex_root:
      die('Both --cache-dir and --pex-root were passed with conflicting values. '
          'Just set --pex-root.')

  if options.disable_cache:
    def warn_ignore_pex_root(set_via):
      pex_warnings.warn('The pex root has been set via {via} but --disable-cache is also set. '
                        'Ignoring {via} and disabling caches.'.format(via=set_via))

    if options.cache_dir:
      warn_ignore_pex_root('--cache-dir')
    elif options.pex_root:
      warn_ignore_pex_root('--pex-root')
    elif os.environ.get('PEX_ROOT'):
      warn_ignore_pex_root('PEX_ROOT')

    pex_root = safe_mkdtemp()
  else:
    pex_root = options.cache_dir or options.pex_root or ENV.PEX_ROOT

  if options.python and options.interpreter_constraint:
    die('The "--python" and "--interpreter-constraint" options cannot be used together.')

  with ENV.patch(PEX_VERBOSE=str(options.verbosity), PEX_ROOT=pex_root) as patched_env:
    with TRACER.timed('Building pex'):
      pex_builder = build_pex(reqs, options, cache=ENV.PEX_ROOT)

    pex_builder.freeze(bytecode_compile=options.compile)
    pex = PEX(pex_builder.path(),
              interpreter=pex_builder.interpreter,
              verify_entry_point=options.validate_ep)

    if options.pex_name is not None:
      log('Saving PEX file to %s' % options.pex_name, V=options.verbosity)
      tmp_name = options.pex_name + '~'
      safe_delete(tmp_name)
      pex_builder.build(
        tmp_name,
        bytecode_compile=options.compile,
        deterministic_timestamp=not options.use_system_time
      )
      os.rename(tmp_name, options.pex_name)
    else:
      if not _compatible_with_current_platform(options.platforms):
        log('WARNING: attempting to run PEX with incompatible platforms!', V=1)
        log('Running on platform {} but built for {}'
            .format(Platform.current(), ', '.join(map(str, options.platforms))), V=1)

      log('Running PEX file at %s with args %s' % (pex_builder.path(), cmdline),
          V=options.verbosity)
      sys.exit(pex.run(args=list(cmdline), env=patched_env))
コード例 #47
0
ファイル: python_eval.py プロジェクト: MathewJennings/pants
  def _compile_target(self, target):
    # "Compiles" a target by forming an isolated chroot of its sources and transitive deps and then
    # attempting to import each of the target's sources in the case of a python library or else the
    # entry point in the case of a python binary.
    #
    # For a library with sources lib/core.py and lib/util.py a "compiler" main file would look like:
    #
    #   if __name__ == '__main__':
    #     import lib.core
    #     import lib.util
    #
    # For a binary with entry point lib.bin:main the "compiler" main file would look like:
    #
    #   if __name__ == '__main__':
    #     from lib.bin import main
    #
    # In either case the main file is executed within the target chroot to reveal missing BUILD
    # dependencies.

    with self.context.new_workunit(name=target.address.spec):
      modules = []
      if isinstance(target, PythonBinary):
        source = 'entry_point {}'.format(target.entry_point)
        components = target.entry_point.rsplit(':', 1)
        module = components[0]
        if len(components) == 2:
          function = components[1]
          data = TemplateData(source=source,
                              import_statement='from {} import {}'.format(module, function))
        else:
          data = TemplateData(source=source, import_statement='import {}'.format(module))
        modules.append(data)
      else:
        for path in target.sources_relative_to_source_root():
          if path.endswith('.py'):
            if os.path.basename(path) == '__init__.py':
              module_path = os.path.dirname(path)
            else:
              module_path, _ = os.path.splitext(path)
            source = 'file {}'.format(os.path.join(target.target_base, path))
            module = module_path.replace(os.path.sep, '.')
            data = TemplateData(source=source, import_statement='import {}'.format(module))
            modules.append(data)

      if not modules:
        # Nothing to eval, so a trivial compile success.
        return 0

      interpreter = self.select_interpreter_for_targets([target])

      if isinstance(target, PythonBinary):
        pexinfo, platforms = target.pexinfo, target.platforms
      else:
        pexinfo, platforms = None, None

      with temporary_file() as imports_file:
        def pre_freeze(chroot):
          generator = Generator(pkgutil.get_data(__name__, self._EVAL_TEMPLATE_PATH),
                                chroot=chroot.path(),
                                modules=modules)
          generator.write(imports_file)
          imports_file.close()
          chroot.builder.set_executable(imports_file.name, '__pants_python_eval__.py')

        with self.temporary_chroot(interpreter=interpreter, pex_info=pexinfo,
                                   targets=[target], platforms=platforms,
                                   pre_freeze=pre_freeze) as chroot:
          pex = PEX(chroot.builder.path(), interpreter=interpreter)
          with self.context.new_workunit(name='eval',
                                         labels=[WorkUnit.COMPILER, WorkUnit.RUN, WorkUnit.TOOL],
                                         cmd=' '.join(pex.cmdline())) as workunit:
            returncode = pex.run(stdout=workunit.output('stdout'), stderr=workunit.output('stderr'))
            workunit.set_outcome(WorkUnit.SUCCESS if returncode == 0 else WorkUnit.FAILURE)
            if returncode != 0:
              self.context.log.error('Failed to eval {}'.format(target.address.spec))
            return returncode
コード例 #48
0
ファイル: isort_prep.py プロジェクト: StephanErb/pants
    class Isort(object):
        class Factory(Subsystem):
            options_scope = 'isort'

            @classmethod
            def register_options(cls, register):
                super(IsortPrep.Isort.Factory, cls).register_options(register)
                register('--version',
                         default='4.3.4',
                         advanced=True,
                         fingerprint=True,
                         help='The version of isort to use.')
                register(
                    '--additional-requirements',
                    default=['setuptools'],
                    type=list_option,
                    advanced=True,
                    fingerprint=True,
                    help=
                    'Additional undeclared dependencies of the requested isort version.'
                )

            @classmethod
            def create_requirements(cls, context, workdir):
                options = cls.global_instance().get_options()
                address = Address(spec_path=fast_relpath(
                    workdir, get_buildroot()),
                                  target_name='isort')
                requirements = ['isort=={}'.format(options.version)
                                ] + options.additional_requirements
                context.build_graph.inject_synthetic_target(
                    address=address,
                    target_type=PythonRequirementLibrary,
                    requirements=[PythonRequirement(r) for r in requirements])
                return context.build_graph.get_target(address=address)

            @classmethod
            def build_isort_pex(cls, context, interpreter, pex_path,
                                requirements_lib):
                with safe_concurrent_creation(pex_path) as chroot:
                    pex_builder = PexBuilderWrapper(
                        PEXBuilder(path=chroot, interpreter=interpreter),
                        PythonRepos.global_instance(),
                        PythonSetup.global_instance(), context.log)
                    pex_builder.add_requirement_libs_from(
                        req_libs=[requirements_lib])
                    pex_builder.set_script('isort')
                    pex_builder.freeze()

        def __init__(self, pex_path, interpreter=None):
            self._pex = PEX(pex_path, interpreter=interpreter)

        def run(self, workunit_factory, args, **kwargs):
            cmdline = ' '.join(self._pex.cmdline(args))
            with workunit_factory(cmd=cmdline) as workunit:
                exit_code = self._pex.run(args,
                                          stdout=workunit.output('stdout'),
                                          stderr=workunit.output('stderr'),
                                          with_chroot=False,
                                          blocking=True,
                                          **kwargs)
                return cmdline, exit_code