def test_compile_multiple_source_files(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'lib', ) """), "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), "ExampleLib.java": JAVA_LIB_SOURCE, "OtherLib.java": dedent("""\ package org.pantsbuild.example.lib; public class OtherLib { public static String hello() { return "Hello!"; } } """), }) expanded_targets = rule_runner.request( Targets, [Addresses([Address(spec_path="", target_name="lib")])]) assert sorted(t.address.spec for t in expanded_targets) == [ "//ExampleLib.java:lib", "//OtherLib.java:lib", ] coarsened_targets = rule_runner.request( CoarsenedTargets, [Addresses([t.address for t in expanded_targets])]) assert len(coarsened_targets) == 2 assert all(len(ctgt.members) == 1 for ctgt in coarsened_targets) coarsened_targets_sorted = sorted( coarsened_targets, key=lambda ctgt: str(list(ctgt.members)[0].address)) request0 = CompileJavaSourceRequest(component=coarsened_targets_sorted[0], resolve=make_resolve(rule_runner)) classpath0 = rule_runner.request(RenderedClasspath, [request0]) assert classpath0.content == { ".ExampleLib.java.lib.javac.jar": { "org/pantsbuild/example/lib/ExampleLib.class", } } request1 = CompileJavaSourceRequest(component=coarsened_targets_sorted[1], resolve=make_resolve(rule_runner)) classpath1 = rule_runner.request(RenderedClasspath, [request1]) assert classpath1.content == { ".OtherLib.java.lib.javac.jar": { "org/pantsbuild/example/lib/OtherLib.class", } }
def test_compile_jdk_specified_in_build_file(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'lib', jdk = 'adopt:1.12', ) """), "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), "ExampleLib.java": JAVA_LIB_JDK12_SOURCE, }) request = CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="lib")), resolve=make_resolve(rule_runner), ) classpath = rule_runner.request(RenderedClasspath, [request]) assert classpath.content == { ".ExampleLib.java.lib.javac.jar": {"org/pantsbuild/example/lib/ExampleLib.class"} }
def test_compile_with_missing_maven_dep_fails(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'main', ) """), "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), "Example.java": dedent(""" package org.pantsbuild.example; import org.joda.time.DateTime; public class Example { public static void main(String[] args) { DateTime dt = new DateTime(); System.out.println(dt.getYear()); } } """), }) request = CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main")), resolve=make_resolve(rule_runner), ) fallible_result = rule_runner.request(FallibleClasspathEntry, [request]) assert fallible_result.result == CompileResult.FAILED and fallible_result.stderr assert "package org.joda.time does not exist" in fallible_result.stderr
def test_compile_of_package_info(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'main', ) """), "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), "package-info.java": dedent(""" package org.pantsbuild.example; /** * This is a package-info.java file which can have package-level annotations and * documentation comments. It does not generate any output. */ """), }) classpath = rule_runner.request( RenderedClasspath, [ CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main")), resolve=make_resolve(rule_runner), ) ], ) assert classpath.content == {}
def test_compile_multiple_source_files(rule_runner: RuleRunner) -> None: rule_runner.write_files( { "BUILD": dedent( """\ coursier_lockfile( name = 'lockfile', requirements = [], sources = [ "coursier_resolve.lockfile", ], ) java_sources( name = 'lib', dependencies = [ ':lockfile', ] ) """ ), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()) .to_json() .decode("utf-8"), "ExampleLib.java": JAVA_LIB_SOURCE, "OtherLib.java": dedent( """\ package org.pantsbuild.example.lib; public class OtherLib { public static String hello() { return "Hello!"; } } """ ), } ) expanded_targets = rule_runner.request( Targets, [Addresses([Address(spec_path="", target_name="lib")])] ) assert sorted(t.address.spec for t in expanded_targets) == [ "//ExampleLib.java:lib", "//OtherLib.java:lib", ] coarsened_targets = rule_runner.request( CoarsenedTargets, [Addresses([t.address for t in expanded_targets])] ) assert len(coarsened_targets) == 1 coarsened_target = coarsened_targets[0] assert len(coarsened_target.members) == 2 request = CompileJavaSourceRequest(component=coarsened_target) compiled_classfiles = rule_runner.request(CompiledClassfiles, [request]) classfile_digest_contents = rule_runner.request(DigestContents, [compiled_classfiles.digest]) assert frozenset(content.path for content in classfile_digest_contents) == frozenset( ["org/pantsbuild/example/lib/ExampleLib.class", "org/pantsbuild/example/lib/OtherLib.class"] )
def test_compile_jdk_versions(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'lib', ) """), "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), "ExampleLib.java": JAVA_LIB_SOURCE, }) request = CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="lib")), resolve=make_resolve(rule_runner), ) rule_runner.set_options(["--jvm-jdk=zulu:8.0.312"], env_inherit=PYTHON_BOOTSTRAP_ENV) classpath = rule_runner.request(RenderedClasspath, [request]) assert classpath.content == { ".ExampleLib.java.lib.javac.jar": {"org/pantsbuild/example/lib/ExampleLib.class"} } rule_runner.set_options(["--jvm-jdk=bogusjdk:999"], env_inherit=PYTHON_BOOTSTRAP_ENV) expected_exception_msg = r".*?JVM bogusjdk:999 not found in index.*?" with pytest.raises(ExecutionError, match=expected_exception_msg): rule_runner.request(ClasspathEntry, [request])
def test_compile_with_missing_dep_fails(rule_runner: RuleRunner) -> None: rule_runner.write_files( { "BUILD": dedent( """\ coursier_lockfile( name = 'lockfile', requirements = [], sources = [ "coursier_resolve.lockfile", ], ) java_sources( name = 'main', dependencies = [ ':lockfile', ] ) """ ), "Example.java": JAVA_LIB_MAIN_SOURCE, "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()) .to_json() .decode("utf-8"), } ) request = CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main") ) ) fallible_result = rule_runner.request(FallibleCompiledClassfiles, [request]) assert fallible_result.result == CompileResult.FAILED and fallible_result.stderr assert "package org.pantsbuild.example.lib does not exist" in fallible_result.stderr
def test_compile_no_deps(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": "java_sources(name='lib')", "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), "ExampleLib.java": JAVA_LIB_SOURCE, }) coarsened_target = expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="lib")) classpath = rule_runner.request( RenderedClasspath, [ CompileJavaSourceRequest(component=coarsened_target, resolve=make_resolve(rule_runner)) ], ) assert classpath.content == { ".ExampleLib.java.lib.javac.jar": {"org/pantsbuild/example/lib/ExampleLib.class"} } # Additionally validate that `check` works. check_results = rule_runner.request( CheckResults, [ JavacCheckRequest([ JavacCheckRequest.field_set_type.create( coarsened_target.representative) ]) ], ).results assert set(check_results) == {CheckResult(0, "", "")}
def test_compile_of_package_info(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'main', ) """), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()).to_json().decode("utf-8"), "package-info.java": dedent(""" package org.pantsbuild.example; /** * This is a package-info.java file which can have package-level annotations and * documentation comments. It does not generate any output. */ """), }) compiled_classfiles = rule_runner.request( ClasspathEntry, [ CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main")), resolve=make_resolve(rule_runner), ) ], ) classpath = rule_runner.request(RenderedClasspath, [compiled_classfiles.digest]) assert classpath.content == {}
def test_compile_with_maven_deps(rule_runner: RuleRunner) -> None: resolved_joda_lockfile = CoursierResolvedLockfile( entries=(CoursierLockfileEntry( coord=Coordinate( group="joda-time", artifact="joda-time", version="2.10.10"), file_name="joda-time-2.10.10.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "dd8e7c92185a678d1b7b933f31209b6203c8ffa91e9880475a1be0346b9617e3", serialized_bytes_length=644419, ), ), )) rule_runner.write_files({ "BUILD": dedent("""\ jvm_artifact( name = "joda-time_joda-time", group = "joda-time", artifact = "joda-time", version = "2.10.10", ) java_sources( name = 'main', dependencies = [ ':joda-time_joda-time', ] ) """), "coursier_resolve.lockfile": resolved_joda_lockfile.to_json().decode("utf-8"), "Example.java": dedent(""" package org.pantsbuild.example; import org.joda.time.DateTime; public class Example { public static void main(String[] args) { DateTime dt = new DateTime(); System.out.println(dt.getYear()); } } """), }) request = CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main")), resolve=make_resolve(rule_runner), ) compiled_classfiles = rule_runner.request(ClasspathEntry, [request]) classpath = rule_runner.request(RenderedClasspath, [compiled_classfiles.digest]) assert classpath.content == { ".Example.java.main.jar": {"org/pantsbuild/example/Example.class"} }
def test_compile_with_deps(rule_runner: RuleRunner) -> None: rule_runner.write_files( { "BUILD": dedent( """\ coursier_lockfile( name = 'lockfile', requirements = [], sources = [ "coursier_resolve.lockfile", ], ) java_sources( name = 'main', dependencies = [ ':lockfile', 'lib:lib', ] ) """ ), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()) .to_json() .decode("utf-8"), "Example.java": JAVA_LIB_MAIN_SOURCE, "lib/BUILD": dedent( """\ java_sources( name = 'lib', dependencies = [ '//:lockfile', ] ) """ ), "lib/ExampleLib.java": JAVA_LIB_SOURCE, } ) compiled_classfiles = rule_runner.request( CompiledClassfiles, [ CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main") ) ) ], ) classfile_digest_contents = rule_runner.request(DigestContents, [compiled_classfiles.digest]) assert len(classfile_digest_contents) == 1 assert classfile_digest_contents[0].path == "org/pantsbuild/example/Example.class"
def test_compile_no_deps(rule_runner: RuleRunner) -> None: rule_runner.write_files( { "BUILD": dedent( """\ coursier_lockfile( name = 'lockfile', requirements = [], sources = [ "coursier_resolve.lockfile", ], ) java_sources( name = 'lib', dependencies = [ ':lockfile', ] ) """ ), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()) .to_json() .decode("utf-8"), "ExampleLib.java": JAVA_LIB_SOURCE, } ) coarsened_target = expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="lib") ) compiled_classfiles = rule_runner.request( CompiledClassfiles, [CompileJavaSourceRequest(component=coarsened_target)], ) classfile_digest_contents = rule_runner.request(DigestContents, [compiled_classfiles.digest]) assert frozenset(content.path for content in classfile_digest_contents) == frozenset( ["org/pantsbuild/example/lib/ExampleLib.class"] ) # Additionally validate that `check` works. check_results = rule_runner.request( CheckResults, [JavacCheckRequest([JavacCheckRequest.field_set_type.create(coarsened_target.members[0])])], ) assert len(check_results.results) == 1 check_result = check_results.results[0] assert check_result.partition_description == str(coarsened_target)
def test_compile_with_missing_maven_dep_fails(rule_runner: RuleRunner) -> None: rule_runner.write_files( { "BUILD": dedent( """\ coursier_lockfile( name = 'lockfile', requirements = [], sources = [ "coursier_resolve.lockfile", ], ) java_sources( name = 'main', dependencies = [ ':lockfile', ] ) """ ), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()) .to_json() .decode("utf-8"), "Example.java": dedent( """ package org.pantsbuild.example; import org.joda.time.DateTime; public class Example { public static void main(String[] args) { DateTime dt = new DateTime(); System.out.println(dt.getYear()); } } """ ), } ) request = CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main") ) ) fallible_result = rule_runner.request(FallibleCompiledClassfiles, [request]) assert fallible_result.result == CompileResult.FAILED and fallible_result.stderr assert "package org.joda.time does not exist" in fallible_result.stderr
def test_compile_jdk_versions(rule_runner: RuleRunner) -> None: rule_runner.write_files( { "BUILD": dedent( """\ coursier_lockfile( name = 'lockfile', requirements = [], sources = [ "coursier_resolve.lockfile", ], ) java_sources( name = 'lib', dependencies = [ ':lockfile', ] ) """ ), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()) .to_json() .decode("utf-8"), "ExampleLib.java": JAVA_LIB_SOURCE, } ) request = CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="lib") ) ) rule_runner.set_options(["--javac-jdk=zulu:1.6"]) assert { contents.path for contents in rule_runner.request( DigestContents, [rule_runner.request(CompiledClassfiles, [request]).digest] ) } == {"org/pantsbuild/example/lib/ExampleLib.class"} rule_runner.set_options(["--javac-jdk=bogusjdk:999"]) expected_exception_msg = r".*?JVM bogusjdk:999 not found in index.*?" with pytest.raises(ExecutionError, match=expected_exception_msg): rule_runner.request(CompiledClassfiles, [request])
def test_compile_jdk_versions(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'lib', ) """), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()).to_json().decode("utf-8"), "ExampleLib.java": JAVA_LIB_SOURCE, }) request = CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="lib")), resolve=make_resolve(rule_runner), ) rule_runner.set_options( [ "--javac-jdk=zulu:8.0.312", NAMED_RESOLVE_OPTIONS, DEFAULT_RESOLVE_OPTION ], env_inherit=PYTHON_BOOTSTRAP_ENV, ) compiled_classfiles = rule_runner.request(ClasspathEntry, [request]) classpath = rule_runner.request(RenderedClasspath, [compiled_classfiles.digest]) assert classpath.content == { ".ExampleLib.java.lib.jar": {"org/pantsbuild/example/lib/ExampleLib.class"} } rule_runner.set_options( [ "--javac-jdk=bogusjdk:999", NAMED_RESOLVE_OPTIONS, DEFAULT_RESOLVE_OPTION ], env_inherit=PYTHON_BOOTSTRAP_ENV, ) expected_exception_msg = r".*?JVM bogusjdk:999 not found in index.*?" with pytest.raises(ExecutionError, match=expected_exception_msg): rule_runner.request(ClasspathEntry, [request])
def test_compile_no_deps(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'lib', ) """), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()).to_json().decode("utf-8"), "ExampleLib.java": JAVA_LIB_SOURCE, }) coarsened_target = expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="lib")) compiled_classfiles = rule_runner.request( ClasspathEntry, [ CompileJavaSourceRequest(component=coarsened_target, resolve=make_resolve(rule_runner)) ], ) classpath = rule_runner.request(RenderedClasspath, [compiled_classfiles.digest]) assert classpath.content == { ".ExampleLib.java.lib.jar": {"org/pantsbuild/example/lib/ExampleLib.class"} } # Additionally validate that `check` works. check_results = rule_runner.request( CheckResults, [ JavacCheckRequest([ JavacCheckRequest.field_set_type.create( coarsened_target.representative) ]) ], ).results assert set(check_results) == {CheckResult(0, "", "")}
def test_compile_with_deps(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'main', dependencies = [ 'lib:lib', ] ) """), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()).to_json().decode("utf-8"), "Example.java": JAVA_LIB_MAIN_SOURCE, "lib/BUILD": dedent("""\ java_sources( name = 'lib', ) """), "lib/ExampleLib.java": JAVA_LIB_SOURCE, }) compiled_classfiles = rule_runner.request( ClasspathEntry, [ CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main")), resolve=make_resolve(rule_runner), ) ], ) classpath = rule_runner.request(RenderedClasspath, [compiled_classfiles.digest]) assert classpath.content == { ".Example.java.main.jar": {"org/pantsbuild/example/Example.class"} }
def test_compile_with_deps(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'main', dependencies = [ 'lib:lib', ] ) """), "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), "Example.java": JAVA_LIB_MAIN_SOURCE, "lib/BUILD": dedent("""\ java_sources( name = 'lib', ) """), "lib/ExampleLib.java": JAVA_LIB_SOURCE, }) classpath = rule_runner.request( RenderedClasspath, [ CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main")), resolve=make_resolve(rule_runner), ) ], ) assert classpath.content == { ".Example.java.main.javac.jar": {"org/pantsbuild/example/Example.class"} }
def test_compile_with_missing_dep_fails(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'main', ) """), "Example.java": JAVA_LIB_MAIN_SOURCE, "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), }) request = CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main")), resolve=make_resolve(rule_runner), ) fallible_result = rule_runner.request(FallibleClasspathEntry, [request]) assert fallible_result.result == CompileResult.FAILED and fallible_result.stderr assert "package org.pantsbuild.example.lib does not exist" in fallible_result.stderr
def test_compile_jdk_12_file_fails_with_jdk_11( rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'lib', jdk = 'adopt:1.11', ) """), "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), "ExampleLib.java": JAVA_LIB_JDK12_SOURCE, }) request = CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="lib")), resolve=make_resolve(rule_runner), ) with pytest.raises(ExecutionError): rule_runner.request(RenderedClasspath, [request])
async def run_junit_test( bash: BashBinary, jdk_setup: JdkSetup, junit: JUnit, test_subsystem: TestSubsystem, field_set: JavaTestFieldSet, ) -> TestResult: transitive_targets = await Get(TransitiveTargets, TransitiveTargetsRequest([field_set.address])) coarsened_targets = await Get( CoarsenedTargets, Addresses(t.address for t in transitive_targets.closure) ) lockfile = await Get( CoursierResolvedLockfile, CoursierLockfileForTargetRequest(Targets(transitive_targets.closure)), ) materialized_classpath = await Get( MaterializedClasspath, MaterializedClasspathRequest( prefix="__thirdpartycp", lockfiles=(lockfile,), artifact_requirements=( ArtifactRequirements( [ Coordinate( group="org.junit.platform", artifact="junit-platform-console", version="1.7.2", ), Coordinate( group="org.junit.jupiter", artifact="junit-jupiter-engine", version="5.7.2", ), Coordinate( group="org.junit.vintage", artifact="junit-vintage-engine", version="5.7.2", ), ] ), ), ), ) transitive_user_classfiles = await MultiGet( Get(CompiledClassfiles, CompileJavaSourceRequest(component=t)) for t in coarsened_targets ) merged_transitive_user_classfiles_digest = await Get( Digest, MergeDigests(classfiles.digest for classfiles in transitive_user_classfiles) ) usercp_relpath = "__usercp" prefixed_transitive_user_classfiles_digest = await Get( Digest, AddPrefix(merged_transitive_user_classfiles_digest, usercp_relpath) ) merged_digest = await Get( Digest, MergeDigests( ( prefixed_transitive_user_classfiles_digest, materialized_classpath.digest, jdk_setup.digest, ) ), ) proc = Process( argv=[ *jdk_setup.args(bash, [materialized_classpath.classpath_arg()]), "org.junit.platform.console.ConsoleLauncher", "--classpath", usercp_relpath, "--scan-class-path", usercp_relpath, *junit.options.args, ], input_digest=merged_digest, description=f"Run JUnit 5 ConsoleLauncher against {field_set.address}", level=LogLevel.DEBUG, ) process_result = await Get( FallibleProcessResult, Process, proc, ) return TestResult.from_fallible_process_result( process_result, address=field_set.address, output_setting=test_subsystem.output, )
def test_compile_with_transitive_cycle(rule_runner: RuleRunner) -> None: """Like test_compile_with_cycle, but the cycle occurs as a transitive dep of the requested target.""" rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'main', dependencies = [ 'a:a', ] ) """), "Main.java": dedent("""\ package org.pantsbuild.main; import org.pantsbuild.a.A; public class Main implements A {} """), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()).to_json().decode("utf-8"), "a/BUILD": dedent("""\ java_sources( name = 'a', dependencies = [ 'b/B.java', ] ) """), "a/A.java": dedent("""\ package org.pantsbuild.a; import org.pantsbuild.b.B; public interface A {} class C implements B {} """), "b/BUILD": dedent("""\ java_sources( name = 'b', dependencies = [ 'a:a', ] ) """), "b/B.java": dedent("""\ package org.pantsbuild.b; import org.pantsbuild.a.A; public interface B {}; class C implements A {} """), }) compiled_classfiles = rule_runner.request( ClasspathEntry, [ CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main")), resolve=make_resolve(rule_runner), ) ], ) classpath = rule_runner.request(RenderedClasspath, [compiled_classfiles.digest]) assert classpath.content == { ".Main.java.main.jar": {"org/pantsbuild/main/Main.class"} }
def test_compile_with_cycle(rule_runner: RuleRunner) -> None: """Test that javac can handle source-level cycles--even across build target boundaries--via graph coarsening. This test has to set up a contrived dependency since build-target cycles are forbidden by the graph. However, file-target cycles are not forbidden, so we configure the graph like so: a:a has a single source file, which has file-target address a/A.java, and which inherits a:a's explicit dependency on b/B.java. b:b depends directly on a:a, and its source b/B.java inherits that dependency. Therefore, after target expansion via Get(Targets, Addresses(...)), we get the cycle of: a/A.java -> b/B.java -> a/A.java """ rule_runner.write_files({ "BUILD": dedent("""\ """), "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), "a/BUILD": dedent("""\ java_sources( name = 'a', dependencies = [ 'b/B.java', ] ) """), "a/A.java": dedent("""\ package org.pantsbuild.a; import org.pantsbuild.b.B; public interface A {} class C implements B {} """), "b/BUILD": dedent("""\ java_sources( name = 'b', dependencies = [ 'a/A.java', ] ) """), "b/B.java": dedent("""\ package org.pantsbuild.b; import org.pantsbuild.a.A; public interface B {}; class C implements A {} """), }) coarsened_target = expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="a", target_name="a")) assert sorted(t.address.spec for t in coarsened_target.members) == [ "a/A.java", "b/B.java" ] request = CompileJavaSourceRequest(component=coarsened_target, resolve=make_resolve(rule_runner)) classpath = rule_runner.request(RenderedClasspath, [request]) assert classpath.content == { "a.A.java.javac.jar": { "org/pantsbuild/a/A.class", "org/pantsbuild/a/C.class", "org/pantsbuild/b/B.class", "org/pantsbuild/b/C.class", } }
def test_compile_with_transitive_multiple_sources(rule_runner: RuleRunner) -> None: """Like test_compile_with_transitive_cycle, but the cycle occurs via subtarget source expansion rather than explicitly.""" rule_runner.write_files( { "BUILD": dedent( """\ coursier_lockfile( name = 'lockfile', requirements = [], sources = [ "coursier_resolve.lockfile", ], ) java_sources( name = 'main', dependencies = [ '//:lockfile', 'lib:lib', ] ) """ ), "Main.java": dedent( """\ package org.pantsbuild.main; import org.pantsbuild.a.A; import org.pantsbuild.b.B; public class Main implements A {} class Other implements B {} """ ), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()) .to_json() .decode("utf-8"), "lib/BUILD": dedent( """\ java_sources( name = 'lib', dependencies = [ '//:lockfile', ] ) """ ), "lib/A.java": dedent( """\ package org.pantsbuild.a; import org.pantsbuild.b.B; public interface A {} class C implements B {} """ ), "lib/B.java": dedent( """\ package org.pantsbuild.b; import org.pantsbuild.a.A; public interface B {}; class C implements A {} """ ), } ) compiled_classfiles = rule_runner.request( CompiledClassfiles, [ CompileJavaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main") ) ) ], ) classfile_digest_contents = rule_runner.request(DigestContents, [compiled_classfiles.digest]) assert frozenset(content.path for content in classfile_digest_contents) == frozenset( ["org/pantsbuild/main/Main.class", "org/pantsbuild/main/Other.class"] )
def test_compile_with_cycle(rule_runner: RuleRunner) -> None: """Test that javac can handle source-level cycles--even across build target boundaries--via graph coarsening. This test has to set up a contrived dependency since build-target cycles are forbidden by the graph. However, file-target cycles are not forbidden, so we configure the graph like so: a:a has a single source file, which has file-target address a/A.java, and which inherits a:a's explicit dependency on b/B.java. b:b depends directly on a:a, and its source b/B.java inherits that dependency. Therefore, after target expansion via Get(Targets, Addresses(...)), we get the cycle of: a/A.java -> b/B.java -> a/A.java """ rule_runner.write_files( { "BUILD": dedent( """\ coursier_lockfile( name = 'lockfile', requirements = [], sources = [ "coursier_resolve.lockfile", ], ) """ ), "coursier_resolve.lockfile": CoursierResolvedLockfile(entries=()) .to_json() .decode("utf-8"), "a/BUILD": dedent( """\ java_sources( name = 'a', dependencies = [ '//:lockfile', 'b/B.java', ] ) """ ), "a/A.java": dedent( """\ package org.pantsbuild.a; import org.pantsbuild.b.B; public interface A {} class C implements B {} """ ), "b/BUILD": dedent( """\ java_sources( name = 'b', dependencies = [ '//:lockfile', 'a/A.java', ] ) """ ), "b/B.java": dedent( """\ package org.pantsbuild.b; import org.pantsbuild.a.A; public interface B {}; class C implements A {} """ ), } ) coarsened_target = expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="a", target_name="a") ) assert sorted([t.address.spec for t in coarsened_target.members]) == ["a/A.java", "b/B.java"] request = CompileJavaSourceRequest(component=coarsened_target) compiled_classfiles = rule_runner.request(CompiledClassfiles, [request]) classfile_digest_contents = rule_runner.request(DigestContents, [compiled_classfiles.digest]) assert frozenset(content.path for content in classfile_digest_contents) == frozenset( [ "org/pantsbuild/a/A.class", "org/pantsbuild/a/C.class", "org/pantsbuild/b/B.class", "org/pantsbuild/b/C.class", ] )
def test_compile_with_transitive_multiple_sources( rule_runner: RuleRunner) -> None: """Like test_compile_with_transitive_cycle, but the cycle occurs via subtarget source expansion rather than explicitly.""" rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'main', dependencies = [ 'lib:lib', ] ) """), "Main.java": dedent("""\ package org.pantsbuild.main; import org.pantsbuild.a.A; import org.pantsbuild.b.B; public class Main implements A {} class Other implements B {} """), "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=()).serialize(), "lib/BUILD": dedent("""\ java_sources( name = 'lib', ) """), "lib/A.java": dedent("""\ package org.pantsbuild.a; import org.pantsbuild.b.B; public interface A {} class C implements B {} """), "lib/B.java": dedent("""\ package org.pantsbuild.b; import org.pantsbuild.a.A; public interface B {}; class C implements A {} """), }) ctgt = expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main")) classpath = rule_runner.request( RenderedClasspath, [ CompileJavaSourceRequest(component=ctgt, resolve=make_resolve(rule_runner)) ], ) assert classpath.content == { ".Main.java.main.javac.jar": { "org/pantsbuild/main/Main.class", "org/pantsbuild/main/Other.class", } }