diff --git a/src/python/pants/backend/codegen/avro/java/rules.py b/src/python/pants/backend/codegen/avro/java/rules.py index 59cfc7ea306..b25a29da6f5 100644 --- a/src/python/pants/backend/codegen/avro/java/rules.py +++ b/src/python/pants/backend/codegen/avro/java/rules.py @@ -38,8 +38,8 @@ from pants.jvm.resolve import jvm_tool from pants.jvm.resolve.coursier_fetch import ( CoursierResolvedLockfile, - MaterializedClasspath, - MaterializedClasspathRequest, + ToolClasspath, + ToolClasspathRequest, ) from pants.jvm.resolve.jvm_tool import GenerateJvmLockfileFromTool, ValidatedJvmToolLockfileRequest from pants.source.source_root import SourceRoot, SourceRootRequest @@ -105,12 +105,7 @@ async def compile_avro_source( lockfile = await Get(CoursierResolvedLockfile, ValidatedJvmToolLockfileRequest(avro_tools)) tool_classpath, subsetted_input_digest, empty_output_dir = await MultiGet( - Get( - MaterializedClasspath, - MaterializedClasspathRequest( - lockfiles=(lockfile,), - ), - ), + Get(ToolClasspath, ToolClasspathRequest(lockfile=lockfile)), Get( Digest, DigestSubset( diff --git a/src/python/pants/backend/codegen/protobuf/scala/rules.py b/src/python/pants/backend/codegen/protobuf/scala/rules.py index d7229a8a215..16ec12e5a96 100644 --- a/src/python/pants/backend/codegen/protobuf/scala/rules.py +++ b/src/python/pants/backend/codegen/protobuf/scala/rules.py @@ -49,8 +49,8 @@ from pants.jvm.resolve.common import ArtifactRequirements, Coordinate from pants.jvm.resolve.coursier_fetch import ( CoursierResolvedLockfile, - MaterializedClasspath, - MaterializedClasspathRequest, + ToolClasspath, + ToolClasspathRequest, ) from pants.jvm.resolve.jvm_tool import ( GatherJvmCoordinatesRequest, @@ -83,7 +83,7 @@ class MaterializeJvmPluginRequest: @dataclass(frozen=True) class MaterializedJvmPlugin: name: str - classpath: MaterializedClasspath + classpath: ToolClasspath def setup_arg(self, plugin_relpath: str) -> str: classpath_arg = ":".join(self.classpath.classpath_entries(plugin_relpath)) @@ -129,12 +129,7 @@ async def generate_scala_from_protobuf( inherit_env, ) = await MultiGet( Get(DownloadedExternalTool, ExternalToolRequest, protoc.get_request(Platform.current)), - Get( - MaterializedClasspath, - MaterializedClasspathRequest( - lockfiles=(lockfile,), - ), - ), + Get(ToolClasspath, ToolClasspathRequest(lockfile=lockfile)), Get(Digest, CreateDigest([Directory(output_dir)])), Get(TransitiveTargets, TransitiveTargetsRequest([request.protocol_target.address])), # Need PATH so that ScalaPB can invoke `mkfifo`. @@ -180,13 +175,7 @@ async def generate_scala_from_protobuf( } input_digest = await Get( - Digest, - MergeDigests( - [ - all_sources_stripped.snapshot.digest, - empty_output_dir, - ] - ), + Digest, MergeDigests([all_sources_stripped.snapshot.digest, empty_output_dir]) ) result = await Get( @@ -248,13 +237,8 @@ async def materialize_jvm_plugin(request: MaterializeJvmPluginRequest) -> Materi option_name="[scalapb].jvm_plugins", ), ) - classpath = await Get( - MaterializedClasspath, MaterializedClasspathRequest(artifact_requirements=(requirements,)) - ) - return MaterializedJvmPlugin( - name=request.plugin.name, - classpath=classpath, - ) + classpath = await Get(ToolClasspath, ToolClasspathRequest(artifact_requirements=requirements)) + return MaterializedJvmPlugin(name=request.plugin.name, classpath=classpath) @rule @@ -292,59 +276,36 @@ async def setup_scalapb_shim_classfiles( tool_classpath, shim_classpath, source_digest = await MultiGet( Get( - MaterializedClasspath, - MaterializedClasspathRequest( + ToolClasspath, + ToolClasspathRequest( prefix="__toolcp", - artifact_requirements=( - ArtifactRequirements.from_coordinates( - [ - Coordinate( - group="org.scala-lang", - artifact="scala-compiler", - version=SHIM_SCALA_VERSION, - ), - Coordinate( - group="org.scala-lang", - artifact="scala-library", - version=SHIM_SCALA_VERSION, - ), - Coordinate( - group="org.scala-lang", - artifact="scala-reflect", - version=SHIM_SCALA_VERSION, - ), - ] - ), + artifact_requirements=ArtifactRequirements.from_coordinates( + [ + Coordinate( + group="org.scala-lang", + artifact="scala-compiler", + version=SHIM_SCALA_VERSION, + ), + Coordinate( + group="org.scala-lang", + artifact="scala-library", + version=SHIM_SCALA_VERSION, + ), + Coordinate( + group="org.scala-lang", + artifact="scala-reflect", + version=SHIM_SCALA_VERSION, + ), + ] ), ), ), - Get( - MaterializedClasspath, - MaterializedClasspathRequest( - prefix="__shimcp", - lockfiles=(lockfile,), - ), - ), - Get( - Digest, - CreateDigest( - [ - scalapb_shim_source, - Directory(dest_dir), - ] - ), - ), + Get(ToolClasspath, ToolClasspathRequest(prefix="__shimcp", lockfile=lockfile)), + Get(Digest, CreateDigest([scalapb_shim_source, Directory(dest_dir)])), ) merged_digest = await Get( - Digest, - MergeDigests( - ( - tool_classpath.digest, - shim_classpath.digest, - source_digest, - ) - ), + Digest, MergeDigests((tool_classpath.digest, shim_classpath.digest, source_digest)) ) # NB: We do not use nailgun for this process, since it is launched exactly once. diff --git a/src/python/pants/backend/codegen/thrift/scrooge/rules.py b/src/python/pants/backend/codegen/thrift/scrooge/rules.py index 99534013b73..ff29921604f 100644 --- a/src/python/pants/backend/codegen/thrift/scrooge/rules.py +++ b/src/python/pants/backend/codegen/thrift/scrooge/rules.py @@ -19,8 +19,8 @@ from pants.jvm.jdk_rules import JdkSetup from pants.jvm.resolve.coursier_fetch import ( CoursierResolvedLockfile, - MaterializedClasspath, - MaterializedClasspathRequest, + ToolClasspath, + ToolClasspathRequest, ) from pants.jvm.resolve.jvm_tool import GenerateJvmLockfileFromTool, ValidatedJvmToolLockfileRequest from pants.source.source_root import SourceRootsRequest, SourceRootsResult @@ -56,12 +56,7 @@ async def generate_scrooge_thrift_sources( lockfile = await Get(CoursierResolvedLockfile, ValidatedJvmToolLockfileRequest(scrooge)) tool_classpath, transitive_targets, empty_output_dir_digest, wrapped_target = await MultiGet( - Get( - MaterializedClasspath, - MaterializedClasspathRequest( - lockfiles=(lockfile,), - ), - ), + Get(ToolClasspath, ToolClasspathRequest(lockfile=lockfile)), Get(TransitiveTargets, TransitiveTargetsRequest([request.thrift_source_field.address])), Get(Digest, CreateDigest([Directory(output_dir)])), Get(WrappedTarget, Address, request.thrift_source_field.address), diff --git a/src/python/pants/backend/java/dependency_inference/java_parser.py b/src/python/pants/backend/java/dependency_inference/java_parser.py index 5a57b442deb..35ee39d5175 100644 --- a/src/python/pants/backend/java/dependency_inference/java_parser.py +++ b/src/python/pants/backend/java/dependency_inference/java_parser.py @@ -19,7 +19,7 @@ from pants.engine.process import BashBinary, FallibleProcessResult, Process, ProcessExecutionFailure from pants.engine.rules import Get, MultiGet, collect_rules, rule from pants.jvm.jdk_rules import JdkSetup -from pants.jvm.resolve.coursier_fetch import MaterializedClasspath, MaterializedClasspathRequest +from pants.jvm.resolve.coursier_fetch import ToolClasspath, ToolClasspathRequest from pants.option.global_options import ProcessCleanupOption from pants.util.logging import LogLevel @@ -88,10 +88,8 @@ async def analyze_java_source_dependencies( (tool_classpath, prefixed_source_files_digest,) = await MultiGet( Get( - MaterializedClasspath, - MaterializedClasspathRequest( - artifact_requirements=(java_parser_artifact_requirements(),), - ), + ToolClasspath, + ToolClasspathRequest(artifact_requirements=java_parser_artifact_requirements()), ), Get(Digest, AddPrefix(source_files.snapshot.digest, source_prefix)), ) diff --git a/src/python/pants/backend/java/dependency_inference/java_parser_launcher.py b/src/python/pants/backend/java/dependency_inference/java_parser_launcher.py index b771f402864..53d4edd46b4 100644 --- a/src/python/pants/backend/java/dependency_inference/java_parser_launcher.py +++ b/src/python/pants/backend/java/dependency_inference/java_parser_launcher.py @@ -13,7 +13,7 @@ from pants.engine.rules import Get, MultiGet, collect_rules, rule from pants.jvm.jdk_rules import JdkSetup from pants.jvm.resolve.common import ArtifactRequirements, Coordinate -from pants.jvm.resolve.coursier_fetch import MaterializedClasspath, MaterializedClasspathRequest +from pants.jvm.resolve.coursier_fetch import ToolClasspath, ToolClasspathRequest from pants.util.logging import LogLevel logger = logging.getLogger(__name__) @@ -59,10 +59,9 @@ async def build_processors(bash: BashBinary, jdk_setup: JdkSetup) -> JavaParserC materialized_classpath, source_digest = await MultiGet( Get( - MaterializedClasspath, - MaterializedClasspathRequest( - prefix="__toolcp", - artifact_requirements=(java_parser_artifact_requirements(),), + ToolClasspath, + ToolClasspathRequest( + prefix="__toolcp", artifact_requirements=java_parser_artifact_requirements() ), ), Get( diff --git a/src/python/pants/backend/java/lint/google_java_format/rules.py b/src/python/pants/backend/java/lint/google_java_format/rules.py index fdff895fef3..24b21476f5f 100644 --- a/src/python/pants/backend/java/lint/google_java_format/rules.py +++ b/src/python/pants/backend/java/lint/google_java_format/rules.py @@ -21,8 +21,8 @@ from pants.jvm.resolve import jvm_tool from pants.jvm.resolve.coursier_fetch import ( CoursierResolvedLockfile, - MaterializedClasspath, - MaterializedClasspathRequest, + ToolClasspath, + ToolClasspathRequest, ) from pants.jvm.resolve.jvm_tool import GenerateJvmLockfileFromTool, ValidatedJvmToolLockfileRequest from pants.util.logging import LogLevel @@ -77,12 +77,7 @@ async def setup_google_java_format( SourceFiles, SourceFilesRequest(field_set.source for field_set in setup_request.request.field_sets), ), - Get( - MaterializedClasspath, - MaterializedClasspathRequest( - lockfiles=(lockfile,), - ), - ), + Get(ToolClasspath, ToolClasspathRequest(lockfile=lockfile)), ) source_files_snapshot = ( diff --git a/src/python/pants/backend/scala/compile/scalac.py b/src/python/pants/backend/scala/compile/scalac.py index 3f581eea0a3..3ba497a1a83 100644 --- a/src/python/pants/backend/scala/compile/scalac.py +++ b/src/python/pants/backend/scala/compile/scalac.py @@ -28,7 +28,7 @@ from pants.jvm.compile import rules as jvm_compile_rules from pants.jvm.jdk_rules import JdkSetup from pants.jvm.resolve.common import ArtifactRequirements, Coordinate -from pants.jvm.resolve.coursier_fetch import MaterializedClasspath, MaterializedClasspathRequest +from pants.jvm.resolve.coursier_fetch import ToolClasspath, ToolClasspathRequest from pants.jvm.resolve.coursier_setup import Coursier from pants.util.logging import LogLevel @@ -116,23 +116,21 @@ async def compile_scala_source( user_classpath = Classpath(direct_dependency_classpath_entries) tool_classpath, sources_digest = await MultiGet( Get( - MaterializedClasspath, - MaterializedClasspathRequest( - artifact_requirements=( - ArtifactRequirements.from_coordinates( - [ - Coordinate( - group="org.scala-lang", - artifact="scala-compiler", - version=scala.version, - ), - Coordinate( - group="org.scala-lang", - artifact="scala-library", - version=scala.version, - ), - ] - ), + ToolClasspath, + ToolClasspathRequest( + artifact_requirements=ArtifactRequirements.from_coordinates( + [ + Coordinate( + group="org.scala-lang", + artifact="scala-compiler", + version=scala.version, + ), + Coordinate( + group="org.scala-lang", + artifact="scala-library", + version=scala.version, + ), + ] ), ), ), diff --git a/src/python/pants/backend/scala/compile/scalac_plugins.py b/src/python/pants/backend/scala/compile/scalac_plugins.py index 9add65c60ec..d49a3e2b168 100644 --- a/src/python/pants/backend/scala/compile/scalac_plugins.py +++ b/src/python/pants/backend/scala/compile/scalac_plugins.py @@ -20,8 +20,8 @@ from pants.jvm.goals import lockfile from pants.jvm.resolve.coursier_fetch import ( CoursierResolvedLockfile, - MaterializedClasspath, - MaterializedClasspathRequest, + ToolClasspath, + ToolClasspathRequest, ) from pants.jvm.resolve.jvm_tool import GenerateJvmLockfileFromTool from pants.jvm.resolve.jvm_tool import rules as jvm_tool_rules @@ -86,7 +86,7 @@ def generate_global_scalac_plugins_lockfile_request( @dataclass(frozen=True) class GlobalScalacPlugins: names: tuple[str, ...] - classpath: MaterializedClasspath + classpath: ToolClasspath def args(self, prefix: str | None = None) -> Iterator[str]: for scalac_plugin_path in self.classpath.classpath_entries(prefix): @@ -101,11 +101,8 @@ async def global_scalac_plugins( ) -> GlobalScalacPlugins: lockfile = await Get(CoursierResolvedLockfile, GlobalScalacPluginsToolLockfileSentinel()) classpath = await Get( - MaterializedClasspath, - MaterializedClasspathRequest( - prefix="__scalac_plugin_cp", - lockfiles=(lockfile,), - ), + ToolClasspath, + ToolClasspathRequest(prefix="__scalac_plugin_cp", lockfile=lockfile), ) return GlobalScalacPlugins(loaded_global_plugins.names, classpath) diff --git a/src/python/pants/backend/scala/dependency_inference/scala_parser.py b/src/python/pants/backend/scala/dependency_inference/scala_parser.py index fef87f91bf1..7b5056261ed 100644 --- a/src/python/pants/backend/scala/dependency_inference/scala_parser.py +++ b/src/python/pants/backend/scala/dependency_inference/scala_parser.py @@ -32,7 +32,7 @@ from pants.jvm.compile import ClasspathEntry from pants.jvm.jdk_rules import JdkSetup from pants.jvm.resolve.common import ArtifactRequirements, Coordinate -from pants.jvm.resolve.coursier_fetch import MaterializedClasspath, MaterializedClasspathRequest +from pants.jvm.resolve.coursier_fetch import ToolClasspath, ToolClasspathRequest from pants.option.global_options import ProcessCleanupOption from pants.util.frozendict import FrozenDict from pants.util.logging import LogLevel @@ -229,10 +229,8 @@ async def analyze_scala_source_dependencies( (tool_classpath, prefixed_source_files_digest,) = await MultiGet( Get( - MaterializedClasspath, - MaterializedClasspathRequest( - artifact_requirements=(SCALA_PARSER_ARTIFACT_REQUIREMENTS,), - ), + ToolClasspath, + ToolClasspathRequest(artifact_requirements=SCALA_PARSER_ARTIFACT_REQUIREMENTS), ), Get(Digest, AddPrefix(source_files.snapshot.digest, source_prefix)), ) @@ -309,47 +307,37 @@ async def setup_scala_parser_classfiles( tool_classpath, parser_classpath, source_digest = await MultiGet( Get( - MaterializedClasspath, - MaterializedClasspathRequest( + ToolClasspath, + ToolClasspathRequest( prefix="__toolcp", - artifact_requirements=( - ArtifactRequirements.from_coordinates( - [ - Coordinate( - group="org.scala-lang", - artifact="scala-compiler", - version=PARSER_SCALA_VERSION, - ), - Coordinate( - group="org.scala-lang", - artifact="scala-library", - version=PARSER_SCALA_VERSION, - ), - Coordinate( - group="org.scala-lang", - artifact="scala-reflect", - version=PARSER_SCALA_VERSION, - ), - ] - ), + artifact_requirements=ArtifactRequirements.from_coordinates( + [ + Coordinate( + group="org.scala-lang", + artifact="scala-compiler", + version=PARSER_SCALA_VERSION, + ), + Coordinate( + group="org.scala-lang", + artifact="scala-library", + version=PARSER_SCALA_VERSION, + ), + Coordinate( + group="org.scala-lang", + artifact="scala-reflect", + version=PARSER_SCALA_VERSION, + ), + ] ), ), ), Get( - MaterializedClasspath, - MaterializedClasspathRequest( - prefix="__parsercp", artifact_requirements=(SCALA_PARSER_ARTIFACT_REQUIREMENTS,) - ), - ), - Get( - Digest, - CreateDigest( - [ - parser_source, - Directory(dest_dir), - ] + ToolClasspath, + ToolClasspathRequest( + prefix="__parsercp", artifact_requirements=SCALA_PARSER_ARTIFACT_REQUIREMENTS ), ), + Get(Digest, CreateDigest([parser_source, Directory(dest_dir)])), ) merged_digest = await Get( diff --git a/src/python/pants/backend/scala/goals/repl.py b/src/python/pants/backend/scala/goals/repl.py index 3227c52e92f..c0f59f4b719 100644 --- a/src/python/pants/backend/scala/goals/repl.py +++ b/src/python/pants/backend/scala/goals/repl.py @@ -13,7 +13,7 @@ from pants.jvm.classpath import Classpath from pants.jvm.jdk_rules import JdkSetup from pants.jvm.resolve.common import ArtifactRequirements, Coordinate -from pants.jvm.resolve.coursier_fetch import MaterializedClasspath, MaterializedClasspathRequest +from pants.jvm.resolve.coursier_fetch import ToolClasspath, ToolClasspathRequest from pants.util.logging import LogLevel @@ -28,29 +28,27 @@ async def create_scala_repl_request( user_classpath, tool_classpath = await MultiGet( Get(Classpath, Addresses(t.address for t in repl.targets)), Get( - MaterializedClasspath, - MaterializedClasspathRequest( + ToolClasspath, + ToolClasspathRequest( prefix="__toolcp", - artifact_requirements=( - ArtifactRequirements.from_coordinates( - [ - Coordinate( - group="org.scala-lang", - artifact="scala-compiler", - version=scala_subsystem.version, - ), - Coordinate( - group="org.scala-lang", - artifact="scala-library", - version=scala_subsystem.version, - ), - Coordinate( - group="org.scala-lang", - artifact="scala-reflect", - version=scala_subsystem.version, - ), - ] - ), + artifact_requirements=ArtifactRequirements.from_coordinates( + [ + Coordinate( + group="org.scala-lang", + artifact="scala-compiler", + version=scala_subsystem.version, + ), + Coordinate( + group="org.scala-lang", + artifact="scala-library", + version=scala_subsystem.version, + ), + Coordinate( + group="org.scala-lang", + artifact="scala-reflect", + version=scala_subsystem.version, + ), + ] ), ), ), diff --git a/src/python/pants/backend/scala/lint/scalafmt/rules.py b/src/python/pants/backend/scala/lint/scalafmt/rules.py index 47c04f08f71..32e5deec878 100644 --- a/src/python/pants/backend/scala/lint/scalafmt/rules.py +++ b/src/python/pants/backend/scala/lint/scalafmt/rules.py @@ -33,8 +33,8 @@ from pants.jvm.jdk_rules import JdkSetup from pants.jvm.resolve.coursier_fetch import ( CoursierResolvedLockfile, - MaterializedClasspath, - MaterializedClasspathRequest, + ToolClasspath, + ToolClasspathRequest, ) from pants.jvm.resolve.jvm_tool import GenerateJvmLockfileFromTool, ValidatedJvmToolLockfileRequest from pants.util.frozendict import FrozenDict @@ -209,12 +209,7 @@ async def setup_scalafmt( SourceFiles, SourceFilesRequest(field_set.source for field_set in setup_request.request.field_sets), ), - Get( - MaterializedClasspath, - MaterializedClasspathRequest( - lockfiles=(lockfile,), - ), - ), + Get(ToolClasspath, ToolClasspathRequest(lockfile=lockfile)), ) source_files_snapshot = ( @@ -228,13 +223,7 @@ async def setup_scalafmt( ) merged_sources_digest = await Get( - Digest, - MergeDigests( - [ - source_files_snapshot.digest, - config_files.snapshot.digest, - ] - ), + Digest, MergeDigests([source_files_snapshot.digest, config_files.snapshot.digest]) ) immutable_input_digests = { **jdk_setup.immutable_input_digests, diff --git a/src/python/pants/backend/scala/test/scalatest.py b/src/python/pants/backend/scala/test/scalatest.py index 0dd33c62ce5..e29aed1c4af 100644 --- a/src/python/pants/backend/scala/test/scalatest.py +++ b/src/python/pants/backend/scala/test/scalatest.py @@ -25,8 +25,8 @@ from pants.jvm.jdk_rules import JdkSetup from pants.jvm.resolve.coursier_fetch import ( CoursierResolvedLockfile, - MaterializedClasspath, - MaterializedClasspathRequest, + ToolClasspath, + ToolClasspathRequest, ) from pants.jvm.resolve.jvm_tool import GenerateJvmLockfileFromTool, ValidatedJvmToolLockfileRequest from pants.jvm.subsystems import JvmSubsystem @@ -72,10 +72,7 @@ async def setup_scalatest_for_target( classpath, scalatest_classpath = await MultiGet( Get(Classpath, Addresses([request.field_set.address])), - Get( - MaterializedClasspath, - MaterializedClasspathRequest(lockfiles=(lockfile,)), - ), + Get(ToolClasspath, ToolClasspathRequest(lockfile=lockfile)), ) merged_classpath_digest = await Get(Digest, MergeDigests(classpath.digests())) diff --git a/src/python/pants/backend/scala/test/scalatest_test.py b/src/python/pants/backend/scala/test/scalatest_test.py index 5a0db0f3f0a..1a8e57f742d 100644 --- a/src/python/pants/backend/scala/test/scalatest_test.py +++ b/src/python/pants/backend/scala/test/scalatest_test.py @@ -3,6 +3,7 @@ from __future__ import annotations +import importlib.resources from textwrap import dedent import pytest @@ -20,15 +21,13 @@ from pants.build_graph.address import Address from pants.core.goals.test import TestResult from pants.core.util_rules import config_files, source_files -from pants.core.util_rules.external_tool import rules as external_tool_rules from pants.engine.addresses import Addresses from pants.engine.target import CoarsenedTargets from pants.jvm import classpath from pants.jvm.jdk_rules import rules as jdk_util_rules -from pants.jvm.resolve.common import ArtifactRequirement, Coordinate +from pants.jvm.resolve.common import Coordinate from pants.jvm.resolve.coursier_fetch import rules as coursier_fetch_rules from pants.jvm.resolve.coursier_setup import rules as coursier_setup_rules -from pants.jvm.resolve.coursier_test_util import TestCoursierWrapper from pants.jvm.target_types import JvmArtifactTarget from pants.jvm.testutil import maybe_skip_jdk_test from pants.jvm.util_rules import rules as util_rules @@ -46,7 +45,6 @@ def rule_runner() -> RuleRunner: *config_files.rules(), *coursier_fetch_rules(), *coursier_setup_rules(), - *external_tool_rules(), *jdk_util_rules(), *scalac_rules(), *scalatest_rules(), @@ -71,13 +69,12 @@ def rule_runner() -> RuleRunner: @maybe_skip_jdk_test def test_simple_success(rule_runner: RuleRunner) -> None: - scalatest = rule_runner.request(Scalatest, []) scalatest_coord = Coordinate(group="org.scalatest", artifact="scalatest_2.13", version="3.2.10") rule_runner.write_files( { - "3rdparty/jvm/default.lock": TestCoursierWrapper( - scalatest.resolved_lockfile() - ).serialize([ArtifactRequirement(coordinate=scalatest_coord)]), + "3rdparty/jvm/default.lock": importlib.resources.read_text( + *Scalatest.default_lockfile_resource + ), "BUILD": dedent( f"""\ jvm_artifact( diff --git a/src/python/pants/jvm/resolve/coursier_fetch.py b/src/python/pants/jvm/resolve/coursier_fetch.py index ba53aa1c4f2..dde6436440e 100644 --- a/src/python/pants/jvm/resolve/coursier_fetch.py +++ b/src/python/pants/jvm/resolve/coursier_fetch.py @@ -668,8 +668,9 @@ async def get_coursier_lockfile_for_resolve( @dataclass(frozen=True) -class MaterializedClasspathRequest: - """A helper to merge various classpath elements. +class ToolClasspathRequest: + """A request to set up the classpath for a JVM tool by fetching artifacts and merging the + classpath. :param prefix: if set, should be a relative directory that will be prepended to every classpath element. This is useful for @@ -680,16 +681,13 @@ class MaterializedClasspathRequest: """ prefix: str | None = None - lockfiles: tuple[CoursierResolvedLockfile, ...] = () - artifact_requirements: tuple[ArtifactRequirements, ...] = () + lockfile: CoursierResolvedLockfile = CoursierResolvedLockfile(entries=()) + artifact_requirements: ArtifactRequirements = ArtifactRequirements() @dataclass(frozen=True) -class MaterializedClasspath: - """A fully fetched and merged classpath, ready to hand to a JVM process invocation. - - TODO: Consider renaming to reflect the fact that this is always a 3rdparty classpath. - """ +class ToolClasspath: + """A fully fetched and merged classpath for running a JVM tool.""" content: Snapshot @@ -713,33 +711,28 @@ def classpath_entries(self, root: str | None = None) -> Iterator[str]: @rule(level=LogLevel.DEBUG) -async def materialize_classpath(request: MaterializedClasspathRequest) -> MaterializedClasspath: +async def materialize_classpath_for_tool(request: ToolClasspathRequest) -> ToolClasspath: """Resolve, fetch, and merge various classpath types to a single `Digest` and metadata.""" - artifact_requirements_lockfiles = await MultiGet( - Get(CoursierResolvedLockfile, ArtifactRequirements, artifact_requirements) - for artifact_requirements in request.artifact_requirements + artifact_requirements_lockfile = await Get( + CoursierResolvedLockfile, ArtifactRequirements, request.artifact_requirements ) - - lockfile_and_requirements_classpath_entries = await MultiGet( - Get( - ResolvedClasspathEntries, - CoursierResolvedLockfile, - lockfile, - ) - for lockfile in (*request.lockfiles, *artifact_requirements_lockfiles) + all_classpath_entries = await MultiGet( + Get(ResolvedClasspathEntries, CoursierResolvedLockfile, lockfile) + for lockfile in (request.lockfile, artifact_requirements_lockfile) ) + merged_snapshot = await Get( Snapshot, MergeDigests( classpath_entry.digest - for classpath_entries in lockfile_and_requirements_classpath_entries + for classpath_entries in all_classpath_entries for classpath_entry in classpath_entries ), ) if request.prefix is not None: merged_snapshot = await Get(Snapshot, AddPrefix(merged_snapshot.digest, request.prefix)) - return MaterializedClasspath(content=merged_snapshot) + return ToolClasspath(content=merged_snapshot) def rules(): diff --git a/src/python/pants/jvm/resolve/jvm_tool.py b/src/python/pants/jvm/resolve/jvm_tool.py index 4f8c8441335..390fb2cc7a6 100644 --- a/src/python/pants/jvm/resolve/jvm_tool.py +++ b/src/python/pants/jvm/resolve/jvm_tool.py @@ -7,14 +7,16 @@ from typing import ClassVar, cast from pants.build_graph.address import Address, AddressInput -from pants.core.goals.generate_lockfiles import DEFAULT_TOOL_LOCKFILE +from pants.core.goals.generate_lockfiles import DEFAULT_TOOL_LOCKFILE, GenerateLockfilesSubsystem from pants.engine.addresses import Addresses +from pants.engine.fs import PathGlobs, Snapshot from pants.engine.internals.selectors import Get, MultiGet from pants.engine.rules import collect_rules, rule from pants.engine.target import Targets from pants.jvm.goals.lockfile import GenerateJvmLockfile from pants.jvm.resolve.common import ArtifactRequirement, ArtifactRequirements, Coordinate from pants.jvm.resolve.coursier_fetch import CoursierResolvedLockfile +from pants.jvm.resolve.key import CoursierResolveKey from pants.jvm.target_types import JvmArtifactFieldSet from pants.option.subsystem import Subsystem from pants.util.meta import frozen_after_init @@ -92,17 +94,6 @@ def lockfile(self) -> str: f"""The path to a lockfile or special string '{DEFAULT_TOOL_LOCKFILE}'.""" return cast(str, self.options.lockfile) - def lockfile_content(self) -> bytes: - lockfile_path = self.lockfile - if lockfile_path == DEFAULT_TOOL_LOCKFILE: - return importlib.resources.read_binary(*self.default_lockfile_resource) - with open(lockfile_path, "rb") as f: - return f.read() - - def resolved_lockfile(self) -> CoursierResolvedLockfile: - lockfile_content = self.lockfile_content() - return CoursierResolvedLockfile.from_serialized(lockfile_content) - @dataclass(frozen=True) class GatherJvmCoordinatesRequest: @@ -168,23 +159,43 @@ async def gather_coordinates_for_jvm_lockfile( @frozen_after_init @dataclass(unsafe_hash=True) class ValidatedJvmToolLockfileRequest: - options_scope: str artifact_inputs: FrozenOrderedSet[str] - lockfile: CoursierResolvedLockfile + lockfile_dest: str + default_lockfile_resource: tuple[str, str] - def __init__(self, tool: JvmToolBase): + def __init__(self, tool: JvmToolBase) -> None: self.options_scope = tool.options_scope self.artifact_inputs = FrozenOrderedSet(tool.artifact_inputs) - self.lockfile = tool.resolved_lockfile() + self.lockfile_dest = tool.lockfile + self.default_lockfile_resource = tool.default_lockfile_resource -@rule(desc="Validate JVM lockfile") +@rule(desc="Validate JVM tool lockfile") async def validate_jvm_lockfile( request: ValidatedJvmToolLockfileRequest, ) -> CoursierResolvedLockfile: + if request.lockfile_dest == DEFAULT_TOOL_LOCKFILE: + lockfile_bytes = importlib.resources.read_binary(*request.default_lockfile_resource) + lockfile = CoursierResolvedLockfile.from_serialized(lockfile_bytes) + else: + lockfile_snapshot = await Get(Snapshot, PathGlobs([request.lockfile_dest])) + if not lockfile_snapshot.files: + raise ValueError( + f"JVM tool `{request.options_scope}` does not have a lockfile generated. " + f"Run `{GenerateLockfilesSubsystem.name} --resolve={request.options_scope}` to " + "generate it." + ) + + lockfile = await Get( + CoursierResolvedLockfile, + CoursierResolveKey( + name=request.options_scope, + path=request.lockfile_dest, + digest=lockfile_snapshot.digest, + ), + ) - lockfile = request.lockfile requirements = await Get( ArtifactRequirements, GatherJvmCoordinatesRequest( @@ -197,7 +208,8 @@ async def validate_jvm_lockfile( f"The lockfile for {request.options_scope} was generated with different " "requirements than are currently set. Check whether any `JAVA` options " "(including environment variables) have changed your requirements " - "or run `./pants generate-lockfiles` to regenerate the lockfiles." + f"or run `{GenerateLockfilesSubsystem.name} --resolve={request.options_scope}` to " + f"regenerate the lockfile." ) return lockfile diff --git a/src/python/pants/jvm/test/junit.py b/src/python/pants/jvm/test/junit.py index 96461b50590..ac530542c96 100644 --- a/src/python/pants/jvm/test/junit.py +++ b/src/python/pants/jvm/test/junit.py @@ -24,8 +24,8 @@ from pants.jvm.jdk_rules import JdkSetup from pants.jvm.resolve.coursier_fetch import ( CoursierResolvedLockfile, - MaterializedClasspath, - MaterializedClasspathRequest, + ToolClasspath, + ToolClasspathRequest, ) from pants.jvm.resolve.jvm_tool import GenerateJvmLockfileFromTool, ValidatedJvmToolLockfileRequest from pants.jvm.subsystems import JvmSubsystem @@ -72,10 +72,7 @@ async def setup_junit_for_target( classpath, junit_classpath = await MultiGet( Get(Classpath, Addresses([request.field_set.address])), - Get( - MaterializedClasspath, - MaterializedClasspathRequest(lockfiles=(lockfile,)), - ), + Get(ToolClasspath, ToolClasspathRequest(lockfile=lockfile)), ) merged_classpath_digest = await Get(Digest, MergeDigests(classpath.digests()))