Example #1
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)
Example #2
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)
Example #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
Example #4
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)
Example #5
0
 def __init__(self, sources, address=None, exports=None, **kwargs):
   payload = Payload()
   payload.add_field('sources', self.create_sources_field(sources,
                                                          sources_rel_path=address.spec_path,
                                                          key_arg='sources'))
   payload.add_field('exports', PrimitivesSetField(exports or []))
   super(SourcesTarget, self).__init__(address=address, payload=payload, **kwargs)
Example #6
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)
Example #7
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)
Example #8
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)
  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)
Example #10
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)
Example #11
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)
Example #12
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)
Example #13
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)
Example #14
0
 def payload_for_scope(self, scope):
   """Returns a payload representing the options for the given scope."""
   payload = Payload()
   for (name, _, kwargs) in self.registration_args_iter_for_scope(scope):
     if not kwargs.get('fingerprint', False):
       continue
     val = self.for_scope(scope)[name]
     val_type = kwargs.get('type', '')
     if val_type == Options.file:
       field = FileField(val)
     elif val_type == Options.target_list:
       field = TargetListField(val)
     else:
       field = PrimitiveField(val)
     payload.add_field(name, field)
   payload.freeze()
   return payload
Example #15
0
    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")
Example #16
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)
Example #17
0
 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 {})})
Example #18
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)
Example #19
0
    def __init__(self,
                 package_manager=None,
                 sources=None,
                 build_script=None,
                 output_dir='dist',
                 dev_dependency=False,
                 style_ignore_path='.eslintignore',
                 address=None,
                 payload=None,
                 bin_executables=None,
                 node_scope=None,
                 **kwargs):
        """
    :param sources: Javascript and other source code files that make up this module; paths are
                    relative to the BUILD file's directory.
    :type sources: `globs`, `rglobs` or a list of strings

    :param package_manager: choose among supported package managers (npm or yarn).
    :param build_script: build script name as defined in package.json.  All files that are needed
      for the build script must be included in sources.  The script should output build results
      in the directory specified by output_dir.  If build_script is not supplied, the node
      installation results will be considered as output. The output can be archived or included as
      resources for JVM target.
    :param output_dir: relative path to assets generated by build script. The path will be
      preserved in the created JAR if the target is used as a JVM target dependency.
    :param dev_dependency: boolean value.  Default is False. If a node_module is used as parts
      of devDependencies and thus should not be included in the final bundle or JVM binaries, set
      this value to True.
    :param style_ignore_path: relative path to file specifying patterns of files to ignore. The syntax
      supported is the same as the .eslintignore/.gitignore syntax.
    :param bin_executables: A map of executable names to local file name. If a single executable is
                            specified (a string), the package name will be the executable name
                            and the value will be the local file name per package.json rules.
    :type bin_executables: `dict`, where key is bin name and value is a local file path to an executable
                           E.G. { 'app': './cli.js', 'runner': './scripts/run.sh' }
                           `string`, file path and package name as  the default bin name
                           E.G. './cli.js' would be interpreted as { 'app': './cli.js' }
    :param node_scope: Groups related packages together by adding a scope. The `@`
      symbol is typically used for specifying scope in the package name in `package.json`.
      However pants target addresses do not allow for `@` in the target address.
      A repo-level default scope can be added with the --node-distribution-node-scope option.
      Any target-level node_scope will override the global node-scope.

    """
        # TODO(John Sirois): Support devDependencies, etc.  The devDependencies case is not
        # clear-cut since pants controlled builds would provide devDependencies as needed to perform
        # tasks.  The reality is likely to be though that both pants will never cover all cases, and a
        # back door to execute new tools during development will be desirable and supporting conversion
        # of pre-existing package.json files as node_module targets will require this.

        bin_executables = bin_executables or {}
        if not (isinstance(bin_executables, dict)
                or isinstance(bin_executables, string_types)):
            raise TargetDefinitionException(
                self,
                'expected a `dict` or `str` object for bin_executables, instead found a {}'
                .format(type(bin_executables)))

        payload = payload or Payload()
        payload.add_fields({
            'sources':
            self.create_sources_field(sources=sources,
                                      sources_rel_path=address.spec_path,
                                      key_arg='sources'),
            'build_script':
            PrimitiveField(build_script),
            'package_manager':
            PrimitiveField(package_manager),
            'output_dir':
            PrimitiveField(output_dir),
            'dev_dependency':
            PrimitiveField(dev_dependency),
            'style_ignore_path':
            PrimitiveField(style_ignore_path),
            'bin_executables':
            PrimitiveField(bin_executables),
            'node_scope':
            PrimitiveField(node_scope),
        })
        super(NodeModule, self).__init__(address=address,
                                         payload=payload,
                                         **kwargs)
Example #20
0
 def __init__(self, payload=None, runtime_platform=None, **kwargs):
     payload = payload or Payload()
     super(HasRuntimePlatform,
           self).__init__(payload=payload,
                          runtime_platform=runtime_platform,
                          **kwargs)
