Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions src/python/pants/backend/codegen/protobuf/java/dependency_inference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Copyright 2022 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).
from dataclasses import dataclass

from pants.backend.codegen.protobuf.target_types import ProtobufDependenciesField
from pants.build_graph.address import Address
from pants.engine.internals.selectors import Get
from pants.engine.rules import collect_rules, rule
from pants.engine.target import InjectDependenciesRequest, InjectedDependencies, WrappedTarget
from pants.engine.unions import UnionRule
from pants.jvm.dependency_inference.artifact_mapper import (
AllJvmArtifactTargets,
ConflictingJvmArtifactVersion,
MissingJvmArtifacts,
UnversionedCoordinate,
find_jvm_artifacts_or_raise,
)
from pants.jvm.subsystems import JvmSubsystem
from pants.jvm.target_types import JvmResolveField
from pants.util.docutil import bin_name

_PROTOBUF_JAVA_RUNTIME_GROUP = "com.google.protobuf"
_PROTOBUF_JAVA_RUNTIME_ARTIFACT = "protobuf-java"


class InjectProtobufJavaRuntimeDependencyRequest(InjectDependenciesRequest):
inject_for = ProtobufDependenciesField


@dataclass(frozen=True)
class ProtobufJavaRuntimeForResolveRequest:
resolve_name: str


@dataclass(frozen=True)
class ProtobufJavaRuntimeForResolve:
addresses: frozenset[Address]


@rule
async def resolve_protobuf_java_runtime_for_resolve(
jvm_artifact_targets: AllJvmArtifactTargets,
jvm: JvmSubsystem,
request: ProtobufJavaRuntimeForResolveRequest,
) -> ProtobufJavaRuntimeForResolve:

try:
addresses = find_jvm_artifacts_or_raise(
required_coordinates=[
UnversionedCoordinate(
group=_PROTOBUF_JAVA_RUNTIME_GROUP,
artifact=_PROTOBUF_JAVA_RUNTIME_ARTIFACT,
)
],
resolve=request.resolve_name,
jvm_artifact_targets=jvm_artifact_targets,
jvm=jvm,
)
return ProtobufJavaRuntimeForResolve(addresses)
except (MissingJvmArtifacts, ConflictingJvmArtifactVersion):
raise MissingProtobufJavaRuntimeInResolveError(request.resolve_name)


@rule
async def inject_protobuf_java_runtime_dependency(
request: InjectProtobufJavaRuntimeDependencyRequest,
jvm: JvmSubsystem,
) -> InjectedDependencies:
wrapped_target = await Get(WrappedTarget, Address, request.dependencies_field.address)
target = wrapped_target.target

if not target.has_field(JvmResolveField):
return InjectedDependencies()
resolve = target[JvmResolveField].normalized_value(jvm)

protobuf_java_runtime_target_info = await Get(
ProtobufJavaRuntimeForResolve, ProtobufJavaRuntimeForResolveRequest(resolve)
)

return InjectedDependencies(protobuf_java_runtime_target_info.addresses)


class MissingProtobufJavaRuntimeInResolveError(ValueError):
def __init__(self, resolve_name: str) -> None:
super().__init__(
f"The JVM resolve `{resolve_name}` does not contain a requirement for the protobuf-java "
"runtime. Since at least one JVM target type in this repository consumes a "
"`protobuf_sources` target in this resolve, the resolve must contain a `jvm_artifact` "
"target for the `protobuf-java` runtime.\n\n Please add the following `jvm_artifact` "
f"target somewhere in the repository and re-run `{bin_name()} generate-lockfiles "
f"--resolve={resolve_name}`:\n"
"jvm_artifact(\n"
f' name="{_PROTOBUF_JAVA_RUNTIME_GROUP}_{_PROTOBUF_JAVA_RUNTIME_ARTIFACT}",\n'
f' group="{_PROTOBUF_JAVA_RUNTIME_GROUP}",\n',
f' artifact="{_PROTOBUF_JAVA_RUNTIME_ARTIFACT}",\n',
' version="<your preferred runtime version>",\n',
f' resolve="{resolve_name}",\n',
")",
)


