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

Deprecate awslambda and binary goals in favor of new package goal #10881

Merged
merged 6 commits into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright 2019 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

import logging
from abc import ABCMeta
from dataclasses import dataclass
from textwrap import dedent
Expand All @@ -13,6 +14,8 @@
from pants.engine.target import FieldSet, TargetRootsToFieldSets, TargetRootsToFieldSetsRequest
from pants.engine.unions import union

logger = logging.getLogger(__name__)


class AWSLambdaError(Exception):
pass
Expand All @@ -32,7 +35,7 @@ class AWSLambdaFieldSet(FieldSet, metaclass=ABCMeta):


class AWSLambdaSubsystem(LineOriented, GoalSubsystem):
"""Generate an AWS Lambda."""
"""Deprecated in favor of the `build` goal."""

name = "awslambda"

Expand All @@ -48,6 +51,10 @@ async def create_awslambda(
distdir: DistDir,
workspace: Workspace,
) -> AWSLambdaGoal:
logger.warning(
"The `awslambda` goal is deprecated in favor of the `package` goal, which behaves "
"identically. `awslambda` will be removed in 2.1.0.dev0."
)
targets_to_valid_field_sets = await Get(
TargetRootsToFieldSets,
TargetRootsToFieldSetsRequest(
Expand Down
6 changes: 3 additions & 3 deletions src/python/pants/backend/awslambda/python/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
See https://www.pantsbuild.org/docs/awslambda-python.
"""

from pants.backend.awslambda.common import awslambda_common_rules
from pants.backend.awslambda.python import awslambda_python_rules
from pants.backend.awslambda.common import rules as common_rules
from pants.backend.awslambda.python import rules as python_rules
from pants.backend.awslambda.python.target_types import PythonAWSLambda


def rules():
return [*awslambda_common_rules.rules(), *awslambda_python_rules.rules()]
return [*common_rules.rules(), *python_rules.rules()]


def target_types():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
import os
from dataclasses import dataclass

from pants.backend.awslambda.common.awslambda_common_rules import (
AWSLambdaFieldSet,
CreatedAWSLambda,
)
from pants.backend.awslambda.common.rules import AWSLambdaFieldSet, CreatedAWSLambda
from pants.backend.awslambda.python.lambdex import Lambdex
from pants.backend.awslambda.python.target_types import (
PythonAwsLambdaHandler,
Expand All @@ -28,6 +25,7 @@
PexFromTargetsRequest,
TwoStepPexFromTargetsRequest,
)
from pants.core.goals.package import BuiltPackage, PackageFieldSet
from pants.engine.fs import Digest, MergeDigests
from pants.engine.process import ProcessResult
from pants.engine.rules import Get, collect_rules, rule
Expand All @@ -39,7 +37,7 @@


@dataclass(frozen=True)
class PythonAwsLambdaFieldSet(AWSLambdaFieldSet):
class PythonAwsLambdaFieldSet(PackageFieldSet, AWSLambdaFieldSet):
required_fields = (PythonAwsLambdaHandler, PythonAwsLambdaRuntime)

handler: PythonAwsLambdaHandler
Expand Down Expand Up @@ -123,6 +121,16 @@ async def create_python_awslambda(
)


@rule
async def package_python_awslambda(field_set: PythonAwsLambdaFieldSet) -> BuiltPackage:
awslambda = await Get(CreatedAWSLambda, AWSLambdaFieldSet, field_set)
return BuiltPackage(
awslambda.digest,
relpath=awslambda.zip_file_relpath,
extra_log_info=f" Runtime: {awslambda.runtime}\n Handler: {awslambda.handler}",
)


@rule(desc="Set up lambdex")
async def setup_lambdex(lambdex: Lambdex) -> LambdexSetup:
requirements_pex = await Get(
Expand All @@ -142,5 +150,6 @@ def rules():
return [
*collect_rules(),
UnionRule(AWSLambdaFieldSet, PythonAwsLambdaFieldSet),
UnionRule(PackageFieldSet, PythonAwsLambdaFieldSet),
*pex_from_targets.rules(),
]
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@

import pytest

from pants.backend.awslambda.common.awslambda_common_rules import CreatedAWSLambda
from pants.backend.awslambda.python.awslambda_python_rules import PythonAwsLambdaFieldSet
from pants.backend.awslambda.python.awslambda_python_rules import rules as awslambda_python_rules
from pants.backend.awslambda.common.rules import CreatedAWSLambda
from pants.backend.awslambda.python.rules import PythonAwsLambdaFieldSet
from pants.backend.awslambda.python.rules import rules as awslambda_python_rules
from pants.backend.awslambda.python.target_types import PythonAWSLambda
from pants.backend.python.target_types import PythonLibrary
from pants.core.goals.package import BuiltPackage
from pants.engine.addresses import Address
from pants.engine.fs import DigestContents
from pants.testutil.rule_runner import QueryRule, RuleRunner
Expand All @@ -23,6 +24,7 @@ def rule_runner() -> RuleRunner:
return RuleRunner(
rules=[
*awslambda_python_rules(),
QueryRule(BuiltPackage, (PythonAwsLambdaFieldSet,)),
QueryRule(CreatedAWSLambda, (PythonAwsLambdaFieldSet,)),
],
target_types=[PythonAWSLambda, PythonLibrary],
Expand All @@ -41,6 +43,9 @@ def create_python_awslambda(rule_runner: RuleRunner, addr: str) -> Tuple[str, by
created_awslambda = rule_runner.request(
CreatedAWSLambda, [PythonAwsLambdaFieldSet.create(target)]
)
built_asset = rule_runner.request(BuiltPackage, [PythonAwsLambdaFieldSet.create(target)])
assert created_awslambda.digest == built_asset.digest
assert created_awslambda.zip_file_relpath == built_asset.relpath
created_awslambda_digest_contents = rule_runner.request(
DigestContents, [created_awslambda.digest]
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
TwoStepPexFromTargetsRequest,
)
from pants.core.goals.binary import BinaryFieldSet, CreatedBinary
from pants.core.goals.package import BuiltPackage, PackageFieldSet
from pants.core.goals.run import RunFieldSet
from pants.engine.fs import PathGlobs, Paths
from pants.engine.rules import Get, collect_rules, rule
Expand All @@ -37,7 +38,7 @@


@dataclass(frozen=True)
class PythonBinaryFieldSet(BinaryFieldSet, RunFieldSet):
class PythonBinaryFieldSet(PackageFieldSet, BinaryFieldSet, RunFieldSet):
required_fields = (PythonEntryPoint, PythonBinarySources)

sources: PythonBinarySources
Expand Down Expand Up @@ -71,11 +72,11 @@ def generate_additional_args(


@rule(level=LogLevel.DEBUG)
async def create_python_binary(
async def package_python_binary(
field_set: PythonBinaryFieldSet,
python_binary_defaults: PythonBinaryDefaults,
global_options: GlobalOptions,
) -> CreatedBinary:
) -> BuiltPackage:
entry_point = field_set.entry_point.value
if entry_point is None:
binary_source_paths = await Get(
Expand Down Expand Up @@ -124,9 +125,18 @@ async def create_python_binary(
)
),
)
pex = two_step_pex.pex
return CreatedBinary(digest=pex.digest, binary_name=pex.name)
return BuiltPackage(two_step_pex.pex.digest, relpath=output_filename)


@rule(level=LogLevel.DEBUG)
async def create_python_binary(field_set: PythonBinaryFieldSet) -> CreatedBinary:
pex = await Get(BuiltPackage, PackageFieldSet, field_set)
return CreatedBinary(pex.digest, pex.relpath)


def rules():
return [*collect_rules(), UnionRule(BinaryFieldSet, PythonBinaryFieldSet)]
return [
*collect_rules(),
UnionRule(PackageFieldSet, PythonBinaryFieldSet),
UnionRule(BinaryFieldSet, PythonBinaryFieldSet),
]
30 changes: 19 additions & 11 deletions src/python/pants/backend/python/goals/pytest_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from pants.backend.python.target_types import (
PythonInterpreterCompatibility,
PythonRuntimeBinaryDependencies,
PythonRuntimePackageDependencies,
PythonTestsSources,
PythonTestsTimeout,
)
Expand All @@ -31,7 +32,7 @@
PythonSourceFiles,
PythonSourceFilesRequest,
)
from pants.core.goals.binary import BinaryFieldSet, CreatedBinary
from pants.core.goals.package import BuiltPackage, PackageFieldSet
from pants.core.goals.test import (
TestDebugRequest,
TestExtraEnv,
Expand Down Expand Up @@ -65,6 +66,7 @@ class PythonTestFieldSet(TestFieldSet):
sources: PythonTestsSources
timeout: PythonTestsTimeout
runtime_binary_dependencies: PythonRuntimeBinaryDependencies
runtime_package_dependencies: PythonRuntimePackageDependencies

def is_conftest_or_type_stub(self) -> bool:
"""We skip both `conftest.py` and `.pyi` stubs, even though though they often belong to a
Expand Down Expand Up @@ -152,24 +154,30 @@ async def setup_pytest_for_target(
PythonSourceFiles, PythonSourceFilesRequest(all_targets, include_files=True)
)

# Create any binaries that the test depends on through the `runtime_binary_dependencies` field.
binaries: Tuple[CreatedBinary, ...] = ()
if request.field_set.runtime_binary_dependencies.value:
runtime_binary_addresses = await MultiGet(
# Create any assets that the test depends on through the `runtime_package_dependencies` field.
assets: Tuple[BuiltPackage, ...] = ()
if (
request.field_set.runtime_package_dependencies.value
or request.field_set.runtime_binary_dependencies.value
):
runtime_package_addresses = await MultiGet(
Get(
Address,
AddressInput,
AddressInput.parse(v, relative_to=request.field_set.address.spec_path),
)
for v in request.field_set.runtime_binary_dependencies.value
for v in (
*(request.field_set.runtime_package_dependencies.value or ()),
*(request.field_set.runtime_binary_dependencies.value or ()),
)
)
runtime_binary_targets = await Get(Targets, Addresses(runtime_binary_addresses))
runtime_package_targets = await Get(Targets, Addresses(runtime_package_addresses))
field_sets_per_target = await Get(
FieldSetsPerTarget,
FieldSetsPerTargetRequest(BinaryFieldSet, runtime_binary_targets),
FieldSetsPerTargetRequest(PackageFieldSet, runtime_package_targets),
)
binaries = await MultiGet(
Get(CreatedBinary, BinaryFieldSet, field_set)
assets = await MultiGet(
Get(BuiltPackage, PackageFieldSet, field_set)
for field_set in field_sets_per_target.field_sets
)

Expand All @@ -194,7 +202,7 @@ async def setup_pytest_for_target(
prepared_sources.source_files.snapshot.digest,
requirements_pex.digest,
pytest_pex.digest,
*(binary.digest for binary in binaries),
*(binary.digest for binary in assets),
)
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import pytest

from pants.backend.python.dependency_inference import rules as dependency_inference_rules
from pants.backend.python.goals import create_python_binary, pytest_runner
from pants.backend.python.goals import package_python_binary, pytest_runner
from pants.backend.python.goals.coverage_py import create_coverage_config
from pants.backend.python.goals.pytest_runner import PythonTestFieldSet
from pants.backend.python.target_types import (
Expand Down Expand Up @@ -40,7 +40,7 @@ def rule_runner() -> RuleRunner:
*dependency_inference_rules.rules(), # For conftest detection.
*distdir.rules(),
*binary.rules(),
*create_python_binary.rules(),
*package_python_binary.rules(),
get_filtered_environment,
QueryRule(TestResult, (PythonTestFieldSet,)),
QueryRule(TestDebugRequest, (PythonTestFieldSet,)),
Expand Down Expand Up @@ -441,7 +441,7 @@ def test_args():
assert result.exit_code == 0


def test_runtime_binary_dependency(rule_runner: RuleRunner) -> None:
def test_runtime_package_dependency(rule_runner: RuleRunner) -> None:
create_python_binary_target(rule_runner, BINARY_SOURCE)
rule_runner.create_file(
f"{PACKAGE}/test_binary_call.py",
Expand All @@ -454,7 +454,7 @@ def test_embedded_binary():
"""
),
)
rule_runner.add_to_build_file(PACKAGE, "python_tests(runtime_binary_dependencies=[':bin'])")
rule_runner.add_to_build_file(PACKAGE, "python_tests(runtime_package_dependencies=[':bin'])")
tgt = rule_runner.get_target(Address(PACKAGE, relative_file_path="test_binary_call.py"))
assert isinstance(tgt, PythonTests)
result = run_pytest(rule_runner, tgt, passthrough_args="-s")
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/goals/run_python_binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import os

from pants.backend.python.goals.create_python_binary import PythonBinaryFieldSet
from pants.backend.python.goals.package_python_binary import PythonBinaryFieldSet
from pants.backend.python.target_types import PythonBinaryDefaults, PythonBinarySources
from pants.backend.python.util_rules.pex import Pex, PexRequest
from pants.backend.python.util_rules.pex_environment import PexEnvironment
Expand Down
4 changes: 2 additions & 2 deletions src/python/pants/backend/python/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from pants.backend.python.dependency_inference import rules as dependency_inference_rules
from pants.backend.python.goals import (
coverage_py,
create_python_binary,
package_python_binary,
pytest_runner,
repl,
run_python_binary,
Expand Down Expand Up @@ -69,7 +69,7 @@ def rules():
*pex_environment.rules(),
*pex_from_targets.rules(),
*pytest_runner.rules(),
*create_python_binary.rules(),
*package_python_binary.rules(),
*python_native_code.rules(),
*repl.rules(),
*run_python_binary.rules(),
Expand Down
35 changes: 31 additions & 4 deletions src/python/pants/backend/python/target_types.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).

import collections.abc
import logging
import os.path
from textwrap import dedent
from typing import Iterable, Optional, Tuple, Union, cast
Expand Down Expand Up @@ -37,6 +38,8 @@
from pants.python.python_requirement import PythonRequirement
from pants.python.python_setup import PythonSetup

logger = logging.getLogger(__name__)

# -----------------------------------------------------------------------------------------------
# Common fields
# -----------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -264,15 +267,38 @@ class PythonTestsDependencies(Dependencies):
supports_transitive_excludes = True


class PythonRuntimeBinaryDependencies(StringSequenceField):
"""Addresses to binary targets that will be built and included in this target at runtime.
# TODO(#10888): Teach project introspection goals that this is a special type of the `Dependencies`
# field.
class PythonRuntimePackageDependencies(StringSequenceField):
"""Addresses to targets that can be built with the `./pants package` goal and whose resulting
assets should be included in the test run.
Eric-Arellano marked this conversation as resolved.
Show resolved Hide resolved

These binary targets do not necessarily need to be `python_binary` targets; they can be any
targets accepted by `./pants binary`
Pants will build the asset as if it had run `./pants package`, and will include the result in
your test environment using the same name it would normally have, but without the `dist/`
prefix. For example, you can include a `python_binary`, `python_awslambda`, or `archive`.
"""

alias = "runtime_package_dependencies"


class PythonRuntimeBinaryDependencies(StringSequenceField):
"""Deprecated in favor of the `runtime_build_dependencies` field, which works with more target
types like `archive` and `python_awslambda`."""

alias = "runtime_binary_dependencies"

@classmethod
def compute_value(
cls, raw_value: Optional[Iterable[str]], *, address: Address
) -> Optional[Tuple[str, ...]]:
if raw_value is not None:
logger.warning(
f"Using the `runtime_binary_dependencies` field in the target {address}. This "
"field is now deprecated in favor of the more flexible "
"`runtime_package_dependencies` field, and it will be removed in 2.1.0.dev0."
)
return super().compute_value(raw_value, address=address)


class PythonTestsTimeout(IntField):
"""A timeout (in seconds) which covers the total runtime of all tests in this target.
Expand Down Expand Up @@ -323,6 +349,7 @@ class PythonTests(Target):
*COMMON_PYTHON_FIELDS,
PythonTestsSources,
PythonTestsDependencies,
PythonRuntimePackageDependencies,
PythonRuntimeBinaryDependencies,
PythonTestsTimeout,
)
Expand Down
Loading