Skip to content

Commit

Permalink
[internal] Hook up check to Go
Browse files Browse the repository at this point in the history
[ci skip-rust]
[ci skip-build-wheels]
  • Loading branch information
Eric-Arellano committed Oct 22, 2021
1 parent 5a2207a commit 94361c2
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 2 deletions.
2 changes: 1 addition & 1 deletion pants.toml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pants_ignore.add = [

build_ignore.add = [
# Disable Go targets by default so Pants developers do not need Go installed.
"/testprojects/src/go/**",
# "/testprojects/src/go/**",
]

# NB: Users must still set `--remote-cache-{read,write}` to enable the remote cache.
Expand Down
3 changes: 2 additions & 1 deletion src/python/pants/backend/experimental/go/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from pants.backend.go import target_type_rules
from pants.backend.go.goals import package_binary, run_binary, tailor, test
from pants.backend.go.goals import check, package_binary, run_binary, tailor, test
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
Expand Down Expand Up @@ -34,6 +34,7 @@ def rules():
return [
*assembly.rules(),
*build_pkg.rules(),
*check.rules(),
*third_party_pkg.rules(),
*golang.rules(),
*import_analysis.rules(),
Expand Down
76 changes: 76 additions & 0 deletions src/python/pants/backend/go/goals/check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from dataclasses import dataclass
from typing import cast

from pants.backend.go.target_types import GoFirstPartyPackageSourcesField
from pants.backend.go.util_rules.build_pkg import (
BuildGoPackageRequest,
BuildGoPackageTargetRequest,
FallibleBuildGoPackageRequest,
FallibleBuiltGoPackage,
)
from pants.core.goals.check import CheckRequest, CheckResult, CheckResults
from pants.engine.rules import Get, MultiGet, collect_rules, rule
from pants.engine.target import FieldSet
from pants.engine.unions import UnionRule


@dataclass(frozen=True)
class GoCheckFieldSet(FieldSet):
required_fields = (GoFirstPartyPackageSourcesField,)

sources: GoFirstPartyPackageSourcesField


class GoCheckRequest(CheckRequest):
field_set_type = GoCheckFieldSet


@rule
async def check_go(request: GoCheckRequest) -> CheckResults:
build_requests = await MultiGet(
Get(FallibleBuildGoPackageRequest, BuildGoPackageTargetRequest(field_set.address))
for field_set in request.field_sets
)
invalid_requests = []
valid_requests = []
for fallible_request in build_requests:
if fallible_request.request is None:
invalid_requests.append(fallible_request)
else:
valid_requests.append(fallible_request.request)

build_results = await MultiGet(
Get(FallibleBuiltGoPackage, BuildGoPackageRequest, request) for request in valid_requests
)

# TODO: Update `build_pkg.py` to use streaming workunits to log compilation results, which has
# the benefit of other contexts like `test.py` using it. Switch this to only preserve the
# exit code.
check_results = [
*(
CheckResult(
result.exit_code,
"",
cast(str, result.stderr),
partition_description=result.import_path,
)
for result in invalid_requests
),
*(
CheckResult(
result.exit_code,
result.stdout or "",
result.stderr or "",
partition_description=result.import_path,
)
for result in build_results
),
]
return CheckResults(check_results, checker_name="go")


def rules():
return [*collect_rules(), UnionRule(CheckRequest, GoCheckRequest)]
85 changes: 85 additions & 0 deletions src/python/pants/backend/go/goals/check_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import annotations

from textwrap import dedent

import pytest

from pants.backend.go import target_type_rules
from pants.backend.go.goals import check
from pants.backend.go.goals.check import GoCheckFieldSet, GoCheckRequest
from pants.backend.go.target_types import GoModTarget
from pants.backend.go.util_rules import (
assembly,
build_pkg,
first_party_pkg,
go_mod,
import_analysis,
sdk,
third_party_pkg,
)
from pants.core.goals.check import CheckResult, CheckResults
from pants.engine.addresses import Address
from pants.testutil.rule_runner import QueryRule, RuleRunner


@pytest.fixture
def rule_runner() -> RuleRunner:
rule_runner = RuleRunner(
rules=[
*check.rules(),
*sdk.rules(),
*assembly.rules(),
*build_pkg.rules(),
*import_analysis.rules(),
*go_mod.rules(),
*first_party_pkg.rules(),
*third_party_pkg.rules(),
*target_type_rules.rules(),
QueryRule(CheckResults, [GoCheckRequest]),
],
target_types=[GoModTarget],
)
rule_runner.set_options([], env_inherit={"PATH"})
return rule_runner


def test_check(rule_runner: RuleRunner) -> None:
rule_runner.write_files(
{
"go.mod": dedent(
"""\
module example.com/greeter
go 1.17
"""
),
"bad/f.go": "invalid!!!",
"good/f.go": dedent(
"""\
package greeter
import "fmt"
func Hello() {
fmt.Println("Hello world!")
}
"""
),
"BUILD": "go_mod(name='mod')",
}
)
targets = [
rule_runner.get_target(Address("", target_name="mod", generated_name="./bad")),
rule_runner.get_target(Address("", target_name="mod", generated_name="./good")),
]
results = rule_runner.request(
CheckResults, [GoCheckRequest(GoCheckFieldSet.create(tgt) for tgt in targets)]
).results
assert set(results) == {
CheckResult(0, "", "", "example.com/greeter/good"),
CheckResult(
1, "", "bad/f.go:1:1: expected 'package', found invalid\n", "example.com/greeter/bad"
),
}

0 comments on commit 94361c2

Please sign in to comment.