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

[internal] Rename ./pants lock to ./pants generate-user-lockfile and ./pants tool-lock to ./pants generate-lockfiles #12641

Merged
merged 3 commits into from
Aug 26, 2021
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
6 changes: 3 additions & 3 deletions build-support/bin/_generate_all_lockfiles_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ def main() -> None:
# and egg problem from https://github.com/pantsbuild/pants/issues/12457. We must
# restore it here so that the lockfile gets generated properly.
"--python-setup-experimental-lockfile=3rdparty/python/lockfiles/user_reqs.txt",
"lock",
"tool-lock",
"generate-lockfiles",
"generate-user-lockfile",
"::",
],
check=True,
Expand Down Expand Up @@ -129,7 +129,7 @@ def main() -> None:
f"--coverage-py-interpreter-constraints={repr(CoverageSubsystem.default_interpreter_constraints)}",
f"--coverage-py-experimental-lockfile={CoverageSubsystem.default_lockfile_path}",
# Run the goal.
"tool-lock",
"generate-lockfiles",
],
check=True,
)
Expand Down
60 changes: 26 additions & 34 deletions src/python/pants/backend/experimental/python/lockfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def from_tool(
),
dest=subsystem.lockfile,
description=f"Generate lockfile for {subsystem.options_scope}",
regenerate_command="./pants tool-lock",
regenerate_command="./pants generate-lockfiles",
)

@property
Expand Down Expand Up @@ -188,35 +188,32 @@ async def generate_lockfile(
# --------------------------------------------------------------------------------------


class LockSubsystem(GoalSubsystem):
name = "lock"
help = "Generate a lockfile."
# TODO(#12314): Unify with the `generate-lockfiles` goal. Stop looking at specs and instead have
# an option like `--lock-resolves` with a list of named resolves (including tools).
class GenerateUserLockfileSubsystem(GoalSubsystem):
name = "generate-user-lockfile"
help = "Generate a lockfile for Python user requirements (experimental)."


class LockGoal(Goal):
subsystem_cls = LockSubsystem
class GenerateUserLockfileGoal(Goal):
subsystem_cls = GenerateUserLockfileSubsystem


@goal_rule
async def lockfile_goal(
async def generate_user_lockfile_goal(
addresses: Addresses,
python_setup: PythonSetup,
workspace: Workspace,
) -> LockGoal:
) -> GenerateUserLockfileGoal:
if python_setup.lockfile is None:
logger.warning(
"You ran `./pants lock`, but `[python-setup].experimental_lockfile` is not set. Please "
"set this option to the path where you'd like the lockfile for your code's "
"dependencies to live."
"You ran `./pants generate-user-lockfile`, but `[python-setup].experimental_lockfile` "
"is not set. Please set this option to the path where you'd like the lockfile for "
"your code's dependencies to live."
)
return LockGoal(exit_code=1)
return GenerateUserLockfileGoal(exit_code=1)

# TODO(#12314): Looking at the transitive closure to generate a single lockfile will not work
# when we have multiple user lockfiles supported. Ideally, `./pants lock ::` would mean
# "regenerate all unique lockfiles", whereas now it means "generate a single lockfile based
# on this transitive closure."
transitive_targets = await Get(TransitiveTargets, TransitiveTargetsRequest(addresses))

reqs = PexRequirements.create_from_requirement_fields(
tgt[PythonRequirementsField]
# NB: By looking at the dependencies, rather than the closure, we only generate for
Expand All @@ -230,7 +227,7 @@ async def lockfile_goal(
"No third-party requirements found for the transitive closure, so a lockfile will not "
"be generated."
)
return LockGoal(exit_code=0)
return GenerateUserLockfileGoal(exit_code=0)

result = await Get(
PythonLockfile,
Expand All @@ -251,7 +248,7 @@ async def lockfile_goal(
workspace.write_digest(result.digest)
logger.info(f"Wrote lockfile to {result.path}")

return LockGoal(exit_code=0)
return GenerateUserLockfileGoal(exit_code=0)


# --------------------------------------------------------------------------------------
Expand All @@ -264,31 +261,26 @@ class PythonToolLockfileSentinel:
pass


# TODO(#12314): Unify this goal with `lock` once we figure out how to unify the semantics,
# particularly w/ CLI specs. This is a separate goal only to facilitate progress.
class ToolLockSubsystem(GoalSubsystem):
name = "tool-lock"
help = "Generate a lockfile for a Python tool."
class GenerateLockfilesSubsystem(GoalSubsystem):
name = "generate-lockfiles"
help = "Generate lockfiles for Python third-party dependencies."
required_union_implementations = (PythonToolLockfileSentinel,)


class ToolLockGoal(Goal):
subsystem_cls = ToolLockSubsystem
class GenerateLockfilesGoal(Goal):
subsystem_cls = GenerateLockfilesSubsystem


@goal_rule
async def generate_all_tool_lockfiles(
workspace: Workspace,
union_membership: UnionMembership,
) -> ToolLockGoal:
# TODO(#12314): Add logic to inspect the Specs and generate for only relevant lockfiles. For
# now, we generate for all tools.
async def generate_lockfiles_goal(
workspace: Workspace, union_membership: UnionMembership
) -> GenerateLockfilesGoal:
requests = await MultiGet(
Get(PythonLockfileRequest, PythonToolLockfileSentinel, sentinel())
for sentinel in union_membership.get(PythonToolLockfileSentinel)
)
if not requests:
return ToolLockGoal(exit_code=0)
return GenerateLockfilesGoal(exit_code=0)

results = await MultiGet(
Get(PythonLockfile, PythonLockfileRequest, req)
Expand All @@ -300,7 +292,7 @@ async def generate_all_tool_lockfiles(
for result in results:
logger.info(f"Wrote lockfile to {result.path}")

return ToolLockGoal(exit_code=0)
return GenerateLockfilesGoal(exit_code=0)


def rules():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def register_options(cls, register):
"recommend this, as lockfiles are essential for reproducible builds.\n\n"
"To use a custom lockfile, set this option to a file path relative to the "
"build root, then activate the backend_package "
"`pants.backend.experimental.python` and run `./pants tool-lock`.\n\n"
"`pants.backend.experimental.python` and run `./pants generate-lockfiles`.\n\n"
"This option is experimental and will likely change. It does not follow the "
"normal deprecation cycle."
),
Expand Down
4 changes: 2 additions & 2 deletions src/python/pants/python/python_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def register_options(cls, register):
"multiple lockfiles. This option's behavior may change without the normal "
"deprecation cycle.\n\n"
"To generate a lockfile, activate the backend `pants.backend.experimental.python`"
"and run `./pants lock ::`.\n\n"
"and run `./pants generate-user-lockfile ::`.\n\n"
"Mutually exclusive with `[python-setup].requirement_constraints`."
),
)
Expand All @@ -137,7 +137,7 @@ def register_options(cls, register):
default=None,
help=(
"If set, Pants will instruct your users to run a custom command to regenerate "
"lockfiles, rather than running `./pants lock` and `./pants tool-lock` like normal."
"lockfiles, rather than running `./pants generate-lockfiles` like normal."
"\n\nThis option is experimental and it may change at any time without the normal "
"deprecation cycle."
),
Expand Down