Пример #1
0
 def __init__(self, address, payload=None, sources=None, include_relpath=None, lib_relpath=None,
              native_lib_names=None, **kwargs):
   """
   :param sources: Files owned by this target.
   :param str include_relpath: The path where C/C++ headers are located, relative to this target's
                               directory. Libraries depending on this target will be able to
                               #include files relative to this directory.
   :param str lib_relpath: The path where native libraries are located, relative to this target's
                           directory.
   :param list native_lib_names: Strings containing the libraries to add to the linker command
                                 line. These libraries become `-l<name>` arguments, so they must
                                 exist and be named `lib<name>.so` (or `lib<name>.dylib` depending
                                 on the platform) or the linker will exit with an error. This field
                                 may also be a dict mapping the OS name ('darwin' or 'linux') to a
                                 list of such strings.
   """
   if not payload:
     payload = Payload()
   payload.add_fields({
     'sources': self.create_sources_field(sources, address.spec_path, key_arg='sources'),
     'include_relpath': PrimitiveField(include_relpath),
     'lib_relpath': PrimitiveField(lib_relpath),
     'native_lib_names': PrimitiveField(native_lib_names),
   })
   super().__init__(address=address, payload=payload, **kwargs)
Пример #2
0
class ManifestEntries(FingerprintedMixin):
    """Describes additional items to add to the app manifest."""
    class ExpectedDictionaryError(Exception):
        pass

    def __init__(self, entries=None):
        """
    :param entries: Additional headers, value pairs to add to the MANIFEST.MF.
      You can just add fixed string header / value pairs.
    :type entries: dictionary of string : string
    """
        self.payload = Payload()
        if entries:
            if not isinstance(entries, dict):
                raise self.ExpectedDictionaryError(
                    "entries must be a dictionary of strings.")
            for key in entries.keys():
                if not isinstance(key, string_types):
                    raise self.ExpectedDictionaryError(
                        "entries must be dictionary of strings, got key {} type {}"
                        .format(key,
                                type(key).__name__))
        self.payload.add_fields({
            'entries': PrimitiveField(entries or {}),
        })

    def fingerprint(self):
        return self.payload.fingerprint()

    @property
    def entries(self):
        return self.payload.entries
Пример #3
0
class ManifestEntries(FingerprintedMixin):
  """Describes additional items to add to the app manifest."""

  class ExpectedDictionaryError(Exception):
    pass

  def __init__(self, entries=None):
    """
    :param entries: Additional headers, value pairs to add to the MANIFEST.MF.
      You can just add fixed string header / value pairs.
    :type entries: dictionary of string : string
    """
    self.payload = Payload()
    if entries:
      if not isinstance(entries, dict):
        raise self.ExpectedDictionaryError("entries must be a dictionary of strings.")
      for key in entries.keys():
        if not isinstance(key, string_types):
          raise self.ExpectedDictionaryError(
            "entries must be dictionary of strings, got key {} type {}"
            .format(key, type(key).__name__))
    self.payload.add_fields({
      'entries' : PrimitiveField(entries or {}),
      })

  def fingerprint(self):
    return self.payload.fingerprint()

  @property
  def entries(self):
    return self.payload.entries
Пример #4
0
 def __init__(self, address, sources, copied=None, **kwargs):
   self.copied = copied
   payload = Payload()
   payload.add_fields({
     'sources': self.create_sources_field(sources, address.spec_path, key_arg='sources'),
   })
   super(DummyTargetBase, self).__init__(address=address, payload=payload, **kwargs)
Пример #5
0
    def __init__(self,
                 address,
                 payload=None,
                 sources=None,
                 ctypes_native_library=None,
                 strict_deps=None,
                 fatal_warnings=None,
                 **kwargs):

        if not payload:
            payload = Payload()
        sources_field = self.create_sources_field(sources,
                                                  address.spec_path,
                                                  key_arg='sources')
        payload.add_fields({
            'sources': sources_field,
            'ctypes_native_library': ctypes_native_library,
            'strict_deps': PrimitiveField(strict_deps),
            'fatal_warnings': PrimitiveField(fatal_warnings),
        })

        if ctypes_native_library and not isinstance(ctypes_native_library,
                                                    NativeArtifact):
            raise TargetDefinitionException(
                "Target must provide a valid pants '{}' object. Received an object with type '{}' "
                "and value: {}.".format(NativeArtifact.alias(),
                                        type(ctypes_native_library).__name__,
                                        ctypes_native_library))

        super(NativeLibrary, self).__init__(address=address,
                                            payload=payload,
                                            **kwargs)
Пример #6
0
 def __init__(self, prefixes=None, provides=None, *args, **kwargs):
   payload = Payload()
   payload.add_fields({
     'prefixes': prefixes,
     'provides': provides,
   })
   super(PomTarget, self).__init__(payload=payload, *args, **kwargs)
