Esempio n. 1
0
 def generate_test_targets(cls):
     if cls.TESTING_TARGETS is None:
         with ParseContext.temp():
             cls.TESTING_TARGETS = [
                 PythonRequirement('pytest'),
                 PythonRequirement('pytest-cov'),
                 PythonRequirement('coverage==3.6b1'),
                 PythonRequirement(
                     'unittest2',
                     version_filter=lambda py, pl: py.startswith('2')),
                 PythonRequirement(
                     'unittest2py3k',
                     version_filter=lambda py, pl: py.startswith('3'))
             ]
     return cls.TESTING_TARGETS
Esempio n. 2
0
  def execute(self):
    if self.options.pex and self.options.ipython:
      self.error('Cannot specify both --pex and --ipython!')

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

    if self.options.verbose:
      print('Build operating on target: %s %s' % (self.target,
        'Extra targets: %s' % ' '.join(map(str, self.extra_targets)) if self.extra_targets else ''))

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

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

    if self.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=[])

      with ParseContext.temp():
        for requirement in requirements:
          self.extra_targets.append(PythonRequirement(requirement))

    executor = PythonChroot(
        self.target,
        self.root_dir,
        builder=builder,
        interpreter=self.interpreter,
        extra_targets=self.extra_targets,
        conn_timeout=self.options.conn_timeout)

    executor.dump()

    if self.options.pex:
      pex_name = os.path.join(self.root_dir, 'dist', '%s.pex' % self.target.name)
      builder.build(pex_name)
      print('Wrote %s' % pex_name)
      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
Esempio n. 3
0
  def _generate_requirement(self, library, builder_cls):
    library_key = self._key_generator.key_for_target(library)
    builder = builder_cls(library, self._root, self._config, '-' + library_key.hash[:8])

    cache_dir = os.path.join(self._egg_cache_root, library_key.id)
    if self._build_invalidator.needs_update(library_key):
      sdist = builder.build(interpreter=self._interpreter)
      safe_mkdir(cache_dir)
      shutil.copy(sdist, os.path.join(cache_dir, os.path.basename(sdist)))
      self._build_invalidator.update(library_key)

    with ParseContext.temp():
      return PythonRequirement(builder.requirement_string(), repository=cache_dir, use_2to3=True)
Esempio n. 4
0
def PythonEgg(egg_glob):
    eggs = glob.glob(egg_glob)

    requirements = set()
    for egg in eggs:
        if os.path.isdir(egg):
            metadata = PathMetadata(egg, os.path.join(egg, 'EGG-INFO'))
        else:
            metadata = EggMetadata(EggZipImporter(egg))
        dist = Distribution.from_filename(egg, metadata=metadata)
        requirements.add(dist.as_requirement())

    if len(requirements) > 1:
        raise ValueError('Got multiple egg versions! => %s' % requirements)

    return PythonRequirement(str(requirements.pop()))
Esempio n. 5
0
  def dump(self):
    self.debug('Building PythonBinary %s:' % self._target)

    targets = self.resolve([self._target] + self._extra_targets)

    for lib in targets['libraries'] | targets['binaries']:
      self._dump_library(lib)

    generated_reqs = OrderedSet()
    if targets['thrifts']:
      for thr in set(targets['thrifts']):
        if thr not in self.MEMOIZED_THRIFTS:
          self.MEMOIZED_THRIFTS[thr] = self._generate_thrift_requirement(thr)
        generated_reqs.add(self.MEMOIZED_THRIFTS[thr])
      with ParseContext.temp():
        # trick pants into letting us add this python requirement, otherwise we get
        # TargetDefinitionException: Error in target BUILD.temp:thrift: duplicate to
        # PythonRequirement(thrift)
        #
        # TODO(wickman) Instead of just blindly adding a PythonRequirement for thrift, we
        # should first detect if any explicit thrift requirements have been added and use
        # those.  Only if they have not been supplied should we auto-inject it.
        generated_reqs.add(PythonRequirement('thrift', use_2to3=True,
            name='thrift-' + ''.join(random.sample('0123456789abcdef' * 8, 8))))

    for antlr in targets['antlrs']:
      generated_reqs.add(self._generate_antlr_requirement(antlr))

    targets['reqs'] |= generated_reqs
    for req in targets['reqs']:
      if not req.should_build(self._interpreter.python, Platform.current()):
        self.debug('Skipping %s based upon version filter' % req)
        continue
      self._dump_requirement(req._requirement, False, req._repository)

    reqs_to_build = (req for req in targets['reqs']
        if req.should_build(self._interpreter.python, Platform.current()))
    for dist in self._resolver.resolve(reqs_to_build, interpreter=self._interpreter):
      self._dump_distribution(dist)

    if len(targets['binaries']) > 1:
      print('WARNING: Target has multiple python_binary targets!', file=sys.stderr)

    return self._builder
Esempio n. 6
0
    def __init__(self, run_tracker, root_dir, parser, argv):
        Command.__init__(self, run_tracker, root_dir, parser, argv)

        self.target = None
        self.extra_targets = []
        self.config = Config.load()
        self.interpreter_cache = PythonInterpreterCache(self.config,
                                                        logger=self.debug)
        self.interpreter_cache.setup()
        interpreters = self.interpreter_cache.select_interpreter(
            list(
                self.interpreter_cache.matches(
                    [self.options.
                     interpreter] if self.options.interpreter else [''])))
        if len(interpreters) != 1:
            self.error('Unable to detect suitable interpreter.')
        self.interpreter = interpreters[0]

        for req in self.options.extra_requirements:
            with ParseContext.temp():
                self.extra_targets.append(PythonRequirement(req,
                                                            use_2to3=True))

        # We parse each arg in the context of the cli usage:
        #   ./pants command (options) [spec] (build args)
        #   ./pants command (options) [spec]... -- (build args)
        # Our command token and our options are parsed out so we see args of the form:
        #   [spec] (build args)
        #   [spec]... -- (build args)
        binaries = []
        for k in range(len(self.args)):
            arg = self.args.pop(0)
            if arg == '--':
                break

            def not_a_target(debug_msg):
                self.debug('Not a target, assuming option: %s.' % e)
                # We failed to parse the arg as a target or else it was in valid address format but did not
                # correspond to a real target.  Assume this is the 1st of the build args and terminate
                # processing args for target addresses.
                self.args.insert(0, arg)

            target = None
            try:
                address = Address.parse(root_dir, arg)
                target = Target.get(address)
                if target is None:
                    not_a_target(debug_msg='Unrecognized target')
                    break
            except Exception as e:
                not_a_target(debug_msg=e)
                break

            for resolved in filter(lambda t: t.is_concrete, target.resolve()):
                if isinstance(resolved, PythonBinary):
                    binaries.append(resolved)
                else:
                    self.extra_targets.append(resolved)

        if len(binaries) == 0:
            # treat as a chroot
            pass
        elif len(binaries) == 1:
            # We found a binary and are done, the rest of the args get passed to it
            self.target = binaries[0]
        else:
            self.error(
                'Can only process 1 binary target, %s contains %d:\n\t%s' %
                (arg, len(binaries), '\n\t'.join(
                    str(binary.address) for binary in binaries)))

        if self.target is None:
            if not self.extra_targets:
                self.error('No valid target specified!')
            self.target = self.extra_targets.pop(0)