diff --git a/src/python/pants/backend/experimental/go/register.py b/src/python/pants/backend/experimental/go/register.py index 7163cdc2432..1801230362c 100644 --- a/src/python/pants/backend/experimental/go/register.py +++ b/src/python/pants/backend/experimental/go/register.py @@ -13,6 +13,7 @@ go_mod, go_pkg, import_analysis, + link, sdk, ) @@ -31,6 +32,7 @@ def rules(): *import_analysis.rules(), *go_mod.rules(), *go_pkg.rules(), + *link.rules(), *sdk.rules(), *tailor.rules(), *target_type_rules.rules(), diff --git a/src/python/pants/backend/go/goals/package_binary.py b/src/python/pants/backend/go/goals/package_binary.py index aa5e6a05d53..f4f674ff333 100644 --- a/src/python/pants/backend/go/goals/package_binary.py +++ b/src/python/pants/backend/go/goals/package_binary.py @@ -11,7 +11,7 @@ is_third_party_package_target, ) from pants.backend.go.util_rules.import_analysis import GatheredImports, GatherImportsRequest -from pants.backend.go.util_rules.sdk import GoSdkProcess +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, @@ -21,7 +21,6 @@ ) from pants.engine.fs import AddPrefix, Digest, MergeDigests from pants.engine.internals.selectors import Get, MultiGet -from pants.engine.process import ProcessResult from pants.engine.rules import collect_rules, rule from pants.engine.target import TransitiveTargets, TransitiveTargetsRequest, WrappedTarget from pants.engine.unions import UnionRule @@ -79,27 +78,20 @@ async def package_go_binary( ) output_filename = PurePath(field_set.output_path.value_or_default(file_ending=None)) - result = await Get( - ProcessResult, - GoSdkProcess( + + binary = await Get( + LinkedGoBinary, + LinkGoBinaryRequest( input_digest=input_digest, - command=( - "tool", - "link", - "-importcfg", - "./importcfg", - "-o", - f"./{output_filename.name}", - "-buildmode=exe", # seen in `go build -x` output - "./__pkg__.a", - ), + archives=("./__pkg__.a",), + import_config_path="./importcfg", + output_filename=f"./{output_filename.name}", description="Link Go binary.", - output_files=(f"./{output_filename.name}",), ), ) renamed_output_digest = await Get( - Digest, AddPrefix(result.output_digest, str(output_filename.parent)) + Digest, AddPrefix(binary.output_digest, str(output_filename.parent)) ) artifact = BuiltPackageArtifact(relpath=str(output_filename)) diff --git a/src/python/pants/backend/go/goals/package_binary_integration_test.py b/src/python/pants/backend/go/goals/package_binary_integration_test.py index 83409756141..f045d8d38b5 100644 --- a/src/python/pants/backend/go/goals/package_binary_integration_test.py +++ b/src/python/pants/backend/go/goals/package_binary_integration_test.py @@ -18,6 +18,7 @@ go_mod, go_pkg, import_analysis, + link, sdk, ) from pants.build_graph.address import Address @@ -40,6 +41,7 @@ def rule_runner() -> RuleRunner: *build_go_pkg.rules(), *go_pkg.rules(), *go_mod.rules(), + *link.rules(), *target_type_rules.rules(), *external_module.rules(), *sdk.rules(), diff --git a/src/python/pants/backend/go/util_rules/link.py b/src/python/pants/backend/go/util_rules/link.py new file mode 100644 index 00000000000..c8214b67dbe --- /dev/null +++ b/src/python/pants/backend/go/util_rules/link.py @@ -0,0 +1,59 @@ +# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md). +# Licensed under the Apache License, Version 2.0 (see LICENSE). +from __future__ import annotations + +from dataclasses import dataclass + +from pants.backend.go.util_rules.sdk import GoSdkProcess +from pants.engine.fs import Digest +from pants.engine.process import ProcessResult +from pants.engine.rules import Get, collect_rules, rule + + +@dataclass(frozen=True) +class LinkGoBinaryRequest: + """Link a Go binary from package archives and an import configuration.""" + + input_digest: Digest + archives: tuple[str, ...] + import_config_path: str + output_filename: str + description: str + + +@dataclass(frozen=True) +class LinkedGoBinary: + """A linked Go binary stored in a `Digest`.""" + + output_digest: Digest + output_filename: str + + +@rule +async def link_go_binary(request: LinkGoBinaryRequest) -> LinkedGoBinary: + result = await Get( + ProcessResult, + GoSdkProcess( + input_digest=request.input_digest, + command=( + "tool", + "link", + "-importcfg", + request.import_config_path, + "-o", + request.output_filename, + "-buildmode=exe", # seen in `go build -x` output + *request.archives, + ), + description="Link Go binary.", + output_files=(request.output_filename,), + ), + ) + + return LinkedGoBinary( + output_digest=result.output_digest, output_filename=request.output_filename + ) + + +def rules(): + return collect_rules()