Пример #7
0
 def __init__(self, zip_url, rev='', **kwargs):
     """
 :param str zip_url:
   - Any URL from which a zipfile can be downloaded containing the source code of the
     remote library.
   - Can be a template string using variables {host}, {id}, {rev}.
     Example: "{host}/{id}/{rev}.zip"
       - {host} The host address to download zip files from. Specified by an option to
                GoFetch, '--remote-lib-host'.
       - {id} The global import identifier of the library, which is specified by the path to
              the BUILD file relative to the source root of all 3rd party Go libraries.
              For example, If the 3rd party source root is "3rdparty/go", a target at
              "3rdparty/go/github.com/user/lib" would have an {id} of "github.com/user/lib".
       - {rev} See :param rev:
   - The zip file is expected to have zipped the library directory itself, and NOT the
     direct contents of the library.
       Expected: `zip -r mylib.zip mylib/`
            Not: `zip -r mylib.zip mylib/*`
 :param str rev: Identifies which version of the remote library to download.
                 This could be a commit SHA (git), node id (hg), etc.
 """
     payload = Payload()
     payload.add_fields({
         'rev': PrimitiveField(rev),
         'zip_url': PrimitiveField(zip_url)
     })
     super(GoRemoteLibrary, self).__init__(payload=payload, **kwargs)
Пример #8
0
 def __init__(self, prefixes=None, provides=None, *args, **kwargs):
     payload = Payload()
     payload.add_fields({
         'prefixes': prefixes,
         'provides': provides,
     })
     super(PomTarget, self).__init__(payload=payload, *args, **kwargs)
Пример #9
0
 def __init__(self, zip_url, rev='', **kwargs):
   """
   :param str zip_url:
     - Any URL from which a zipfile can be downloaded containing the source code of the
       remote library.
     - Can be a template string using variables {host}, {id}, {rev}.
       Example: "{host}/{id}/{rev}.zip"
         - {host} The host address to download zip files from. Specified by an option to
                  GoFetch, '--remote-lib-host'.
         - {id} The global import identifier of the library, which is specified by the path to
                the BUILD file relative to the source root of all 3rd party Go libraries.
                For example, If the 3rd party source root is "3rdparty/go", a target at
                "3rdparty/go/github.com/user/lib" would have an {id} of "github.com/user/lib".
         - {rev} See :param rev:
     - The zip file is expected to have zipped the library directory itself, and NOT the
       direct contents of the library.
         Expected: `zip -r mylib.zip mylib/`
              Not: `zip -r mylib.zip mylib/*`
   :param str rev: Identifies which version of the remote library to download.
                   This could be a commit SHA (git), node id (hg), etc.
   """
   payload = Payload()
   payload.add_fields({
     'rev': PrimitiveField(rev),
     'zip_url': PrimitiveField(zip_url)
   })
   super(GoRemoteLibrary, self).__init__(payload=payload, **kwargs)
Пример #10
0
 def __init__(self, binary=None, handler=None, **kwargs):
     """
     :param string binary: Target spec of the ``python_binary`` that contains the handler.
     :param string handler: Lambda handler entrypoint (module.dotted.name:handler_func).
     """
     payload = Payload()
     payload.add_fields({"binary": PrimitiveField(binary), "handler": PrimitiveField(handler)})
     super().__init__(payload=payload, **kwargs)
Пример #11
0
 def __init__(self, distribution_fingerprint=None, *args, **kwargs):
  """Synthetic target that represents a resolved webpack distribution."""
  # Creating the synthetic target lets us avoid any special casing in regards to build order or cache invalidation.
  payload = Payload()
  payload.add_fields({
    'distribution_fingerprint': PrimitiveField(distribution_fingerprint),
  })
  super(ResolvedWebPackDistribution, self).__init__(payload=payload, *args, **kwargs)
Пример #12
0
 def __init__(self, distribution_fingerprint=None, *args, **kwargs):
  """Synthetic target that represents a resolved webpack distribution."""
  # Creating the synthetic target lets us avoid any special casing in regards to build order or cache invalidation.
  payload = Payload()
  payload.add_fields({
    'distribution_fingerprint': PrimitiveField(distribution_fingerprint),
  })
  super(WebPackDistribution, self).__init__(payload=payload, *args, **kwargs)
Пример #13
0
 def __init__(self, address, sources, *args, **kwargs):
     payload = Payload()
     payload.add_fields({
         "sources":
         self.create_sources_field(sources=sources,
                                   sources_rel_path=address.spec_path)
     })
     super().__init__(address=address, payload=payload, *args, **kwargs)
Пример #14
0
 def __init__(self, libraries=None, *args, **kwargs):
     """
 :param libraries: Libraries that this target depends on that are not pants targets.
 For example, 'm' or 'rt' that are expected to be installed on the local system.
 :type libraries: List of libraries to link against.
 """
     payload = Payload()
     payload.add_fields({'libraries': PrimitiveField(libraries)})
     super(CppBinary, self).__init__(payload=payload, **kwargs)
Пример #15
0
 def __init__(self, deferred_sources_address=None, *args, **kwargs):
     payload = Payload()
     payload.add_fields({
         'def_sources':
         DeferredSourcesField(ref_address=deferred_sources_address),
     })
     super(TestDeferredSourcesTarget, self).__init__(payload=payload,
                                                     *args,
                                                     **kwargs)
