Skip to content

Commit

Permalink
Allow passing arguments to PEX invocation used for pex_binary (#20737)
Browse files Browse the repository at this point in the history
This adds a new field `extra_build_args` to `pex_binary` that just
faithfully passes through arbitrary arguments to the `pex ...`
invocation used to build the PEX. This gives users more control and
flexibility for new PEX features that Pants might not (yet) expose
natively.

For instance, the functionality requested in #20227 can now be solved by
passing `extra_build_args=["--no-compress"]`, and similarly people can
now start taking advantage of the `--no-pre-install-wheels`
functionality for their own PEXes (relates to #20562).
  • Loading branch information
huonw authored Apr 5, 2024
1 parent b1f2262 commit ff0f561
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/python/pants/backend/python/goals/package_pex_binary.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
PexExecutableField,
PexExecutionMode,
PexExecutionModeField,
PexExtraBuildArgsField,
PexIgnoreErrorsField,
PexIncludeRequirementsField,
PexIncludeSourcesField,
Expand Down Expand Up @@ -83,6 +84,7 @@ class PexBinaryFieldSet(PackageFieldSet, RunFieldSet):
venv_hermetic_scripts: PexVenvHermeticScripts
environment: EnvironmentField
check: PexCheckField
extra_build_args: PexExtraBuildArgsField

@property
def _execution_mode(self) -> PexExecutionMode:
Expand Down Expand Up @@ -116,6 +118,8 @@ def generate_additional_args(self, pex_binary_defaults: PexBinaryDefaults) -> Tu
args.append("--venv-site-packages-copies")
if self.venv_hermetic_scripts.value is False:
args.append("--non-hermetic-venv-scripts")
if self.extra_build_args.value:
args.extend(self.extra_build_args.value)
return tuple(args)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@

from pants.backend.python import target_types_rules
from pants.backend.python.goals import package_dists, package_pex_binary
from pants.backend.python.goals.package_pex_binary import PexBinaryFieldSet
from pants.backend.python.goals.package_pex_binary import (
PexBinaryFieldSet,
PexFromTargetsRequestForBuiltPackage,
)
from pants.backend.python.macros.python_artifact import PythonArtifact
from pants.backend.python.subsystems.setuptools import PythonDistributionFieldSet
from pants.backend.python.target_types import (
Expand Down Expand Up @@ -49,6 +52,7 @@ def rule_runner() -> PythonRuleRunner:
*core_target_types_rules(),
*package_dists.rules(),
QueryRule(BuiltPackage, [PexBinaryFieldSet]),
QueryRule(PexFromTargetsRequestForBuiltPackage, [PexBinaryFieldSet]),
QueryRule(BuiltPackage, [PythonDistributionFieldSet]),
],
target_types=[
Expand Down Expand Up @@ -455,3 +459,33 @@ def test_sh_boot_plumb(rule_runner: PythonRuleRunner) -> None:
with open(executable, "rb") as f:
shebang = f.readline().decode()
assert "#!/bin/sh" in shebang


def test_extra_build_args(rule_runner: PythonRuleRunner) -> None:
rule_runner.write_files(
{
"src/py/project/app.py": dedent(
"""\
print("hello")
"""
),
"src/py/project/BUILD": dedent(
"""\
python_sources(name="lib")
pex_binary(
entry_point="app.py",
extra_build_args=["--example-extra-arg", "value-goes-here"]
)
"""
),
}
)

tgt = rule_runner.get_target(Address("src/py/project"))
field_set = PexBinaryFieldSet.create(tgt)
result = rule_runner.request(PexFromTargetsRequestForBuiltPackage, [field_set])

additional_args = result.request.additional_args

assert additional_args[-2] == "--example-extra-arg"
assert additional_args[-1] == "value-goes-here"
26 changes: 24 additions & 2 deletions src/python/pants/backend/python/target_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,11 +415,32 @@ def compute_value(cls, raw_value: Optional[str], address: Address) -> Optional[E


class PexArgsField(StringSequenceField):
alias = "args"
alias: ClassVar[str] = "args"
help = help_text(
"""
lambda: f"""
Freeze these command-line args into the PEX. Allows you to run generic entry points
on specific arguments without creating a shim file.
This is different to `{PexExtraBuildArgsField.alias}`: `{PexArgsField.alias}`
records arguments used by the packaged PEX when executed,
`{PexExtraBuildArgsField.alias}` passes arguments to the process that does the
packaging.
"""
)


class PexExtraBuildArgsField(StringSequenceField):
alias: ClassVar[str] = "extra_build_args"
default = ()
help = help_text(
lambda: f"""
Extra arguments to pass to the `pex` invocation used to build this PEX. These are
passed after all other arguments. This can be used to pass extra options that
Pants doesn't have built-in support for.
This is different to `{PexArgsField.alias}`: `{PexArgsField.alias}` records
arguments used by the packaged PEX when executed, `{PexExtraBuildArgsField.alias}`
passes arguments to the process that does the packaging.
"""
)

Expand Down Expand Up @@ -789,6 +810,7 @@ class PexBinary(Target):
PexScriptField,
PexExecutableField,
PexArgsField,
PexExtraBuildArgsField,
PexEnvField,
OutputPathField,
)
Expand Down

0 comments on commit ff0f561

Please sign in to comment.