Skip to content

Commit

Permalink
Allow --dry-run for venv updates.
Browse files Browse the repository at this point in the history
  • Loading branch information
jsirois committed Feb 20, 2024
1 parent 487c7db commit 812adc3
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 7 deletions.
22 changes: 17 additions & 5 deletions pex/cli/commands/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from pex.cli.command import BuildTimeCommand
from pex.commands.command import JsonMixin, OutputMixin
from pex.common import is_exe, pluralize, safe_delete, safe_open
from pex.compatibility import commonpath
from pex.compatibility import commonpath, shlex_quote
from pex.dist_metadata import Distribution, MetadataType, Requirement, RequirementParseError
from pex.enum import Enum
from pex.interpreter import PythonInterpreter
Expand Down Expand Up @@ -1334,10 +1334,6 @@ def _update(self):

def _sync(self):
# type: () -> Result
if self.options.dry_run and any((self.options.venv, self.passthrough_args)):
return Error(
"Cannot update a venv or execute a command in it when performing a dry run."
)

requirement_configuration = requirement_options.configure(self.options)
resolver_configuration = cast(
Expand Down Expand Up @@ -1438,6 +1434,22 @@ def _sync(self):
if not sync_target:
return Ok()

if self.options.dry_run:
would_update_venv_msg = "Would sync venv at {venv}".format(
venv=sync_target.venv.venv_dir
)
if sync_target.command:
return Ok(
os.linesep.join(
(
would_update_venv_msg + " and run the following command in it:",
" " + " ".join(shlex_quote(arg) for arg in sync_target.command),
)
)
)
else:
return Ok(would_update_venv_msg + ".")

lock_file = try_(parse_lockfile(self.options, lock_file_path=lock_file_path))
target = LocalInterpreter.create(sync_target.venv.interpreter)
resolve_result = try_(
Expand Down
60 changes: 58 additions & 2 deletions tests/integration/cli/commands/test_lock_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from pex.resolve.resolved_requirement import Pin
from pex.typing import TYPE_CHECKING
from pex.venv.virtualenv import Virtualenv
from testing import IntegResults, re_exact
from testing import IntegResults, make_env, re_exact
from testing.cli import run_pex3
from testing.find_links import FindLinksRepo

Expand Down Expand Up @@ -659,7 +659,6 @@ def test_sync_venv_run(
), "We expect the initial venv to include Pip."
assert_cowsay5(venv)

lock = os.path.join(str(tmpdir), "lock.json")
result = run_sync(
*(
repo_args
Expand Down Expand Up @@ -695,6 +694,63 @@ def test_sync_venv_run(
)


def test_sync_venv_dry_run(
tmpdir, # type: Any
repo_args, # type: List[str]
path_mappings, # type: PathMappings
):
# type: (...) -> None

lock = os.path.join(str(tmpdir), "lock.json")
run_pex3("lock", "create", "cowsay==5.0", "-o", lock, *repo_args).assert_success()
locked_resolve = assert_lock(lock, path_mappings, expected_pins=[pin("cowsay", "5.0")])

venv_dir = os.path.join(str(tmpdir), "venv")
run_pex3("venv", "create", "-d", venv_dir, "--lock", lock, "--pip", *repo_args).assert_success()
venv = Virtualenv(venv_dir)
assert_cowsay5(venv)

run_sync(
*(
repo_args
+ [
"cowsay<6.1",
"--lock",
lock,
"--dry-run",
"--",
"cowsay",
"-t",
"I would have mooed!",
]
),
# Simulate an activated venv with its bin dir inserted n the PATH.
env=make_env(
PATH=os.pathsep.join(
[venv.bin_dir] + os.environ.get("PATH", os.defpath).split(os.pathsep)
)
)
).assert_success(
expected_output_re=re_exact(
dedent(
"""\
Updates for lock generated by {platform}:
Would update cowsay from 5 to 6
Updates to lock input requirements:
Would update 'cowsay==5.0' to 'cowsay<6.1'
Would sync venv at {venv_dir} and run the following command in it:
{cowsay} -t 'I would have mooed!'
"""
).format(
platform=locked_resolve.platform_tag,
venv_dir=venv_dir,
cowsay=venv.bin_path("cowsay"),
)
),
expected_error_re=NO_OUTPUT,
)


@skip_cowsay6_for_python27
def test_sync_venv_run_retain_pip(
tmpdir, # type: Any
Expand Down

0 comments on commit 812adc3

Please sign in to comment.