Example #1
0
  def __init__(self,
               name,
               sources,
               resources=None,
               dependencies=None,
               provides=None,
               compatibility=None,
               exclusives=None):
    TargetWithSources.__init__(self, name, sources=sources, exclusives=exclusives)
    TargetWithDependencies.__init__(self, name, dependencies=dependencies, exclusives=exclusives)

    self.add_labels('python')
    self.resources = self._resolve_paths(resources) if resources else OrderedSet()

    if provides and not isinstance(provides, PythonArtifact):
      raise TargetDefinitionException(self,
        "Target must provide a valid pants setup_py object. Received a '%s' object instead." %
          provides.__class__.__name__)
    self.provides = provides

    self.compatibility = compatibility or ['']
    for req in self.compatibility:
      try:
        PythonIdentity.parse_requirement(req)
      except ValueError as e:
        raise TargetDefinitionException(str(e))
Example #2
0
    def __init__(self,
                 name,
                 main=None,
                 basename=None,
                 source=None,
                 resources=None,
                 dependencies=None,
                 excludes=None,
                 deploy_excludes=None,
                 configurations=None,
                 exclusives=None):
        """
    :param string name: The name of this target, which combined with this
      build file defines the target :class:`twitter.pants.base.address.Address`.
    :param string main: The name of the ``main`` class, e.g.,
      ``'com.twitter.common.examples.pingpong.Main'``. This class may be
      present as the source of this target or depended-upon library.
    :param string basename: Base name for the generated ``.jar`` file, e.g.,
      ``'pingpong'``. (By default, uses ``name`` param)
    :param string source: Name of one ``.java`` or ``.scala`` file (a good
      place for a ``main``).
    :param resources: List of ``resource``\s to include in bundle.
    :param dependencies: List of targets (probably ``java_library`` and
     ``scala_library`` targets) to "link" in.
    :param excludes: List of ``exclude``\s to filter this target's transitive
     dependencies against.
    :param deploy_excludes: List of ``excludes`` to apply at deploy time.
      If you, for example, deploy a java servlet that has one version of
      ``servlet.jar`` onto a Tomcat environment that provides another version,
      they might conflict. ``deploy_excludes`` gives you a way to build your
      code but exclude the conflicting ``jar`` when deploying.
    :param configurations: Ivy configurations to resolve for this target.
      This parameter is not intended for general use.
    :type configurations: tuple of strings
    """
        super(JvmBinary, self).__init__(name=name,
                                        sources=[source] if source else None,
                                        dependencies=dependencies,
                                        excludes=excludes,
                                        configurations=configurations,
                                        exclusives=exclusives)

        if main and not isinstance(main, Compatibility.string):
            raise TargetDefinitionException(
                self, 'main must be a fully qualified classname')

        if source and not isinstance(source, Compatibility.string):
            raise TargetDefinitionException(
                self, 'source must be a single relative file path')

        self.main = main
        self.basename = basename or name
        self.resources = resources
        self.deploy_excludes = deploy_excludes or []
Example #3
0
    def __init__(self, spec, exclusives=None):
        """
    :param string spec: target address. E.g.,
      src/main/java/com/twitter/common/util/BUILD:util
    """
        # it's critical the spec is parsed 1st, the results are needed elsewhere in constructor flow
        parse_context = ParseContext.locate()

        def parse_address():
            if spec.startswith(':'):
                # the :[target] could be in a sibling BUILD - so parse using the canonical address
                pathish = "%s:%s" % (parse_context.buildfile.canonical_relpath,
                                     spec[1:])
                return Address.parse(parse_context.buildfile.root_dir, pathish,
                                     False)
            else:
                return Address.parse(parse_context.buildfile.root_dir, spec,
                                     False)

        try:
            self.address = parse_address()
        except IOError as e:
            self.address = parse_context.buildfile.relpath
            raise TargetDefinitionException(
                self, '%s%s' % (self._DEFINITION_ERROR_MSG, e))

        # We must disable the re-init check, because our funky __getattr__ breaks it.
        # We're not involved in any multiple inheritance, so it's OK to disable it here.
        super(Pants, self).__init__(self.address.target_name,
                                    reinit_check=False,
                                    exclusives=exclusives)
