Example #1
0
  def __init__(self,
               name,
               sources=None,
               excludes=None,
               resources=None,
               premain=None,
               agent_class=None,
               can_redefine=False,
               can_retransform=False,
               can_set_native_method_prefix=False,
               **kwargs):
    """
    :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=name,
        sources=self.assert_list(sources, key_arg='sources'),
        provides=None,
        excludes=self.assert_list(excludes, key_arg='excludes'),
        resources=self.assert_list(resources, key_arg='resources'),
        **kwargs)

    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, string_types):
      raise TargetDefinitionException(self, 'The premain must be a fully qualified class name, '
                                            'given {} of type {}'.format(premain, type(premain)))

    if agent_class and not isinstance(agent_class, string_types):
      raise TargetDefinitionException(self,
                                      'The agent_class must be a fully qualified class name, given '
                                      '{} of type {}'.format(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

    # TODO(Eric Ayers) As of 2/5/2015 this call is DEPRECATED and should be removed soon
    self.add_labels('java_agent')
Example #2
0
 def binary(self):
   """Returns the binary this target references."""
   dependencies = self.dependencies
   if len(dependencies) != 1:
     raise TargetDefinitionException(self, 'An app must define exactly one binary '
                                           'dependency, have: {}'.format(dependencies))
   binary = dependencies[0]
   if not isinstance(binary, self.binary_target_type()):
     raise TargetDefinitionException(self, 'Expected binary dependency to be a {} '
                                           'target, found {}'.format(self.binary_target_type(),
                                                                     binary))
   return binary
Example #3
0
 def binary(self):
     dependencies = self.dependencies
     if len(dependencies) != 1:
         raise TargetDefinitionException(
             self, 'A JvmApp must define exactly one JvmBinary '
             'dependency, have: %s' % dependencies)
     binary = dependencies[0]
     if not isinstance(binary, JvmBinary):
         raise TargetDefinitionException(
             self, 'Expected JvmApp binary dependency to be a JvmBinary '
             'target, found %s' % binary)
     return binary
Example #4
0
 def binary(self):
     """Returns the binary that builds the pex for this lambda."""
     dependencies = self.dependencies
     if len(dependencies) != 1:
         raise TargetDefinitionException(
             self, f'An app must define exactly one binary '
             'dependency, have: {dependencies}')
     binary = dependencies[0]
     if not isinstance(binary, PythonBinary):
         raise TargetDefinitionException(
             self, f'Expected binary dependency to be a python_binary '
             'target, found {binary}')
     return binary
Example #5
0
 def binary(self):
   """:returns: The JvmBinary instance this JvmApp references.
   :rtype: JvmBinary
   """
   dependencies = self.dependencies
   if len(dependencies) != 1:
     raise TargetDefinitionException(self, 'A JvmApp must define exactly one JvmBinary '
                                           'dependency, have: {}'.format(dependencies))
   binary = dependencies[0]
   if not isinstance(binary, JvmBinary):
     raise TargetDefinitionException(self, 'Expected JvmApp binary dependency to be a JvmBinary '
                                           'target, found {}'.format(binary))
   return binary
Example #6
0
async def resolve_target(
    hydrated_struct: HydratedStruct,
    registered_target_types: RegisteredTargetTypes,
    union_membership: UnionMembership,
) -> WrappedTarget:
    kwargs = hydrated_struct.value.kwargs().copy()
    type_alias = kwargs.pop("type_alias")

    # We special case `address` and the field `name`. The `Target` constructor requires an
    # `Address`, so we use the value pre-calculated via `build_files.py`'s `hydrate_struct` rule.
    # We throw away the field `name` because it can be accessed via `tgt.address.target_name`, so
    # there is no (known) reason to preserve the field.
    address = cast(Address, kwargs.pop("address"))
    kwargs.pop("name", None)

    # We convert `source` into `sources` because the Target API has no `Source` field, only
    # `Sources`.
    if "source" in kwargs and "sources" in kwargs:
        raise TargetDefinitionException(
            address, "Cannot specify both `source` and `sources` fields."
        )
    if "source" in kwargs:
        source = kwargs.pop("source")
        if not isinstance(source, str):
            raise TargetDefinitionException(
                address,
                f"The `source` field must be a string containing a path relative to the target, "
                f"but got {source} of type {type(source)}.",
            )
        kwargs["sources"] = [source]

    target_type = registered_target_types.aliases_to_types.get(type_alias, None)
    if target_type is None:
        raise TargetDefinitionException(
            address,
            f"Target type {repr(type_alias)} is not recognized. All valid target types: "
            f"{sorted(registered_target_types.aliases)}.",
        )

    # Not every target type has the Dependencies field registered, but the StructWithDependencies
    # code means that `kwargs` will always have an entry. We must remove `dependencies` from
    # `kwargs` for target types without the value, otherwise we'll get an "unrecognized field"
    # error. But, we also need to be careful to error if the user did explicitly specify
    # `dependencies` in the BUILD file.
    if kwargs["dependencies"] is None and not target_type.class_has_field(
        Dependencies, union_membership=union_membership
    ):
        kwargs.pop("dependencies")

    return WrappedTarget(target_type(kwargs, address=address))
Example #7
0
  def create(cls, parse_context, **kwargs):
    if 'name' in kwargs:
      raise TargetDefinitionException(Address(parse_context.rel_path, kwargs['name']).spec,
                                      'A {} does not accept a name; instead, the name is taken '
                                      'from the BUILD file location.'.format(cls.alias()))
    name = os.path.basename(parse_context.rel_path)

    if 'sources' in kwargs:
      raise TargetDefinitionException(Address(parse_context.rel_path, name).spec,
                                      'A {} does not accept sources; instead, it always globs all '
                                      'the *.go sources in the BUILD file\'s '
                                      'directory.'.format(cls.alias()))

    parse_context.create_object(cls, type_alias=cls.alias(), name=name, **kwargs)
Example #8
0
  def __init__(self,
               address=None,
               payload=None,
               sources=None,
               provides=None,
               compatibility=None,
               **kwargs):
    """
    :param dependencies: The addresses of targets that this target depends on.
      These dependencies may
      be ``python_library``-like targets (``python_library``,
      ``python_thrift_library``, ``python_antlr_library`` and so forth) or
      ``python_requirement_library`` targets.
    :type dependencies: list of strings
    :param sources: Files to "include". Paths are relative to the
      BUILD file's directory.
    :type sources: ``EagerFilesetWithSpec``
    :param provides:
      The `setup_py <#setup_py>`_ to publish that represents this
      target outside the repo.
    :param compatibility: either a string that represents interpreter compatibility for this target
      using the Requirement-style format, e.g. ``'CPython>=2.7,<3'`` (Select a CPython interpreter
      with version ``>=2.7`` AND version ``<3``) or a list of Requirement-style strings which will
      be OR'ed together. If the compatibility requirement is agnostic to interpreter class, using
      the example above, a Requirement-style compatibility constraint like '>=2.7,<3' (N.B.: not
      prefixed with CPython) can be used.
    """
    self.address = address
    payload = payload or Payload()
    payload.add_fields({
      'sources': self.create_sources_field(sources, address.spec_path, key_arg='sources'),
      'provides': provides,
      'compatibility': PrimitiveField(maybe_list(compatibility or ())),
    })
    super(PythonTarget, self).__init__(address=address, payload=payload, **kwargs)

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

    self._provides = provides

    # Check that the compatibility requirements are well-formed.
    for req in self.payload.compatibility:
      try:
        PythonIdentity.parse_requirement(req)
      except ValueError as e:
        raise TargetDefinitionException(self, str(e))
Example #9
0
    def __init__(self,
                 address=None,
                 payload=None,
                 sources=None,
                 compatibility=None,
                 setup_requires=None,
                 **kwargs):
        """
    :param address: The Address that maps to this Target in the BuildGraph.
    :type address: :class:`pants.build_graph.address.Address`
    :param payload: The configuration encapsulated by this target.  Also in charge of most
                    fingerprinting details.
    :type payload: :class:`pants.base.payload.Payload`
    :param sources: Files to "include". Paths are relative to the
      BUILD file's directory.
    :type sources: ``Fileset`` or list of strings. Must include setup.py.
    :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.
    """
        payload = payload or Payload()
        payload.add_fields({
            'sources':
            self.create_sources_field(sources,
                                      address.spec_path,
                                      key_arg='sources'),
            'compatibility':
            PrimitiveField(maybe_list(compatibility or ())),
            'setup_requires':
            PrimitiveField(maybe_list(setup_requires or ()))
        })
        super(PythonDistribution, self).__init__(address=address,
                                                 payload=payload,
                                                 **kwargs)

        if not 'setup.py' in sources:
            raise TargetDefinitionException(
                self,
                'A setup.py in the top-level directory relative to the target definition is required.'
            )

        # Check that the compatibility requirements are well-formed.
        for req in self.payload.compatibility:
            try:
                PythonIdentity.parse_requirement(req)
            except ValueError as e:
                raise TargetDefinitionException(self, str(e))
Example #10
0
  def execute(self):
    dist_targets = self.context.targets(is_local_python_dist)
    build_graph = self.context.build_graph

    if dist_targets:
      with self.invalidated(dist_targets,
                            fingerprint_strategy=DefaultFingerprintStrategy(),
                            invalidate_dependents=True) as invalidation_check:
        for vt in invalidation_check.invalid_vts:
          if vt.target.dependencies:
            raise TargetDefinitionException(
              vt.target, 'The `dependencies` field is disallowed on `python_dist` targets. '
                         'List any 3rd party requirements in the install_requirements argument '
                         'of your setup function.'
            )
          self._create_dist(vt.target, vt.results_dir)

        for vt in invalidation_check.all_vts:
          dist = self._get_whl_from_dir(os.path.join(vt.results_dir, 'dist'))
          req_lib_addr = Address.parse('{}__req_lib'.format(vt.target.address.spec))
          self._inject_synthetic_dist_requirements(dist, req_lib_addr)
          # Make any target that depends on the dist depend on the synthetic req_lib,
          # for downstream consumption.
          for dependent in build_graph.dependents_of(vt.target.address):
            build_graph.inject_dependency(dependent, req_lib_addr)
Example #11
0
    def _instantiate_target(
            self, legacy_hydrated_target: "LegacyHydratedTarget") -> TargetV1:
        """Given a LegacyHydratedTarget previously parsed from a BUILD file, instantiate a
        Target."""
        target_cls = self._target_types[
            legacy_hydrated_target.adaptor.type_alias]
        try:
            # Pop dependencies, which were already consumed during construction.
            kwargs = legacy_hydrated_target.adaptor.kwargs()
            kwargs.pop("dependencies")

            # Replace the `address` field of type `Address` with type `BuildFileAddress`.
            kwargs["address"] = legacy_hydrated_target.build_file_address

            # Instantiate.
            if issubclass(target_cls, AppBase):
                return self._instantiate_app(target_cls, kwargs)
            elif target_cls is RemoteSources:
                return self._instantiate_remote_sources(kwargs)
            return target_cls(build_graph=self, **kwargs)
        except TargetDefinitionException:
            raise
        except Exception as e:
            raise TargetDefinitionException(
                legacy_hydrated_target.build_file_address,
                "Failed to instantiate Target with type {}: {}".format(
                    target_cls, e),
            )
Example #12
0
 def _validate(self, target):
     # TODO: Fix ThriftDefaults to only pertain to scrooge (see TODO there) and then
     # get rid of this spurious validation.
     if self._thrift_defaults.language(target) != self.thrift_generator:
         raise TargetDefinitionException(
             target, 'Compiler {} supports only language={}.'.format(
                 self._COMPILER, self.thrift_generator))
Example #13
0
 def java_sources(self):
   for spec in self._java_sources_specs:
     address = Address.parse(spec, relative_to=self.address.spec_path)
     target = self._build_graph.get_target(address)
     if target is None:
       raise TargetDefinitionException(self, 'No such java target: {}'.format(spec))
     yield target
Example #14
0
    def _compute_sources(self, target):
        relative_sources = OrderedSet()
        source_roots = OrderedSet()

        def capture_and_relativize_to_source_root(source):
            source_root = self.context.source_roots.find_by_path(source)
            if not source_root:
                source_root = self.context.source_roots.find(target)
            source_roots.add(source_root.path)
            return fast_relpath(source, source_root.path)

        if target.payload.get_field_value('ordered_sources'):
            # Re-match the filespecs against the sources in order to apply them in the literal order
            # they were specified in.
            filespec = target.globs_relative_to_buildroot()
            excludes = filespec.get('excludes', [])
            for filespec in filespec.get('globs', []):
                sources = [
                    s for s in target.sources_relative_to_buildroot()
                    if globs_matches([s], [filespec], excludes)
                ]
                if len(sources) != 1:
                    raise TargetDefinitionException(
                        target,
                        'With `ordered_sources=True`, expected one match for each file literal, '
                        'but got: {} for literal `{}`.'.format(
                            sources, filespec))
                relative_sources.add(
                    capture_and_relativize_to_source_root(sources[0]))
        else:
            # Otherwise, use the default (unspecified) snapshot ordering.
            for source in target.sources_relative_to_buildroot():
                relative_sources.add(
                    capture_and_relativize_to_source_root(source))
        return relative_sources, source_roots
Example #15
0
    def __init__(self,
                 address=None,
                 payload=None,
                 sources=None,
                 setup_requires=None,
                 **kwargs):
        """
    :param address: The Address that maps to this Target in the BuildGraph.
    :type address: :class:`pants.build_graph.address.Address`
    :param payload: The configuration encapsulated by this target.  Also in charge of most
                    fingerprinting details.
    :type payload: :class:`pants.base.payload.Payload`
    :param sources: Files to "include". Paths are relative to the
      BUILD file's directory.
    :type sources: :class:`twitter.common.dirutil.Fileset` or list of strings. Must include
                   setup.py.
    :param list setup_requires: A list of python requirements to provide during the invocation of
                                setup.py.
    """
        if not 'setup.py' in sources:
            raise TargetDefinitionException(
                self, 'A file named setup.py must be in the same '
                'directory as the BUILD file containing this target.')

        payload = payload or Payload()
        payload.add_fields({
            'setup_requires':
            PrimitiveField(maybe_list(setup_requires or ()))
        })
        super(PythonDistribution, self).__init__(address=address,
                                                 payload=payload,
                                                 sources=sources,
                                                 **kwargs)
Example #16
0
    def _instantiate_target(self, target_adaptor):
        """Given a TargetAdaptor struct previously parsed from a BUILD file, instantiate a Target.

    TODO: This assumes that the SymbolTable used for parsing matches the SymbolTable passed
    to this graph. Would be good to make that more explicit, but it might be better to nuke
    the Target subclassing pattern instead, and lean further into the "configuration composition"
    model explored in the `exp` package.
    """
        target_cls = self._target_types[target_adaptor.type_alias]
        try:
            # Pop dependencies, which were already consumed during construction.
            kwargs = target_adaptor.kwargs()
            kwargs.pop('dependencies')

            # Instantiate.
            if target_cls is JvmApp:
                return self._instantiate_jvm_app(kwargs)
            elif target_cls is RemoteSources:
                return self._instantiate_remote_sources(kwargs)
            return target_cls(build_graph=self, **kwargs)
        except TargetDefinitionException:
            raise
        except Exception as e:
            raise TargetDefinitionException(
                target_adaptor.address,
                'Failed to instantiate Target with type {}: {}'.format(
                    target_cls, e))
Example #17
0
    def __init__(self, *args, **kwargs):
        self.target_type = self.get_target_type()

        if 'name' not in kwargs:
            raise Addressable.AddressableInitError(
                'name is a required parameter to all Targets specified within a BUILD file.'
                '  Target type was: {target_type}.'.format(
                    target_type=self.target_type))

        if args:
            raise Addressable.AddressableInitError(
                'All arguments passed to Targets within BUILD files must use explicit keyword syntax.'
                '  Target type was: {target_type}.'
                '  Arguments passed were: {args}'.format(
                    target_type=self.target_type, args=args))

        self.kwargs = kwargs
        self.name = kwargs['name']
        self.dependency_specs = self.kwargs.pop('dependencies', [])

        for dep_spec in self.dependency_specs:
            if not isinstance(dep_spec, string_types):
                msg = (
                    'dependencies passed to Target constructors must be strings.  {dep_spec} is not'
                    ' a string.  Target type was: {target_type}.'.format(
                        target_type=self.target_type, dep_spec=dep_spec))
                raise TargetDefinitionException(target=self, msg=msg)
Example #18
0
    def __init__(self,
                 name=None,
                 payload=None,
                 binary=None,
                 bundles=None,
                 basename=None,
                 **kwargs):
        """
    :param string binary: Target spec of the ``jvm_binary`` that contains the
      app main.
    :param bundles: One or more ``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.
    """
        payload = payload or Payload()
        payload.add_fields({
            'bundles': BundleField(bundles or []),
        })
        super(JvmApp, self).__init__(name=name, payload=payload, **kwargs)

        if name == basename:
            raise TargetDefinitionException(self,
                                            'basename must not equal name.')
        self._basename = basename or name
        self._binary = binary
Example #19
0
    def __call__(self, name=None, dist=None):
        """
    :param string name: The name to use for the target, defaults to the dist name if specified and
                        otherwise the parent dir name.
    :param string dist: The pants dist to create a requirement for. This must be a
                        'pantsbuild.pants*' distribution; eg:
                        'pantsbuild.pants.contrib.python.checks'.
    """
        name = name or dist or os.path.basename(self._parse_context.rel_path)
        dist = dist or 'pantsbuild.pants'
        if not (dist == 'pantsbuild.pants'
                or dist.startswith('pantsbuild.pants.')):
            target = Address(spec_path=self._parse_context.rel_path,
                             target_name=name)
            raise TargetDefinitionException(
                target=target,
                msg='The {} target only works for pantsbuild.pants '
                'distributions, given {}'.format(self.alias, dist))

        # TODO(John Sirois): Modify to constraint to >=3.5,<4 as part of
        # https://github.com/pantsbuild/pants/issues/6062
        env_marker = "python_version>='2.7' and python_version<'3'"

        requirement = PythonRequirement(
            requirement="{key}=={version} ; {env_marker}".format(
                key=dist, version=pants_version(), env_marker=env_marker))

        self._parse_context.create_object('python_requirement_library',
                                          name=name,
                                          requirements=[requirement])
Example #20
0
    def create_sources_field(self, sources, sources_rel_path, key_arg=None):
        """Factory method to create a SourcesField appropriate for the type of the sources object.

    Note that this method is called before the call to Target.__init__ so don't expect fields to
    be populated!

    :API: public

    :return: a payload field object representing the sources parameter
    :rtype: SourcesField
    """
        if not sources:
            sources = FilesetWithSpec.empty(sources_rel_path)
        elif not isinstance(sources, FilesetWithSpec):
            key_arg_section = "'{}' to be ".format(key_arg) if key_arg else ""
            raise TargetDefinitionException(
                self,
                "Expected {}a glob, an address or a list, but was {}".format(
                    key_arg_section, type(sources)))
        elif not isinstance(sources, EagerFilesetWithSpec):
            deprecated_conditional(lambda: True, '1.12.0.dev0', (
                'FilesetWithSpec sources values are deprecated except for EagerFilesetWithSpec values. '
                'Saw value of type {}').format(type(sources)))

        return SourcesField(sources=sources)
Example #21
0
    def __init__(
        self,
        unhydrated_values: Dict[str, Any],
        *,
        address: Address,
        # NB: `union_membership` is only optional to facilitate tests. In production, we should
        # always provide this parameter. This should be safe to do because production code should
        # rarely directly instantiate Targets and should instead use the engine to request them.
        union_membership: Optional[UnionMembership] = None,
    ) -> None:
        self.address = address
        self.plugin_fields = self._find_plugin_fields(union_membership
                                                      or UnionMembership({}))

        self.field_values = {}
        aliases_to_field_types = {
            field_type.alias: field_type
            for field_type in self.field_types
        }
        for alias, value in unhydrated_values.items():
            if alias not in aliases_to_field_types:
                raise TargetDefinitionException(
                    address,
                    f"Unrecognized field `{alias}={value}`. Valid fields for the target type "
                    f"`{self.alias}`: {sorted(aliases_to_field_types.keys())}.",
                )
            field_type = aliases_to_field_types[alias]
            self.field_values[field_type] = field_type(value, address=address)
        # For undefined fields, mark the raw value as None.
        for field_type in set(self.field_types) - set(
                self.field_values.keys()):
            self.field_values[field_type] = field_type(raw_value=None,
                                                       address=address)
Example #22
0
 def __init__(self,
              payload=None,
              jars=None,
              managed_dependencies=None,
              **kwargs):
     """
 :param jars: List of `jar <#jar>`_\s to depend upon.
 :param managed_dependencies: Address of a managed_jar_dependencies() target to use. If omitted, uses
   the default managed_jar_dependencies() target set by --jar-dependency-management-default-target.
 """
     jars = self.assert_list(jars,
                             expected_type=JarDependency,
                             key_arg='jars')
     payload = payload or Payload()
     payload.add_fields({
         'jars':
         JarsField(jars),
         'excludes':
         ExcludesField([]),
         'managed_dependencies':
         PrimitiveField(managed_dependencies),
     })
     super(JarLibrary, self).__init__(payload=payload, **kwargs)
     # NB: Waiting to validate until superclasses are initialized.
     if not jars:
         raise TargetDefinitionException(
             self, 'Must have a non-empty list of jars.')
     self.add_labels('jars', 'jvm')
Example #23
0
    def export_addresses(self):
        exports = self._cached_exports_addresses
        if exports is None:

            exports = []
            for export_spec in getattr(self, 'export_specs', tuple()):
                if isinstance(export_spec, Target):
                    exports.append(export_spec.address)
                else:
                    exports.append(
                        Address.parse(export_spec,
                                      relative_to=self.address.spec_path))
            exports = tuple(exports)

            dep_addresses = {d.address for d in self.dependencies}
            invalid_export_specs = [
                a.spec for a in exports if a not in dep_addresses
            ]
            if len(invalid_export_specs) > 0:
                raise TargetDefinitionException(
                    self,
                    'Invalid exports: these exports must also be dependencies\n  {}'
                    .format('\n  '.join(invalid_export_specs)))

            self._cached_exports_addresses = exports
        return exports
Example #24
0
    def exports(self, dep_context):
        """
    :param dep_context: A DependencyContext with configuration for the request.

    :return: targets that this target directly exports. Note that this list is not transitive,
      but that exports are transitively expanded during the computation of strict_dependencies.
    :rtype: list of Target
    """
        exports = self._cached_exports_map.get(dep_context, None)
        if exports is None:
            exports = []
            for export in getattr(self, 'export_specs', []):
                if not isinstance(export, Target):
                    export_spec = export
                    export_addr = Address.parse(
                        export_spec, relative_to=self.address.spec_path)
                    export = self._build_graph.get_target(export_addr)
                    if export not in self.dependencies:
                        # A target can only export its dependencies.
                        raise TargetDefinitionException(
                            self,
                            'Invalid export: "{}" must also be a dependency.'.
                            format(export_spec))
                if isinstance(export, dep_context.codegen_types):
                    export = _get_synthetic_target(self, export)
                exports.append(export)
            self._cached_exports_map[dep_context] = exports
        return exports
Example #25
0
    def __call__(self, name=None, dist=None):
        """
        :param string name: The name to use for the target, defaults to the dist name if specified and
                            otherwise the parent dir name.
        :param string dist: The pants dist to create a requirement for. This must be a
                            'pantsbuild.pants*' distribution; eg:
                            'pantsbuild.pants.contrib.python.checks'.
        """
        name = name or dist or os.path.basename(self._parse_context.rel_path)
        dist = dist or "pantsbuild.pants"
        if not (dist == "pantsbuild.pants"
                or dist.startswith("pantsbuild.pants.")):
            target = Address(spec_path=self._parse_context.rel_path,
                             target_name=name)
            raise TargetDefinitionException(
                target=target,
                msg="The {} target only works for pantsbuild.pants "
                "distributions, given {}".format(self.alias, dist),
            )

        requirement = PythonRequirement(requirement="{key}=={version}".format(
            key=dist, version=pants_version()))

        self._parse_context.create_object("python_requirement_library",
                                          name=name,
                                          requirements=[requirement])
Example #26
0
  def create_sources_field(self, sources, sources_rel_path, address=None, key_arg=None):
    """Factory method to create a SourcesField appropriate for the type of the sources object.

    Note that this method is called before the call to Target.__init__ so don't expect fields to
    be populated!

    :API: public

    :return: a payload field object representing the sources parameter
    :rtype: SourcesField
    """

    if sources is None:
      sources = FilesetWithSpec.empty(sources_rel_path)
    elif isinstance(sources, FilesetWithSpec):
      pass
    elif isinstance(sources, (set, list, tuple)):
      # Received a literal sources list: convert to a FilesetWithSpec via Files.
      sources = Files.create_fileset_with_spec(sources_rel_path, *sources)
    else:
      key_arg_section = "'{}' to be ".format(key_arg) if key_arg else ""
      raise TargetDefinitionException(self, "Expected {}a glob, an address or a list, but was {}"
                                            .format(key_arg_section, type(sources)))

    return SourcesField(sources=sources)
Example #27
0
 def _validate_target(self, target):
     # TODO: move this check to an optional phase in goal_runner, so
     # that missing sources can be detected early.
     if not target.payload.sources.source_paths and not self.get_options(
     ).allow_empty_sources:
         msg = 'JUnitTests target must include a non-empty set of sources.'
         raise TargetDefinitionException(target, msg)
Example #28
0
 def _validate_rpc_style(self, target):
   rpc_style = self._thrift_defaults.rpc_style(target)
   if rpc_style not in _RPC_STYLES:
     raise TargetDefinitionException(
         target,
         'rpc_style {} not supported: expected one of {}.'.format(rpc_style, _RPC_STYLES))
   return rpc_style
Example #29
0
 def _validate_language(self, target):
   language = self._thrift_defaults.language(target)
   if language not in self._registered_language_aliases():
     raise TargetDefinitionException(
         target,
         'language {} not supported: expected one of {}.'.format(language, self._registered_language_aliases().keys()))
   return language
Example #30
0
    def create_sources_field(self, sources, sources_rel_path, key_arg=None):
        """Factory method to create a SourcesField appropriate for the type of the sources object.

    Note that this method is called before the call to Target.__init__ so don't expect fields to
    be populated!

    :API: public

    :return: a payload field object representing the sources parameter
    :rtype: SourcesField
    """
        if sources is None:
            # Make sure we don't apply the defaulting to uses of this method other than for
            # creating a sources= field (e.g., we also use this for creating resources= fields).
            # Note that the check for supports_default_sources() precedes the subsystem check.
            # This is so that tests don't need to set up the subsystem when creating targets that
            # legitimately do not require sources.
            if ((key_arg is None or key_arg == 'sources')
                    and self.supports_default_sources() and self.Arguments.
                    global_instance().get_options().implicit_sources):
                sources = self.default_sources(sources_rel_path)
            else:
                sources = FilesetWithSpec.empty(sources_rel_path)
        elif isinstance(sources, (set, list, tuple)):
            # Received a literal sources list: convert to a FilesetWithSpec via Files.
            sources = Files.create_fileset_with_spec(sources_rel_path,
                                                     *sources)
        elif not isinstance(sources, FilesetWithSpec):
            key_arg_section = "'{}' to be ".format(key_arg) if key_arg else ""
            raise TargetDefinitionException(
                self,
                "Expected {}a glob, an address or a list, but was {}".format(
                    key_arg_section, type(sources)))

        return SourcesField(sources=sources)