Пример #16
0
 def __init__(self, address, sources, copied=None, **kwargs):
     self.copied = copied
     payload = Payload()
     payload.add_fields({
         "sources":
         self.create_sources_field(sources,
                                   address.spec_path,
                                   key_arg="sources")
     })
     super().__init__(address=address, payload=payload, **kwargs)
 def __init__(self, address, sources, *args, **kwargs):
     payload = Payload()
     payload.add_fields({
         'sources':
         self.create_sources_field(sources=sources,
                                   sources_rel_path=address.spec_path)
     })
     super(DummyCacheLibrary, self).__init__(address=address,
                                             payload=payload,
                                             *args,
                                             **kwargs)
Пример #18
0
  def __init__(self, package=None, **kwargs):
    """
    :param str package: Optional name of the package (i.e. "network" or "containers").  Defaults to `name` if omitted
    """

    self.package  = package or kwargs['name']

    payload = Payload()
    payload.add_fields({
      'package': PrimitiveField(self.package),
    })
    super(HaskellStackagePackage, self).__init__(payload = payload, **kwargs)
Пример #19
0
    def __init__(self, apply_pattern, action):
        """Creates a rule for handling duplicate jar entries.

    :param string apply_pattern: A regular expression that matches duplicate jar entries this rule
      applies to.
    :param action: An action to take to handle one or more duplicate entries.  Must be one of:
      ``Duplicate.SKIP``, ``Duplicate.REPLACE``, ``Duplicate.CONCAT``, ``Duplicate.CONCAT_TEXT``,
      or ``Duplicate.FAIL``.
    """
        payload = Payload()
        payload.add_fields({"action": PrimitiveField(self.validate_action(action))})
        super(Duplicate, self).__init__(apply_pattern, payload=payload)
Пример #20
0
    def __init__(self, package=None, **kwargs):
        """
    :param str package: Optional name of the package (i.e. "network" or "containers").  Defaults to `name` if omitted
    """

        self.package = package or kwargs['name']

        payload = Payload()
        payload.add_fields({
            'package': PrimitiveField(self.package),
        })
        super(HaskellStackagePackage, self).__init__(payload=payload, **kwargs)
Пример #21
0
  def __init__(self, resolver, **kwargs):
    """
    :param str resolver: The `stack` resolver (i.e. "lts-3.1" or "nightly-2015-08-29")
    """

    self.resolver = resolver

    payload = Payload()
    payload.add_fields({
      'resolver': PrimitiveField(self.resolver),
    })
    super(HaskellProject, self).__init__(payload = payload, **kwargs)
Пример #22
0
  def __init__(self, resolver, **kwargs):
    """
    :param str resolver: The `stack` resolver (i.e. "lts-3.1" or "nightly-2015-08-29")
    """

    self.resolver = resolver

    payload = Payload()
    payload.add_fields({
      'resolver': PrimitiveField(self.resolver),
    })
    super(HaskellProject, self).__init__(payload = payload, **kwargs)
Пример #23
0
    def __init__(self, apply_pattern, action):
        """Creates a rule for handling duplicate jar entries.

        :param string apply_pattern: A regular expression that matches duplicate jar entries this rule
          applies to.
        :param action: An action to take to handle one or more duplicate entries.  Must be one of:
          ``Duplicate.SKIP``, ``Duplicate.REPLACE``, ``Duplicate.CONCAT``, ``Duplicate.CONCAT_TEXT``,
          or ``Duplicate.FAIL``.
        """
        payload = Payload()
        payload.add_fields(
            {"action": PrimitiveField(self.validate_action(action))})
        super().__init__(apply_pattern, payload=payload)
Пример #24
0
    def __init__(self, version, package=None, **kwargs):
        """
    :param str version: The package version string (i.e. "0.4.3.0" or "1.0.0")
    :param str package: Optional name of the package (i.e. "network" or "containers").  Defaults to `name` if omitted
    """
        self.version = version
        self.package = package or kwargs['name']

        payload = Payload()
        payload.add_fields({
            'version': PrimitiveField(self.version),
            'package': PrimitiveField(self.package),
        })
        super(HaskellHackagePackage, self).__init__(**kwargs)
Пример #25
0
 def __init__(self,
              libraries=None,
              *args,
              **kwargs):
   """
   :param libraries: Libraries that this target depends on that are not pants targets.
   For example, 'm' or 'rt' that are expected to be installed on the local system.
   :type libraries: List of libraries to link against.
   """
   payload = Payload()
   payload.add_fields({
     'libraries': PrimitiveField(libraries)
   })
   super(CppBinary, self).__init__(payload=payload, **kwargs)
Пример #26
0
 def __init__(self,
              binary=None,
              handler=None,
              **kwargs):
   """
   :param string binary: Target spec of the ``python_binary`` that contains the handler.
   :param string handler: Lambda handler entrypoint (module.dotted.name:handler_func).
   """
   payload = Payload()
   payload.add_fields({
     'binary': PrimitiveField(binary),
     'handler': PrimitiveField(handler),
   })
   super(PythonAWSLambda, self).__init__(payload=payload, **kwargs)