Example #4
0
    def __init__(self, name, binary, bundles, basename=None):
        """
    :param string name: The name of this target, which combined with this
      build file defines the target :class:`twitter.pants.base.address.Address`.
    :param binary: The :class:`twitter.pants.targets.jvm_binary.JvmBinary`,
      or a :class:`twitter.pants.targets.pants_target.Pants` pointer to one.
    :param bundles: One or more :class:`twitter.pants.targets.jvm_binary.Bundle`'s
      describing "extra files" that should be included with this app
      (e.g.: config files, startup scripts).
    :param string basename: Name of this application, if different from the
      ``name``. Pants uses this in the ``bundle`` goal to name the distribution
      artifact. In most cases this parameter is not necessary.
    """
        super(JvmApp, self).__init__(name, dependencies=[])

        self._binaries = maybe_list(
            util.resolve(binary),
            expected_type=(Pants, JarLibrary, JvmBinary),
            raise_type=partial(TargetDefinitionException, self))

        self._bundles = maybe_list(bundles,
                                   expected_type=Bundle,
                                   raise_type=partial(
                                       TargetDefinitionException, self))

        if name == basename:
            raise TargetDefinitionException(self,
                                            'basename must not equal name.')
        self.basename = basename or name

        self._resolved_binary = None
        self._resolved_bundles = []
Example #5
0
    def __init__(self,
                 name,
                 sources,
                 resources=None,
                 dependencies=None,
                 provides=None,
                 compatibility=None,
                 exclusives=None):
        TargetWithSources.__init__(self,
                                   name,
                                   sources=sources,
                                   exclusives=exclusives)
        TargetWithDependencies.__init__(self,
                                        name,
                                        dependencies=dependencies,
                                        exclusives=exclusives)

        self.add_labels('python')
        self.resources = self._resolve_paths(
            resources) if resources else OrderedSet()
        self.provides = provides
        self.compatibility = compatibility or ['']
        for req in self.compatibility:
            try:
                PythonIdentity.parse_requirement(req)
            except ValueError as e:
                raise TargetDefinitionException(str(e))
Example #6
0
    def _maybe_resolve_bundles(self):
        if self._bundles is not None:

            def is_resolvable(item):
                return hasattr(item, 'resolve')

            def is_bundle(bundle):
                return isinstance(bundle, Bundle)

            def resolve(item):
                return list(item.resolve()) if is_resolvable(item) else [None]

            if is_resolvable(self._bundles):
                self._bundles = resolve(self._bundles)

            try:
                for item in iter(self._bundles):
                    for bundle in resolve(item):
                        if not is_bundle(bundle):
                            raise TypeError()
                        self._resolved_bundles.append(bundle)
            except TypeError:
                raise TargetDefinitionException(
                    self, 'bundles must be one or more Bundle objects, '
                    'got %s' % self._bundles)
            self._bundles = None
Example #7
0
 def resolve(self):
   # De-reference this pants pointer to an actual parsed target.
   resolved = Target.get(self.address)
   if not resolved:
     raise TargetDefinitionException(self, '%s%s' % (self._DEFINITION_ERROR_MSG, self.address))
   for dep in resolved.resolve():
     yield dep
Example #8
0
 def _find():
   for root_dir, types in cls._TYPES_BY_ROOT.items():
     if target_path.startswith(root_dir):  # The only candidate root for this target.
       # Validate the target type, if restrictions were specified.
       if types and not isinstance(target, tuple(types)):
         # TODO: Find a way to use the BUILD file aliases in the error message, instead
         # of target.__class__.__name__. E.g., java_tests instead of JavaTests.
         raise TargetDefinitionException(target,
             'Target type %s not allowed under %s' % (target.__class__.__name__, root_dir))
       return root_dir
   return None
