Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[internal] Infer main field for go_binary #13117

Merged
merged 3 commits into from
Oct 5, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
11 changes: 7 additions & 4 deletions src/python/pants/backend/experimental/go/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from pants.backend.go import target_type_rules
from pants.backend.go import target_types as go_target_types
from pants.backend.go.goals import custom_goals, package_binary, tailor
from pants.backend.go.lint import fmt
from pants.backend.go.lint.gofmt import skip_field as gofmt_skip_field
from pants.backend.go.lint.gofmt.rules import rules as gofmt_rules
from pants.backend.go.subsystems import golang
from pants.backend.go.target_types import GoBinary, GoExternalPackageTarget, GoModTarget, GoPackage
from pants.backend.go.target_types import (
GoBinaryTarget,
GoExternalPackageTarget,
GoModTarget,
GoPackage,
)
from pants.backend.go.util_rules import (
assembly,
build_go_pkg,
Expand All @@ -24,7 +28,7 @@


def target_types():
return [GoBinary, GoPackage, GoModTarget, GoExternalPackageTarget]
return [GoModTarget, GoPackage, GoExternalPackageTarget, GoBinaryTarget]


def rules():
Expand All @@ -34,7 +38,6 @@ def rules():
*compile.rules(),
*external_module.rules(),
*golang.rules(),
*go_target_types.rules(),
*import_analysis.rules(),
*go_mod.rules(),
*go_pkg.rules(),
Expand Down
22 changes: 9 additions & 13 deletions src/python/pants/backend/go/goals/package_binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@
from dataclasses import dataclass
from pathlib import PurePath

from pants.backend.go.target_types import GoBinaryMainAddress
from pants.backend.go.target_types import (
GoBinaryMainPackage,
GoBinaryMainPackageField,
GoBinaryMainPackageRequest,
)
from pants.backend.go.util_rules.build_go_pkg import BuildGoPackageRequest, BuiltGoPackage
from pants.backend.go.util_rules.import_analysis import ImportConfig, ImportConfigRequest
from pants.backend.go.util_rules.link import LinkedGoBinary, LinkGoBinaryRequest
from pants.build_graph.address import Address, AddressInput
from pants.core.goals.package import (
BuiltPackage,
BuiltPackageArtifact,
Expand All @@ -23,23 +26,16 @@

@dataclass(frozen=True)
class GoBinaryFieldSet(PackageFieldSet):
required_fields = (GoBinaryMainAddress,)
required_fields = (GoBinaryMainPackageField,)

main_address: GoBinaryMainAddress
main: GoBinaryMainPackageField
output_path: OutputPathField


@rule
async def package_go_binary(field_set: GoBinaryFieldSet) -> BuiltPackage:
main_go_package_address = await Get(
Address,
AddressInput,
AddressInput.parse(field_set.main_address.value, relative_to=field_set.address.spec_path),
)

built_package = await Get(
BuiltGoPackage, BuildGoPackageRequest(main_go_package_address, is_main=True)
)
main_pkg = await Get(GoBinaryMainPackage, GoBinaryMainPackageRequest(field_set.main))
built_package = await Get(BuiltGoPackage, BuildGoPackageRequest(main_pkg.address, is_main=True))
main_pkg_path = built_package.import_paths_to_pkg_a_files["main"]
import_config = await Get(
ImportConfig, ImportConfigRequest(built_package.import_paths_to_pkg_a_files)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from pants.backend.go import target_type_rules
from pants.backend.go.goals import package_binary
from pants.backend.go.goals.package_binary import GoBinaryFieldSet
from pants.backend.go.target_types import GoBinary, GoModTarget, GoPackage
from pants.backend.go.target_types import GoBinaryTarget, GoModTarget, GoPackage
from pants.backend.go.util_rules import (
assembly,
build_go_pkg,
Expand Down Expand Up @@ -50,7 +50,7 @@ def rule_runner() -> RuleRunner:
*sdk.rules(),
QueryRule(BuiltPackage, (GoBinaryFieldSet,)),
],
target_types=[GoBinary, GoPackage, GoModTarget],
target_types=[GoBinaryTarget, GoPackage, GoModTarget],
)
rule_runner.set_options([], env_inherit={"PATH"})
return rule_runner
Expand Down Expand Up @@ -88,8 +88,8 @@ def test_package_simple(rule_runner: RuleRunner) -> None:
"BUILD": dedent(
"""\
go_mod(name='mod')
go_package(name='main')
go_binary(name='bin', main=':main')
go_package(name='pkg')
go_binary(name='bin')
"""
),
}
Expand Down Expand Up @@ -165,8 +165,8 @@ def test_package_with_dependencies(rule_runner: RuleRunner) -> None:
"BUILD": dedent(
"""\
go_mod(name='mod')
go_package(name='main')
go_binary(name='bin', main=':main')
go_package(name='pkg')
go_binary(name='bin')
"""
),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from pants.backend.go.lint import fmt
from pants.backend.go.lint.gofmt.rules import GofmtFieldSet, GofmtRequest
from pants.backend.go.lint.gofmt.rules import rules as gofmt_rules
from pants.backend.go.target_types import GoBinary, GoPackage
from pants.backend.go.target_types import GoBinaryTarget, GoPackage
from pants.core.goals.fmt import FmtResult
from pants.core.goals.lint import LintResult, LintResults
from pants.core.util_rules import source_files
Expand All @@ -24,7 +24,7 @@
@pytest.fixture()
def rule_runner() -> RuleRunner:
return RuleRunner(
target_types=[GoBinary, GoPackage],
target_types=[GoBinaryTarget, GoPackage],
rules=[
*fmt.rules(),
*gofmt_rules(),
Expand Down
76 changes: 73 additions & 3 deletions src/python/pants/backend/go/target_type_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
from dataclasses import dataclass

from pants.backend.go.target_types import (
GoBinaryDependenciesField,
GoBinaryMainPackage,
GoBinaryMainPackageField,
GoBinaryMainPackageRequest,
GoExternalModulePathField,
GoExternalModuleVersionField,
GoExternalPackageDependencies,
Expand All @@ -33,22 +37,24 @@
)
from pants.backend.go.util_rules.go_pkg import ResolvedGoPackage, ResolveGoPackageRequest
from pants.backend.go.util_rules.import_analysis import GoStdLibImports
from pants.base.exceptions import ResolveError
from pants.base.specs import (
AddressSpecs,
DescendantAddresses,
MaybeEmptyDescendantAddresses,
MaybeEmptySiblingAddresses,
SiblingAddresses,
)
from pants.build_graph.address import Address
from pants.engine.internals.selectors import Get, MultiGet
from pants.engine.rules import collect_rules, rule
from pants.engine.addresses import Address, AddressInput
from pants.engine.rules import Get, MultiGet, collect_rules, rule
from pants.engine.target import (
GeneratedTargets,
GenerateTargetsRequest,
InferDependenciesRequest,
InferredDependencies,
InjectDependenciesRequest,
InjectedDependencies,
InvalidFieldException,
Targets,
WrappedTarget,
)
Expand Down Expand Up @@ -285,6 +291,69 @@ def create_tgt(
)


# -----------------------------------------------------------------------------------------------
# The `main` field for `go_binary`
# -----------------------------------------------------------------------------------------------


@rule
async def determine_main_pkg_for_go_binary(
request: GoBinaryMainPackageRequest,
) -> GoBinaryMainPackage:
addr = request.field.address
if request.field.value:
wrapped_specified_tgt = await Get(
WrappedTarget,
AddressInput,
AddressInput.parse(request.field.value, relative_to=addr.spec_path),
)
if not wrapped_specified_tgt.target.has_field(GoPackageSources):
raise InvalidFieldException(
f"The {repr(GoBinaryMainPackageField.alias)} field in target {addr} must point to "
"a `go_package` target, but was the address for a "
f"`{wrapped_specified_tgt.target.alias}` target.\n\n"
"Hint: consider leaving off this field so that Pants will find the `go_package` "
"target for you."
)
return GoBinaryMainPackage(wrapped_specified_tgt.target.address)

build_dir_targets = await Get(Targets, AddressSpecs([SiblingAddresses(addr.spec_path)]))
internal_pkg_targets = [tgt for tgt in build_dir_targets if tgt.has_field(GoPackageSources)]
if len(internal_pkg_targets) == 1:
return GoBinaryMainPackage(internal_pkg_targets[0].address)

wrapped_tgt = await Get(WrappedTarget, Address, addr)
alias = wrapped_tgt.target.alias
if not internal_pkg_targets:
raise ResolveError(
f"The `{alias}` target {addr} requires that there is a `go_package` "
"target in the same directory, but none were found."
)
raise ResolveError(
f"There are multiple `go_package` targets in the same directory of the `{alias}` "
f"target {addr}, so it is ambiguous what to use as the `main` package.\n\n"
f"To fix, please either set the `main` field for `{addr} or remove these "
"`go_package` targets so that only one remains: "
f"{sorted(tgt.address.spec for tgt in internal_pkg_targets)}"
)


class InjectGoBinaryMainDependencyRequest(InjectDependenciesRequest):
inject_for = GoBinaryDependenciesField


@rule
async def inject_go_binary_main_dependency(
request: InjectGoBinaryMainDependencyRequest,
) -> InjectedDependencies:
wrapped_tgt = await Get(WrappedTarget, Address, request.dependencies_field.address)
main_pkg = await Get(
GoBinaryMainPackage,
GoBinaryMainPackageRequest(wrapped_tgt.target[GoBinaryMainPackageField]),
)
return InjectedDependencies([main_pkg.address])


def rules():
return (
*collect_rules(),
Expand All @@ -293,5 +362,6 @@ def rules():
UnionRule(InjectDependenciesRequest, InjectGoPackageDependenciesRequest),
UnionRule(InferDependenciesRequest, InferGoPackageDependenciesRequest),
UnionRule(InjectDependenciesRequest, InjectGoExternalPackageDependenciesRequest),
UnionRule(InjectDependenciesRequest, InjectGoBinaryMainDependencyRequest),
UnionRule(GenerateTargetsRequest, GenerateGoExternalPackageTargetsRequest),
)
Loading