Example #21
0
    def __init__(self,
                 address=None,
                 spec=None,
                 sources=None,
                 remote_sources=None,
                 defines=None,
                 payload=None,
                 **kwargs):
        """
    :param spec: the RPM spec file to use to build the RPMs
    :param spec: string
    :param sources: source files to be placed in the rpmbuild SOURCES directory
    :type sources: ``Fileset`` or list of strings. Paths are relative to the
      BUILD file's directory.
    :param remote_sources: URLs for files to download and place in the rpmbuild SOURCES directory
    :type remote_sources: list[str or tuple(str, str)]
    :param defines: macro definitions to pass into rpmbuild
    :type defines: dict[str, str]
    """

        self.address = address

        # Validate the parameters.
        if spec and not isinstance(spec, string_types):
            raise TargetDefinitionException(
                self, 'spec must be a single relative file path')
        remote_sources = remote_sources or []
        if not isinstance(remote_sources, list) or any(
            [not self._validate_remote_source(x) for x in remote_sources]):
            raise TargetDefinitionException(
                self,
                'remote_sources must be a list of either a string or tuple of two strings'
            )
        defines = defines or {}
        if not isinstance(defines, dict):
            raise TargetDefinitionException(self,
                                            'defines must be a dictionary')

        payload = payload or Payload()
        payload.add_fields({
            'rpm_spec':
            self.create_sources_field([spec],
                                      address.spec_path,
                                      key_arg='rpm_spec'),
            'sources':
            self.create_sources_field(sources,
                                      address.spec_path,
                                      key_arg='sources'),
            'remote_sources':
            PrimitiveField(remote_sources),
            'defines':
            PrimitiveField(defines),
        })

        # Ensure that only a single spec file was resolved.
        if len(payload.rpm_spec.relative_to_buildroot()) != 1:
            raise TargetDefinitionException(
                self, 'spec must be a single relative file path')

        super(RpmSpecTarget, self).__init__(address=address,
                                            payload=payload,
                                            **kwargs)
Example #22
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),
                )
Example #23
0
    def __init__(self,
                 address=None,
                 payload=None,
                 sources=None,
                 provides=None,
                 excludes=None,
                 resources=None,
                 services=None,
                 platform=None,
                 strict_deps=None,
                 fatal_warnings=None,
                 **kwargs):
        """
    :param excludes: List of `exclude <#exclude>`_\s to filter this target's
      transitive dependencies against.
    :param sources: Source code files to build. Paths are relative to the BUILD
      file's directory.
    :type sources: ``Fileset`` (from globs or rglobs) or list of strings
    :param services: A dict mapping service interface names to the classes owned by this target
                     that implement them.  Keys are fully qualified service class names, values are
                     lists of strings, each string the fully qualified class name of a class owned
                     by this target that implements the service interface and should be
                     discoverable by the jvm service provider discovery mechanism described here:
                     https://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
    :param platform: The name of the platform (defined under the jvm-platform subsystem) to use
      for compilation (that is, a key into the --jvm-platform-platforms dictionary). If unspecified,
      the platform will default to the first one of these that exist: (1) the default_platform
      specified for jvm-platform, (2) a platform constructed from whatever java version is returned
      by DistributionLocator.cached().version.
    :type platform: str
    :param strict_deps: When True, only the directly declared deps of the target will be used at
      compilation time. This enforces that all direct deps of the target are declared, and can
      improve compilation speed due to smaller classpaths. Transitive deps are always provided
      at runtime.
    :type strict_deps: bool
    :param fatal_warnings: Whether to turn warnings into errors for this target.  If present,
                           takes priority over the language's fatal-warnings option.
    :type fatal_warnings: bool
    """
        self.address = address  # Set in case a TargetDefinitionException is thrown early
        payload = payload or Payload()
        excludes = ExcludesField(
            self.assert_list(excludes,
                             expected_type=Exclude,
                             key_arg='excludes'))

        payload.add_fields({
            'sources':
            self.create_sources_field(sources,
                                      address.spec_path,
                                      key_arg='sources'),
            'provides':
            provides,
            'excludes':
            excludes,
            'platform':
            PrimitiveField(platform),
            'strict_deps':
            PrimitiveField(strict_deps),
            'fatal_warnings':
            PrimitiveField(fatal_warnings),
        })
        self._resource_specs = self.assert_list(resources, key_arg='resources')

        super(JvmTarget, self).__init__(address=address,
                                        payload=payload,
                                        **kwargs)

        # Service info is only used when generating resources, it should not affect, for example, a
        # compile fingerprint or javadoc fingerprint.  As such, its not a payload field.
        self._services = services or {}

        self.add_labels('jvm')
Example #24
0
 def test_none(self):
   payload = Payload()
   payload.add_field('foo', None)
   payload2 = Payload()
   payload2.add_field('foo', PrimitiveField(None))
   self.assertNotEqual(payload.fingerprint(), payload2.fingerprint())
