Skip to content

Commit

Permalink
Merge pull request #11096 from sbidoul/install-dry-run-sbi
Browse files Browse the repository at this point in the history
Add --dry-run option to pip install
  • Loading branch information
sbidoul authored Jun 26, 2022
2 parents 25dd005 + 701a5d6 commit 65680b4
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 1 deletion.
2 changes: 2 additions & 0 deletions news/11096.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Add ``--dry-run`` option to ``pip install``, to let it print what it would install but
not actually change anything in the target environment.
23 changes: 23 additions & 0 deletions src/pip/_internal/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ def add_options(self) -> None:
self.cmd_opts.add_option(cmdoptions.pre())

self.cmd_opts.add_option(cmdoptions.editable())
self.cmd_opts.add_option(
"--dry-run",
action="store_true",
dest="dry_run",
default=False,
help=(
"Don't actually install anything, just print what would be. "
"Can be used in combination with --ignore-installed "
"to 'resolve' the requirements."
),
)
self.cmd_opts.add_option(
"-t",
"--target",
Expand Down Expand Up @@ -342,6 +353,18 @@ def run(self, options: Values, args: List[str]) -> int:
reqs, check_supported_wheels=not options.target_dir
)

if options.dry_run:
would_install_items = sorted(
(r.metadata["name"], r.metadata["version"])
for r in requirement_set.requirements_to_install
)
if would_install_items:
write_output(
"Would install %s",
" ".join("-".join(item) for item in would_install_items),
)
return SUCCESS

try:
pip_req = requirement_set.get_requirement("pip")
except KeyError:
Expand Down
13 changes: 12 additions & 1 deletion src/pip/_internal/req/req_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
BaseDistribution,
get_default_environment,
get_directory_distribution,
get_wheel_distribution,
)
from pip._internal.metadata.base import FilesystemWheel
from pip._internal.models.direct_url import DirectUrl
from pip._internal.models.link import Link
from pip._internal.operations.build.metadata import generate_metadata
Expand Down Expand Up @@ -558,7 +560,16 @@ def metadata(self) -> Any:
return self._metadata

def get_dist(self) -> BaseDistribution:
return get_directory_distribution(self.metadata_directory)
if self.metadata_directory:
return get_directory_distribution(self.metadata_directory)
elif self.local_file_path and self.is_wheel:
return get_wheel_distribution(
FilesystemWheel(self.local_file_path), canonicalize_name(self.name)
)
raise AssertionError(
f"InstallRequirement {self} has no metadata directory and no wheel: "
f"can't make a distribution."
)

def assert_source_matches_version(self) -> None:
assert self.source_dir
Expand Down
13 changes: 13 additions & 0 deletions src/pip/_internal/req/req_set.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,16 @@ def get_requirement(self, name: str) -> InstallRequirement:
@property
def all_requirements(self) -> List[InstallRequirement]:
return self.unnamed_requirements + list(self.requirements.values())

@property
def requirements_to_install(self) -> List[InstallRequirement]:
"""Return the list of requirements that need to be installed.
TODO remove this property together with the legacy resolver, since the new
resolver only returns requirements that need to be installed.
"""
return [
install_req
for install_req in self.all_requirements
if not install_req.constraint and not install_req.satisfied_by
]
9 changes: 9 additions & 0 deletions tests/functional/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -2238,3 +2238,12 @@ def test_install_logs_pip_version_in_debug(
result = script.pip("install", "-v", fake_package)
pattern = "Using pip .* from .*"
assert_re_match(pattern, result.stdout)


def test_install_dry_run(script: PipTestEnvironment, data: TestData) -> None:
"""Test that pip install --dry-run logs what it would install."""
result = script.pip(
"install", "--dry-run", "--find-links", data.find_links, "simple"
)
assert "Would install simple-3.0" in result.stdout
assert "Successfully installed" not in result.stdout

0 comments on commit 65680b4

Please sign in to comment.