Example #1
0
 def _fetch_tool_jar_from_scalac_classpath(self, products, jar_name):
   scala_version = ScalaPlatform.global_instance().version
   classpath = self.tool_classpath_from_products(products,
                                                 ScalaPlatform.versioned_tool_name('scalac', scala_version),
                                                 scope=self.options_scope)
   candidates = [jar for jar in classpath if jar_name in jar]
   assert(len(candidates) == 1)
   return candidates[0]
Example #2
0
  def execute(self):
    """Stages IDE project artifacts to a project directory and generates IDE configuration files."""
    # Grab the targets in-play before the context is replaced by `self._prepare_project()` below.
    targets = self.context.targets()

    self._prepare_project()

    if self.context.options.is_known_scope('compile.checkstyle'):
      checkstyle_classpath = self.tool_classpath('checkstyle', scope='compile.checkstyle')
    else:  # Checkstyle not enabled.
      checkstyle_classpath = []

    if self.skip_scala:
      scalac_classpath = []
    else:
      scalac_classpath = ScalaPlatform.global_instance().compiler_classpath(self.context.products)

    self._project.set_tool_classpaths(checkstyle_classpath, scalac_classpath)
    self.map_internal_jars(targets)
    self.map_external_jars(targets)

    idefile = self.generate_project(self._project)
    if idefile:
      try:
        desktop.ui_open(idefile)
      except desktop.OpenError as e:
        raise TaskError(e)
Example #3
0
 def setup_repl_session(self, targets):
     repl_name = ScalaPlatform.global_instance().repl
     return (
         self.tool_classpath("pants-runner")
         + self.tool_classpath(repl_name, scope=ScalaPlatform.options_scope)
         + self.classpath(targets)
     )
Example #4
0
  def create_scaladoc_command(self, classpath, gendir, *targets):
    sources = []
    for target in targets:
      sources.extend(target.sources_relative_to_buildroot())
      # TODO(Tejal Desai): pantsbuild/pants/65: Remove java_sources attribute for ScalaLibrary
      # A '.scala' owning target may not have java_sources, eg: junit_tests
      if hasattr(target, 'java_sources'):
        for java_target in target.java_sources:
          sources.extend(java_target.sources_relative_to_buildroot())

    if not sources:
      return None

    scala_platform = ScalaPlatform.global_instance()
    tool_classpath = [cp_entry.path for cp_entry in scala_platform.compiler_classpath_entries(
      self.context.products, self.context._scheduler)]

    args = ['-usejavacp',
            '-classpath', ':'.join(classpath),
            '-d', gendir]

    args.extend(self.args)

    args.extend(sources)

    java_executor = SubprocessExecutor(DistributionLocator.cached())
    runner = java_executor.runner(jvm_options=self.jvm_options,
                                  classpath=tool_classpath,
                                  main='scala.tools.nsc.ScalaDoc',
                                  args=args)
    return runner.command
Example #5
0
  def create_scaladoc_command(self, classpath, gendir, *targets):
    sources = []
    for target in targets:
      sources.extend(target.sources_relative_to_buildroot())
      # TODO(Tejal Desai): pantsbuild/pants/65: Remove java_sources attribute for ScalaLibrary
      for java_target in target.java_sources:
        sources.extend(java_target.sources_relative_to_buildroot())

    if not sources:
      return None

    scala_platform = ScalaPlatform.global_instance()
    tool_classpath = scala_platform.compiler_classpath(self.context.products)

    args = ['-usejavacp',
            '-classpath', ':'.join(classpath),
            '-d', gendir]

    args.extend(self.args)

    args.extend(sources)

    java_executor = SubprocessExecutor()
    runner = java_executor.runner(jvm_options=self.jvm_options,
                                  classpath=tool_classpath,
                                  main='scala.tools.nsc.ScalaDoc',
                                  args=args)
    return runner.command
  def _language_platform_version_info(self):
    ret = []

    # Go through all the bootstrap tools required to compile.
    targets = (ScalaPlatform.global_instance().tool_targets(self.context, 'scalac') +
               self.tool_targets(self.context, 'zinc'))
    for lib in (t for t in targets if isinstance(t, JarLibrary)):
      for jar in lib.jar_dependencies:
        ret.append(jar.cache_key())

    # We must invalidate on the set of plugins and their settings.
    ret.extend(self.plugin_args())

    # Invalidate if any compiler args change.
    # Note that while some args are obviously important for invalidation (e.g., the jvm target
    # version), some might not be. However we must invalidated on all the args, because Zinc
    # ignores analysis files if the compiler args they were created with are different from the
    # current ones, and does a full recompile. So if we allow cached artifacts with those analysis
    # files to be used, Zinc will do unnecessary full recompiles on subsequent edits.
    ret.extend(self._args)

    # Invalidate if use of name hashing changes.
    ret.append('name-hashing-{0}'.format('on' if self.get_options().name_hashing else 'off'))

    return ret