Example #25
0
  def __init__(self,
               name=None,
               address=None,
               payload=None,
               main=None,
               basename=None,
               sources=None,
               deploy_excludes=None,
               deploy_jar_rules=None,
               manifest_entries=None,
               shading_rules=None,
               extra_jvm_options=None,
               **kwargs):
    """
    :API: public

    :param string main: The name of the ``main`` class, e.g.,
      ``'org.pantsbuild.example.hello.main.HelloMain'``. 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.,
      ``'hello'``. (By default, uses ``name`` param)  Note this is unsafe
      because of the possible conflict when multiple binaries are built.
    :param EagerFilesetWithSpec sources: Zero or one source files. If more than one source is
      required, they should be put in a library target which should be added to dependencies.
    :param dependencies: Targets (probably ``java_library`` and
     ``scala_library`` targets) to "link" in.
    :type dependencies: list of target specs
    :param deploy_excludes: List of `exclude <#exclude>`_\\s 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 deploy_jar_rules: `Jar rules <#jar_rules>`_ for packaging this binary in a
      deploy jar.
    :param manifest_entries: dict that specifies entries for `ManifestEntries <#manifest_entries>`_
      for adding to MANIFEST.MF when packaging this binary.
    :param list shading_rules: Optional list of shading rules to apply when building a shaded
      (aka monolithic aka fat) binary jar. The order of the rules matters: the first rule which
      matches a fully-qualified class name is used to shade it. See shading_relocate(),
      shading_exclude(), shading_relocate_package(), and shading_exclude_package().
    :param list extra_jvm_options: A list of options to be passed to the jvm when running the
      binary. Example: ['-Dexample.property=1', '-DMyFlag', '-Xmx4G'] If unspecified, no extra jvm options will be added.
    """
    self.address = address  # Set in case a TargetDefinitionException is thrown early
    if main and not isinstance(main, str):
      raise TargetDefinitionException(self, 'main must be a fully qualified classname')
    if deploy_jar_rules and not isinstance(deploy_jar_rules, JarRules):
      raise TargetDefinitionException(self,
                                      'deploy_jar_rules must be a JarRules specification. got {}'
                                      .format(type(deploy_jar_rules).__name__))
    if manifest_entries and not isinstance(manifest_entries, dict):
      raise TargetDefinitionException(self,
                                      'manifest_entries must be a dict. got {}'
                                      .format(type(manifest_entries).__name__))
    payload = payload or Payload()
    payload.add_fields({
      'basename': PrimitiveField(basename or name),
      'deploy_excludes': ExcludesField(self.assert_list(deploy_excludes,
                                                        expected_type=Exclude,
                                                        key_arg='deploy_excludes')),
      'deploy_jar_rules': FingerprintedField(deploy_jar_rules or JarRules.default()),
      'manifest_entries': FingerprintedField(ManifestEntries(manifest_entries)),
      'main': PrimitiveField(main),
      'shading_rules': PrimitiveField(shading_rules or ()),
      'extra_jvm_options': PrimitiveField(list(extra_jvm_options or ())),
    })

    super().__init__(name=name, address=address, payload=payload, sources=sources, **kwargs)
Example #26
0
 def __init__(self, contents, **kwargs):
     payload = Payload()
     payload.add_field("contents", PrimitiveField(contents))
     super().__init__(payload=payload, **kwargs)
Example #27
0
 def test_missing_payload_field(self):
     payload = Payload()
     payload.add_field("foo", PrimitiveField("test-value"))
     payload.add_field("bar", PrimitiveField(None))
     self.assertEquals("test-value", payload.foo)
     self.assertEquals("test-value", payload.get_field("foo").value)
     self.assertEquals("test-value", payload.get_field_value("foo"))
     self.assertEquals(None, payload.bar)
     self.assertEquals(None, payload.get_field("bar").value)
     self.assertEquals(None, payload.get_field_value("bar"))
     self.assertEquals(None, payload.get_field("bar", default="nothing").value)
     self.assertEquals(None, payload.get_field_value("bar", default="nothing"))
     with self.assertRaises(KeyError):
         self.assertEquals(None, payload.field_doesnt_exist)
     self.assertEquals(None, payload.get_field("field_doesnt_exist"))
     self.assertEquals(None, payload.get_field_value("field_doesnt_exist"))
     self.assertEquals("nothing", payload.get_field("field_doesnt_exist", default="nothing"))
     self.assertEquals("nothing", payload.get_field_value("field_doesnt_exist", default="nothing"))
Example #28
0
    def __init__(self,
                 cwd=None,
                 payload=None,
                 timeout=None,
                 extra_jvm_options=None,
                 extra_env_vars=None,
                 concurrency=None,
                 threads=None,
                 runtime_platform=None,
                 **kwargs):
        """
        :param str cwd: working directory (relative to the build root) for the tests under this
          target. If unspecified (None), the working directory will be controlled by junit_run's --cwd
          and --chroot options.
        :param str test_platform: Deprecated. The name of the platform (defined under the jvm-platform subsystem) to
          use for running tests (that is, a key into the --jvm-platform-platforms dictionary). If
          unspecified, the platform will default to the same one used for compilation.
        :param int timeout: A timeout (in seconds) which covers the total runtime of all tests in this
          target. Only applied if `--test-junit-timeouts` is set to True.
        :param list extra_jvm_options: A list of options to be passed to the jvm when running the
          tests. Example: ['-Dexample.property=1', '-DMyFlag', '-Xmx4g'] If unspecified, no extra jvm options will be added.
        :param dict extra_env_vars: A map of environment variables to set when running the tests, e.g.
          { 'FOOBAR': 12 }. Using `None` as the value will cause the variable to be unset.
        :param string concurrency: One of 'SERIAL', 'PARALLEL_CLASSES', 'PARALLEL_METHODS',
          or 'PARALLEL_CLASSES_AND_METHODS'.  Overrides the setting of --test-junit-default-concurrency.
        :param int threads: Use the specified number of threads when running the test. Overrides
          the setting of --test-junit-parallel-threads.
        :param str runtime_platform: The name of the platform (defined under the jvm-platform subsystem)
          to use for runtime (that is, a key into the --jvm-platform-platforms dictionary). If
          unspecified, the platform will default to the first one of these that exist: (1) the
          default_runtime_platform specified for jvm-platform, (2) the platform that would be used for
          the platform kwarg.
        """

        payload = payload or Payload()

        if extra_env_vars is None:
            extra_env_vars = {}
        for key, value in extra_env_vars.items():
            if value is not None:
                extra_env_vars[key] = str(value)

        deprecated_conditional(
            lambda: "test_platform" in kwargs,
            "1.28.0.dev0",
            "test_platform",
            "Replaced with runtime_platform.",
        )
        if "test_platform" in kwargs and runtime_platform:
            raise TargetDefinitionException(
                self,
                "Cannot specify runtime_platform and test_platform together.")
        if "test_platform" in kwargs and "runtime_platform" not in kwargs:
            kwargs["runtime_platform"] = kwargs["test_platform"]
            del kwargs["test_platform"]

        payload.add_fields({
            # TODO(zundel): Do extra_jvm_options and extra_env_vars really need to be fingerprinted?
            "extra_jvm_options":
            PrimitiveField(tuple(extra_jvm_options or ())),
            "extra_env_vars":
            PrimitiveField(tuple(extra_env_vars.items())),
        })
        super().__init__(payload=payload,
                         runtime_platform=runtime_platform,
                         **kwargs)

        # These parameters don't need to go into the fingerprint:
        self._concurrency = concurrency
        self._cwd = cwd
        self._threads = None
        self._timeout = timeout

        try:
            if threads is not None:
                self._threads = int(threads)
        except ValueError:
            raise TargetDefinitionException(
                self,
                "The value for 'threads' must be an integer, got " + threads)
        if concurrency and concurrency not in self.VALID_CONCURRENCY_OPTS:
            raise TargetDefinitionException(
                self,
                "The value for 'concurrency' must be one of " +
                repr(self.VALID_CONCURRENCY_OPTS) + " got: " + concurrency,
            )