Example #9
0
  def _maybe_resolve_binary(self):
    if self._binaries is not None:
      binaries_list = []
      for binary in self._binaries:
        binaries_list.extend(filter(lambda t: t.is_concrete, binary.resolve()))

      if len(binaries_list) != 1 or not isinstance(binaries_list[0], JvmBinary):
        raise TargetDefinitionException(self,
                                        'must supply exactly 1 JvmBinary, got %s' % binaries_list)
      self._resolved_binary = binaries_list[0]
      self.update_dependencies([self._resolved_binary])
      self._binaries = None
Example #10
0
 def update_dependencies(self, dependencies):
     if dependencies:
         for dependency in dependencies:
             if hasattr(dependency, 'address'):
                 self.dependency_addresses.add(dependency.address)
             if not hasattr(dependency, "resolve"):
                 raise TargetDefinitionException(
                     self, 'Cannot add %s as a dependency of %s' %
                     (dependency, self))
             for resolved_dependency in dependency.resolve():
                 if resolved_dependency.is_concrete and not self.valid_dependency(
                         resolved_dependency):
                     raise TargetDefinitionException(
                         self, 'Cannot add %s as a dependency of %s' %
                         (resolved_dependency, self))
                 self._dependencies.add(resolved_dependency)
                 if isinstance(resolved_dependency, InternalTarget):
                     self._internal_dependencies.add(resolved_dependency)
         self._jar_dependencies = OrderedSet(
             filter(lambda tgt: isinstance(tgt, JarDependency),
                    self._dependencies - self._internal_dependencies))
Example #11
0
 def iter_entry_points(cls, target):
     """Yields the name, entry_point pairs of binary targets in this PythonArtifact."""
     for name, binary_target in target.provides.binaries.items():
         concrete_target = binary_target.get()
         if not isinstance(
                 concrete_target,
                 PythonBinary) or concrete_target.entry_point is None:
             raise TargetDefinitionException(
                 target,
                 'Cannot add a binary to a PythonArtifact if it does not contain an entry_point.'
             )
         yield name, concrete_target.entry_point
Example #12
0
    def __init__(self,
                 name,
                 sources=None,
                 java_sources=None,
                 provides=None,
                 dependencies=None,
                 excludes=None,
                 resources=None,
                 exclusives=None):
        """
    :param string name: The name of this target, which combined with this
      build file defines the target :class:`twitter.pants.base.address.Address`.
    :param sources: A list of filenames representing the source code
      this library is compiled from.
    :type sources: list of strings
    :param java_sources:
      :class:`twitter.pants.targets.java_library.JavaLibrary` or list of
      JavaLibrary targets this library has a circular dependency on.
      Prefer using dependencies to express non-circular dependencies.
    :param Artifact provides:
      The :class:`twitter.pants.targets.artifact.Artifact`
      to publish that represents this target outside the repo.
    :param dependencies: List of :class:`twitter.pants.base.target.Target` instances
      this target depends on.
    :type dependencies: list of targets
    :param excludes: List of :class:`twitter.pants.targets.exclude.Exclude` instances
      to filter this target's transitive dependencies against.
    :param resources: An optional list of paths (DEPRECATED) or ``resources``
      targets containing resources that belong on this library's classpath.
    :param exclusives: An optional list of exclusives tags.
    """
        super(ScalaLibrary, self).__init__(name,
                                           sources,
                                           provides,
                                           dependencies,
                                           excludes,
                                           exclusives=exclusives)

        if (sources is None) and (resources is None):
            raise TargetDefinitionException(
                self, 'Must specify sources and/or resources.')

        self.resources = resources

        self._java_sources = []
        self._raw_java_sources = util.resolve(java_sources)

        self.add_labels('scala')
