Example #1
0
    def test_get_internal_classpath_entries_for_targets(self):
        b = self.make_target('b', JvmTarget)
        a = self.make_target('a', JvmTarget, dependencies=[b])

        classpath_product = ClasspathProducts(self.pants_workdir)

        # This artifact classpath entry should be ignored.
        example_jar_path = self._example_jar_path()
        self.add_jar_classpath_element_for_path(classpath_product, a,
                                                example_jar_path)

        classpath_product.add_for_target(
            b, [('default', self.path('b/loose/classes/dir'))])
        classpath_product.add_for_target(
            a, [('default', self.path('a/loose/classes/dir')),
                ('default', self.path('an/internally/generated.jar'))])

        classpath = classpath_product.get_internal_classpath_entries_for_targets(
            a.closure(bfs=True))
        self.assertEqual(
            [('default', ClasspathEntry(self.path('a/loose/classes/dir'))),
             ('default',
              ClasspathEntry(self.path('an/internally/generated.jar'))),
             ('default', ClasspathEntry(self.path('b/loose/classes/dir')))],
            classpath)
Example #2
0
    def test_classpath_by_targets(self):
        b = self.make_target('b', JvmTarget)
        a = self.make_target('a',
                             JvmTarget,
                             dependencies=[b],
                             excludes=[Exclude('com.example', 'lib')])

        classpath_products = ClasspathProducts(self.pants_workdir)

        path1 = self._path('jar/path1')
        path2 = self._path('jar/path2')
        path3 = os.path.join(self.pants_workdir, 'jar/path3')
        resolved_jar = ResolvedJar(M2Coordinate(org='com.example',
                                                name='lib',
                                                rev='1.0'),
                                   cache_path='somewhere',
                                   pants_path=path3)
        classpath_products.add_for_target(a, [('default', path1)])
        classpath_products.add_for_target(a, [('non-default', path2)])
        classpath_products.add_for_target(b, [('default', path2)])
        classpath_products.add_jars_for_targets([b], 'default', [resolved_jar])
        classpath_products.add_excludes_for_targets([a])

        # (a, path2) filtered because of conf
        # (b, path3) filtered because of excludes
        self.assertEqual(
            OrderedDict([(a, [ClasspathEntry(path1)]),
                         (b, [ClasspathEntry(path2)])]),
            ClasspathUtil.classpath_by_targets(a.closure(bfs=True),
                                               classpath_products))
Example #3
0
    def test_get_product_target_mappings_for_targets_intransitive(self):
        b = self.make_target('b',
                             JvmTarget,
                             excludes=[Exclude('com.example', 'lib')])
        a = self.make_target('a', JvmTarget, dependencies=[b])

        classpath_product = ClasspathProducts(self.pants_workdir)
        example_jar_path = self._example_jar_path()
        resolved_jar = self.add_jar_classpath_element_for_path(
            classpath_product, a, example_jar_path)

        classpath_product.add_for_target(
            b, [('default', self.path('b/loose/classes/dir'))])
        classpath_product.add_for_target(
            a, [('default', self.path('a/loose/classes/dir')),
                ('default', self.path('an/internally/generated.jar'))])

        classpath_target_tuples = classpath_product.get_product_target_mappings_for_targets(
            [a])
        self.assertEqual([
            (('default',
              ArtifactClasspathEntry(example_jar_path, resolved_jar.coordinate,
                                     resolved_jar.cache_path)), a),
            (('default', ClasspathEntry(self.path('a/loose/classes/dir'))), a),
            (('default',
              ClasspathEntry(self.path('an/internally/generated.jar'))), a)
        ], classpath_target_tuples)
Example #4
0
 def create_compile_context(self, target, target_workdir):
     return CompileContext(
         target, os.path.join(target_workdir, 'z.analysis'),
         ClasspathEntry(os.path.join(target_workdir, 'classes')),
         ClasspathEntry(os.path.join(target_workdir, 'z.jar')),
         os.path.join(target_workdir, 'logs'),
         os.path.join(target_workdir, 'zinc_args'),
         self._compute_sources_for_target(target))
Example #5
0
 def create_compile_context(self, target, target_workdir):
   return CompileContext(target=target,
                         analysis_file=os.path.join(target_workdir, 'z.analysis'),
                         classes_dir=ClasspathEntry(os.path.join(target_workdir, 'classes')),
                         jar_file=ClasspathEntry(os.path.join(target_workdir, 'z.jar')),
                         log_dir=os.path.join(target_workdir, 'logs'),
                         args_file=os.path.join(target_workdir, 'zinc_args'),
                         post_compile_merge_dir=os.path.join(target_workdir,
                                                             'post_compile_merge_dir'),
                         sources=self._compute_sources_for_target(target))