Example #29
0
  def test_validate_target_representation_args_invalid_type(self):
    with self.assertRaises(AssertionError):
      Target._validate_target_representation_args(kwargs=Payload(), payload=None)

    with self.assertRaises(AssertionError):
      Target._validate_target_representation_args(kwargs=None, payload={})
Example #30
0
 def payload_for_scope(self, scope):
   return Payload()
Example #31
0
 def test_partial_fingerprint(self):
   payload = Payload()
   payload.add_field('foo', PrimitiveField())
   fingerprint1 = payload.fingerprint()
   self.assertEqual(fingerprint1, payload.fingerprint(field_keys=('foo',)))
   payload.add_field('bar', PrimitiveField())
   fingerprint2 = payload.fingerprint()
   self.assertEqual(fingerprint1, payload.fingerprint(field_keys=('foo',)))
   self.assertNotEqual(fingerprint2, payload.fingerprint(field_keys=('foo',)))
   self.assertNotEqual(fingerprint2, payload.fingerprint(field_keys=('bar',)))
   self.assertEqual(fingerprint2, payload.fingerprint(field_keys=('bar', 'foo')))
Example #32
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
            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 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),
        })

        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))
Example #33
0
 def test_missing_payload_field(self):
   payload = Payload()
   payload.add_field('foo', PrimitiveField('test-value'))
   payload.add_field('bar', PrimitiveField(None))
   self.assertEqual('test-value', payload.foo);
   self.assertEqual('test-value', payload.get_field('foo').value)
   self.assertEqual('test-value', payload.get_field_value('foo'))
   self.assertEqual(None, payload.bar);
   self.assertEqual(None, payload.get_field('bar').value)
   self.assertEqual(None, payload.get_field_value('bar'))
   self.assertEqual(None, payload.get_field('bar', default='nothing').value)
   self.assertEqual(None, payload.get_field_value('bar', default='nothing'))
   with self.assertRaises(KeyError):
     self.assertEqual(None, payload.field_doesnt_exist)
   self.assertEqual(None, payload.get_field('field_doesnt_exist'))
   self.assertEqual(None, payload.get_field_value('field_doesnt_exist'))
   self.assertEqual('nothing', payload.get_field('field_doesnt_exist', default='nothing'))
   self.assertEqual('nothing', payload.get_field_value('field_doesnt_exist', default='nothing'))
Example #34
0
    def __init__(self,
                 payload=None,
                 service_writer=None,
                 service_writer_options=None,
                 service_factory=None,
                 service_factory_options=None,
                 roots=None,
                 registry_class=None,
                 enum_options=None,
                 no_options=None,
                 **kwargs):
        """
    :param string service_writer: the name of the class to pass as the --service_writer option to
    the Wire compiler (For wire 1.x compatibility)
    :param list service_writer_options: A list of options to pass to the service writer (For
    wire 1.x compatibility)
    :param string service_factory: the name of the class to pass as the --service_factory option to
    the Wire compiler
    :param list service_factory_options: A list of options to pass to the service factory
    :param list roots: passed through to the --roots option of the Wire compiler
    :param string registry_class: fully qualified class name of RegistryClass to create. If in
    doubt, specify com.squareup.wire.SimpleServiceWriter
    :param list enum_options: list of enums to pass to as the --enum-enum_options option, # optional
    :param boolean no_options: boolean that determines if --no_options flag is passed
    """

        if service_writer and service_factory:
            raise TargetDefinitionException(
                self,
                'Specify only one of "service_writer" (wire 1.x only) or "service_factory"'
            )
        if not service_writer and service_writer_options:
            raise TargetDefinitionException(
                self, 'service_writer_options requires setting service_writer')
        if not service_factory and service_factory_options:
            raise TargetDefinitionException(
                self,
                'service_factory_options requires setting service_factory')

        payload = payload or Payload()
        payload.add_fields({
            'service_writer':
            PrimitiveField(service_writer or None),
            'service_writer_options':
            PrimitiveField(
                assert_list(service_writer_options,
                            key_arg='service_writer_options',
                            raise_type=TargetDefinitionException)),
            'service_factory':
            PrimitiveField(service_factory or None),
            'service_factory_options':
            PrimitiveField(
                assert_list(service_factory_options,
                            key_arg='service_factory_options',
                            raise_type=TargetDefinitionException)),
            'roots':
            PrimitiveField(roots or []),
            'registry_class':
            PrimitiveField(registry_class or None),
            'enum_options':
            PrimitiveField(enum_options or []),
            'no_options':
            PrimitiveField(no_options or False),
        })

        super(JavaWireLibrary, self).__init__(payload=payload, **kwargs)
        self.add_labels('codegen')