Example #7
0
  def traversable_dependency_specs(self):
    for spec in super(ScalaLibrary, self).traversable_dependency_specs:
      yield spec

    # TODO(John Sirois): Targets should be able to set their scala platform version
    # explicitly, and not have to conform to this global setting.
    for library_spec in ScalaPlatform.global_instance().runtime:
      yield library_spec
Example #8
0
    def _compile_vts(self, vts, ctx, upstream_analysis, dependency_classpath,
                     progress_message, settings, compiler_option_sets,
                     zinc_file_manager, counter):
        """Compiles sources for the given vts into the given output dir.

    :param vts: VersionedTargetSet with one entry for the target.
    :param ctx: - A CompileContext instance for the target.
    :param dependency_classpath: A list of classpath entries of type ClasspathEntry for dependencies

    May be invoked concurrently on independent target sets.

    Postcondition: The individual targets in vts are up-to-date, as if each were
                   compiled individually.
    """
        if not ctx.sources:
            self.context.log.warn(
                'Skipping {} compile for targets with no sources:\n  {}'.
                format(self.name(), vts.targets))
        else:
            counter_val = str(counter()).rjust(counter.format_length(), b' ')
            counter_str = '[{}/{}] '.format(counter_val, counter.size)
            # Do some reporting.
            self.context.log.info(
                counter_str, 'Compiling ',
                items_to_report_element(ctx.sources,
                                        '{} source'.format(self.name())),
                ' in ',
                items_to_report_element(
                    [t.address.reference() for t in vts.targets], 'target'),
                ' (', progress_message, ').')
            with self.context.new_workunit('compile',
                                           labels=[WorkUnitLabel.COMPILER
                                                   ]) as compile_workunit:
                try:
                    self.compile(
                        ctx,
                        self._args,
                        dependency_classpath,
                        upstream_analysis,
                        settings,
                        compiler_option_sets,
                        zinc_file_manager,
                        self._get_plugin_map('javac', Java.global_instance(),
                                             ctx.target),
                        self._get_plugin_map('scalac',
                                             ScalaPlatform.global_instance(),
                                             ctx.target),
                    )
                    self._capture_logs(compile_workunit, ctx.log_dir)
                except TaskError:
                    if self.get_options().suggest_missing_deps:
                        logs = [
                            path for _, name, _, path in self._find_logs(
                                compile_workunit) if name == self.name()
                        ]
                        if logs:
                            self._find_missing_deps(logs, ctx.target)
                    raise
Example #9
0
  def scalac_compiler_plugins_src(self, zinc_compile_instance=None):
    """Returns an instance of JvmToolMixin that should provide scalac compiler plugins.

    TODO: Remove this method once the deprecation of `(scalac|javac)_plugins` on Zinc has
    completed in `1.9.0.dev0`.
    """
    return Zinc._select_jvm_tool_mixin(zinc_compile_instance,
                                       ScalaPlatform.global_instance(),
                                       ['scalac_plugins', 'scalac_plugin_args', 'scalac_plugin_dep'])
Example #10
0
  def scalac_compiler_plugins_src(self, zinc_compile_instance=None):
    """Returns an instance of JvmToolMixin that should provide scalac compiler plugins.

    TODO: Remove this method once the deprecation of `(scalac|javac)_plugins` on Zinc has
    completed in `1.9.0.dev0`.
    """
    return Zinc._select_jvm_tool_mixin(zinc_compile_instance,
                                       ScalaPlatform.global_instance(),
                                       ['scalac_plugins', 'scalac_plugin_args', 'scalac_plugin_dep'])
  def test_scala_exclude(self):
    init_subsystem(ScalaPlatform)

    name = 'foo_lib'
    suffixed_name = ScalaPlatform.global_instance().suffix_version(name)

    self.assertEqual(
        suffixed_name,
        ScalaExclude(org='example.com', name=name).name
      )
Example #12
0
  def test_scala_exclude(self):
    init_subsystem(ScalaPlatform)

    name = 'foo_lib'
    suffixed_name = ScalaPlatform.global_instance().suffix_version(name)

    self.assertEqual(
        suffixed_name,
        ScalaExclude(org='example.com', name=name).name
      )