Example #6
0
    def _default_work_for_vts(self, vts, ctx, input_classpath_product_key,
                              counter, all_compile_contexts,
                              output_classpath_product):
        progress_message = ctx.target.address.spec

        # Double check the cache before beginning compilation
        hit_cache = self.check_cache(vts, counter)

        if not hit_cache:
            # Compute the compile classpath for this target.
            dependency_cp_entries = self._zinc.compile_classpath_entries(
                input_classpath_product_key,
                ctx.target,
                extra_cp_entries=self._extra_compile_time_classpath,
            )

            upstream_analysis = dict(
                self._upstream_analysis(all_compile_contexts,
                                        dependency_cp_entries))

            is_incremental = self.should_compile_incrementally(vts, ctx)
            if not is_incremental:
                # Purge existing analysis file in non-incremental mode.
                safe_delete(ctx.analysis_file)
                # Work around https://github.com/pantsbuild/pants/issues/3670
                safe_rmtree(ctx.classes_dir.path)

            dep_context = DependencyContext.global_instance()
            tgt, = vts.targets
            compiler_option_sets = dep_context.defaulted_property(
                tgt, 'compiler_option_sets')
            zinc_file_manager = dep_context.defaulted_property(
                tgt, 'zinc_file_manager')
            with Timer() as timer:
                directory_digest = self._compile_vts(
                    vts, ctx, upstream_analysis, dependency_cp_entries,
                    progress_message, tgt.platform, compiler_option_sets,
                    zinc_file_manager, counter)

            ctx.classes_dir = ClasspathEntry(ctx.classes_dir.path,
                                             directory_digest)

            self._record_target_stats(tgt, len(dependency_cp_entries),
                                      len(ctx.sources), timer.elapsed,
                                      is_incremental, 'compile')

            # Write any additional resources for this target to the target workdir.
            self.write_extra_resources(ctx)

            # Jar the compiled output.
            self._create_context_jar(ctx)

        # Update the products with the latest classes.
        output_classpath_product.add_for_target(
            ctx.target,
            [(conf, self._classpath_for_context(ctx)) for conf in self._confs],
        )
        self.register_extra_products_from_contexts([ctx.target],
                                                   all_compile_contexts)
Example #7
0
    def compile_compiler_bridge(self, context):
        """Compile the compiler bridge to be used by zinc, using our scala bootstrapper.
    It will compile and cache the jar, and materialize it if not already there.

    :param context: The context of the task trying to compile the bridge.
                    This is mostly needed to use its scheduler to create digests of the relevant jars.
    :return: The absolute path to the compiled scala-compiler-bridge jar.
    """
        bridge_jar_name = 'scala-compiler-bridge.jar'
        bridge_jar = os.path.join(self._compiler_bridge_cache_dir,
                                  bridge_jar_name)
        global_bridge_cache_dir = os.path.join(
            self._zinc_factory.get_options().pants_bootstrapdir,
            fast_relpath(self._compiler_bridge_cache_dir, self._workdir()))
        globally_cached_bridge_jar = os.path.join(global_bridge_cache_dir,
                                                  bridge_jar_name)

        # Workaround to avoid recompiling the bridge for every integration test
        # We check the bootstrapdir (.cache) for the bridge.
        # If it exists, we make a copy to the buildroot.
        #
        # TODO Remove when action caches are implemented.
        if os.path.exists(globally_cached_bridge_jar):
            # Cache the bridge jar under buildroot, to allow snapshotting
            safe_mkdir(
                self._relative_to_buildroot(self._compiler_bridge_cache_dir))
            safe_hardlink_or_copy(globally_cached_bridge_jar, bridge_jar)

        if not os.path.exists(bridge_jar):
            res = self._run_bootstrapper(bridge_jar, context)
            context._scheduler.materialize_directories(
                (DirectoryToMaterialize(get_buildroot(),
                                        res.output_directory_digest), ))
            # For the workaround above to work, we need to store a copy of the bridge in
            # the bootstrapdir cache (.cache).
            safe_mkdir(global_bridge_cache_dir)
            safe_hardlink_or_copy(bridge_jar, globally_cached_bridge_jar)

            return ClasspathEntry(bridge_jar, res.output_directory_digest)
        else:
            bridge_jar_snapshot = context._scheduler.capture_snapshots(
                (PathGlobsAndRoot(
                    PathGlobs((self._relative_to_buildroot(bridge_jar), )),
                    text_type(get_buildroot())), ))[0]
            bridge_jar_digest = bridge_jar_snapshot.directory_digest
            return ClasspathEntry(bridge_jar, bridge_jar_digest)
Example #8
0
 def _snapshotted_classpath(self, results_dir):
     relpath = fast_relpath(results_dir, get_buildroot())
     classes_dir_snapshot, = self.context._scheduler.capture_snapshots([
         PathGlobsAndRoot(
             PathGlobs([relpath]),
             get_buildroot(),
             Digest.load(relpath),
         ),
     ])
     return ClasspathEntry(results_dir,
                           classes_dir_snapshot.directory_digest)
Example #9
0
 def extra_compile_classpath_iter():
     for conf in self._confs:
         for jar in self.extra_compile_time_classpath_elements():
             if isinstance(jar, string_types):
                 # Backwards compatibility
                 deprecated_conditional(
                     lambda: True,
                     "1.12.0.dev0",
                     "Extra compile classpath auto-promotion from string to ClasspathEntry",
                 )
                 jar = ClasspathEntry(jar)
             yield (conf, jar)
Example #10
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 #11
0
 def _set_directory_digest_for_compile_context(self, directory_digest,
                                               target, compile_contexts):
     cc = self.select_runtime_context(compile_contexts[target])
     new_classpath_entry = ClasspathEntry(cc.classes_dir.path,
                                          directory_digest)
     cc.classes_dir = new_classpath_entry
Example #12
0
 def _set_directory_digest_for_compile_context(self, ctx, directory_digest):
     if self.get_options().use_classpath_jars:
         ctx.jar_file = ClasspathEntry(ctx.jar_file.path, directory_digest)
     else:
         ctx.classes_dir = ClasspathEntry(ctx.classes_dir.path,
                                          directory_digest)