Example #13
0
 def _excludes(self, dep):
   """
   A generator for Exclude objects that will recursively exclude all artifacts
   provided by the given dep.
   """
   if isinstance(dep, JarDependency):
     yield Exclude(dep.org, dep.name)
   elif isinstance(dep, ExportableJvmLibrary):
     if not dep.provides:
       raise TargetDefinitionException(self,
           'Targets passed to `overrides` must represent published artifacts. %s does not.' % dep)
     yield Exclude(dep.provides.org, dep.provides.name)
   elif isinstance(dep, JarLibrary):
     for d in dep._pre_override_dependencies:
       for exclude in self._excludes(d):
         yield exclude
Example #14
0
 def _construct_provider_map(cls, root_target, descendant, parents,
                             providers, depmap):
     if isinstance(descendant, PythonTarget) and descendant.provides:
         providers.append(descendant)
     for dependency in cls._combined_dependencies(descendant):
         for prv in providers:
             for dep in dependency.resolve():
                 depmap[prv].add(dep)
                 if dep in parents:
                     raise TargetDefinitionException(
                         root_target, '%s and %s combined have a cycle!' %
                         (root_target, dep))
                 parents.add(dep)
                 cls._construct_provider_map(root_target, dep, parents,
                                             providers, depmap)
                 parents.remove(dep)
     if isinstance(descendant, PythonTarget) and descendant.provides:
         assert providers[-1] == descendant
         providers.pop()
Example #15
0
    def __init__(self,
                 name,
                 sources=None,
                 provides=None,
                 dependencies=None,
                 excludes=None,
                 resources=None,
                 exclusives=None):
        """
    :param string name: The name of this target, which combined with this
      build file defines the target :class:`twitter.pants.base.address.Address`.
    :param sources: A list of filenames representing the source code
      this library is compiled from.
    :type sources: list of strings
    :param Artifact provides:
      The :class:`twitter.pants.targets.artifact.Artifact`
      to publish that represents this target outside the repo.
    :param dependencies: List of :class:`twitter.pants.base.target.Target` instances
      this target depends on.
    :type dependencies: list of targets
    :param excludes: List of :class:`twitter.pants.targets.exclude.Exclude` instances
      to filter this target's transitive dependencies against.
    :param resources: An optional list of file paths (DEPRECATED) or
      ``resources`` targets (which in turn point to file paths). The paths
      indicate text file resources to place in this module's jar.
    :param exclusives: An optional map of exclusives tags. See CheckExclusives for details.
    """
        super(JavaLibrary, self).__init__(name,
                                          sources,
                                          provides,
                                          dependencies,
                                          excludes,
                                          exclusives=exclusives)

        if (sources is None) and (resources is None):
            raise TargetDefinitionException(
                self, 'Must specify sources and/or resources.')

        self.resources = resources
        self.add_labels('java')