Example #13
0
  def _compiler_plugins_cp_entries(self):
    """Any additional global compiletime classpath entries for compiler plugins."""
    java_options_src = Java.global_instance()
    scala_options_src = ScalaPlatform.global_instance()

    def cp(instance, toolname):
      scope = instance.options_scope
      return instance.tool_classpath_from_products(self._products, toolname, scope=scope)
    classpaths = (cp(java_options_src, 'javac-plugin-dep') +
                  cp(scala_options_src, 'scalac-plugin-dep'))
    return [(conf, ClasspathEntry(jar)) for conf in self.DEFAULT_CONFS for jar in classpaths]
Example #14
0
  def _compile_vts(self, vts, ctx, upstream_analysis, classpath, progress_message, settings, 
                   compiler_option_sets, zinc_file_manager, counter):
    """Compiles sources for the given vts into the given output dir.

    :param vts: VersionedTargetSet with one entry for the target.
    :param ctx: - A CompileContext instance for the target.
    :param classpath: A list of classpath entries

    May be invoked concurrently on independent target sets.

    Postcondition: The individual targets in vts are up-to-date, as if each were
                   compiled individually.
    """
    if not ctx.sources:
      self.context.log.warn('Skipping {} compile for targets with no sources:\n  {}'
                            .format(self.name(), vts.targets))
    else:
      counter_val = str(counter()).rjust(counter.format_length(), b' ')
      counter_str = '[{}/{}] '.format(counter_val, counter.size)
      # Do some reporting.
      self.context.log.info(
        counter_str,
        'Compiling ',
        items_to_report_element(ctx.sources, '{} source'.format(self.name())),
        ' in ',
        items_to_report_element([t.address.reference() for t in vts.targets], 'target'),
        ' (',
        progress_message,
        ').')
      with self.context.new_workunit('compile', labels=[WorkUnitLabel.COMPILER]) as compile_workunit:
        if self.get_options().capture_classpath:
          self._record_compile_classpath(classpath, vts.targets, ctx.classes_dir)

        try:
          self.compile(
            ctx,
            self._args,
            classpath,
            upstream_analysis,
            settings,
            compiler_option_sets,
            zinc_file_manager,
            self._get_plugin_map('javac', Java.global_instance(), ctx.target),
            self._get_plugin_map('scalac', ScalaPlatform.global_instance(), ctx.target),
          )
          self._capture_logs(compile_workunit, ctx.log_dir)
        except TaskError:
          if self.get_options().suggest_missing_deps:
            logs = [path
                    for _, name, _, path in self._find_logs(compile_workunit)
                    if name == self.name()]
            if logs:
              self._find_missing_deps(logs, ctx.target)
          raise
Example #15
0
    def initialize_graph_info(self):
        scala_platform = ScalaPlatform.global_instance()
        scala_platform_map = {
            "scala_version":
            scala_platform.version,
            "compiler_classpath": [
                cp_entry.path
                for cp_entry in scala_platform.compiler_classpath_entries(
                    self.context.products)
            ],
        }

        jvm_platforms_map = {
            "default_platform":
            JvmPlatform.global_instance().default_platform.name,
            "platforms": {
                str(platform_name): {
                    "target_level": str(platform.target_level),
                    "source_level": str(platform.source_level),
                    "args": platform.args,
                }
                for platform_name, platform in
                JvmPlatform.global_instance().platforms_by_name.items()
            },
        }

        graph_info = {
            "version": DEFAULT_EXPORT_VERSION,
            "targets": {},
            "jvm_platforms": jvm_platforms_map,
            "scala_platform": scala_platform_map,
            # `jvm_distributions` are static distribution settings from config,
            # `preferred_jvm_distributions` are distributions that pants actually uses for the
            # given platform setting.
            "preferred_jvm_distributions": {},
        }

        for platform_name, platform in JvmPlatform.global_instance(
        ).platforms_by_name.items():
            preferred_distributions = {}
            for strict, strict_key in [(True, "strict"),
                                       (False, "non_strict")]:
                try:
                    dist = JvmPlatform.preferred_jvm_distribution(
                        [platform], strict=strict)
                    preferred_distributions[strict_key] = dist.home
                except DistributionLocator.Error:
                    pass

            if preferred_distributions:
                graph_info["preferred_jvm_distributions"][
                    platform_name] = preferred_distributions

        return graph_info
