diff --git a/src/python/pants/backend/python/goals/lockfile.py b/src/python/pants/backend/python/goals/lockfile.py index 5d1326222c7..fc8f19435aa 100644 --- a/src/python/pants/backend/python/goals/lockfile.py +++ b/src/python/pants/backend/python/goals/lockfile.py @@ -37,6 +37,7 @@ from pants.engine.process import ProcessCacheScope, ProcessResult from pants.engine.rules import Get, MultiGet, collect_rules, goal_rule, rule from pants.engine.unions import UnionMembership, union +from pants.python.python_repos import PythonRepos from pants.util.logging import LogLevel from pants.util.ordered_set import FrozenOrderedSet @@ -69,7 +70,7 @@ def register_options(cls, register) -> None: "generate the lockfile for those two tools.\n\n" "If you specify an invalid resolve name, like 'fake', Pants will output all " "possible values.\n\n" - "If not specified, will generate for all resolves." + "If not specified, Pants will generate for all resolves." ), ) register( @@ -245,7 +246,13 @@ async def generate_lockfiles_goal( workspace: Workspace, union_membership: UnionMembership, generate_lockfiles_subsystem: GenerateLockfilesSubsystem, + 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_tool_requests = await MultiGet( Get(PythonLockfileRequest, PythonToolLockfileSentinel, sentinel()) for sentinel in determine_tool_sentinels_to_generate( @@ -269,6 +276,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 UnrecognizedResolveNamesError(Exception): pass 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 "