def is_missing_jvm(version): with subsystem_instance(DistributionLocator): try: DistributionLocator.cached(minimum_version=version, maximum_version='{}.9999'.format(version)) return False except DistributionLocator.Error: return True
def missing_jvm(version): with subsystem_instance(DistributionLocator): try: DistributionLocator.locate(minimum_version=version, maximum_version="{}.9999".format(version)) return False except DistributionLocator.Error: return True
def execute(self): (accept_predicate, reject_predicate) = Target.lang_discriminator('java') targets = self.require_homogeneous_targets(accept_predicate, reject_predicate) if targets: tools_classpath = self.tool_classpath('scala-repl') self.context.release_lock() with preserve_stty_settings(): classpath = self.classpath(targets, cp=tools_classpath) # The scala repl requires -Dscala.usejavacp=true since Scala 2.8 when launching in the way # we do here (not passing -classpath as a program arg to scala.tools.nsc.MainGenericRunner). jvm_options = self.jvm_options if not any(opt.startswith('-Dscala.usejavacp=') for opt in jvm_options): jvm_options.append('-Dscala.usejavacp=true') print('') # Start REPL output on a new line. try: # NOTE: We execute with no workunit, as capturing REPL output makes it very sluggish. DistributionLocator.cached().execute_java(classpath=classpath, main=self.get_options().main, jvm_options=jvm_options, args=self.args) except KeyboardInterrupt: # TODO(John Sirois): Confirm with Steve Gury that finally does not work on mac and an # explicit catch of KeyboardInterrupt is required. pass
def preferred_jvm_distribution(self, platforms): """Returns a jvm Distribution with a version that should work for all the platforms.""" if not platforms: return DistributionLocator.cached() min_version = max(platform.target_level for platform in platforms) max_version = Revision(*(min_version.components + [9999])) if self._strict_jvm_version else None return DistributionLocator.cached(minimum_version=min_version, maximum_version=max_version)
def get_two_distributions(): with subsystem_instance(DistributionLocator): try: java7 = DistributionLocator.locate(minimum_version='1.7', maximum_version='1.7.9999') java8 = DistributionLocator.locate(minimum_version='1.8', maximum_version='1.8.9999') return java7, java8 except DistributionLocator.Error: return None
def test_default_to_path(self): with self.java_home_exe() as (jdk1_home, jdk2_home): with distribution(executables=EXE('bin/java', version='3')) as path_jdk: with env(PATH=os.path.join(path_jdk, 'bin')): dist = DistributionLocator.locate(minimum_version='2') self.assertEqual(path_jdk, dist.home) dist = DistributionLocator.locate(maximum_version='2') self.assertEqual(jdk1_home, dist.home)
def test_locate_java_home_trumps(self): with self.java_home_exe() as (jdk1_home, jdk2_home): with distribution(executables=EXE('bin/java', version='3')) as java_home: with env(JAVA_HOME=java_home): dist = DistributionLocator.locate() self.assertEqual(java_home, dist.home) dist = DistributionLocator.locate(maximum_version='1.1') self.assertEqual(jdk1_home, dist.home) dist = DistributionLocator.locate(minimum_version='1.1', maximum_version='2') self.assertEqual(jdk2_home, dist.home)
def launch_repl(self, classpath): # The scala repl requires -Dscala.usejavacp=true since Scala 2.8 when launching in the way # we do here (not passing -classpath as a program arg to scala.tools.nsc.MainGenericRunner). jvm_options = self.jvm_options if not any(opt.startswith("-Dscala.usejavacp=") for opt in jvm_options): jvm_options.append("-Dscala.usejavacp=true") # NOTE: We execute with no workunit, as capturing REPL output makes it very sluggish. DistributionLocator.cached().execute_java( classpath=classpath, main=self.get_options().main, jvm_options=jvm_options, args=self.args )
def test_validate_live(self): with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.dirname(self.JAVA), minimum_version='999.9.9').validate() with self.assertRaises(Distribution.Error): Distribution(bin_path=os.path.dirname(self.JAVA), maximum_version='0.0.1').validate() Distribution(bin_path=os.path.dirname(self.JAVA)).validate() Distribution(bin_path=os.path.dirname(self.JAVA), minimum_version='1.3.1').validate() Distribution(bin_path=os.path.dirname(self.JAVA), maximum_version='999.999.999').validate() Distribution(bin_path=os.path.dirname(self.JAVA), minimum_version='1.3.1', maximum_version='999.999.999').validate() with subsystem_instance(DistributionLocator): DistributionLocator.locate(jdk=False)
def locate_tools_jar(): try: return DistributionLocator.cached(jdk=True).find_libs(['tools.jar']) except DistributionLocator.Error: self.context.log.info('Failed to locate tools.jar. ' 'Install a JDK to increase performance of Zinc.') return []
def launch_repl(self, classpath): # The scala repl requires -Dscala.usejavacp=true since Scala 2.8 when launching in the way # we do here (not passing -classpath as a program arg to scala.tools.nsc.MainGenericRunner). jvm_options = self.jvm_options if not any(opt.startswith('-Dscala.usejavacp=') for opt in jvm_options): jvm_options.append('-Dscala.usejavacp=true') # NOTE: We execute with no workunit, as capturing REPL output makes it very sluggish. # # NOTE: Disable creating synthetic jar here because the classLoader used by REPL # does not load Class-Path from manifest. DistributionLocator.cached().execute_java(classpath=classpath, main=self.get_options().main, jvm_options=jvm_options, args=self.args, create_synthetic_jar=False)
def resolve_jars(self, targets): executor = SubprocessExecutor(DistributionLocator.cached()) confs = [] if self.get_options().libraries: confs.append('default') if self.get_options().libraries_sources: confs.append('sources') if self.get_options().libraries_javadocs: confs.append('javadoc') # TODO(gmalmquist): This is a terrible hack for backwards-compatibility with the pants-plugin. # Kill it ASAP, and update test_export_integration#test_export_jar_path_with_excludes_soft to # use the flag actually scoped for this task. export_options = self.get_options() try: ivy_options = self.context.options.for_scope('resolve.ivy') except OptionsError: # No resolve.ivy task installed, so continue silently. ivy_options = [] for name in set.intersection(set(export_options), set(ivy_options)): if not ivy_options.is_default(name): setattr(export_options, name, RankedValue(RankedValue.FLAG, ivy_options[name])) confs = confs or export_options.confs compile_classpath = None if confs: compile_classpath = ClasspathProducts(self.get_options().pants_workdir) self.resolve(executor=executor, targets=targets, classpath_products=compile_classpath, confs=confs, extra_args=()) return compile_classpath
def execute(self): targets = self.context.targets(predicate=self._is_benchmark) if not targets: raise TaskError('No jvm targets specified for benchmarking.') # For rewriting JDK classes to work, the JAR file has to be listed specifically in # the JAR manifest as something that goes in the bootclasspath. # The MANIFEST list a jar 'allocation.jar' this is why we have to rename it agent_tools_classpath = self.tool_classpath('benchmark-agent') agent_jar = agent_tools_classpath[0] allocation_jar = os.path.join(os.path.dirname(agent_jar), "allocation.jar") # TODO(Steve Gury): Find a solution to avoid copying the jar every run and being resilient # to version upgrade shutil.copyfile(agent_jar, allocation_jar) os.environ['ALLOCATION_JAR'] = str(allocation_jar) benchmark_tools_classpath = self.tool_classpath('benchmark-tool') # Collect a transitive classpath for the benchmark targets. classpath = self.classpath(targets, benchmark_tools_classpath) java_executor = SubprocessExecutor(DistributionLocator.cached()) exit_code = execute_java(classpath=classpath, main=self._CALIPER_MAIN, jvm_options=self.jvm_options, args=self.args, workunit_factory=self.context.new_workunit, workunit_name='caliper', workunit_labels=[WorkUnitLabel.RUN], executor=java_executor, create_synthetic_jar=self.synthetic_classpath) if exit_code != 0: raise TaskError('java {} ... exited non-zero ({})'.format(self._CALIPER_MAIN, exit_code))
def test_no_jvm_restriction(self): with subsystem_instance(DistributionLocator): distribution = DistributionLocator.locate() target_spec = 'testprojects/src/java/org/pantsbuild/testproject/printversion' run = self.run_pants(['run', target_spec]) self.assert_success(run) self.assertIn('java.home:{}'.format(distribution.home), run.stdout_data)
def set_distribution(self, minimum_version=None, maximum_version=None, jdk=False): try: self._dist = DistributionLocator.cached( minimum_version=minimum_version, maximum_version=maximum_version, jdk=jdk ) except DistributionLocator.Error as e: raise TaskError(e)
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
def resolve_jars(self, targets): # TODO: Why is this computed directly here instead of taking from the actual product # computed by the {Ivy,Coursier}Resolve task? executor = SubprocessExecutor(DistributionLocator.cached()) confs = [] if self.get_options().libraries: confs.append('default') if self.get_options().libraries_sources: confs.append('sources') if self.get_options().libraries_javadocs: confs.append('javadoc') compile_classpath = None if confs: compile_classpath = ClasspathProducts(self.get_options().pants_workdir) if JvmResolveSubsystem.global_instance().get_options().resolver == 'ivy': IvyTaskMixin.resolve(self, executor=executor, targets=targets, classpath_products=compile_classpath, confs=confs) else: CoursierMixin.resolve(self, targets, compile_classpath, sources=self.get_options().libraries_sources, javadoc=self.get_options().libraries_javadocs, executor=executor) return compile_classpath
def distribution(self): if self._dist is None: # Currently no Java 8 for Android. I considered max=1.7.0_50. See comment in _render_args(). self._dist = DistributionLocator.cached(minimum_version='1.6.0_00', maximum_version='1.7.0_99', jdk=True) return self._dist
def runner(self, jvm_options=None, args=None, executor=None): """Creates an ivy commandline client runner for the given args.""" args = args or [] jvm_options = jvm_options or [] executor = executor or SubprocessExecutor(DistributionLocator.cached()) if not isinstance(executor, Executor): raise ValueError( "The executor argument must be an Executor instance, given {} of type {}".format( executor, type(executor) ) ) if self._ivy_cache_dir and "-cache" not in args: # TODO(John Sirois): Currently this is a magic property to support hand-crafted <caches/> in # ivysettings.xml. Ideally we'd support either simple -caches or these hand-crafted cases # instead of just hand-crafted. Clean this up by taking over ivysettings.xml and generating # it from BUILD constructs. jvm_options += ["-Divy.cache.dir={}".format(self._ivy_cache_dir)] if self._ivy_settings and "-settings" not in args: args = ["-settings", self._ivy_settings] + args jvm_options += self._extra_jvm_options return executor.runner( classpath=self._classpath, main="org.apache.ivy.Main", jvm_options=jvm_options, args=args )
def execute( self, jvm_options=None, args=None, executor=None, workunit_factory=None, workunit_name=None, workunit_labels=None, ): """Executes the ivy commandline client with the given args. Raises Ivy.Error if the command fails for any reason. :param executor: Java executor to run ivy with. """ # NB(gmalmquist): It should be OK that we can't declare a subsystem_dependency in this file # (because it's just a plain old object), because Ivy is only constructed by Bootstrapper, which # makes an explicit call to IvySubsystem.global_instance() in its constructor, which in turn has # a declared dependency on DistributionLocator. executor = executor or SubprocessExecutor(DistributionLocator.cached()) runner = self.runner(jvm_options=jvm_options, args=args, executor=executor) try: with self.resolution_lock: result = util.execute_runner(runner, workunit_factory, workunit_name, workunit_labels) if result != 0: raise self.Error( "Ivy command failed with exit code {}{}".format(result, ": " + " ".join(args) if args else "") ) except executor.Error as e: raise self.Error("Problem executing ivy: {}".format(e))
def execute_junit_runner(self, content): # Create the temporary base test directory test_rel_path = 'tests/java/org/pantsbuild/foo' test_abs_path = os.path.join(self.build_root, test_rel_path) self.create_dir(test_rel_path) # Generate the temporary java test source code. test_java_file_rel_path = os.path.join(test_rel_path, 'FooTest.java') test_java_file_abs_path = os.path.join(self.build_root, test_java_file_rel_path) self.create_file(test_java_file_rel_path, content) # Invoke ivy to resolve classpath for junit. classpath_file_abs_path = os.path.join(test_abs_path, 'junit.classpath') with subsystem_instance(IvySubsystem) as ivy_subsystem: distribution = DistributionLocator.cached(jdk=True) ivy = Bootstrapper(ivy_subsystem=ivy_subsystem).ivy() ivy.execute(args=['-cachepath', classpath_file_abs_path, '-dependency', 'junit', 'junit-dep', '4.10'], executor=SubprocessExecutor(distribution=distribution)) with open(classpath_file_abs_path) as fp: classpath = fp.read() # Now directly invoking javac to compile the test java code into java class # so later we can inject the class into products mapping for JUnitRun to execute # the test on. javac = distribution.binary('javac') subprocess.check_call( [javac, '-d', test_abs_path, '-cp', classpath, test_java_file_abs_path]) # Create a java_tests target and a synthetic resource target. java_tests = self.create_library(test_rel_path, 'java_tests', 'foo_test', ['FooTest.java']) resources = self.make_target('some_resources', Resources) # Set the context with the two targets, one java_tests target and # one synthetic resources target. # The synthetic resources target is to make sure we won't regress # in the future with bug like https://github.com/pantsbuild/pants/issues/508. Note # in that bug, the resources target must be the first one in the list. context = self.context(target_roots=[resources, java_tests]) # Before we run the task, we need to inject the "classes_by_target" with # the compiled test java classes that JUnitRun will know which test # classes to execute. In a normal run, this "classes_by_target" will be # populated by java compiling step. class_products = context.products.get_data( 'classes_by_target', lambda: defaultdict(MultipleRootedProducts)) java_tests_products = MultipleRootedProducts() java_tests_products.add_rel_paths(test_abs_path, ['FooTest.class']) class_products[java_tests] = java_tests_products # Also we need to add the FooTest.class's classpath to the compile_classpath # products data mapping so JUnitRun will be able to add that into the final # classpath under which the junit will be executed. self.populate_compile_classpath(context=context, classpath=[test_abs_path]) # Finally execute the task. self.execute(context)
def create_analysis_tools(self): return AnalysisTools( DistributionLocator.cached().real_home, ZincAnalysisParser(), ZincAnalysis, get_buildroot(), self.get_options().pants_workdir, )
def preferred_jvm_distribution(cls, platforms, strict=False): """Returns a jvm Distribution with a version that should work for all the platforms. Any one of those distributions whose version is >= all requested platforms' versions can be returned unless strict flag is set. :param iterable platforms: An iterable of platform settings. :param bool strict: If true, only distribution whose version matches the minimum required version can be returned, i.e, the max target_level of all the requested platforms. :returns: Distribution one of the selected distributions. """ if not platforms: return DistributionLocator.cached() min_version = max(platform.target_level for platform in platforms) max_version = Revision(*(min_version.components + [9999])) if strict else None return DistributionLocator.cached(minimum_version=min_version, maximum_version=max_version)
def execute_junit_runner(self, content, create_some_resources=True, **kwargs): # Create the temporary base test directory test_rel_path = 'tests/java/org/pantsbuild/foo' test_abs_path = self.create_dir(test_rel_path) # Generate the temporary java test source code. test_java_file_rel_path = os.path.join(test_rel_path, 'FooTest.java') test_java_file_abs_path = self.create_file(test_java_file_rel_path, content) # Create the temporary classes directory under work dir test_classes_abs_path = self.create_workdir_dir(test_rel_path) # Invoke ivy to resolve classpath for junit. classpath_file_abs_path = os.path.join(test_abs_path, 'junit.classpath') ivy_subsystem = global_subsystem_instance(IvySubsystem) distribution = DistributionLocator.cached(jdk=True) ivy = Bootstrapper(ivy_subsystem=ivy_subsystem).ivy() ivy.execute(args=['-cachepath', classpath_file_abs_path, '-dependency', 'junit', 'junit-dep', '4.10'], executor=SubprocessExecutor(distribution=distribution)) with open(classpath_file_abs_path) as fp: classpath = fp.read() # Now directly invoking javac to compile the test java code into java class # so later we can inject the class into products mapping for JUnitRun to execute # the test on. javac = distribution.binary('javac') subprocess.check_call( [javac, '-d', test_classes_abs_path, '-cp', classpath, test_java_file_abs_path]) # If a target_name is specified create a target with it, otherwise create a java_tests target. if 'target_name' in kwargs: target = self.target(kwargs['target_name']) else: target = self.create_library(test_rel_path, 'java_tests', 'foo_test', ['FooTest.java']) target_roots = [] if create_some_resources: # Create a synthetic resource target. target_roots.append(self.make_target('some_resources', Resources)) target_roots.append(target) # Set the context with the two targets, one java_tests target and # one synthetic resources target. # The synthetic resources target is to make sure we won't regress # in the future with bug like https://github.com/pantsbuild/pants/issues/508. Note # in that bug, the resources target must be the first one in the list. context = self.context(target_roots=target_roots) # Before we run the task, we need to inject the "runtime_classpath" with # the compiled test java classes that JUnitRun will know which test # classes to execute. In a normal run, this "runtime_classpath" will be # populated by java compilation step. self.populate_runtime_classpath(context=context, classpath=[test_classes_abs_path]) # Finally execute the task. self.execute(context)
def assert_run_ant_version(classpath): with subsystem_instance(DistributionLocator): executor = SubprocessExecutor(DistributionLocator.cached()) process = executor.spawn(classpath, 'org.apache.tools.ant.Main', args=['-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = process.communicate() self.assertEqual(0, process.returncode) self.assertTrue(out.strip().startswith('Apache Ant(TM) version 1.9.4')) self.assertEqual('', err.strip())
def execute(self): # The called binary may block for a while, allow concurrent pants activity during this pants # idle period. # # TODO(John Sirois): refactor lock so that I can do: # with self.context.lock.yield(): # - blocking code # # Currently re-acquiring the lock requires a path argument that was set up by the goal # execution engine. I do not want task code to learn the lock location. # http://jira.local.twitter.com/browse/AWESOME-1317 target = self.require_single_root_target() working_dir = None cwd_opt = self.get_options().cwd if cwd_opt != _CWD_NOT_PRESENT: working_dir = self.get_options().cwd if not working_dir: working_dir = target.address.spec_path logger.debug("Working dir is {0}".format(working_dir)) if isinstance(target, JvmApp): binary = target.binary else: binary = target # This task is installed in the "run" goal. # This means that, when invoked with ./pants run, it will run regardless of whether # the target is a jvm target. # As a result, not all targets passed here will have good defaults for extra_jvm_options extra_jvm_options = binary.payload.get_field_value("extra_jvm_options", []) # We can't throw if binary isn't a JvmBinary, because perhaps we were called on a # python_binary, in which case we have to no-op and let python_run do its thing. # TODO(benjy): Some more elegant way to coordinate how tasks claim targets. if isinstance(binary, JvmBinary): jvm = DistributionLocator.cached() executor = CommandLineGrabber(jvm) if self.only_write_cmd_line else None self.context.release_lock() with self.context.new_workunit(name='run', labels=[WorkUnitLabel.RUN]): result = jvm.execute_java( classpath=self.classpath([target]), main=self.get_options().main or binary.main, executor=executor, jvm_options=self.jvm_options + extra_jvm_options, args=self.args, cwd=working_dir, synthetic_jar_dir=self.workdir, create_synthetic_jar=self.synthetic_classpath ) if self.only_write_cmd_line: with safe_open(expand_path(self.only_write_cmd_line), 'w') as outfile: outfile.write(' '.join(executor.cmd)) elif result != 0: raise TaskError('java {} ... exited non-zero ({})'.format(binary.main, result), exit_code=result)
def execute_codegen(self, target, target_workdir): execute_java = DistributionLocator.cached().execute_java args = self.format_args_for_target(target, target_workdir) if args: result = execute_java( classpath=self.tool_classpath("wire-compiler"), main="com.squareup.wire.WireCompiler", args=args ) if result != 0: raise TaskError("Wire compiler exited non-zero ({0})".format(result))
def execute_tool(self, classpath, main, args=None): init_subsystem(DistributionLocator) executor = SubprocessExecutor(DistributionLocator.cached()) process = executor.spawn(classpath, main, args=args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = process.communicate() self.assertEqual(0, process.returncode) self.assertEqual('', err.strip()) yield out
def create(cls, context, executor=None): """Creates and returns a new Shader. :param Executor executor: Optional java executor to run jarjar with. """ if executor is None: executor = SubprocessExecutor(DistributionLocator.cached()) classpath = cls.global_instance().tool_classpath_from_products(context.products, 'jarjar', cls.options_scope) return Shader(classpath, executor)
def test_jvm_meets_min_and_max_distribution(self): with subsystem_instance(DistributionLocator): distribution = DistributionLocator.locate() target_spec = 'testprojects/src/java/org/pantsbuild/testproject/printversion' run = self.run_pants(['run', target_spec], config={ 'jvm-distributions': { 'minimum_version': str(distribution.version), 'maximum_version': str(distribution.version) } }) self.assert_success(run) self.assertIn('java.home:{}'.format(distribution.home), run.stdout_data)
def _execute_junit_runner(self, list_of_filename_content_tuples, create_some_resources=True, target_name=None): # Create the temporary base test directory test_rel_path = 'tests/java/org/pantsbuild/foo' test_abs_path = self.create_dir(test_rel_path) # Create the temporary classes directory under work dir test_classes_abs_path = self.create_workdir_dir(test_rel_path) test_java_file_abs_paths = [] # Generate the temporary java test source code. for filename, content in list_of_filename_content_tuples: test_java_file_rel_path = os.path.join(test_rel_path, filename) test_java_file_abs_path = self.create_file(test_java_file_rel_path, content) test_java_file_abs_paths.append(test_java_file_abs_path) # Invoke ivy to resolve classpath for junit. classpath_file_abs_path = os.path.join(test_abs_path, 'junit.classpath') ivy_subsystem = global_subsystem_instance(IvySubsystem) distribution = DistributionLocator.cached(jdk=True) ivy = Bootstrapper(ivy_subsystem=ivy_subsystem).ivy() ivy.execute(args=['-cachepath', classpath_file_abs_path, '-dependency', 'junit', 'junit-dep', '4.10'], executor=SubprocessExecutor(distribution=distribution)) with open(classpath_file_abs_path) as fp: classpath = fp.read() # Now directly invoking javac to compile the test java code into java class # so later we can inject the class into products mapping for JUnitRun to execute # the test on. javac = distribution.binary('javac') subprocess.check_call( [javac, '-d', test_classes_abs_path, '-cp', classpath] + test_java_file_abs_paths) # If a target_name is specified create a target with it, otherwise create a junit_tests target. if target_name: target = self.target(target_name) else: target = self.create_library(test_rel_path, 'junit_tests', 'foo_test', ['FooTest.java']) target_roots = [] if create_some_resources: # Create a synthetic resource target. target_roots.append(self.make_target('some_resources', Resources)) target_roots.append(target) # Set the context with the two targets, one junit_tests target and # one synthetic resources target. # The synthetic resources target is to make sure we won't regress # in the future with bug like https://github.com/pantsbuild/pants/issues/508. Note # in that bug, the resources target must be the first one in the list. context = self.context(target_roots=target_roots) # Before we run the task, we need to inject the "runtime_classpath" with # the compiled test java classes that JUnitRun will know which test # classes to execute. In a normal run, this "runtime_classpath" will be # populated by java compilation step. self.populate_runtime_classpath(context=context, classpath=[test_classes_abs_path]) # Finally execute the task. self.execute(context)
def test_locate_java_not_executable(self): with distribution(files='bin/java') as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): with self.assertRaises(Distribution.Error): DistributionLocator.locate()
def test_locate_jdk_is_jre(self): with distribution(executables=exe('bin/java')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): with self.assertRaises(Distribution.Error): DistributionLocator.locate(jdk=True)
def resolve(self, targets, compile_classpath, sources, javadoc, executor): """This is the core function for coursier resolve. Validation strategy: 1. All targets are going through the `invalidated` to get fingerprinted in the target level. No cache is fetched at this stage because it is disabled. 2. Once each target is fingerprinted, we combine them into a `VersionedTargetSet` where they are fingerprinted together, because each run of 3rdparty resolve is context sensitive. Artifacts are stored in `VersionedTargetSet`'s results_dir, the contents are the aggregation of each coursier run happened within that context. Caching: (TODO): https://github.com/pantsbuild/pants/issues/5187 Currently it is disabled due to absolute paths in the coursier results. :param targets: a collection of targets to do 3rdparty resolve against :param compile_classpath: classpath product that holds the resolution result. IMPORTANT: this parameter will be changed. :param sources: if True, fetch sources for 3rdparty :param javadoc: if True, fetch javadoc for 3rdparty :param executor: An instance of `pants.java.executor.Executor`. If None, a subprocess executor will be assigned. :return: n/a """ manager = JarDependencyManagement.global_instance() jar_targets = manager.targets_by_artifact_set(targets) executor = executor or SubprocessExecutor(DistributionLocator.cached()) if not isinstance(executor, Executor): raise ValueError( "The executor argument must be an Executor instance, given {} of type {}" .format(executor, type(executor))) for artifact_set, target_subset in jar_targets.items(): raw_jar_deps, global_excludes = calculate_classpath(target_subset) confs_for_fingerprint = ["sources"] * sources + ["javadoc" ] * javadoc fp_strategy = CoursierResolveFingerprintStrategy( confs_for_fingerprint) compile_classpath.add_excludes_for_targets(target_subset) with self.invalidated( target_subset, invalidate_dependents=False, silent=False, fingerprint_strategy=fp_strategy, ) as invalidation_check: if not invalidation_check.all_vts: continue resolve_vts = VersionedTargetSet.from_versioned_targets( invalidation_check.all_vts) vt_set_results_dir = self._prepare_vts_results_dir(resolve_vts) pants_jar_base_dir = self._prepare_workdir() coursier_cache_dir = CoursierSubsystem.global_instance( ).get_options().cache_dir # If a report is requested, do not proceed with loading validated result. if not self.get_options().report: # Check each individual target without context first # If the individuals are valid, check them as a VersionedTargetSet # The order of 'or' statement matters, because checking for cache is more expensive. if resolve_vts.valid or ( self.artifact_cache_reads_enabled() and len( self.check_artifact_cache([resolve_vts])[0]) == len(resolve_vts.targets)): # Load up from the results dir success = self._load_from_results_dir( compile_classpath, vt_set_results_dir, coursier_cache_dir, invalidation_check, pants_jar_base_dir, ) if success: resolve_vts.update() return jars_to_resolve, pinned_coords = self._compute_jars_to_resolve_and_pin( raw_jar_deps, artifact_set, manager) results = self._get_result_from_coursier( jars_to_resolve, global_excludes, pinned_coords, coursier_cache_dir, sources, javadoc, executor, ) for conf, result_list in results.items(): for result in result_list: self._load_json_result( conf, compile_classpath, coursier_cache_dir, invalidation_check, pants_jar_base_dir, result, self._override_classifiers_for_conf(conf), ) self._populate_results_dir(vt_set_results_dir, results) resolve_vts.update() if self.artifact_cache_writes_enabled(): self.update_artifact_cache([(resolve_vts, [vt_set_results_dir])])
def create_analysis_tools(self): return AnalysisTools(DistributionLocator.cached().real_home, ZincAnalysisParser(), ZincAnalysis, get_buildroot(), self.get_options().pants_workdir)
def _fallback_platform(self): logger.warn('No default jvm platform is defined.') source_level = JvmPlatform.parse_java_version(DistributionLocator.cached().version) target_level = source_level platform_name = '(DistributionLocator.cached().version {})'.format(source_level) return JvmPlatformSettings(source_level, target_level, [], name=platform_name)
def preferred_jvm_distribution(self, platform): """Returns a jvm Distribution with a version that should work for all the platforms.""" if not platform: return DistributionLocator.cached() return DistributionLocator.cached( minimum_version=platform.target_level)
def test_locate_version_to_high(self): with distribution(executables=exe('bin/java', '1.8.0')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): with self.assertRaises(Distribution.Error): DistributionLocator.locate(maximum_version='1.7.999')
def test_locate_version_within_range(self): with distribution(executables=exe('bin/java', '1.7.0')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): DistributionLocator.locate(minimum_version='1.6.0', maximum_version='1.7.999')
def get_path(key): return DistributionLocator.cached().system_properties.get(key, '').split(':')
def test_locate_jdk1(self): with env(): with self.java_home_exe() as (jdk1_home, _): dist = DistributionLocator.locate() self.assertEqual(jdk1_home, dist.home)
def must_be_explicit_dep(dep): # We don't require explicit deps on the java runtime, so we shouldn't consider that # a missing dep. return (dep not in analyzer.bootstrap_jar_classfiles and not dep.startswith(DistributionLocator.cached().real_home))
def test_locate_jdk_via_jre_path(self): with distribution(executables=[exe('jre/bin/java'), exe('bin/javac')], java_home='jre') as dist_root: with env(PATH=os.path.join(dist_root, 'jre', 'bin')): DistributionLocator.locate(jdk=True)
def test_locate_jdk_by_path(self): with distribution(executables=[exe('bin/java'), exe('bin/javac')]) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): DistributionLocator.locate(jdk=True)
def test_locate_jre_by_path(self): with distribution(executables=exe('bin/java')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): DistributionLocator.locate()
def create_analysis_tools(self): return AnalysisTools(DistributionLocator.cached().real_home, ZincAnalysisParser(), ZincAnalysis)
def test_locate_jdk1(self): with env(): with self.java_dist_dir() as (jdk1_home, _): dist = DistributionLocator.locate(maximum_version='1') self.assertEqual(jdk1_home, dist.home)
def set_distribution(self, minimum_version=None, maximum_version=None, jdk=False): try: self._dist = DistributionLocator.cached(minimum_version=minimum_version, maximum_version=maximum_version, jdk=jdk) except DistributionLocator.Error as e: raise TaskError(e)
def test_locate_via_java_home(self): with distribution(executables=exe('bin/java')) as dist_root: with env(JAVA_HOME=dist_root): DistributionLocator.locate()
def execute_junit_runner(self, content): # Create the temporary base test directory test_rel_path = 'tests/java/org/pantsbuild/foo' test_abs_path = os.path.join(self.build_root, test_rel_path) self.create_dir(test_rel_path) # Generate the temporary java test source code. test_java_file_rel_path = os.path.join(test_rel_path, 'FooTest.java') test_java_file_abs_path = os.path.join(self.build_root, test_java_file_rel_path) self.create_file(test_java_file_rel_path, content) # Invoke ivy to resolve classpath for junit. classpath_file_abs_path = os.path.join(test_abs_path, 'junit.classpath') with subsystem_instance(IvySubsystem) as ivy_subsystem: distribution = DistributionLocator.cached(jdk=True) ivy = Bootstrapper(ivy_subsystem=ivy_subsystem).ivy() ivy.execute(args=[ '-cachepath', classpath_file_abs_path, '-dependency', 'junit', 'junit-dep', '4.10' ], executor=SubprocessExecutor(distribution=distribution)) with open(classpath_file_abs_path) as fp: classpath = fp.read() # Now directly invoking javac to compile the test java code into java class # so later we can inject the class into products mapping for JUnitRun to execute # the test on. javac = distribution.binary('javac') subprocess.check_call([ javac, '-d', test_abs_path, '-cp', classpath, test_java_file_abs_path ]) # Create a java_tests target and a synthetic resource target. java_tests = self.create_library(test_rel_path, 'java_tests', 'foo_test', ['FooTest.java']) resources = self.make_target('some_resources', Resources) # Set the context with the two targets, one java_tests target and # one synthetic resources target. # The synthetic resources target is to make sure we won't regress # in the future with bug like https://github.com/pantsbuild/pants/issues/508. Note # in that bug, the resources target must be the first one in the list. context = self.context(target_roots=[resources, java_tests]) # Before we run the task, we need to inject the "classes_by_target" with # the compiled test java classes that JUnitRun will know which test # classes to execute. In a normal run, this "classes_by_target" will be # populated by java compiling step. class_products = context.products.get_data( 'classes_by_target', lambda: defaultdict(MultipleRootedProducts)) java_tests_products = MultipleRootedProducts() java_tests_products.add_rel_paths(test_abs_path, ['FooTest.class']) class_products[java_tests] = java_tests_products # Also we need to add the FooTest.class's classpath to the compile_classpath # products data mapping so JUnitRun will be able to add that into the final # classpath under which the junit will be executed. self.populate_compile_classpath(context=context, classpath=[test_abs_path]) # Finally execute the task. self.execute(context)
def test_locate_version_less_then_or_equal(self): with distribution(executables=exe('bin/java', '1.7.0')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): DistributionLocator.locate(maximum_version='1.7.999')
def test_validate_live_jdk(self): Distribution(bin_path=os.path.dirname(self.JAVAC), jdk=True).validate() Distribution(bin_path=os.path.dirname(self.JAVAC), jdk=True).binary('javap') with subsystem_instance(DistributionLocator): DistributionLocator.locate(jdk=True)
def _analyzer(self): return JvmDependencyAnalyzer( get_buildroot(), DistributionLocator.cached(), self.context.products.get_data('runtime_classpath'))
def test_cached_too_high(self): with distribution( executables=exe('bin/java', '1.7.0_83')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): with self.assertRaises(Distribution.Error): DistributionLocator.cached(maximum_version='1.7.0_55')
def _distribution(self): return DistributionLocator.cached()
def test_cached_good_bounds(self): with distribution( executables=exe('bin/java', '1.7.0_33')) as dist_root: with env(PATH=os.path.join(dist_root, 'bin')): DistributionLocator.cached(minimum_version='1.6.0_35', maximum_version='1.7.0_55')
def setUp(self): self.jarjar = '/not/really/jarjar.jar' init_subsystem(DistributionLocator) executor = SubprocessExecutor(DistributionLocator.cached()) self.shader = Shader(jarjar_classpath=[self.jarjar], executor=executor) self.output_jar = '/not/really/shaded.jar'
def test_locate_jdk2(self): with env(): with self.java_home_exe() as (_, jdk2_home): dist = DistributionLocator.locate(minimum_version='2') self.assertEqual(jdk2_home, dist.home)
def test_locate_invalid_java_home(self): with distribution(executables=exe('java')) as dist_root: with env(JAVA_HOME=dist_root): with self.assertRaises(Distribution.Error): DistributionLocator.locate()
def test_locate_none(self): with env(): with self.assertRaises(Distribution.Error): with subsystem_instance(DistributionLocator): DistributionLocator.locate()