diff --git a/src/python/pants/backend/python/goals/lockfile.py b/src/python/pants/backend/python/goals/lockfile.py index ad81f28e53a..8f2b2297c9b 100644 --- a/src/python/pants/backend/python/goals/lockfile.py +++ b/src/python/pants/backend/python/goals/lockfile.py @@ -47,6 +47,7 @@ from pants.engine.rules import Get, MultiGet, collect_rules, goal_rule, rule from pants.engine.target import TransitiveTargets, TransitiveTargetsRequest, UnexpandedTargets from pants.engine.unions import UnionMembership, union +from pants.python.python_repos import PythonRepos from pants.python.python_setup import PythonSetup from pants.util.logging import LogLevel from pants.util.ordered_set import FrozenOrderedSet @@ -327,7 +328,13 @@ async def generate_lockfiles_goal( union_membership: UnionMembership, generate_lockfiles_subsystem: GenerateLockfilesSubsystem, python_setup: PythonSetup, + python_repos: PythonRepos, ) -> GenerateLockfilesGoal: + if python_repos.repos: + warn_python_repos("repos") + if python_repos.indexes != [python_repos.pypi_index]: + warn_python_repos("indexes") + specified_user_resolves, specified_tool_sentinels = determine_resolves_to_generate( python_setup.resolves_to_lockfiles.keys(), union_membership[PythonToolLockfileSentinel], @@ -359,6 +366,19 @@ async def generate_lockfiles_goal( return GenerateLockfilesGoal(exit_code=0) +def warn_python_repos(option: str) -> None: + logger.warning( + f"The option `[python-repos].{option}` is configured, but it does not currently work " + "with lockfile generation. Lockfile generation will fail if the relevant requirements " + "cannot be located on PyPI.\n\n" + "If lockfile generation fails, you can disable lockfiles by setting " + "`[tool].lockfile = ''`, e.g. setting `[black].lockfile`. You can also manually " + "generate a lockfile, such as by using pip-compile or `pip freeze`. Set the " + "`[tool].lockfile` option to the path you manually generated. When manually maintaining " + "lockfiles, set `[python-setup].invalid_lockfile_behavior = 'ignore'." + ) + + class AmbiguousResolveNamesError(Exception): def __init__(self, ambiguous_names: list[str]) -> None: if len(ambiguous_names) == 1: diff --git a/src/python/pants/backend/python/subsystems/python_tool_base.py b/src/python/pants/backend/python/subsystems/python_tool_base.py index ad68a5c4e22..fbf2dab1db7 100644 --- a/src/python/pants/backend/python/subsystems/python_tool_base.py +++ b/src/python/pants/backend/python/subsystems/python_tool_base.py @@ -110,7 +110,11 @@ def register_options(cls, register): "To use a custom lockfile, set this option to a file path relative to the " f"build root, then run `./pants generate-lockfiles " f"--resolve={cls.options_scope}`.\n\n" - "" + "Lockfile generation currently does not wire up the `[python-repos]` options. " + "If lockfile generation fails, you can manually generate a lockfile, such as " + "by using pip-compile or `pip freeze`. Set this option to the path to your " + "manually generated lockfile. When manually maintaining lockfiles, set " + "`[python-setup].invalid_lockfile_behavior = 'ignore'`." ), ) diff --git a/src/python/pants/python/python_repos.py b/src/python/pants/python/python_repos.py index 476ec968efb..1c6988ae7c0 100644 --- a/src/python/pants/python/python_repos.py +++ b/src/python/pants/python/python_repos.py @@ -13,6 +13,8 @@ class PythonRepos(Subsystem): "custom cheeseshops when resolving requirements." ) + pypi_index = "https://pypi.org/simple/" + @classmethod def register_options(cls, register): super().register_options(register) @@ -30,7 +32,7 @@ def register_options(cls, register): "--indexes", advanced=True, type=list, - default=["https://pypi.org/simple/"], + default=[cls.pypi_index], help=( "URLs of code repository indexes to look for requirements. If set to an empty " "list, then Pex will use no indices (meaning it will not use PyPI). The values "