Пример #27
0
  def __init__(self, version, package=None, **kwargs):
    """
    :param str version: The package version string (i.e. "0.4.3.0" or "1.0.0")
    :param str package: Optional name of the package (i.e. "network" or "containers").  Defaults to `name` if omitted
    """
    self.version = version
    self.package  = package or kwargs['name']

    payload = Payload()
    payload.add_fields({
      'version': PrimitiveField(self.version),
      'package': PrimitiveField(self.package),
    })
    super(HaskellHackagePackage, self).__init__(**kwargs)
Пример #28
0
    def __init__(self, package=None, path=None, **kwargs):
        """
    :param str package: Optional name of the package (i.e. "network" or "containers").  Defaults to `name` if omitted
    :param str path: Optional path to a remote source archive in TAR or ZIP format.
    """

        self.package = package or kwargs['name']
        self.path = path

        payload = Payload()
        payload.add_fields({
            'package': PrimitiveField(self.package),
            'path': PrimitiveField(self.path),
        })
        super(HaskellSourcePackage, self).__init__(payload=payload, **kwargs)
Пример #29
0
  def __init__(self, package=None, path=None, **kwargs):
    """
    :param str package: Optional name of the package (i.e. "network" or "containers").  Defaults to `name` if omitted
    :param str path: Optional path to a remote source archive in TAR or ZIP format.
    """

    self.package = package or kwargs['name']
    self.path = path

    payload = Payload()
    payload.add_fields({
      'package': PrimitiveField(self.package),
      'path': PrimitiveField(self.path),
    })
    super(HaskellSourcePackage, self).__init__(payload = payload, **kwargs)
Пример #30
0
    def __init__(self,
                 sources=None,
                 address=None,
                 **kwargs):
        
        payload = Payload()

        payload.add_fields({
            'sources': self.create_sources_field(
                sources, 
                address.spec_path, 
                key_arg='sources'
            )
        })
        super(Dockerfile, self).__init__(
            address=address,
            payload=payload,
            **kwargs
        )
Пример #31
0
    def __init__(self,
                 address,
                 payload=None,
                 sources=None,
                 ctypes_native_library=None,
                 strict_deps=None,
                 fatal_warnings=None,
                 compiler_option_sets=None,
                 toolchain_variant=None,
                 **kwargs):

        if not payload:
            payload = Payload()
        sources_field = self.create_sources_field(sources,
                                                  address.spec_path,
                                                  key_arg="sources")
        payload.add_fields({
            "sources":
            sources_field,
            "ctypes_native_library":
            ctypes_native_library,
            "strict_deps":
            PrimitiveField(strict_deps),
            "fatal_warnings":
            PrimitiveField(fatal_warnings),
            "compiler_option_sets":
            PrimitivesSetField(compiler_option_sets),
            "toolchain_variant":
            PrimitiveField(toolchain_variant),
        })

        if ctypes_native_library and not isinstance(ctypes_native_library,
                                                    NativeArtifact):
            raise TargetDefinitionException(
                "Target must provide a valid pants '{}' object. Received an object with type '{}' "
                "and value: {}.".format(
                    NativeArtifact.alias(),
                    type(ctypes_native_library).__name__,
                    ctypes_native_library,
                ))

        super().__init__(address=address, payload=payload, **kwargs)
Пример #32
0
    def create_synthetic_target(cls, options, address_mapper, build_graph,
                                discovered_targets):
        """Create a synthetic target that depends on the set of jar_library_targets.

    The created target is injected into the build graph as an unconnected target with a payload of
    a JarsField populated by the JarDependencies implied by the jar_library_targets.

    :param `pants.option.options.Option` options: The Task's scoped options.
    :param `pants.build_graph.AddressMapper` address_mapper: Populated build_graph instance.
    :param `pants.build_graph.BuildGraph` build_graph: Populated build_graph instance
    :param collection[`pants.target.Target`] discovered_targets: Targets newly injected into build graph but possibly
      not in the context of any target_root.
    :returns synthetic target:
    :rtype subclass of `pants.target.Target`:
    """
        synthetic_address = cls.get_synthetic_address()

        # JarLibrary targets have a unique attribute called `managed_dependencies`, which holds a spec of a
        # `managed_jar_dependency` target. That will not be inserted along with the rest of the jar_library's closure
        # since at address_mapping time it is not a dependency. We could take care to track them down and insert them
        # but it looks to me like this handling is already wired into the JarDependency and JarLibrary pipeline. If we
        # end up seeing misses, we can add the logic to insert them as a special case, but for now I hope to hand that
        # special casing off.
        jar_library_targets = [
            t for t in discovered_targets if isinstance(t, JarLibrary)
        ]
        all_jar_deps = JarLibrary.to_jar_dependencies(
            synthetic_address,
            [t.address.spec for t in jar_library_targets],
            build_graph,
        )
        payload = Payload()
        payload.add_fields({
            'jars': JarsField(sorted(all_jar_deps)),
        })
        synthetic_target = cls.inject_synthetic_target(
            build_graph,
            synthetic_address,
            payload=payload,
            dependencies=[j.address for j in jar_library_targets],
        )
        return synthetic_target