Example #35
0
    def test_validate_target_representation_args_invalid_exactly_one(self):
        with self.assertRaises(AssertionError):
            Target._validate_target_representation_args(None, None)

        with self.assertRaises(AssertionError):
            Target._validate_target_representation_args({}, Payload())
 def __init__(self, payload, runtime_platform=None, **kwargs):
     payload = payload or Payload()
     payload.add_fields(
         {"runtime_platform": PrimitiveField(runtime_platform),}
     )
     super(RuntimePlatformMixin, self).__init__(payload=payload, **kwargs)
Example #37
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.

  :API: public
  """

  @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_TEXT)]  # 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`.

    :API: public
    """
    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.

    :API: public
    """
    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().encode())
    for rule in self.rules:
      hasher.update(rule.fingerprint().encode())
    return hasher.hexdigest()

  @property
  def value(self):
    return self._jar_rules
Example #38
0
 def __init__(self, base_image=None, payload=None, **kwargs):
     payload = payload or Payload()
     payload.add_fields({'base_image': PrimitiveField(base_image)})
     self.base_image = base_image
     super(DockerBundleTarget, self).__init__(payload=payload, **kwargs)
Example #39
0
 def __init__(self, target_base=None, payload=None, *args, **kwargs):
   payload = payload or Payload()
   super(AbsoluteResources, self).__init__(payload=payload, *args, **kwargs)
Example #40
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))
Example #41
0
    def __init__(self,
                 name,
                 address,
                 build_graph,
                 type_alias=None,
                 payload=None,
                 tags=None,
                 description=None,
                 no_cache=False,
                 scope=None,
                 _transitive=None,
                 **kwargs):
        """
    :API: public

    :param string name: The name of this target, which combined with this build file defines the
                        target address.
    :param dependencies: Target address specs of other targets that this target depends on.
    :type dependencies: list of strings
    :param address: The Address that maps to this Target in the BuildGraph.
    :type address: :class:`pants.build_graph.address.Address`
    :param build_graph: The BuildGraph that this Target lives within.
    :type build_graph: :class:`pants.build_graph.build_graph.BuildGraph`
    :param string type_alias: The type_alias used to construct this target, may be None if
                              constructed directly.
    :param payload: The configuration encapsulated by this target.  Also in charge of most
                    fingerprinting details.
    :type payload: :class:`pants.base.payload.Payload`
    :param tags: Arbitrary string tags that describe this target. Usable by downstream/custom tasks
                 for reasoning about the build graph. NOT included in payloads and thus not used in
                 fingerprinting, thus not suitable for anything that affects how a particular
                 target is built.
    :type tags: :class:`collections.Iterable` of strings
    :param no_cache: If True, results for this target should not be stored in the artifact cache.
    :param string description: Human-readable description of this target.
    :param string scope: The scope of this target, used to determine its inclusion on the classpath
      (and possibly more things in the future). See :class:`pants.build_graph.target_scopes.Scopes`.
      A value of None, '', or 'default' results in the default scope, which is included everywhere.
    """
        # NB: dependencies are in the pydoc above as a BUILD dictionary hack only; implementation hides
        # the dependencies via TargetAddressable.

        self.payload = payload or Payload()
        self._scope = Scope(scope)
        self.payload.add_field('scope_string', PrimitiveField(str(scope)))
        self.payload.add_field(
            'transitive',
            PrimitiveField(True if _transitive is None else _transitive))
        self.payload.freeze()
        self.name = name
        self.address = address
        self._build_graph = build_graph
        self._type_alias = type_alias
        self._tags = set(tags or [])
        self.description = description

        self._cached_fingerprint_map = {}
        self._cached_all_transitive_fingerprint_map = {}
        self._cached_direct_transitive_fingerprint_map = {}
        self._cached_strict_dependencies_map = {}
        self._cached_exports_addresses = None
        self._no_cache = no_cache
        if kwargs:
            self.Arguments.check(self, kwargs, self.payload)
Example #42
0
    def __init__(self,
                 cwd=None,
                 test_platform=None,
                 payload=None,
                 timeout=None,
                 extra_jvm_options=None,
                 extra_env_vars=None,
                 concurrency=None,
                 threads=None,
                 **kwargs):
        """
    :param str cwd: working directory (relative to the build root) for the tests under this
      target. If unspecified (None), the working directory will be controlled by junit_run's --cwd.
    :param str test_platform: The name of the platform (defined under the jvm-platform subsystem) to
      use for running tests (that is, a key into the --jvm-platform-platforms dictionary). If
      unspecified, the platform will default to the same one used for compilation.
    :param int timeout: A timeout (in seconds) which covers the total runtime of all tests in this
      target. Only applied if `--test-junit-timeouts` is set to True.
    :param list extra_jvm_options: A list of key value pairs of jvm options to use when running the
      tests. Example: ['-Dexample.property=1'] If unspecified, no extra jvm options will be added.
    :param dict extra_env_vars: A map of environment variables to set when running the tests, e.g.
      { 'FOOBAR': 12 }. Using `None` as the value will cause the variable to be unset.
    :param string concurrency: One of 'SERIAL', 'PARALLEL_CLASSES', 'PARALLEL_METHODS',
      or 'PARALLEL_CLASSES_AND_METHODS'.  Overrides the setting of --test-junit-default-concurrency.
    :param int threads: Use the specified number of threads when running the test. Overrides
      the setting of --test-junit-parallel-threads.
    """

        payload = payload or Payload()

        if extra_env_vars is None:
            extra_env_vars = {}
        for key, value in extra_env_vars.items():
            if value is not None:
                extra_env_vars[key] = str(value)

        payload.add_fields({
            'test_platform':
            PrimitiveField(test_platform),
            # TODO(zundel): Do extra_jvm_options and extra_env_vars really need to be fingerprinted?
            'extra_jvm_options':
            PrimitiveField(tuple(extra_jvm_options or ())),
            'extra_env_vars':
            PrimitiveField(tuple(extra_env_vars.items())),
        })
        super(JavaTests, self).__init__(payload=payload, **kwargs)

        # These parameters don't need to go into the fingerprint:
        self._concurrency = concurrency
        self._cwd = cwd
        self._threads = None
        self._timeout = timeout

        try:
            if threads is not None:
                self._threads = int(threads)
        except ValueError:
            raise TargetDefinitionException(
                self,
                "The value for 'threads' must be an integer, got " + threads)
        if concurrency and concurrency not in self.VALID_CONCURRENCY_OPTS:
            raise TargetDefinitionException(
                self, "The value for 'concurrency' must be one of " +
                repr(self.VALID_CONCURRENCY_OPTS) + " got: " + concurrency)

        # TODO(John Sirois): These could be scala, clojure, etc.  'jvm' and 'tests' are the only truly
        # applicable labels - fixup the 'java' misnomer.
        self.add_labels('java', 'tests')
Example #43
0
 def test_validate_target_representation_args_valid(self):
     Target._validate_target_representation_args(kwargs={}, payload=None)
     Target._validate_target_representation_args(kwargs=None,
                                                 payload=Payload())
Example #44
0
 def test_freeze(self):
   payload = Payload()
   payload.add_field('foo', PrimitiveField())
   payload.freeze()
   with self.assertRaises(PayloadFrozenError):
     payload.add_field('bar', PrimitiveField())
Example #45
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
Example #46
0
 def test_fingerprint(self):
   payload = Payload()
   payload.add_field('foo', PrimitiveField())
   fingerprint1 = payload.fingerprint()
   self.assertEqual(fingerprint1, payload.fingerprint())
   payload.add_field('bar', PrimitiveField())
   fingerprint2 = payload.fingerprint()
   self.assertNotEqual(fingerprint1, fingerprint2)
   self.assertEqual(fingerprint2, payload.fingerprint())
   payload.freeze()
   self.assertEqual(fingerprint2, payload.fingerprint())
 def _make_payload_from_sources(self, sources):
   p = Payload()
   p.add_field('sources', SourcesField('', sources))
   p.freeze()
   return p
Example #48
0
 def test_none(self):
   payload = Payload()
   payload.add_field('foo', None)
   payload2 = Payload()
   payload2.add_field('foo', PrimitiveField(None))
   self.assertNotEqual(payload.fingerprint(), payload2.fingerprint())
Example #49
0
 def __init__(self, contents, **kwargs):
     payload = Payload()
     payload.add_field("contents", PrimitiveField(contents))
     super(MinimalImplResourcesTaskTest.TestTarget,
           self).__init__(payload=payload, **kwargs)
Example #50
0
    def __init__(self,
                 name=None,
                 address=None,
                 payload=None,
                 main=None,
                 basename=None,
                 source=None,
                 deploy_excludes=None,
                 deploy_jar_rules=None,
                 manifest_entries=None,
                 shading_rules=None,
                 **kwargs):
        """
    :API: public

    :param string main: The name of the ``main`` class, e.g.,
      ``'org.pantsbuild.example.hello.main.HelloMain'``. 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.,
      ``'hello'``. (By default, uses ``name`` param)  Note this is unsafe
      because of the possible conflict when multiple binaries are built.
    :param string source: Name of one ``.java`` or ``.scala`` file (a good
      place for a ``main``).
    :param dependencies: Targets (probably ``java_library`` and
     ``scala_library`` targets) to "link" in.
    :type dependencies: list of target specs
    :param deploy_excludes: List of `exclude <#exclude>`_\s 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 deploy_jar_rules: `Jar rules <#jar_rules>`_ for packaging this binary in a
      deploy jar.
    :param manifest_entries: dict that specifies entries for `ManifestEntries <#manifest_entries>`_
      for adding to MANIFEST.MF when packaging this binary.
    :param list shading_rules: Optional list of shading rules to apply when building a shaded
      (aka monolithic aka fat) binary jar. The order of the rules matters: the first rule which
      matches a fully-qualified class name is used to shade it. See shading_relocate(),
      shading_exclude(), shading_relocate_package(), and shading_exclude_package().
    """
        self.address = address  # Set in case a TargetDefinitionException is thrown early
        if main and not isinstance(main, string_types):
            raise TargetDefinitionException(
                self, 'main must be a fully qualified classname')
        if source and not isinstance(source, string_types):
            raise TargetDefinitionException(
                self, 'source must be a single relative file path')
        if deploy_jar_rules and not isinstance(deploy_jar_rules, JarRules):
            raise TargetDefinitionException(
                self,
                'deploy_jar_rules must be a JarRules specification. got {}'.
                format(type(deploy_jar_rules).__name__))
        if manifest_entries and not isinstance(manifest_entries, dict):
            raise TargetDefinitionException(
                self, 'manifest_entries must be a dict. got {}'.format(
                    type(manifest_entries).__name__))
        sources = [source] if source else None
        if 'sources' in kwargs:
            raise self.IllegalArgument(
                address.spec,
                'jvm_binary only supports a single "source" argument, typically used to specify a main '
                'class source file. Other sources should instead be placed in a java_library, which '
                'should be referenced in the jvm_binary\'s dependencies.')
        payload = payload or Payload()
        payload.add_fields({
            'basename':
            PrimitiveField(basename or name),
            'deploy_excludes':
            ExcludesField(
                self.assert_list(deploy_excludes,
                                 expected_type=Exclude,
                                 key_arg='deploy_excludes')),
            'deploy_jar_rules':
            FingerprintedField(deploy_jar_rules or JarRules.default()),
            'manifest_entries':
            FingerprintedField(ManifestEntries(manifest_entries)),
            'main':
            PrimitiveField(main),
            'shading_rules':
            PrimitiveField(shading_rules or ()),
        })

        super(JvmBinary,
              self).__init__(name=name,
                             address=address,
                             payload=payload,
                             sources=self.assert_list(sources,
                                                      key_arg='sources'),
                             **kwargs)
Example #51
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)
Example #52
0
    def __init__(
            self,
            address=None,
            payload=None,
            sources=None,
            provides=None,
            excludes=None,
            services=None,
            platform=None,
            strict_deps=None,
            exports=None,
            fatal_warnings=None,
            compiler_option_sets=None,
            zinc_file_manager=None,
            # Some subclasses can have both .java and .scala sources
            # (e.g., JUnitTests, JvmBinary, even ScalaLibrary), so it's convenient
            # to have both plugins settings here, even though for other subclasses
            # (e.g., JavaLibrary) only one will be relevant.
            javac_plugins=None,
            javac_plugin_args=None,
            scalac_plugins=None,
            scalac_plugin_args=None,
            **kwargs):
        """
    :API: public

    :param excludes: List of `exclude <#exclude>`_\s to filter this target's
      transitive dependencies against.
    :param sources: Source code files to build. Paths are relative to the BUILD
      file's directory.
    :type sources: ``Fileset`` (from globs or rglobs) or list of strings
    :param services: A dict mapping service interface names to the classes owned by this target
                     that implement them.  Keys are fully qualified service class names, values are
                     lists of strings, each string the fully qualified class name of a class owned
                     by this target that implements the service interface and should be
                     discoverable by the jvm service provider discovery mechanism described here:
                     https://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html
    :param str platform: The name of the platform (defined under the jvm-platform subsystem) to use
                         for compilation (that is, a key into the --jvm-platform-platforms
                         dictionary). If unspecified, the platform will default to the first one of
                         these that exist: (1) the default_platform specified for jvm-platform,
                         (2) a platform constructed from whatever java version is returned by
                         DistributionLocator.cached().version.
    :param bool strict_deps: When True, only the directly declared deps of the target will be used
                             at compilation time. This enforces that all direct deps of the target
                             are declared, and can improve compilation speed due to smaller
                             classpaths. Transitive deps are always provided at runtime.
    :param list exports: A list of exported targets, which will be accessible to dependents even
                         with strict_deps turned on. A common use case is for library targets to
                         to export dependencies that it knows its dependents will need. Then any
                         dependents of that library target will have access to those dependencies
                         even when strict_deps is True. Note: exports is transitive, which means
                         dependents have access to the closure of exports. An example will be that
                         if A exports B, and B exports C, then any targets that depends on A will
                         have access to both B and C.
    :param bool fatal_warnings: Whether to turn warnings into errors for this target.  If present,
                                takes priority over the language's fatal-warnings option. Deprecated.
    :param bool zinc_file_manager: Whether to use zinc provided file manager that allows
                                   transactional rollbacks, but in certain cases may conflict with
                                   user libraries.
    :param javac_plugins: names of compiler plugins to use when compiling this target with javac.
    :param dict javac_plugin_args: Map from javac plugin name to list of arguments for that plugin.
    :param scalac_plugins: names of compiler plugins to use when compiling this target with scalac.
    :param dict scalac_plugin_args: Map from scalac plugin name to list of arguments for that plugin.
    """

        self.address = address  # Set in case a TargetDefinitionException is thrown early
        payload = payload or Payload()
        excludes = ExcludesField(
            self.assert_list(excludes,
                             expected_type=Exclude,
                             key_arg='excludes'))
        deprecated_conditional(
            lambda: fatal_warnings is not None,
            removal_version='1.11.0dev0',
            entity_description='fatal_warnings',
            hint_message=
            "fatal_warnings should be defined as part of the target compiler_option_sets"
        )
        if fatal_warnings is not None:
            compiler_option_sets = [] if compiler_option_sets is None else compiler_option_sets
            if fatal_warnings:
                compiler_option_sets.append('fatal_warnings')
            else:
                try:
                    compiler_option_sets.remove('fatal_warnings')
                except ValueError:
                    pass
        payload.add_fields({
            'sources':
            self.create_sources_field(sources,
                                      address.spec_path,
                                      key_arg='sources'),
            'provides':
            provides,
            'excludes':
            excludes,
            'platform':
            PrimitiveField(platform),
            'strict_deps':
            PrimitiveField(strict_deps),
            'exports':
            PrimitivesSetField(exports or []),
            'compiler_option_sets':
            PrimitivesSetField(compiler_option_sets),
            'zinc_file_manager':
            PrimitiveField(zinc_file_manager),
            'javac_plugins':
            PrimitivesSetField(javac_plugins or []),
            'javac_plugin_args':
            PrimitiveField(javac_plugin_args),
            'scalac_plugins':
            PrimitivesSetField(scalac_plugins or []),
            'scalac_plugin_args':
            PrimitiveField(scalac_plugin_args),
        })

        super(JvmTarget, self).__init__(address=address,
                                        payload=payload,
                                        **kwargs)

        # Service info is only used when generating resources, it should not affect, for example, a
        # compile fingerprint or javadoc fingerprint.  As such, its not a payload field.
        self._services = services or {}
Example #53
0
 def test_field_duplication(self):
   payload = Payload()
   payload.add_field('foo', PrimitiveField())
   payload.freeze()
   with self.assertRaises(PayloadFieldAlreadyDefinedError):
     payload.add_field('foo', PrimitiveField())
Example #54
0
    def __init__(
            self,
            address=None,
            payload=None,
            sources=None,
            resources=None,  # Old-style resources (file list, Fileset).
            resource_targets=None,  # New-style resources (Resources target specs).
            provides=None,
            compatibility=None,
            **kwargs):
        """
    :param dependencies: Other 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 target specs
    :param sources: Files to "include". Paths are relative to the
      BUILD file's directory.
    :type sources: ``Fileset`` or list of strings
    :param resources: non-Python resources, e.g. templates, keys, other data
      (it is
      recommended that your application uses the pkgutil package to access these
      resources in a .zip-module friendly way.)
    :param provides:
      The `setup_py <#setup_py>`_ to publish that represents this
      target outside the repo.
    :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.
    """
        self.address = address
        payload = payload or Payload()
        payload.add_fields({
            'sources':
            self.create_sources_field(sources,
                                      address.spec_path,
                                      key_arg='sources'),
            'resources':
            self.create_sources_field(resources,
                                      address.spec_path,
                                      key_arg='resources'),
            'provides':
            provides,
            'compatibility':
            PrimitiveField(maybe_list(compatibility or ())),
        })
        super(PythonTarget, self).__init__(address=address,
                                           payload=payload,
                                           **kwargs)
        self._resource_target_specs = resource_targets
        self.add_labels('python')

        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 #55
0
 def test_partial_fingerprint(self):
   payload = Payload()
   payload.add_field('foo', PrimitiveField())
   fingerprint1 = payload.fingerprint()
   self.assertEqual(fingerprint1, payload.fingerprint(field_keys=('foo',)))
   payload.add_field('bar', PrimitiveField())
   fingerprint2 = payload.fingerprint()
   self.assertEqual(fingerprint1, payload.fingerprint(field_keys=('foo',)))
   self.assertNotEqual(fingerprint2, payload.fingerprint(field_keys=('foo',)))
   self.assertNotEqual(fingerprint2, payload.fingerprint(field_keys=('bar',)))
   self.assertEqual(fingerprint2, payload.fingerprint(field_keys=('bar', 'foo')))
Example #56
0
 def test_freeze(self):
   payload = Payload()
   payload.add_field('foo', PrimitiveField())
   payload.freeze()
   with self.assertRaises(PayloadFrozenError):
     payload.add_field('bar', PrimitiveField())
Example #57
0
 def test_missing_payload_field(self):
   payload = Payload()
   payload.add_field('foo', PrimitiveField('test-value'))
   payload.add_field('bar', PrimitiveField(None))
   self.assertEquals('test-value', payload.foo);
   self.assertEquals('test-value', payload.get_field('foo').value)
   self.assertEquals('test-value', payload.get_field_value('foo'))
   self.assertEquals(None, payload.bar);
   self.assertEquals(None, payload.get_field('bar').value)
   self.assertEquals(None, payload.get_field_value('bar'))
   self.assertEquals(None, payload.get_field('bar', default='nothing').value)
   self.assertEquals(None, payload.get_field_value('bar', default='nothing'))
   with self.assertRaises(KeyError):
     self.assertEquals(None, payload.field_doesnt_exist)
   self.assertEquals(None, payload.get_field('field_doesnt_exist'))
   self.assertEquals(None, payload.get_field_value('field_doesnt_exist'))
   self.assertEquals('nothing', payload.get_field('field_doesnt_exist', default='nothing'))
   self.assertEquals('nothing', payload.get_field_value('field_doesnt_exist', default='nothing'))
Example #58
0
 def test_field_duplication(self):
   payload = Payload()
   payload.add_field('foo', PrimitiveField())
   payload.freeze()
   with self.assertRaises(PayloadFieldAlreadyDefinedError):
     payload.add_field('foo', PrimitiveField())
Example #59
0
 def __init__(self, contents, **kwargs):
   payload = Payload()
   payload.add_field('contents', PrimitiveField(contents))
   super(MinimalImplResourcesTaskTest.TestTarget, self).__init__(payload=payload, **kwargs)
Example #60
0
 def test_fingerprint(self):
   payload = Payload()
   payload.add_field('foo', PrimitiveField())
   fingerprint1 = payload.fingerprint()
   self.assertEqual(fingerprint1, payload.fingerprint())
   payload.add_field('bar', PrimitiveField())
   fingerprint2 = payload.fingerprint()
   self.assertNotEqual(fingerprint1, fingerprint2)
   self.assertEqual(fingerprint2, payload.fingerprint())
   payload.freeze()
   self.assertEqual(fingerprint2, payload.fingerprint())