Example #16
0
    def __init__(self,
                 name,
                 sources=None,
                 dependencies=None,
                 excludes=None,
                 resources=None,
                 exclusives=None,
                 premain=None,
                 agent_class=None,
                 can_redefine=False,
                 can_retransform=False,
                 can_set_native_method_prefix=False):
        """
    :param string name: The name of this target, which combined with this
      build file defines the target :class:`twitter.pants.base.address.Address`.
    :param sources: A list of filenames representing the source code
      this library is compiled from.
    :type sources: list of strings
    :param dependencies: List of :class:`twitter.pants.base.target.Target` instances
      this target depends on.
    :type dependencies: list of targets
    :param excludes: List of :class:`twitter.pants.targets.exclude.Exclude` instances
      to filter this target's transitive dependencies against.
    :param resources: An optional list of file paths (DEPRECATED) or
      ``resources`` targets (which in turn point to file paths). The paths
      indicate text file resources to place in this module's jar.
    :param exclusives: An optional map of exclusives tags. See CheckExclusives for details.
    :param string premain: When an agent is specified at JVM launch time this attribute specifies
      the agent class. Exactly one of ``premain`` or ``agent_class`` must be specified.
    :param string agent_class: If an implementation supports a mechanism to start agents sometime
      after the VM has started then this attribute specifies the agent class. Exactly one of
      ``premain`` or ``agent_class`` must be specified.
    :param bool can_redefine: `True` if the ability to redefine classes is needed by this agent;
      `False` by default.
    :param bool can_retransform: `True` if the ability to retransform classes is needed by this
      agent; `False` by default.
    :param bool can_set_native_method_prefix: `True` if the ability to set he native method prefix
      is needed by this agent; `False` by default.
    """

        super(JavaAgent, self).__init__(name,
                                        sources,
                                        provides=None,
                                        dependencies=dependencies,
                                        excludes=excludes,
                                        resources=resources,
                                        exclusives=exclusives)

        if not premain or agent_class:
            raise TargetDefinitionException(
                self, "Must have at least one of 'premain' or 'agent_class' "
                "defined.")
        if premain and not isinstance(premain, Compatibility.string):
            raise TargetDefinitionException(
                self, 'The premain must be a fully qualified class name, '
                'given %s of type %s' % (premain, type(premain)))

        if agent_class and not isinstance(agent_class, Compatibility.string):
            raise TargetDefinitionException(
                self,
                'The agent_class must be a fully qualified class name, given '
                '%s of type %s' % (agent_class, type(agent_class)))

        self._premain = premain
        self._agent_class = agent_class
        self._can_redefine = can_redefine
        self._can_retransform = can_retransform
        self._can_set_native_method_prefix = can_set_native_method_prefix

        self.add_labels('java_agent')