Example #16
0
        def call(srcs):
          def to_java_boolean(x):
            return str(x).lower()

          cp = ScalaPlatform.global_instance().style_classpath(self.context.products)
          scalastyle_args = [
            '-c', scalastyle_config,
            '-v', to_java_boolean(scalastyle_verbose),
            '-q', to_java_boolean(scalastyle_quiet),
            ]
          return self.runjava(classpath=cp,
                              main=self._MAIN,
                              jvm_options=self.get_options().jvm_options,
                              args=scalastyle_args + srcs)
  def defaulted_property(self, target, option_name):
    """Computes a language property setting for the given JvmTarget.

    :param selector A function that takes a target or platform and returns the boolean value of the
                    property for that target or platform, or None if that target or platform does
                    not directly define the property.

    If the target does not override the language property, returns true iff the property
    is true for any of the matched languages for the target.
    """
    if target.has_sources('.java'):
      matching_subsystem = Java.global_instance()
    elif target.has_sources('.scala'):
      matching_subsystem = ScalaPlatform.global_instance()
    else:
      return getattr(target, option_name)

    return matching_subsystem.get_scalar_mirrored_target_option(option_name, target)
Example #18
0
    def defaulted_property(self, target, option_name):
        """Computes a language property setting for the given JvmTarget.

    :param selector A function that takes a target or platform and returns the boolean value of the
                    property for that target or platform, or None if that target or platform does
                    not directly define the property.

    If the target does not override the language property, returns true iff the property
    is true for any of the matched languages for the target.
    """
        if target.has_sources('.java'):
            matching_subsystem = Java.global_instance()
        elif target.has_sources('.scala'):
            matching_subsystem = ScalaPlatform.global_instance()
        else:
            return getattr(target, option_name)

        return matching_subsystem.get_scalar_mirrored_target_option(
            option_name, target)
Example #19
0
  def defaulted_property(self, target, selector):
    """Computes a language property setting for the given JvmTarget.

    :param selector A function that takes a target or platform and returns the boolean value of the
                    property for that target or platform, or None if that target or platform does
                    not directly define the property.

    If the target does not override the language property, returns true iff the property
    is true for any of the matched languages for the target.
    """
    if selector(target) is not None:
      return selector(target)

    prop = False
    if target.has_sources('.java'):
      prop |= selector(Java.global_instance())
    if target.has_sources('.scala'):
      prop |= selector(ScalaPlatform.global_instance())
    return prop
Example #20
0
    def _compute_language_property(self, target, selector):
        """Computes the a language property setting for the given target sources.

    :param target The target whose language property will be calculated.
    :param selector A function that takes a target or platform and returns the boolean value of the
                    property for that target or platform, or None if that target or platform does
                    not directly define the property.

    If the target does not override the language property, returns true iff the property
    is true for any of the matched languages for the target.
    """
        if selector(target) is not None:
            return selector(target)

        property = False
        if target.has_sources(".java"):
            property |= selector(Java.global_instance())
        if target.has_sources(".scala"):
            property |= selector(ScalaPlatform.global_instance())
        return property
Example #21
0
  def execute(self):
    """Stages IDE project artifacts to a project directory and generates IDE configuration files."""
    # Grab the targets in-play before the context is replaced by `self._prepare_project()` below.
    targets = self.context.targets()

    self._prepare_project()

    if self.context.options.is_known_scope('compile.checkstyle'):
      checkstyle_classpath = self.tool_classpath('checkstyle', scope='compile.checkstyle')
    else:  # Checkstyle not enabled.
      checkstyle_classpath = []

    if self.skip_scala:
      scalac_classpath = []
    else:
      scalac_classpath = ScalaPlatform.global_instance().compiler_classpath(self.context.products)

    self._project.set_tool_classpaths(checkstyle_classpath, scalac_classpath)
    self.map_internal_jars(targets)
    self.map_external_jars(targets)

    idefile = self.generate_project(self._project)
    if idefile:
      binary_util.ui_open(idefile)
Example #22
0
 def subsystem_dependencies(cls):
   return super(ScaladocGen, cls).subsystem_dependencies() + (DistributionLocator, ScalaPlatform.scoped(cls))
Example #23
0
 def prepare(cls, options, round_manager):
   super(ScaladocGen, cls).prepare(options, round_manager)
   ScalaPlatform.prepare_tools(round_manager)