Пример #33
0
  def __init__(self, address, payload=None, sources=None, ctypes_native_library=None,
               strict_deps=None, fatal_warnings=None, **kwargs):

    if not payload:
      payload = Payload()
    sources_field = self.create_sources_field(sources, address.spec_path, key_arg='sources')
    payload.add_fields({
      'sources': sources_field,
      'ctypes_native_library': ctypes_native_library,
      'strict_deps': PrimitiveField(strict_deps),
      'fatal_warnings': PrimitiveField(fatal_warnings),
    })

    if ctypes_native_library and not isinstance(ctypes_native_library, NativeArtifact):
      raise TargetDefinitionException(
        "Target must provide a valid pants '{}' object. Received an object with type '{}' "
        "and value: {}."
        .format(NativeArtifact.alias(), type(ctypes_native_library).__name__, ctypes_native_library))

    super(NativeLibrary, self).__init__(address=address, payload=payload, **kwargs)
Пример #34
0
class JarRules(FingerprintedMixin):
    """A set of rules for packaging up a deploy jar.

  Deploy jars are executable jars with fully self-contained classpaths and as such, assembling them
  presents problems given jar semantics.

  One issue is signed jars that must be included on the
  classpath.  These have a signature that depends on the jar contents and assembly of the deploy jar
  changes the content of the jar, breaking the signatures.  For cases like these the signed jars
  must be verified and then the signature information thrown away.  The `Skip <#Skip>`_
  rule supports this sort of issue by allowing outright entry exclusion in the final deploy jar.

  Another issue is duplicate jar entries.  Although the underlying zip format supports these, the
  java jar tool and libraries do not.  As such some action must be taken for each duplicate entry
  such that there are no duplicates in the final deploy jar.  The four
  `Duplicate <#Duplicate>`_ rules support resolution of these cases by allowing 1st wins,
  last wins, concatenation of the duplicate entry contents or raising an exception.
  """
    @classmethod
    def skip_signatures_and_duplicates_concat_well_known_metadata(
            cls, default_dup_action=None, additional_rules=None):
        """Produces a rule set useful in many deploy jar creation contexts.

    The rule set skips duplicate entries by default, retaining the 1st encountered.  In addition it
    has the following special handling:

    - jar signature metadata is dropped
    - jar indexing files INDEX.LIST are dropped
    - ``java.util.ServiceLoader`` provider-configuration files are concatenated in the order
      encountered

    :param default_dup_action: An optional default action to take for duplicates.  Defaults to
      `Duplicate.SKIP` if not specified.
    :param additional_rules: Optionally one or more jar rules to add to those described above.
    :returns: JarRules
    """
        default_dup_action = Duplicate.validate_action(default_dup_action
                                                       or Duplicate.SKIP)
        additional_rules = assert_list(additional_rules,
                                       expected_type=(Duplicate, Skip))

        rules = [
            Skip(r'^META-INF/[^/]+\.SF$'),  # signature file
            Skip(r'^META-INF/[^/]+\.DSA$'),  # default signature alg. file
            Skip(r'^META-INF/[^/]+\.RSA$'),  # default signature alg. file
            Skip(r'^META-INF/INDEX.LIST$'
                 ),  # interferes with Class-Path: see man jar for i option
            Duplicate(r'^META-INF/services/', Duplicate.CONCAT)
        ]  # 1 svc fqcn per line

        return JarRules(rules=rules + additional_rules,
                        default_dup_action=default_dup_action)

    _DEFAULT = None

    @classmethod
    def default(cls):
        """Returns the default set of jar rules.

    Can be set with `set_default` but otherwise defaults to
    `skip_signatures_and_duplicates_concat_well_known_metadata`.
    """
        if cls._DEFAULT is None:
            cls._DEFAULT = cls.skip_signatures_and_duplicates_concat_well_known_metadata(
            )
        return cls._DEFAULT

    @classmethod
    def set_default(cls, rules):
        """Sets the default site-wide jar rules."""
        if not isinstance(rules, JarRules):
            raise ValueError('The default rules must be a JarRules instance.')
        cls._DEFAULT = rules

    def __init__(self, rules=None, default_dup_action=Duplicate.SKIP):
        """Creates a new set of jar rules with the default duplicate action of ``Duplicate.SKIP``.

    :param rules: One or more rules that will be applied in order to jar entries being packaged in
      a deploy jar. `Skip <#Skip>`_ rules can go here.
    :param default_dup_action: The default action to take when a duplicate entry is encountered and
      no explicit rules apply to the entry.
    """
        self.payload = Payload()
        self.payload.add_fields({
            'default_dup_action':
            PrimitiveField(Duplicate.validate_action(default_dup_action))
        })
        self._rules = assert_list(rules,
                                  expected_type=JarRule,
                                  key_arg="rules")

    @property
    def default_dup_action(self):
        """The default action to take when a duplicate jar entry is encountered."""
        return self.payload.default_dup_action

    @property
    def rules(self):
        """A copy of the list of explicit entry rules in effect."""
        return list(self._rules)

    def fingerprint(self):
        hasher = sha1()
        hasher.update(self.payload.fingerprint())
        for rule in self.rules:
            hasher.update(rule.fingerprint())
        return hasher.hexdigest()

    @property
    def value(self):
        return self._jar_rules
