def test_fetch_one_coord_with_mismatched_coord( rule_runner: RuleRunner) -> None: """This test demonstrates that fetch_one_coord is picky about inexact coordinates. Even though the expected jar was downloaded, the coordinate in the lockfile entry was inexact, meaning it wasn't an exact string match for the coordinate fetched and reported by Coursier, which is exact. This shouldn't happen in practice, because these lockfile entries are ultimately derived from Coursier reports which always give exact coordinate strings. """ expected_exception_msg = ( r'Coursier resolved coord.*?"org.hamcrest:hamcrest-core:1.3".*?' r'does not match requested coord.*?"org.hamcrest:hamcrest-core:1.3\+".*?' ) lockfile_entry = CoursierLockfileEntry( coord=MavenCoord(coord="org.hamcrest:hamcrest-core:1.3+"), file_name="hamcrest-core-1.3.jar", direct_dependencies=MavenCoordinates([]), dependencies=MavenCoordinates([]), file_digest=FileDigest( fingerprint= "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9", serialized_bytes_length=45024, ), ) with pytest.raises(ExecutionError, match=expected_exception_msg): rule_runner.request(ResolvedClasspathEntry, [lockfile_entry])
def test_fetch_one_coord_with_no_deps(rule_runner: RuleRunner) -> None: classpath_entry = rule_runner.request( ResolvedClasspathEntry, [ CoursierLockfileEntry( coord=HAMCREST_COORD, file_name="hamcrest-core-1.3.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9", serialized_bytes_length=45024, ), ) ], ) assert classpath_entry.coord == HAMCREST_COORD assert classpath_entry.file_name == "hamcrest-core-1.3.jar" file_digest = rule_runner.request( FileDigest, [ExtractFileDigest(classpath_entry.digest, "hamcrest-core-1.3.jar")]) assert file_digest == FileDigest( fingerprint= "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9", serialized_bytes_length=45024, )
def test_fetch_one_coord_with_transitive_deps(rule_runner: RuleRunner) -> None: junit_coord = Coordinate(group="junit", artifact="junit", version="4.13.2") classpath_entry = rule_runner.request( ResolvedClasspathEntry, [ CoursierLockfileEntry( coord=junit_coord, file_name="junit-4.13.2.jar", direct_dependencies=Coordinates([HAMCREST_COORD]), dependencies=Coordinates([HAMCREST_COORD]), file_digest=FileDigest( fingerprint= "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3", serialized_bytes_length=384581, ), ) ], ) assert classpath_entry.coord == junit_coord assert classpath_entry.file_name == "junit-4.13.2.jar" file_digest = rule_runner.request( FileDigest, [ExtractFileDigest(classpath_entry.digest, "junit-4.13.2.jar")]) assert file_digest == FileDigest( fingerprint= "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3", serialized_bytes_length=384581, )
def test_fetch_one_coord_with_transitive_deps(rule_runner: RuleRunner) -> None: classpath_entry = rule_runner.request( ResolvedClasspathEntry, [ CoursierLockfileEntry( coord=MavenCoord(coord="junit:junit:4.13.2"), file_name="junit-4.13.2.jar", direct_dependencies=MavenCoordinates( [MavenCoord(coord="org.hamcrest:hamcrest-core:1.3")]), dependencies=MavenCoordinates( [MavenCoord(coord="org.hamcrest:hamcrest-core:1.3")]), file_digest=FileDigest( fingerprint= "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3", serialized_bytes_length=384581, ), ) ], ) assert classpath_entry.coord == MavenCoord(coord="junit:junit:4.13.2") assert classpath_entry.file_name == "junit-4.13.2.jar" file_digest = rule_runner.request( FileDigest, [ExtractFileDigest(classpath_entry.digest, "junit-4.13.2.jar")]) assert file_digest == FileDigest( fingerprint= "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3", serialized_bytes_length=384581, )
def lockfile() -> CoursierResolvedLockfile: # Calculate transitive deps transitive_ = {(i, k) for i, j in direct.items() for k in j} while True: old_len = len(transitive_) transitive_ |= {(i, k) for i, j in transitive_ for k in direct[j]} if old_len == len(transitive_): break transitive = DefaultDict(set) for (i, j) in transitive_: transitive[i].add(j) entries = ( CoursierLockfileEntry( coord=coord, file_name=f"{coord.artifact}.jar", direct_dependencies=Coordinates(direct[coord]), dependencies=Coordinates(transitive[coord]), file_digest=mock.Mock(), ) for coord in direct ) return CoursierResolvedLockfile(entries=tuple(entries))
def test_resolve_with_inexact_coord(rule_runner: RuleRunner) -> None: resolved_lockfile = rule_runner.request( CoursierResolvedLockfile, [ # Note the open-ended coordinate here. We will still resolve this for the user, but the result # will be exact and pinned. As noted above, this is an especially brittle unit test, but version # 4.8 was chosen because it has multiple patch versions and no new versions have been uploaded # to 4.8.x in over a decade. ArtifactRequirements( [Coordinate(group="junit", artifact="junit", version="4.8+")]), ], ) assert resolved_lockfile == CoursierResolvedLockfile( entries=(CoursierLockfileEntry( coord=Coordinate(group="junit", artifact="junit", version="4.8.2"), file_name="junit-4.8.2.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "a2aa2c3bb2b72da76c3e6a71531f1eefdc350494819baf2b1d80d7146e020f9e", serialized_bytes_length=237344, ), ), ))
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", ) scala_sources( name = 'main', dependencies = [":joda-time_joda-time"], ) """), "coursier_resolve.lockfile": resolved_joda_lockfile.to_json().decode("utf-8"), "Example.scala": dedent(""" package org.pantsbuild.example import org.joda.time.DateTime object Main { def main(args: Array[String]): Unit = { val dt = new DateTime() println(dt.getYear) } } """), }) request = CompileScalaSourceRequest( 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.scala.main.jar": { "META-INF/MANIFEST.MF", "org/pantsbuild/example/Main$.class", "org/pantsbuild/example/Main.class", } }
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_resolve_with_a_jar(rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": textwrap.dedent("""\ jvm_artifact( name="jeremy", group="jeremy", artifact="jeremy", version="4.13.2", jar="jeremy.jar", ) """), "jeremy.jar": "hello dave", }) targets = rule_runner.request(Targets, [ RawSpecs(recursive_globs=(RecursiveGlobSpec(""), ), description_of_origin="tests") ]) jeremy_target = targets[0] jar_field = jeremy_target[JvmArtifactJarSourceField] requirement = ArtifactRequirement( coordinate=Coordinate( group="jeremy", artifact="jeremy", version="4.13.2", ), jar=jar_field, ) resolved_lockfile = rule_runner.request( CoursierResolvedLockfile, [ArtifactRequirements([requirement])], ) coordinate = requirement.coordinate assert resolved_lockfile == CoursierResolvedLockfile( entries=(CoursierLockfileEntry( coord=Coordinate(group=coordinate.group, artifact=coordinate.artifact, version=coordinate.version), file_name= f"{coordinate.group}_{coordinate.artifact}_{coordinate.version}.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "55b9afa8d7776cd6c318eec51f506e9c7f66c247dcec343d4667f5f269714f86", serialized_bytes_length=10, ), pants_address=jar_field.address.spec, ), ))
def test_resolve_with_transitive_deps(rule_runner: RuleRunner) -> None: resolved_lockfile = rule_runner.request( CoursierResolvedLockfile, [ MavenRequirements.create_from_maven_coordinates_fields( fields=(), additional_requirements=["junit:junit:4.13.2"], ) ], ) assert resolved_lockfile == CoursierResolvedLockfile(entries=( CoursierLockfileEntry( coord=MavenCoord(coord="junit:junit:4.13.2"), file_name="junit-4.13.2.jar", direct_dependencies=MavenCoordinates( [MavenCoord(coord="org.hamcrest:hamcrest-core:1.3")]), dependencies=MavenCoordinates( [MavenCoord(coord="org.hamcrest:hamcrest-core:1.3")]), file_digest=FileDigest( fingerprint= "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3", serialized_bytes_length=384581, ), ), CoursierLockfileEntry( coord=MavenCoord(coord="org.hamcrest:hamcrest-core:1.3"), file_name="hamcrest-core-1.3.jar", direct_dependencies=MavenCoordinates([]), dependencies=MavenCoordinates([]), file_digest=FileDigest( fingerprint= "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9", serialized_bytes_length=45024, ), ), ))
def test_resolve_with_no_deps(rule_runner: RuleRunner) -> None: resolved_lockfile = rule_runner.request( CoursierResolvedLockfile, [ArtifactRequirements([HAMCREST_COORD])], ) assert resolved_lockfile == CoursierResolvedLockfile( entries=(CoursierLockfileEntry( coord=HAMCREST_COORD, file_name="hamcrest-core-1.3.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9", serialized_bytes_length=45024, ), ), ))
def test_coursier_resolve_updates_bogus_lockfile( rule_runner: RuleRunner) -> None: rule_runner.write_files({ "BUILD": dedent("""\ java_sources( name = 'here_to_provide_dependencies', dependencies = [ ':org.hamcrest_hamcrest-core', ], sources = ["*.txt"], ) jvm_artifact( name = 'org.hamcrest_hamcrest-core', group = 'org.hamcrest', artifact = 'hamcrest-core', version = "1.3", ) coursier_lockfile( name = 'example-lockfile', ) """), "coursier_resolve.lockfile": "]bad json[", }) result = rule_runner.run_goal_rule(CoursierResolve, args=ARGS, env_inherit=PYTHON_BOOTSTRAP_ENV) assert result.exit_code == 0 assert result.stderr == "Updated lockfile at: coursier_resolve.lockfile\n" expected_lockfile = CoursierResolvedLockfile(entries=(CoursierLockfileEntry( coord=HAMCREST_COORD, file_name="hamcrest-core-1.3.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9", serialized_bytes_length=45024, ), ), )) assert (Path(rule_runner.build_root, "coursier_resolve.lockfile").read_bytes() == expected_lockfile.to_json())
def test_fetch_one_coord_with_jar(rule_runner: RuleRunner) -> None: coord = Coordinate(group="jeremy", artifact="jeremy", version="4.13.2") file_name = f"{coord.group}_{coord.artifact}_{coord.version}.jar" rule_runner.write_files({ "BUILD": textwrap.dedent(f"""\ jvm_artifact( name="jeremy", group="{coord.group}", artifact="{coord.artifact}", version="{coord.version}", jar="jeremy.jar", ) """), "jeremy.jar": "hello dave", }) classpath_entry = rule_runner.request( ClasspathEntry, [ CoursierLockfileEntry( coord=coord, file_name=file_name, direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "55b9afa8d7776cd6c318eec51f506e9c7f66c247dcec343d4667f5f269714f86", serialized_bytes_length=10, ), pants_address="//:jeremy", ) ], ) assert classpath_entry.filenames == (file_name, ) file_digest = rule_runner.request( FileDigest, [ExtractFileDigest(classpath_entry.digest, file_name)], ) assert file_digest == FileDigest( fingerprint= "55b9afa8d7776cd6c318eec51f506e9c7f66c247dcec343d4667f5f269714f86", serialized_bytes_length=10, )
async def fetch_nailgun() -> Nailgun: nailgun = await Get( ClasspathEntry, CoursierLockfileEntry( coord=Coordinate.from_coord_str( "com.martiansoftware:nailgun-server:0.9.1"), file_name="com.martiansoftware_nailgun-server_0.9.1.jar", direct_dependencies=Coordinates(), dependencies=Coordinates(), file_digest=FileDigest( fingerprint= "4518faa6bf4bd26fccdc4d85e1625dc679381a08d56872d8ad12151dda9cef25", serialized_bytes_length=32927, ), ), ) return Nailgun(nailgun)
def test_fetch_one_coord_with_bad_fingerprint(rule_runner: RuleRunner) -> None: expected_exception_msg = ( r".*?CoursierError:.*?Coursier fetch for .*?hamcrest.*? succeeded.*?" r"66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9.*?" r"did not match.*?ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" ) lockfile_entry = CoursierLockfileEntry( coord=HAMCREST_COORD, file_name="hamcrest-core-1.3.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", serialized_bytes_length=45024, ), ) with pytest.raises(ExecutionError, match=expected_exception_msg): rule_runner.request(ClasspathEntry, [lockfile_entry])
def test_resolve_with_no_deps(rule_runner: RuleRunner) -> None: resolved_lockfile = rule_runner.request( CoursierResolvedLockfile, [ MavenRequirements.create_from_maven_coordinates_fields( fields=(), additional_requirements=["org.hamcrest:hamcrest-core:1.3"], ) ], ) assert resolved_lockfile == CoursierResolvedLockfile( entries=(CoursierLockfileEntry( coord=MavenCoord(coord="org.hamcrest:hamcrest-core:1.3"), file_name="hamcrest-core-1.3.jar", direct_dependencies=MavenCoordinates([]), dependencies=MavenCoordinates([]), file_digest=FileDigest( fingerprint= "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9", serialized_bytes_length=45024, ), ), ))
def test_coursier_resolve_noop_does_not_touch_lockfile( rule_runner: RuleRunner) -> None: expected_lockfile = CoursierResolvedLockfile(entries=(CoursierLockfileEntry( coord=HAMCREST_COORD, file_name="hamcrest-core-1.3.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9", serialized_bytes_length=45024, ), ), )) rule_runner.write_files({ "BUILD": dedent("""\ jvm_artifact( name = 'org.hamcrest_hamcrest-core', group = 'org.hamcrest', artifact = 'hamcrest-core', version = "1.3", ) coursier_lockfile( name = 'example-lockfile', requirements = [ ':org.hamcrest_hamcrest-core', ], sources = [ "coursier_resolve.lockfile", ], ) """), "coursier_resolve.lockfile": expected_lockfile.to_json().decode("utf-8"), }) result = rule_runner.run_goal_rule(CoursierResolve, args=["::"]) assert result.exit_code == 0 assert result.stderr == ""
def test_resolve_with_working_url(rule_runner: RuleRunner) -> None: requirement = ArtifactRequirement( coordinate=Coordinate( group="apache-commons-local", artifact="commons-collections", version="1.0.0_JAR_LOCAL", ), url= "https://repo1.maven.org/maven2/org/apache/commons/commons-collections4/4.2/commons-collections4-4.2.jar", ) resolved_lockfile = rule_runner.request( CoursierResolvedLockfile, [ArtifactRequirements([requirement])], ) coordinate = requirement.coordinate assert resolved_lockfile == CoursierResolvedLockfile( entries=(CoursierLockfileEntry( coord=Coordinate(group=coordinate.group, artifact=coordinate.artifact, version=coordinate.version), file_name= f"{coordinate.group}_{coordinate.artifact}_{coordinate.version}.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "6a594721d51444fd97b3eaefc998a77f606dedb03def494f74755aead3c9df3e", serialized_bytes_length=752798, ), remote_url=requirement.url, pants_address=None, ), ))
# additional_requirements=["junit:junit:4.13.2"], # ) # ], # ) # The `repr` of the resulting lockfile object can be directly copied # into code to get the following: JUNIT4_RESOLVED_LOCKFILE = CoursierResolvedLockfile(entries=( CoursierLockfileEntry( coord=Coordinate(group="junit", artifact="junit", version="4.13.2"), file_name="junit-4.13.2.jar", direct_dependencies=Coordinates([ Coordinate( group="org.hamcrest", artifact="hamcrest-core", version="1.3") ]), dependencies=Coordinates([ Coordinate( group="org.hamcrest", artifact="hamcrest-core", version="1.3") ]), file_digest=FileDigest( fingerprint= "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3", serialized_bytes_length=384581, ), ), CoursierLockfileEntry( coord=Coordinate( group="org.hamcrest", artifact="hamcrest-core", version="1.3"), file_name="hamcrest-core-1.3.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest(
def test_compile_with_multiple_scala_versions(rule_runner: RuleRunner) -> None: scala_library_coord_2_12 = Coordinate(group="org.scala-lang", artifact="scala-library", version="2.12.15") scala_library_coord_2_13 = Coordinate(group="org.scala-lang", artifact="scala-library", version="2.13.8") rule_runner.write_files({ "BUILD": dedent("""\ scala_sources( name = 'main_2.12', resolve = "scala2.12", ) scala_sources( name = 'main_2.13', resolve = "scala2.13", ) jvm_artifact( name="org.scala-lang_scala-library_2.12.15", group="org.scala-lang", artifact="scala-library", version="2.12.15", resolve="scala2.12", ) jvm_artifact( name="org.scala-lang_scala-library_2.13.8", group="org.scala-lang", artifact="scala-library", version="2.13.8", resolve="scala2.13", ) """), "Example.scala": SCALA_LIB_SOURCE, "3rdparty/jvm/scala2.12.lock": TestCoursierWrapper.new(entries=(CoursierLockfileEntry( coord=scala_library_coord_2_12, file_name="org.scala-lang_scala-library_2.12.15.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "e518bb640e2175de5cb1f8e326679b8d975376221f1b547757de429bbf4563f0", 5443542, ), ), ), ).serialize([ArtifactRequirement(scala_library_coord_2_12)]), "3rdparty/jvm/scala2.13.lock": TestCoursierWrapper.new(entries=(CoursierLockfileEntry( coord=scala_library_coord_2_13, file_name="org.scala-lang_scala-library_2.13.8.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "a0882b82514190c2bac7d1a459872a75f005fc0f3e88b2bc0390367146e35db7", 6003601, ), ), ), ).serialize([ArtifactRequirement(scala_library_coord_2_13)]), }) rule_runner.set_options( [ '--scala-version-for-resolve={"scala2.12":"2.12.15","scala2.13":"2.13.8"}', '--jvm-resolves={"scala2.12":"3rdparty/jvm/scala2.12.lock","scala2.13":"3rdparty/jvm/scala2.13.lock"}', ], env_inherit=PYTHON_BOOTSTRAP_ENV, ) classpath_2_12 = rule_runner.request( ClasspathEntry, [ CompileScalaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main_2.12")), resolve=make_resolve(rule_runner, "scala2.12", "3rdparty/jvm/scala2.12.lock"), ) ], ) entries_2_12 = list(ClasspathEntry.closure([classpath_2_12])) filenames_2_12 = sorted( itertools.chain.from_iterable(entry.filenames for entry in entries_2_12)) assert filenames_2_12 == [ ".Example.scala.main_2.12.scalac.jar", "org.scala-lang_scala-library_2.12.15.jar", ] classpath_2_13 = rule_runner.request( ClasspathEntry, [ CompileScalaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main_2.13")), resolve=make_resolve(rule_runner, "scala2.13", "3rdparty/jvm/scala2.13.lock"), ) ], ) entries_2_13 = list(ClasspathEntry.closure([classpath_2_13])) filenames_2_13 = sorted( itertools.chain.from_iterable(entry.filenames for entry in entries_2_13)) assert filenames_2_13 == [ ".Example.scala.main_2.13.scalac.jar", "org.scala-lang_scala-library_2.13.8.jar", ]
def test_compile_with_multiple_scalac_plugins(rule_runner: RuleRunner) -> None: better_monadic_coord = Coordinate(group="com.olegpy", artifact="better-monadic-for_2.13", version="0.3.1") kind_projector_coord = Coordinate(group="org.typelevel", artifact="kind-projector_2.13.6", version="0.13.2") scala_compiler_coord = Coordinate(group="org.scala-lang", artifact="scala-compiler", version="2.13.6") scala_library_coord = Coordinate(group="org.scala-lang", artifact="scala-library", version="2.13.6") scala_reflect_coord = Coordinate(group="org.scala-lang", artifact="scala-reflect", version="2.13.6") jna_coord = Coordinate(group="net.java.dev.jna", artifact="jna", version="5.3.1") jline_coord = Coordinate(group="org.jline", artifact="jline", version="3.19.0") rule_runner.write_files({ "lib/BUILD": dedent(f"""\ scala_sources() jvm_artifact( name="kind-projector-lib", group="{kind_projector_coord.group}", artifact="{kind_projector_coord.artifact}", version="{kind_projector_coord.version}", ) scalac_plugin( name="kind-projector", plugin_name="kind-projector", # TODO: Support relative addresses. artifact="lib:kind-projector-lib", ) jvm_artifact( name="better-monadic-for-lib", group="{better_monadic_coord.group}", artifact="{better_monadic_coord.artifact}", version="{better_monadic_coord.version}", ) scalac_plugin( name="better-monadic-for", plugin_name="bm4", # TODO: Support relative addresses. artifact="lib:better-monadic-for-lib", ) """), "3rdparty/jvm/BUILD": DEFAULT_SCALA_LIBRARY_TARGET, "3rdparty/jvm/default.lock": DEFAULT_LOCKFILE, "3rdparty/jvm/scalac-plugins.lock": TestCoursierWrapper.new(entries=( CoursierLockfileEntry( coord=better_monadic_coord, file_name="com.olegpy_better-monadic-for_2.13_0.3.1.jar", direct_dependencies=Coordinates( [scala_compiler_coord, scala_library_coord]), dependencies=Coordinates( [scala_compiler_coord, scala_library_coord]), file_digest=FileDigest( "fac649fa7de697d1f98d3f814c4b70f5372c547fa41778383e22cee6c16084f5", 130370, ), ), CoursierLockfileEntry( coord=jna_coord, file_name="net.java.dev.jna_jna_5.3.1.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "01cb505c0698d0f7acf3524c7e73acb7dc424a5bae5e9c86ce44075ab32bc4ee", 1505196, ), ), CoursierLockfileEntry( coord=jline_coord, file_name="org.jline_jline_3.19.0.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "c99ddcfa5431cab88d1cd40fd63bec6ab5a3fe2e83877051198539af66592a46", 987021, ), ), CoursierLockfileEntry( coord=scala_compiler_coord, file_name="org.scala-lang_scala-compiler_2.13.6.jar", direct_dependencies=Coordinates([ jna_coord, jline_coord, scala_library_coord, scala_reflect_coord ]), dependencies=Coordinates([ jna_coord, jline_coord, scala_library_coord, scala_reflect_coord ]), file_digest=FileDigest( "310d263d622a3d016913e94ee00b119d270573a5ceaa6b21312d69637fd9eec1", 12010571, ), ), CoursierLockfileEntry( coord=scala_library_coord, file_name="org.scala-lang_scala-library_2.13.6.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "f19ed732e150d3537794fd3fe42ee18470a3f707efd499ecd05a99e727ff6c8a", 5955737, ), ), CoursierLockfileEntry( coord=scala_reflect_coord, file_name="org.scala-lang_scala-reflect_2.13.6.jar", direct_dependencies=Coordinates([scala_library_coord]), dependencies=Coordinates([scala_library_coord]), file_digest=FileDigest( "f713593809b387c60935bb9a940dfcea53bd0dbf8fdc8d10739a2896f8ac56fa", 3769997, ), ), CoursierLockfileEntry( coord=kind_projector_coord, file_name="org.typelevel_kind-projector_2.13.6_0.13.2.jar", direct_dependencies=Coordinates( [scala_compiler_coord, scala_library_coord]), dependencies=Coordinates([ scala_compiler_coord, scala_reflect_coord, scala_library_coord, jna_coord, jline_coord, ]), file_digest=FileDigest( "3d713d02bbe0d52b01c22ac11a50970460114f32b339f3ea429d52461d6c39ff", 44257, ), ), )).serialize([ ArtifactRequirement(better_monadic_coord), ArtifactRequirement(kind_projector_coord), ]), "lib/A.scala": dedent("""\ trait Functor[F[_]] { def map[A, B](fa: F[A])(f: A => B): F[B] } object KindProjectorTest { implicit def eitherFunctor[E]: Functor[Either[E, *]] = new Functor[Either[E, *]] { def map[A, B](fa: Either[E, A])(f: A => B): Either[E, B] = { fa match { case Left(e) => Left(e) case Right(a) => Right(f(a)) } } } } object BetterMonadicForTest { def example: Option[String] = { case class ImplicitTest(id: String) for { x <- Option(42) implicit0(it: ImplicitTest) <- Option(ImplicitTest("eggs")) _ <- Option("dummy") _ = "dummy" _ = assert(implicitly[ImplicitTest] eq it) } yield "ok" } } """), }) rule_runner.set_options( args=[ "--scalac-plugins-global=['lib:better-monadic-for', 'lib:kind-projector']", "--scalac-plugins-global-lockfile=3rdparty/jvm/scalac-plugins.lock", ], env_inherit=PYTHON_BOOTSTRAP_ENV, ) request = CompileScalaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="lib", relative_file_path="A.scala")), resolve=make_resolve(rule_runner), ) rule_runner.request(RenderedClasspath, [request])
def test_compile_with_local_scalac_plugin(rule_runner: RuleRunner) -> None: acyclic_coord = Coordinate(group="com.lihaoyi", artifact="acyclic_2.13", version="0.2.1") scala_library_coord = Coordinate(group="org.scala-lang", artifact="scala-library", version="2.13.6") rule_runner.write_files({ "lib/BUILD": dedent(f"""\ jvm_artifact( name = "acyclic_lib", group = "{acyclic_coord.group}", artifact = "{acyclic_coord.artifact}", version = "{acyclic_coord.version}", packages=["acyclic.**"], ) scalac_plugin( name = "acyclic", # TODO: Support relative addresses. artifact = "lib:acyclic_lib", ) scala_sources( scalac_plugins=["acyclic"], ) """), "3rdparty/jvm/BUILD": DEFAULT_SCALA_LIBRARY_TARGET, "3rdparty/jvm/default.lock": TestCoursierWrapper.new(entries=( CoursierLockfileEntry( coord=acyclic_coord, file_name="acyclic_2.13-0.2.1.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "4bc4656140ad5e4802fedcdbe920ec7c92dbebf5e76d1c60d35676a314481944", 62534, ), ), CoursierLockfileEntry( coord=scala_library_coord, file_name="org.scala-lang_scala-library_2.13.6.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "f19ed732e150d3537794fd3fe42ee18470a3f707efd499ecd05a99e727ff6c8a", 5955737, ), ), )).serialize([ ArtifactRequirement(coordinate=acyclic_coord), ArtifactRequirement(scala_library_coord), ]), "3rdparty/jvm/scalac-plugins.lock": TestCoursierWrapper.new(entries=( CoursierLockfileEntry( coord=acyclic_coord, file_name="acyclic_2.13-0.2.1.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "4bc4656140ad5e4802fedcdbe920ec7c92dbebf5e76d1c60d35676a314481944", 62534, ), ), CoursierLockfileEntry( coord=scala_library_coord, file_name="org.scala-lang_scala-library_2.13.6.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "f19ed732e150d3537794fd3fe42ee18470a3f707efd499ecd05a99e727ff6c8a", 5955737, ), ), )).serialize([ ArtifactRequirement(coordinate=acyclic_coord), ]), "lib/A.scala": dedent(""" package lib import acyclic.file class A { val b: B = null } """), "lib/B.scala": dedent(""" package lib class B { val a: A = null } """), }) rule_runner.set_options( args=[], env_inherit=PYTHON_BOOTSTRAP_ENV, ) request = CompileScalaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="lib", relative_file_path="A.scala")), resolve=make_resolve(rule_runner), ) fallible_result = rule_runner.request(FallibleClasspathEntry, [request]) assert fallible_result.result == CompileResult.FAILED and fallible_result.stderr assert "error: Unwanted cyclic dependency" in fallible_result.stderr
def test_compile_with_maven_deps(rule_runner: RuleRunner) -> None: joda_coord = Coordinate(group="joda-time", artifact="joda-time", version="2.10.10") scala_library_coord = Coordinate(group="org.scala-lang", artifact="scala-library", version="2.13.6") resolved_joda_lockfile = TestCoursierWrapper.new(entries=( CoursierLockfileEntry( coord=joda_coord, file_name="joda-time-2.10.10.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( fingerprint= "dd8e7c92185a678d1b7b933f31209b6203c8ffa91e9880475a1be0346b9617e3", serialized_bytes_length=644419, ), ), CoursierLockfileEntry( coord=scala_library_coord, file_name="org.scala-lang_scala-library_2.13.6.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "f19ed732e150d3537794fd3fe42ee18470a3f707efd499ecd05a99e727ff6c8a", 5955737, ), ), )) rule_runner.write_files({ "BUILD": dedent(f"""\ jvm_artifact( name = "joda-time_joda-time", group = "{joda_coord.group}", artifact = "{joda_coord.artifact}", version = "{joda_coord.version}", ) scala_sources( name = 'main', dependencies = [":joda-time_joda-time"], ) """), "3rdparty/jvm/BUILD": DEFAULT_SCALA_LIBRARY_TARGET, "3rdparty/jvm/default.lock": resolved_joda_lockfile.serialize([ ArtifactRequirement(joda_coord), ArtifactRequirement(scala_library_coord) ]), "Example.scala": dedent(""" package org.pantsbuild.example import org.joda.time.DateTime object Main { def main(args: Array[String]): Unit = { val dt = new DateTime() println(dt.getYear) } } """), }) classpath = rule_runner.request( RenderedClasspath, [ CompileScalaSourceRequest( component=expect_single_expanded_coarsened_target( rule_runner, Address(spec_path="", target_name="main")), resolve=make_resolve(rule_runner), ) ], ) assert classpath.content == { ".Example.scala.main.scalac.jar": { "META-INF/MANIFEST.MF", "org/pantsbuild/example/Main$.class", "org/pantsbuild/example/Main.class", } }
], target_types=[ JvmArtifactTarget, ScalaSourcesGeneratorTarget, ScalacPluginTarget ], ) rule_runner.set_options(args=[], env_inherit=PYTHON_BOOTSTRAP_ENV) return rule_runner DEFAULT_LOCKFILE = TestCoursierWrapper( CoursierResolvedLockfile((CoursierLockfileEntry( coord=Coordinate(group="org.scala-lang", artifact="scala-library", version="2.13.6"), file_name="org.scala-lang_scala-library_2.13.6.jar", direct_dependencies=Coordinates(), dependencies=Coordinates(), file_digest=FileDigest( "f19ed732e150d3537794fd3fe42ee18470a3f707efd499ecd05a99e727ff6c8a", 5955737), ), ))).serialize([ ArtifactRequirement(coordinate=Coordinate(group="org.scala-lang", artifact="scala-library", version="2.13.6")) ]) DEFAULT_SCALA_LIBRARY_TARGET = textwrap.dedent("""\ jvm_artifact( name="org.scala-lang_scala-library_2.13.6", group="org.scala-lang", artifact="scala-library",
def test_resolve_with_packaging(rule_runner: RuleRunner) -> None: # Tests that an artifact pom which actually reports packaging ends up with proper version and # packaging information. # see https://github.com/pantsbuild/pants/issues/13986 resolved_lockfile = rule_runner.request( CoursierResolvedLockfile, [ ArtifactRequirements.from_coordinates([ Coordinate(group="org.bouncycastle", artifact="bcutil-jdk15on", version="1.70") ]), ], ) assert resolved_lockfile == CoursierResolvedLockfile(entries=( CoursierLockfileEntry( coord=Coordinate( group="org.bouncycastle", artifact="bcprov-jdk15on", version="1.70", packaging="jar", strict=True, ), file_name="org.bouncycastle_bcprov-jdk15on_jar_1.70.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "8f3c20e3e2d565d26f33e8d4857a37d0d7f8ac39b62a7026496fcab1bdac30d4", 5867298), remote_url=None, pants_address=None, ), CoursierLockfileEntry( coord=Coordinate( group="org.bouncycastle", artifact="bcutil-jdk15on", version="1.70", packaging="jar", strict=True, ), file_name="org.bouncycastle_bcutil-jdk15on_1.70.jar", direct_dependencies=Coordinates([ Coordinate( group="org.bouncycastle", artifact="bcprov-jdk15on", version="1.70", packaging="jar", strict=True, ) ]), dependencies=Coordinates([ Coordinate( group="org.bouncycastle", artifact="bcprov-jdk15on", version="1.70", packaging="jar", strict=True, ) ]), file_digest=FileDigest( "52dc5551b0257666526c5095424567fed7dc7b00d2b1ba7bd52298411112b1d0", 482530), remote_url=None, pants_address=None, ), ))
def test_basic_war_packaging(rule_runner: RuleRunner) -> None: servlet_coordinate = Coordinate(group="javax.servlet", artifact="servlet-api", version="2.5") rule_runner.write_files( { "war-test/BUILD": textwrap.dedent( """\ jvm_artifact( name="javax.servlet_servlet-api", group="javax.servlet", artifact="servlet-api", version="2.5", ) jvm_war( name="war", dependencies=[":javax.servlet_servlet-api"], descriptor="web.xml", content=[":html"], ) files(name="orig_html", sources=["*.html"]) relocated_files( name="html", files_targets=[":orig_html"], src="war-test", dest="", ) """ ), "war-test/web.xml": textwrap.dedent( """\ <web-app> </web-app> """ ), "war-test/index.html": textwrap.dedent( """\ <html> <body> <p>This is the home page.</p> </html> """ ), "3rdparty/jvm/default.lock": TestCoursierWrapper.new( ( CoursierLockfileEntry( coord=servlet_coordinate, file_name="javax.servlet_servlet-api_2.5.jar", direct_dependencies=Coordinates(), dependencies=Coordinates(), file_digest=FileDigest( "c658ea360a70faeeadb66fb3c90a702e4142a0ab7768f9ae9828678e0d9ad4dc", 105112, ), ), ), ).serialize([ArtifactRequirement(servlet_coordinate)]), } ) war_tgt = rule_runner.get_target(Address("war-test", target_name="war")) built_package = rule_runner.request(BuiltPackage, [PackageWarFileFieldSet.create(war_tgt)]) assert built_package.digest != EMPTY_DIGEST assert len(built_package.artifacts) == 1 package = built_package.artifacts[0] assert package.relpath == "war-test/war.war" contents = rule_runner.request(DigestContents, [built_package.digest]) assert len(contents) == 1 zip_bytes = BytesIO(contents[0].content) with zipfile.ZipFile(zip_bytes, "r") as zf: files = zf.filelist filenames = [f.filename for f in files] assert sorted(filenames) == [ "WEB-INF/", "WEB-INF/classes/", "WEB-INF/lib/", "WEB-INF/lib/javax.servlet_servlet-api_2.5.jar", "WEB-INF/web.xml", "index.html", ]
async def setup_jdk(coursier: Coursier, javac: JavacSubsystem, bash: BashBinary) -> JdkSetup: nailgun = await Get( ResolvedClasspathEntry, CoursierLockfileEntry( coord=Coordinate.from_coord_str( "com.martiansoftware:nailgun-server:0.9.1"), file_name="nailgun-server-0.9.1.jar", direct_dependencies=Coordinates(), dependencies=Coordinates(), file_digest=FileDigest( fingerprint= "4518faa6bf4bd26fccdc4d85e1625dc679381a08d56872d8ad12151dda9cef25", serialized_bytes_length=32927, ), ), ) if javac.options.jdk == "system": coursier_jdk_option = "--system-jvm" else: coursier_jdk_option = f"--jvm={javac.options.jdk}" java_home_command = f"{coursier.coursier.exe} java-home {coursier_jdk_option}" java_version_result = await Get( FallibleProcessResult, Process( argv=( bash.path, "-c", f"$({java_home_command})/bin/java -version", ), input_digest=coursier.digest, description=f"Ensure download of JDK {coursier_jdk_option}.", cache_scope=ProcessCacheScope.PER_RESTART_SUCCESSFUL, ), ) if java_version_result.exit_code != 0: raise ValueError( f"Failed to locate Java for JDK `{javac.options.jdk}`:\n" f"{java_version_result.stderr.decode('utf-8')}") java_version = java_version_result.stdout.decode("utf-8").strip() # TODO: Locate `ln`. jdk_preparation_script = textwrap.dedent(f"""\ # pants javac script using Coursier {coursier_jdk_option}. `java -version`: {java_version}" set -eu /bin/ln -s "$({java_home_command})" "{JdkSetup.java_home}" exec "$@" """) jdk_preparation_script_digest = await Get( Digest, CreateDigest([ FileContent( JdkSetup.jdk_preparation_script, jdk_preparation_script.encode("utf-8"), is_executable=True, ), ]), ) return JdkSetup( digest=await Get( Digest, MergeDigests([ coursier.digest, jdk_preparation_script_digest, nailgun.digest, ]), ), nailgun_jar=nailgun.file_name, )
from pants.jvm.resolve.coursier_fetch import CoursierLockfileEntry from pants.jvm.resolve.coursier_test_util import TestCoursierWrapper from pants.jvm.target_types import JvmArtifactTarget from pants.source import source_root from pants.testutil.rule_runner import RuleRunner, logging from pants.testutil.skip_utils import requires_thrift LIBTHRIFT_RESOLVE = TestCoursierWrapper.new( entries=( CoursierLockfileEntry( coord=Coordinate( group="org.apache.thrift", artifact="libthrift", version="0.15.0", ), file_name="libthrift-0.15.0.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "e9c47420147cbb87a6df08bc36da04e2be1561967b5ef82d2f3ef9ec090d85d0", 305670, ), ), # Note: The transitive dependencies of libthrift have been intentionally omitted from this resolve. ), ).serialize([ ArtifactRequirement( Coordinate( group="org.apache.thrift", artifact="libthrift", version="0.15.0", )) ])
string name = 1; } // The response message containing the greetings message HelloReply { string message = 1; } """ SCALAPB_RESOLVE = TestCoursierWrapper.new(entries=(CoursierLockfileEntry( coord=Coordinate( group="com.thesamet.scalapb", artifact="scalapb-runtime_2.13", version="0.11.6", ), file_name="scalapb-runtime_2.13-0.11.6.jar", direct_dependencies=Coordinates([]), dependencies=Coordinates([]), file_digest=FileDigest( "439b613f40b9ac43db4d68de5bef36befc56393d9c9cd002e2b965ce94f6f793", 2426575, ), ), ), ).serialize([ ArtifactRequirement( Coordinate( group="com.thesamet.scalapb", artifact="scalapb-runtime_2.13", version="0.11.6", )) ])