Example #24
0
    def register_options(cls, register):
      super(Zinc.Factory, cls).register_options(register)

      zinc_rev = '1.0.3'

      shader_rules = [
          # The compiler-interface and compiler-bridge tool jars carry xsbt and
          # xsbti interfaces that are used across the shaded tool jar boundary so
          # we preserve these root packages wholesale along with the core scala
          # APIs.
          Shader.exclude_package('scala', recursive=True),
          Shader.exclude_package('xsbt', recursive=True),
          Shader.exclude_package('xsbti', recursive=True),
          # Unfortunately, is loaded reflectively by the compiler.
          Shader.exclude_package('org.apache.logging.log4j', recursive=True),
        ]

      cls.register_jvm_tool(register,
                            Zinc.ZINC_BOOTSTRAPPER_TOOL_NAME,
                            classpath=[
                              JarDependency('org.pantsbuild', 'zinc-bootstrapper_2.11', '0.0.4'),
                            ],
                            main=Zinc.ZINC_BOOTSTRAPER_MAIN,
                            custom_rules=shader_rules,
                          )

      cls.register_jvm_tool(register,
                            Zinc.ZINC_COMPILER_TOOL_NAME,
                            classpath=[
                              JarDependency('org.pantsbuild', 'zinc-compiler_2.11', '0.0.9'),
                            ],
                            main=Zinc.ZINC_COMPILE_MAIN,
                            custom_rules=shader_rules)

      cls.register_jvm_tool(register,
                            'compiler-bridge',
                            classpath=[
                              ScalaJarDependency(org='org.scala-sbt',
                                                name='compiler-bridge',
                                                rev=zinc_rev,
                                                classifier='sources',
                                                intransitive=True),
                            ])

      cls.register_jvm_tool(register,
                            'compiler-interface',
                            classpath=[
                              JarDependency(org='org.scala-sbt',
                                            name='compiler-interface',
                                            rev=zinc_rev),
                            ],
                            # NB: We force a noop-jarjar'ing of the interface, since it is now
                            # broken up into multiple jars, but zinc does not yet support a sequence
                            # of jars for the interface.
                            main='no.such.main.Main',
                            custom_rules=shader_rules)

      cls.register_jvm_tool(register,
                            Zinc.ZINC_EXTRACTOR_TOOL_NAME,
                            classpath=[
                              JarDependency('org.pantsbuild', 'zinc-extractor_2.11', '0.0.6')
                            ])

      # Register scalac for fixed versions of Scala, 2.10, 2.11 and 2.12.
      # Relies on ScalaPlatform to get the revision version from the major.minor version.
      # The tool with the correct scala version will be retrieved later,
      # taking the user-passed option into account.
      supported_scala_versions=['2.10', '2.11', '2.12']
      wanted_jars = ['scala-compiler', 'scala-library', 'scala-reflect']
      for scala_version in supported_scala_versions:
        cls.register_jvm_tool(register,
                              ScalaPlatform.versioned_tool_name('scalac', scala_version),
                              classpath=[
                                ScalaPlatform.create_jardep(jar, scala_version) for jar in wanted_jars
                              ])

      # Register custom scalac tool.
      cls.register_jvm_tool(register,
                            ScalaPlatform.versioned_tool_name('scalac', 'custom'),
                            classpath=[JarDependency('missing spec', ' //:scalac')])
Example #25
0
 def _scala_platform(self):
     return ScalaPlatform.global_instance()
Example #26
0
  def compute_dependency_specs(cls, kwargs=None, payload=None):
    for spec in super(ScalaLibrary, cls).compute_dependency_specs(kwargs, payload):
      yield spec

    for spec in ScalaPlatform.global_instance().injectables_specs_for_key('scala-library'):
      yield spec
Example #27
0
 def scalac_classpath_entries(self):
   """Returns classpath entries for the scalac classpath."""
   return ScalaPlatform.global_instance().compiler_classpath_entries(
     self.context.products, self.context._scheduler)
Example #28
0
  def compute_dependency_specs(cls, kwargs=None, payload=None):
    for spec in super(ScalacPlugin, cls).compute_dependency_specs(kwargs, payload):
      yield spec

    for spec in ScalaPlatform.global_instance().injectables_specs_for_key('scalac'):
      yield spec
Example #29
0
 def traversable_dependency_specs(self):
   for spec in super(ScalacPlugin, self).traversable_dependency_specs:
     yield spec
   yield ScalaPlatform.compiler_library_target_spec(self._build_graph)
Example #30
0
 def compiler_classpath(self):
   return ScalaPlatform.global_instance().compiler_classpath(self.context.products)
Example #31
0
 def prepare(cls, options, round_manager):
   super(BaseZincCompile, cls).prepare(options, round_manager)
   ScalaPlatform.prepare_tools(round_manager)
Example #32
0
 def traversable_dependency_specs(self):
   for spec in super(ScalaLibrary, self).traversable_dependency_specs:
     yield spec
   yield ScalaPlatform._synthetic_runtime_target(self._build_graph)
Example #33
0
 def name(self):
   return ScalaPlatform.global_instance().suffix_version(self.base_name)
Example #34
0
 def name(self):
   base_name = super(ScalaExclude, self).name
   return ScalaPlatform.global_instance().suffix_version(base_name)