From bcc52ed108f32686e7299b46bc5ec9d11cebb9a6 Mon Sep 17 00:00:00 2001 From: Jo <10510431+j178@users.noreply.github.com> Date: Mon, 21 Oct 2024 00:13:41 +0800 Subject: [PATCH] Add `uv pip show --files` (#8369) ## Summary Resolves #8357 --- crates/uv-cli/src/lib.rs | 4 ++ crates/uv/src/commands/pip/show.rs | 13 ++++++ crates/uv/src/lib.rs | 1 + crates/uv/src/settings.rs | 3 ++ crates/uv/tests/it/pip_show.rs | 66 ++++++++++++++++++++++++++++++ docs/reference/cli.md | 2 + 6 files changed, 89 insertions(+) diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index fb8681130..865a04f6a 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -2005,6 +2005,10 @@ pub struct PipShowArgs { #[arg(long, overrides_with("strict"), hide = true)] pub no_strict: bool, + /// Show the full list of installed files for each package. + #[arg(short, long)] + pub files: bool, + /// The Python interpreter to find the package in. /// /// By default, uv looks for packages in a virtual environment but will look diff --git a/crates/uv/src/commands/pip/show.rs b/crates/uv/src/commands/pip/show.rs index 7c1f249c1..6afc9aa3a 100644 --- a/crates/uv/src/commands/pip/show.rs +++ b/crates/uv/src/commands/pip/show.rs @@ -1,6 +1,7 @@ use std::fmt::Write; use anyhow::Result; +use fs_err::File; use itertools::{Either, Itertools}; use owo_colors::OwoColorize; use rustc_hash::FxHashMap; @@ -8,6 +9,7 @@ use rustc_hash::FxHashMap; use uv_cache::Cache; use uv_distribution_types::{Diagnostic, Name}; use uv_fs::Simplified; +use uv_install_wheel::read_record_file; use uv_installer::SitePackages; use uv_normalize::PackageName; use uv_python::{EnvironmentPreference, PythonEnvironment, PythonRequest}; @@ -22,6 +24,7 @@ pub(crate) fn pip_show( strict: bool, python: Option<&str>, system: bool, + files: bool, cache: &Cache, printer: Printer, ) -> Result { @@ -184,6 +187,16 @@ pub(crate) fn pip_show( )?; } } + + // If requests, show the list of installed files. + if files { + let path = distribution.path().join("RECORD"); + let record = read_record_file(&mut File::open(path)?)?; + writeln!(printer.stdout(), "Files:")?; + for entry in record { + writeln!(printer.stdout(), " {}", entry.path)?; + } + } } // Validate that the environment is consistent. diff --git a/crates/uv/src/lib.rs b/crates/uv/src/lib.rs index 37f975543..590051ce6 100644 --- a/crates/uv/src/lib.rs +++ b/crates/uv/src/lib.rs @@ -624,6 +624,7 @@ async fn run(mut cli: Cli) -> Result { args.settings.strict, args.settings.python.as_deref(), args.settings.system, + args.files, &cache, printer, ) diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index 829173f26..1b7d57088 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -1628,6 +1628,7 @@ impl PipListSettings { #[derive(Debug, Clone)] pub(crate) struct PipShowSettings { pub(crate) package: Vec, + pub(crate) files: bool, pub(crate) settings: PipSettings, } @@ -1638,6 +1639,7 @@ impl PipShowSettings { package, strict, no_strict, + files, python, system, no_system, @@ -1646,6 +1648,7 @@ impl PipShowSettings { Self { package, + files, settings: PipSettings::combine( PipOptions { python: python.and_then(Maybe::into_option), diff --git a/crates/uv/tests/it/pip_show.rs b/crates/uv/tests/it/pip_show.rs index 0d0931f9b..31b4c02cb 100644 --- a/crates/uv/tests/it/pip_show.rs +++ b/crates/uv/tests/it/pip_show.rs @@ -458,3 +458,69 @@ fn show_required_by_multiple() -> Result<()> { Ok(()) } + +#[test] +fn show_files() { + let context = TestContext::new("3.12"); + + uv_snapshot!(context + .pip_install() + .arg("requests==2.31.0") + .arg("--strict"), @r#" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 5 packages in [TIME] + Prepared 5 packages in [TIME] + Installed 5 packages in [TIME] + + certifi==2024.2.2 + + charset-normalizer==3.3.2 + + idna==3.6 + + requests==2.31.0 + + urllib3==2.2.1 + "# + ); + + // Windows has a different files order. + #[cfg(not(windows))] + uv_snapshot!(context.filters(), context.pip_show().arg("requests").arg("--files"), @r#" + success: true + exit_code: 0 + ----- stdout ----- + Name: requests + Version: 2.31.0 + Location: [SITE_PACKAGES]/ + Requires: certifi, charset-normalizer, idna, urllib3 + Required-by: + Files: + requests-2.31.0.dist-info/INSTALLER + requests-2.31.0.dist-info/LICENSE + requests-2.31.0.dist-info/METADATA + requests-2.31.0.dist-info/RECORD + requests-2.31.0.dist-info/REQUESTED + requests-2.31.0.dist-info/WHEEL + requests-2.31.0.dist-info/top_level.txt + requests/__init__.py + requests/__version__.py + requests/_internal_utils.py + requests/adapters.py + requests/api.py + requests/auth.py + requests/certs.py + requests/compat.py + requests/cookies.py + requests/exceptions.py + requests/help.py + requests/hooks.py + requests/models.py + requests/packages.py + requests/sessions.py + requests/status_codes.py + requests/structures.py + requests/utils.py + + ----- stderr ----- + "#); +} diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 59591b572..143e2d5e5 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -6440,6 +6440,8 @@ uv pip show [OPTIONS] [PACKAGE]...

See --project to only change the project root directory.

+
--files, -f

Show the full list of installed files for each package

+
--help, -h

Display the concise help for this command

--native-tls

Whether to load TLS certificates from the platform’s native certificate store.