Example #17
0
    def __init__(
            self,
            name,
            source=None,
            dependencies=None,
            entry_point=None,
            inherit_path=False,  # pex option
            zip_safe=True,  # pex option
            always_write_cache=False,  # pex option
            repositories=None,  # pex option
            indices=None,  # pex option
            ignore_errors=False,  # pex option
            allow_pypi=False,  # pex option
            platforms=(),
            compatibility=None,
            exclusives=None):
        """
    :param name: target name
    :param source: the python source file that becomes this binary's __main__.
      If None specified, drops into an interpreter by default.
    :param dependencies: List of :class:`twitter.pants.base.target.Target` instances
      this target depends on.
    :type dependencies: list of targets
    :param entry_point: the default entry point for this binary.  if None, drops into the entry
      point that is defined by source
    :param inherit_path: inherit the sys.path of the environment that this binary runs in
    :param zip_safe: whether or not this binary is safe to run in compacted (zip-file) form
    :param always_write_cache: whether or not the .deps cache of this PEX file should always
      be written to disk.
    :param repositories: a list of repositories to query for dependencies.
    :param indices: a list of indices to use for packages.
    :param platforms: extra platforms to target when building this binary.
    :param compatibility: either a string or list of strings that represents
      interpreter compatibility for this target, using the Requirement-style format,
      e.g. ``'CPython>=3', or just ['>=2.7','<3']`` for requirements agnostic to interpreter class.
    :param dict exclusives: An optional dict of exclusives tags. See CheckExclusives for details.
    """

        # TODO(John Sirois): Fixup TargetDefinitionException - it has awkward Target base-class
        # initialization requirements right now requiring this Target.__init__.
        Target.__init__(self, name, exclusives=exclusives)

        if source is None and entry_point is None:
            raise TargetDefinitionException(
                self,
                'A python binary target must specify either source or entry_point.'
            )

        PythonTarget.__init__(
            self,
            name,
            [] if source is None else [source],
            compatibility=compatibility,
            dependencies=dependencies,
            exclusives=exclusives,
        )

        if not isinstance(platforms, (list, tuple)) and not isinstance(
                platforms, Compatibility.string):
            raise TargetDefinitionException(
                self, 'platforms must be a list, tuple or string.')

        self._entry_point = entry_point
        self._inherit_path = bool(inherit_path)
        self._zip_safe = bool(zip_safe)
        self._always_write_cache = bool(always_write_cache)
        self._repositories = maybe_list(repositories or [])
        self._indices = maybe_list(indices or [])
        self._ignore_errors = bool(ignore_errors)
        self._platforms = tuple(maybe_list(platforms or []))

        if source and entry_point:
            entry_point_module = entry_point.split(':', 1)[0]
            source_entry_point = self._translate_to_entry_point(
                self.sources[0])
            if entry_point_module != source_entry_point:
                raise TargetDefinitionException(
                    self,
                    'Specified both source and entry_point but they do not agree: %s vs %s'
                    % (source_entry_point, entry_point_module))
 def check_value_for_arg(arg, value, values):
     if value not in values:
         raise TargetDefinitionException(
             self, "%s may only be set to %s ('%s' not valid)" %
             (arg, ', or '.join(map(repr, values)), value))
     return value
    def __init__(self,
                 name,
                 sources,
                 provides=None,
                 dependencies=None,
                 excludes=None,
                 compiler=_COMPILER_DEFAULT,
                 language=_LANGUAGE_DEFAULT,
                 rpc_style=_RPC_STYLE_DEFAULT,
                 namespace_map=None,
                 exclusives=None):
        """
    :param string name: The name of this target, which combined with this
      build file defines the target :class:`twitter.pants.base.address.Address`.
    :param sources: A list of filenames representing the source code
      this library is compiled from.
    :type sources: list of strings
    :param Artifact provides:
      The :class:`twitter.pants.targets.artifact.Artifact`
      to publish that represents this target outside the repo.
    :param dependencies: List of :class:`twitter.pants.base.target.Target` instances
      this target depends on.
    :type dependencies: list of targets
    :param excludes: List of :class:`twitter.pants.targets.exclude.Exclude` instances
      to filter this target's transitive dependencies against.
    :param compiler: An optional compiler used to compile the thrift files.
    :param language: The language used to generate the output files.
      One of 'java' or 'scala' with a default of 'java'.
    :param rpc_style: An optional rpc style to generate service stubs with.
      One of 'sync', 'finagle' or 'ostrich' with a default of 'sync'.
    :param namespace_map: A dictionary of namespaces to remap (old: new)
    :param exclusives: An optional map of exclusives tags. See CheckExclusives for details.
    """

        # It's critical that provides is set 1st since _provides() is called elsewhere in the
        # constructor flow.
        self._provides = provides

        super(JavaThriftLibrary, self).__init__(name,
                                                sources,
                                                dependencies,
                                                excludes,
                                                exclusives=exclusives)

        self.add_labels('codegen')

        # 'java' shouldn't be here, but is currently required to prevent lots of chunking islands.
        # See comment in goal.py for details.
        self.add_labels('java')

        if dependencies:
            if not isinstance(dependencies, Iterable):
                raise TargetDefinitionException(
                    self,
                    'dependencies must be Iterable but was: %s' % dependencies)
            maybe_list(dependencies,
                       expected_type=(JarDependency, JavaThriftLibrary, Pants),
                       raise_type=partial(TargetDefinitionException, self))

        def check_value_for_arg(arg, value, values):
            if value not in values:
                raise TargetDefinitionException(
                    self, "%s may only be set to %s ('%s' not valid)" %
                    (arg, ', or '.join(map(repr, values)), value))
            return value

        # TODO(John Sirois): The defaults should be grabbed from the workspace config.

        # some gen BUILD files explicitly set this to None
        compiler = compiler or self._COMPILER_DEFAULT
        self.compiler = check_value_for_arg('compiler', compiler,
                                            self._COMPILERS)

        language = language or self._LANGUAGE_DEFAULT
        self.language = check_value_for_arg('language', language,
                                            self._LANGUAGES)

        rpc_style = rpc_style or self._RPC_STYLE_DEFAULT
        self.rpc_style = check_value_for_arg('rpc_style', rpc_style,
                                             self._RPC_STYLES)

        self.namespace_map = namespace_map