Пример #35
0
 def __init__(self, address, source, *args, **kwargs):
   payload = Payload()
   payload.add_fields({'sources': self.create_sources_field(sources=[source],
                                                            sources_rel_path=address.spec_path)})
   self.source = source
   super(DummyLibrary, self).__init__(address=address, payload=payload, *args, **kwargs)
Пример #36
0
 def __init__(self, deferred_sources_address=None, *args, **kwargs):
   payload = Payload()
   payload.add_fields({
     'def_sources': DeferredSourcesField(ref_address=deferred_sources_address),
   })
   super(TestDeferredSourcesTarget, self).__init__(payload=payload, *args, **kwargs)
Пример #37
0
  def __init__(self,
               sources=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
               shebang=None,              # pex option
               emit_warnings=None,        # pex option
               platforms=(),
               **kwargs):
    """
    :param string entry_point: the default entry point for this binary.  if None, drops into the entry
      point that is defined by source. Something like
      "pants.bin.pants_exe:main", where "pants.bin.pants_exe" is the package
      name and "main" is the function name (if ommitted, the module is
      executed directly, presuming it has a ``__main.py__``).
    :param sources: Zero or one source files. If more than one file is required, it should be put in
      a python_library which should be added to dependencies.
    :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 ignore_errors: should we ignore inability to resolve dependencies?
    :param str shebang: Use this shebang for the generated pex.
    :param bool emit_warnings: Whether or not to emit pex warnings.
    :param platforms: extra platforms to target when building this binary. If this is, e.g.,
      ``['current', 'linux-x86_64', 'macosx-10.4-x86_64']``, then when building the pex, then
      for any platform-dependent modules, Pants will include ``egg``\\s for Linux (64-bit Intel),
      Mac OS X (version 10.4 or newer), and the current platform (whatever is being used when
      making the PEX).
    """

    if inherit_path is False:
      inherit_path = "false"

    payload = Payload()
    payload.add_fields({
      'entry_point': PrimitiveField(entry_point),
      'inherit_path': PrimitiveField(inherit_path),
      'zip_safe': PrimitiveField(bool(zip_safe)),
      'always_write_cache': PrimitiveField(bool(always_write_cache)),
      'repositories': PrimitiveField(maybe_list(repositories or [])),
      'indices': PrimitiveField(maybe_list(indices or [])),
      'ignore_errors': PrimitiveField(bool(ignore_errors)),
      'platforms': PrimitiveField(tuple(maybe_list(platforms or []))),
      'shebang': PrimitiveField(shebang),
      'emit_warnings': PrimitiveField(self.Defaults.should_emit_warnings(emit_warnings)),
    })

    super(PythonBinary, self).__init__(sources=sources, payload=payload, **kwargs)

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

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

    if sources and sources.files and entry_point:
      entry_point_module = entry_point.split(':', 1)[0]
      entry_source = list(self.sources_relative_to_source_root())[0]
      source_entry_point = self._translate_to_entry_point(entry_source)
      if entry_point_module != source_entry_point:
        raise TargetDefinitionException(self,
            'Specified both source and entry_point but they do not agree: {} vs {}'.format(
            source_entry_point, entry_point_module))