def rules():
return (
*collect_rules(),
UnionRule(InjectDependenciesRequest, InjectProtobufJavaRuntimeDependencyRequest),
)
10 changes: 5 additions & 5 deletions src/python/pants/backend/codegen/protobuf/java/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Licensed under the Apache License, Version 2.0 (see LICENSE).


from pants.backend.codegen.protobuf.java import dependency_inference
from pants.backend.codegen.protobuf.protoc import Protoc
from pants.backend.codegen.protobuf.target_types import (
ProtobufSourceField,
Expand Down Expand Up @@ -32,7 +33,7 @@
TransitiveTargetsRequest,
)
from pants.engine.unions import UnionRule
from pants.jvm.target_types import JvmJdkField
from pants.jvm.target_types import PrefixedJvmJdkField, PrefixedJvmResolveField
from pants.source.source_root import SourceRoot, SourceRootRequest
from pants.util.logging import LogLevel

Expand Down Expand Up @@ -121,15 +122,14 @@ async def generate_java_from_protobuf(
return GeneratedSources(source_root_restored)


class PrefixedJvmJdkField(JvmJdkField):
alias = "jvm_jdk"


def rules():
return [
*collect_rules(),
*pex.rules(),
*dependency_inference.rules(),
UnionRule(GenerateSourcesRequest, GenerateJavaFromProtobufRequest),
ProtobufSourceTarget.register_plugin_field(PrefixedJvmJdkField),
ProtobufSourcesGeneratorTarget.register_plugin_field(PrefixedJvmJdkField),
ProtobufSourceTarget.register_plugin_field(PrefixedJvmResolveField),
ProtobufSourcesGeneratorTarget.register_plugin_field(PrefixedJvmResolveField),
]
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class MissingScalaPBRuntimeInResolveError(ValueError):
def __init__(self, resolve_name: str, version: str, scala_binary_version: str) -> None:
super().__init__(
f"The JVM resolve `{resolve_name}` does not contain a requirement for the ScalaPB runtime. "
"Since at least one Scala target type in this repository consumes a `protobuf_sources` target "
"Since at least one JVM target type in this repository consumes a `protobuf_sources` target "
"in this resolve, the resolve must contain a `jvm_artifact` target for the ScalaPB runtime.\n\n"
"Please add the following `jvm_artifact` target somewhere in the repository and re-run "
f"`{bin_name()} generate-lockfiles --resolve={resolve_name}`:\n"
Expand Down
10 changes: 1 addition & 9 deletions src/python/pants/backend/codegen/protobuf/scala/rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
from pants.jvm.resolve.common import ArtifactRequirements, Coordinate, GatherJvmCoordinatesRequest
from pants.jvm.resolve.coursier_fetch import ToolClasspath, ToolClasspathRequest
from pants.jvm.resolve.jvm_tool import GenerateJvmLockfileFromTool
from pants.jvm.target_types import JvmJdkField, JvmResolveField
from pants.jvm.target_types import PrefixedJvmJdkField, PrefixedJvmResolveField
from pants.source.source_root import SourceRoot, SourceRootRequest
from pants.util.logging import LogLevel
from pants.util.ordered_set import FrozenOrderedSet
Expand Down Expand Up @@ -324,14 +324,6 @@ def generate_scalapbc_lockfile_request(
return GenerateJvmLockfileFromTool.create(tool)


class PrefixedJvmJdkField(JvmJdkField):
alias = "jvm_jdk"


class PrefixedJvmResolveField(JvmResolveField):
alias = "jvm_resolve"


def rules():
return [
*collect_rules(),
Expand Down
8 changes: 8 additions & 0 deletions src/python/pants/jvm/target_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ def normalized_value(self, jvm_subsystem: JvmSubsystem) -> str:
return resolve


class PrefixedJvmResolveField(JvmResolveField):
alias = "jvm_resolve"


class JvmJdkField(StringField):
alias = "jdk"
required = False
Expand All @@ -66,6 +70,10 @@ class JvmJdkField(StringField):
)


class PrefixedJvmJdkField(JvmJdkField):
alias = "jvm_jdk"


# -----------------------------------------------------------------------------------------------
# `jvm_artifact` targets
# -----------------------------------------------------------------------------------------------
Expand Down