From 0805da894c7979ac2ade0888938bf72766a563f6 Mon Sep 17 00:00:00 2001 From: Jacob Floyd Date: Wed, 29 Mar 2023 00:38:39 -0500 Subject: [PATCH] narrow pex_binary files warning --- .../python/goals/package_pex_binary.py | 31 +++++++-- .../package_pex_binary_integration_test.py | 64 ++++++++++++++++++- 2 files changed, 87 insertions(+), 8 deletions(-) diff --git a/src/python/pants/backend/python/goals/package_pex_binary.py b/src/python/pants/backend/python/goals/package_pex_binary.py index f9ac4f25331..ab74db458c5 100644 --- a/src/python/pants/backend/python/goals/package_pex_binary.py +++ b/src/python/pants/backend/python/goals/package_pex_binary.py @@ -8,6 +8,7 @@ from pants.backend.python.target_types import ( PexArgsField, PexBinaryDefaults, + PexBinaryDependenciesField, PexCompletePlatformsField, PexEmitWarningsField, PexEntryPointField, @@ -44,6 +45,8 @@ from pants.core.util_rules.environments import EnvironmentField from pants.engine.rules import Get, MultiGet, collect_rules, rule from pants.engine.target import ( + DependenciesRequest, + Targets, TransitiveTargets, TransitiveTargetsRequest, targets_with_sources_types, @@ -63,6 +66,8 @@ class PexBinaryFieldSet(PackageFieldSet, RunFieldSet): required_fields = (PexEntryPointField,) + dependencies: PexBinaryDependenciesField + entry_point: PexEntryPointField script: PexScriptField args: PexArgsField @@ -121,22 +126,34 @@ async def package_pex_binary( pex_binary_defaults: PexBinaryDefaults, union_membership: UnionMembership, ) -> BuiltPackage: - resolved_entry_point, transitive_targets = await MultiGet( - Get(ResolvedPexEntryPoint, ResolvePexEntryPointRequest(field_set.entry_point)), - Get(TransitiveTargets, TransitiveTargetsRequest([field_set.address])), + resolved_pex_entry_point_get = Get( + ResolvedPexEntryPoint, ResolvePexEntryPointRequest(field_set.entry_point) ) + if field_set.include_sources.value: + resolved_entry_point, transitive_targets = await MultiGet( + resolved_pex_entry_point_get, + Get(TransitiveTargets, TransitiveTargetsRequest([field_set.address])), + ) + dep_targets = tuple(transitive_targets.dependencies) + depends = "transitively depends" + else: + resolved_entry_point, dependencies_targets = await MultiGet( + resolved_pex_entry_point_get, + Get(Targets, DependenciesRequest(field_set.dependencies)), + ) + dep_targets = tuple(dependencies_targets) + depends = "depends" + # Warn if users depend on `files` targets, which won't be included in the PEX and is a common # gotcha. - file_tgts = targets_with_sources_types( - [FileSourceField], transitive_targets.dependencies, union_membership - ) + file_tgts = targets_with_sources_types([FileSourceField], dep_targets, union_membership) if file_tgts: files_addresses = sorted(tgt.address.spec for tgt in file_tgts) logger.warning( softwrap( f""" - The `pex_binary` target {field_set.address} transitively depends on the below `files` + The `pex_binary` target {field_set.address} {depends} on the below `files` targets, but Pants will not include them in the PEX. Filesystem APIs like `open()` are not able to load files within the binary itself; instead, they read from the current working directory. diff --git a/src/python/pants/backend/python/goals/package_pex_binary_integration_test.py b/src/python/pants/backend/python/goals/package_pex_binary_integration_test.py index 99b935deac9..3e05a98a8b2 100644 --- a/src/python/pants/backend/python/goals/package_pex_binary_integration_test.py +++ b/src/python/pants/backend/python/goals/package_pex_binary_integration_test.py @@ -13,11 +13,14 @@ import pytest from pants.backend.python import target_types_rules -from pants.backend.python.goals import package_pex_binary +from pants.backend.python.goals import package_pex_binary, setup_py from pants.backend.python.goals.package_pex_binary import PexBinaryFieldSet +from pants.backend.python.macros.python_artifact import PythonArtifact +from pants.backend.python.subsystems.setuptools import PythonDistributionFieldSet from pants.backend.python.target_types import ( PexBinary, PexLayout, + PythonDistribution, PythonRequirementTarget, PythonSourcesGeneratorTarget, ) @@ -43,17 +46,21 @@ def rule_runner() -> RuleRunner: *pex_from_targets.rules(), *target_types_rules.rules(), *core_target_types_rules(), + *setup_py.rules(), QueryRule(BuiltPackage, [PexBinaryFieldSet]), + QueryRule(BuiltPackage, [PythonDistributionFieldSet]), ], target_types=[ FileTarget, FilesGeneratorTarget, PexBinary, + PythonDistribution, PythonRequirementTarget, PythonSourcesGeneratorTarget, RelocatedFiles, ResourcesGeneratorTarget, ], + objects={"python_artifact": PythonArtifact}, ) rule_runner.set_options([], env_inherit={"PATH", "PYENV_ROOT", "HOME"}) return rule_runner @@ -104,6 +111,61 @@ def test_warn_files_targets(rule_runner: RuleRunner, caplog) -> None: assert result.artifacts[0].relpath == "src.py.project/project.pex" +def test_include_sources_avoids_files_targets_warning(rule_runner: RuleRunner, caplog) -> None: + rule_runner.write_files( + { + "assets/f.txt": "", + "assets/BUILD": dedent( + """\ + files(name='files', sources=['f.txt']) + relocated_files( + name='relocated', + files_targets=[':files'], + src='assets', + dest='new_assets', + ) + """ + ), + "src/py/project/__init__.py": "", + "src/py/project/app.py": "print('hello')", + "src/py/project/BUILD": dedent( + """\ + python_sources( + name='sources', + ) + + python_distribution( + name='wheel', + dependencies=[ + ':sources', + 'assets:relocated', + ], + provides=python_artifact( + name='my-dist', + version='1.2.3', + ), + ) + + pex_binary( + dependencies=[':wheel'], + entry_point="none", + include_sources=False, + ) + """ + ), + } + ) + tgt = rule_runner.get_target(Address("src/py/project")) + field_set = PexBinaryFieldSet.create(tgt) + + assert not caplog.records + result = rule_runner.request(BuiltPackage, [field_set]) + assert not caplog.records + + assert len(result.artifacts) == 1 + assert result.artifacts[0].relpath == "src.py.project/project.pex" + + @pytest.mark.parametrize( "layout", [pytest.param(layout, id=layout.value) for layout in PexLayout],