Пример #38
0
    def __init__(
            self,
            source=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
            platforms=(),
            **kwargs):
        """
    :param source: relative path to one python source file that becomes this
      binary's __main__.
      If None specified, drops into an interpreter by default.
    :param string entry_point: the default entry point for this binary.  if None, drops into the entry
      point that is defined by source. Something like
      "pants.bin.pants_exe:main", where "pants.bin.pants_exe" is the package
      name and "main" is the function name (if ommitted, the module is
      executed directly, presuming it has a ``__main.py__``).
    :param sources: Overridden by source. To specify more than one source file,
      use a python_library and have the python_binary depend on that library.
    :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 ignore_errors: should we ignore inability to resolve dependencies?
    :param platforms: extra platforms to target when building this binary. If this is, e.g.,
      ``['current', 'linux-x86_64', 'macosx-10.4-x86_64']``, then when building the pex, then
      for any platform-dependent modules, Pants will include ``egg``\s for Linux (64-bit Intel),
      Mac OS X (version 10.4 or newer), and the current platform (whatever is being used when
      making the PEX).
    :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()
        payload.add_fields({
            'entry_point':
            PrimitiveField(entry_point),
            'inherit_path':
            PrimitiveField(bool(inherit_path)),
            'zip_safe':
            PrimitiveField(bool(zip_safe)),
            'always_write_cache':
            PrimitiveField(bool(always_write_cache)),
            'repositories':
            PrimitiveField(maybe_list(repositories or [])),
            'indices':
            PrimitiveField(maybe_list(indices or [])),
            'ignore_errors':
            PrimitiveField(bool(ignore_errors)),
            'platforms':
            PrimitiveField(tuple(maybe_list(platforms or []))),
        })

        sources = [] if source is None else [source]
        super(PythonBinary, self).__init__(sources=sources,
                                           payload=payload,
                                           **kwargs)

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

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

        if source and entry_point:
            entry_point_module = entry_point.split(':', 1)[0]
            entry_source = list(self.sources_relative_to_source_root())[0]
            source_entry_point = self._translate_to_entry_point(entry_source)
            if entry_point_module != source_entry_point:
                raise TargetDefinitionException(
                    self,
                    'Specified both source and entry_point but they do not agree: {} vs {}'
                    .format(source_entry_point, entry_point_module))
Пример #39
0
    def __init__(
            self,
            sources=None,
            entry_point=None,
            inherit_path=False,  # pex option
            zip_safe=True,  # pex option
            always_write_cache=False,  # pex option
            ignore_errors=False,  # pex option
            shebang=None,  # pex option
            emit_warnings=None,  # pex option
            platforms=(),
            **kwargs):
        """
        :param string entry_point: the default entry point for this binary.  if None, drops into the entry
          point that is defined by source. Something like
          "pants.bin.pants_exe:main", where "pants.bin.pants_exe" is the package
          name and "main" is the function name (if omitted, the module is
          executed directly, presuming it has a ``__main.py__``).
        :param sources: Zero or one source files. If more than one file is required, it should be put in
          a python_library which should be added to dependencies.
        :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 ignore_errors: should we ignore inability to resolve dependencies?
        :param str shebang: Use this shebang for the generated pex.
        :param bool emit_warnings: Whether or not to emit pex warnings.
        :param platforms: extra platforms to target when building this binary. If this is, e.g.,
          ``['current', 'linux-x86_64', 'macosx-10.4-x86_64']``, then when building the pex, then
          for any platform-dependent modules, Pants will include ``egg``\\s for Linux (64-bit Intel),
          Mac OS X (version 10.4 or newer), and the current platform (whatever is being used when
          making the PEX).
        """

        if inherit_path is False:
            inherit_path = "false"

        payload = Payload()
        payload.add_fields({
            "entry_point":
            PrimitiveField(entry_point),
            "inherit_path":
            PrimitiveField(inherit_path),
            "zip_safe":
            PrimitiveField(bool(zip_safe)),
            "always_write_cache":
            PrimitiveField(bool(always_write_cache)),
            "ignore_errors":
            PrimitiveField(bool(ignore_errors)),
            "platforms":
            PrimitiveField(
                tuple(ensure_str_list(platforms or [],
                                      allow_single_str=True))),
            "shebang":
            PrimitiveField(shebang),
            "emit_warnings":
            PrimitiveField(self.Defaults.should_emit_warnings(emit_warnings)),
        })

        super().__init__(sources=sources, payload=payload, **kwargs)

        if (not sources or not sources.files) and entry_point is None:
            raise TargetDefinitionException(
                self,
                "A python binary target must specify either a single source or entry_point."
            )

        if not isinstance(platforms,
                          (list, tuple)) and not isinstance(platforms, str):
            raise TargetDefinitionException(
                self, "platforms must be a list, tuple or str.")

        if sources and sources.files and entry_point:
            entry_point_module = entry_point.split(":", 1)[0]
            entry_source = list(self.sources_relative_to_source_root())[0]
            source_entry_point = self.translate_source_path_to_py_module_specifier(
                entry_source)
            if entry_point_module != source_entry_point:
                raise TargetDefinitionException(
                    self,
                    "Specified both source and entry_point but they do not agree: {} vs {}"
                    .format(source_entry_point, entry_point_module),
                )
Пример #40
0
class JarRules(FingerprintedMixin):
  """A set of rules for packaging up a deploy jar.

  Deploy jars are executable jars with fully self-contained classpaths and as such, assembling them
  presents problems given jar semantics.

  One issue is signed jars that must be included on the
  classpath.  These have a signature that depends on the jar contents and assembly of the deploy jar
  changes the content of the jar, breaking the signatures.  For cases like these the signed jars
  must be verified and then the signature information thrown away.  The `Skip <#Skip>`_
  rule supports this sort of issue by allowing outright entry exclusion in the final deploy jar.

  Another issue is duplicate jar entries.  Although the underlying zip format supports these, the
  java jar tool and libraries do not.  As such some action must be taken for each duplicate entry
  such that there are no duplicates in the final deploy jar.  The four
  `Duplicate <#Duplicate>`_ rules support resolution of these cases by allowing 1st wins,
  last wins, concatenation of the duplicate entry contents or raising an exception.
  """
  @classmethod
  def skip_signatures_and_duplicates_concat_well_known_metadata(cls, default_dup_action=None,
                                                                additional_rules=None):
    """Produces a rule set useful in many deploy jar creation contexts.

    The rule set skips duplicate entries by default, retaining the 1st encountered.  In addition it
    has the following special handling:

    - jar signature metadata is dropped
    - ``java.util.ServiceLoader`` provider-configuration files are concatenated in the order
      encountered

    :param default_dup_action: An optional default action to take for duplicates.  Defaults to
      `Duplicate.SKIP` if not specified.
    :param additional_rules: Optionally one or more jar rules to add to those described above.
    :returns: JarRules
    """
    default_dup_action = Duplicate.validate_action(default_dup_action or Duplicate.SKIP)
    additional_rules = assert_list(additional_rules, expected_type=(Duplicate, Skip))

    rules = [Skip(r'^META-INF/[^/]+\.SF$'),  # signature file
             Skip(r'^META-INF/[^/]+\.DSA$'),  # default signature alg. file
             Skip(r'^META-INF/[^/]+\.RSA$'),  # default signature alg. file
             Duplicate(r'^META-INF/services/', Duplicate.CONCAT)]  # 1 svc fqcn per line

    return JarRules(rules=rules + additional_rules, default_dup_action=default_dup_action)

  _DEFAULT = None

  @classmethod
  def default(cls):
    """Returns the default set of jar rules.

    Can be set with `set_default` but otherwise defaults to
    `skip_signatures_and_duplicates_concat_well_known_metadata`.
    """
    if cls._DEFAULT is None:
      cls._DEFAULT = cls.skip_signatures_and_duplicates_concat_well_known_metadata()
    return cls._DEFAULT

  @classmethod
  def set_default(cls, rules):
    """Sets the default site-wide jar rules."""
    if not isinstance(rules, JarRules):
      raise ValueError('The default rules must be a JarRules instance.')
    cls._DEFAULT = rules

  def __init__(self, rules=None, default_dup_action=Duplicate.SKIP):
    """Creates a new set of jar rules with the default duplicate action of ``Duplicate.SKIP``.

    :param rules: One or more rules that will be applied in order to jar entries being packaged in
      a deploy jar. `Skip <#Skip>`_ rules can go here.
    :param default_dup_action: The default action to take when a duplicate entry is encountered and
      no explicit rules apply to the entry.
    """
    self.payload = Payload()
    self.payload.add_fields({
      'default_dup_action' : PrimitiveField(Duplicate.validate_action(default_dup_action))
    })
    self._rules = assert_list(rules, expected_type=JarRule)

  @property
  def default_dup_action(self):
    """The default action to take when a duplicate jar entry is encountered."""
    return self.payload.default_dup_action

  @property
  def rules(self):
    """A copy of the list of explicit entry rules in effect."""
    return list(self._rules)

  def fingerprint(self):
    hasher = sha1()
    hasher.update(self.payload.fingerprint())
    for rule in self.rules:
      hasher.update(rule.fingerprint())
    return hasher.hexdigest()

  @property
  def value(self):
    return self._jar_rules
Пример #41
0
  def __init__(self,
               source=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
               shebang=None,              # pex option
               platforms=(),
               **kwargs):
    """
    :param source: relative path to one python source file that becomes this
      binary's __main__.
      If None specified, drops into an interpreter by default.
    :param string entry_point: the default entry point for this binary.  if None, drops into the entry
      point that is defined by source. Something like
      "pants.bin.pants_exe:main", where "pants.bin.pants_exe" is the package
      name and "main" is the function name (if ommitted, the module is
      executed directly, presuming it has a ``__main.py__``).
    :param sources: Overridden by source. To specify more than one source file,
      use a python_library and have the python_binary depend on that library.
    :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 ignore_errors: should we ignore inability to resolve dependencies?
    :param platforms: extra platforms to target when building this binary. If this is, e.g.,
      ``['current', 'linux-x86_64', 'macosx-10.4-x86_64']``, then when building the pex, then
      for any platform-dependent modules, Pants will include ``egg``\s for Linux (64-bit Intel),
      Mac OS X (version 10.4 or newer), and the current platform (whatever is being used when
      making the PEX).
    :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.
    """

    if inherit_path is False:
      inherit_path = "false"

    payload = Payload()
    payload.add_fields({
      'entry_point': PrimitiveField(entry_point),
      'inherit_path': PrimitiveField(inherit_path),
      'zip_safe': PrimitiveField(bool(zip_safe)),
      'always_write_cache': PrimitiveField(bool(always_write_cache)),
      'repositories': PrimitiveField(maybe_list(repositories or [])),
      'indices': PrimitiveField(maybe_list(indices or [])),
      'ignore_errors': PrimitiveField(bool(ignore_errors)),
      'platforms': PrimitiveField(tuple(maybe_list(platforms or []))),
      'shebang': PrimitiveField(shebang),
    })

    sources = [] if source is None else [source]
    super(PythonBinary, self).__init__(sources=sources, payload=payload, **kwargs)

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

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

    if source and entry_point:
      entry_point_module = entry_point.split(':', 1)[0]
      entry_source = list(self.sources_relative_to_source_root())[0]
      source_entry_point = self._translate_to_entry_point(entry_source)
      if entry_point_module != source_entry_point:
        raise TargetDefinitionException(self,
            'Specified both source and entry_point but they do not agree: {} vs {}'.format(
            source_entry_point, entry_point_module))