Add some rustdoc to pip tree (#4615)

This commit is contained in:
Charlie Marsh 2024-06-28 09:39:40 -04:00 committed by GitHub
parent b3b4b47394
commit 14564f97c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,8 +1,9 @@
use std::fmt::Write;
use distribution_types::{Diagnostic, InstalledDist, Name}; use distribution_types::{Diagnostic, InstalledDist, Name};
use owo_colors::OwoColorize; use owo_colors::OwoColorize;
use pep508_rs::MarkerEnvironment; use pep508_rs::MarkerEnvironment;
use pypi_types::VerbatimParsedUrl;
use std::collections::{HashMap, HashSet};
use std::fmt::Write;
use tracing::debug; use tracing::debug;
use uv_cache::Cache; use uv_cache::Cache;
use uv_configuration::PreviewMode; use uv_configuration::PreviewMode;
@ -15,9 +16,6 @@ use uv_toolchain::ToolchainRequest;
use crate::commands::ExitStatus; use crate::commands::ExitStatus;
use crate::printer::Printer; use crate::printer::Printer;
use std::collections::{HashMap, HashSet};
use pypi_types::VerbatimParsedUrl;
/// Display the installed packages in the current environment as a dependency tree. /// Display the installed packages in the current environment as a dependency tree.
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
@ -84,21 +82,25 @@ pub(crate) fn pip_tree(
Ok(ExitStatus::Success) Ok(ExitStatus::Success)
} }
// Filter out all required packages of the given distribution if they /// Filter out all required packages of the given distribution if they
// are required by an extra. /// are required by an extra.
// For example, `requests==2.32.3` requires `charset-normalizer`, `idna`, `urllib`, and `certifi` at ///
// all times, `PySocks` on `socks` extra and `chardet` on `use_chardet_on_py3` extra. /// For example, `requests==2.32.3` requires `charset-normalizer`, `idna`, `urllib`, and `certifi` at
// This function will return `["charset-normalizer", "idna", "urllib", "certifi"]` for `requests`. /// all times, `PySocks` on `socks` extra and `chardet` on `use_chardet_on_py3` extra.
/// This function will return `["charset-normalizer", "idna", "urllib", "certifi"]` for `requests`.
fn required_with_no_extra( fn required_with_no_extra(
dist: &InstalledDist, dist: &InstalledDist,
marker_environment: &MarkerEnvironment, markers: &MarkerEnvironment,
) -> Vec<pep508_rs::Requirement<VerbatimParsedUrl>> { ) -> Vec<pep508_rs::Requirement<VerbatimParsedUrl>> {
let metadata = dist.metadata().unwrap(); let metadata = dist.metadata().unwrap();
return metadata return metadata
.requires_dist .requires_dist
.into_iter() .into_iter()
.filter(|r| { .filter(|requirement| {
r.marker.is_none() || r.marker.as_ref().unwrap().evaluate(marker_environment, &[]) requirement
.marker
.as_ref()
.map_or(true, |m| m.evaluate(markers, &[]))
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
} }
@ -106,24 +108,20 @@ fn required_with_no_extra(
#[derive(Debug)] #[derive(Debug)]
struct DisplayDependencyGraph<'a> { struct DisplayDependencyGraph<'a> {
site_packages: &'a SitePackages, site_packages: &'a SitePackages,
// Map from package name to the installed distribution. /// Map from package name to the installed distribution.
dist_by_package_name: HashMap<&'a PackageName, &'a InstalledDist>, dist_by_package_name: HashMap<&'a PackageName, &'a InstalledDist>,
// Set of package names that are required by at least one installed distribution. /// Set of package names that are required by at least one installed distribution.
// It is used to determine the starting nodes when recursing the /// It is used to determine the starting nodes when recursing the
// dependency graph. /// dependency graph.
required_packages: HashSet<PackageName>, required_packages: HashSet<PackageName>,
/// Maximum display depth of the dependency tree
// Maximum display depth of the dependency tree
depth: usize, depth: usize,
/// Prune the given package from the display of the dependency tree.
// Prune the given package from the display of the dependency tree.
prune: Vec<PackageName>, prune: Vec<PackageName>,
/// Whether to de-duplicate the displayed dependencies.
// Whether to de-duplicate the displayed dependencies.
no_dedupe: bool, no_dedupe: bool,
/// The marker environment for the current interpreter.
// The marker environment for the current interpreter. markers: &'a MarkerEnvironment,
marker_environment: &'a MarkerEnvironment,
} }
impl<'a> DisplayDependencyGraph<'a> { impl<'a> DisplayDependencyGraph<'a> {
@ -133,7 +131,7 @@ impl<'a> DisplayDependencyGraph<'a> {
depth: usize, depth: usize,
prune: Vec<PackageName>, prune: Vec<PackageName>,
no_dedupe: bool, no_dedupe: bool,
marker_environment: &'a MarkerEnvironment, markers: &'a MarkerEnvironment,
) -> DisplayDependencyGraph<'a> { ) -> DisplayDependencyGraph<'a> {
let mut dist_by_package_name = HashMap::new(); let mut dist_by_package_name = HashMap::new();
let mut required_packages = HashSet::new(); let mut required_packages = HashSet::new();
@ -141,7 +139,7 @@ impl<'a> DisplayDependencyGraph<'a> {
dist_by_package_name.insert(site_package.name(), site_package); dist_by_package_name.insert(site_package.name(), site_package);
} }
for site_package in site_packages.iter() { for site_package in site_packages.iter() {
for required in required_with_no_extra(site_package, marker_environment) { for required in required_with_no_extra(site_package, markers) {
required_packages.insert(required.name.clone()); required_packages.insert(required.name.clone());
} }
} }
@ -153,11 +151,11 @@ impl<'a> DisplayDependencyGraph<'a> {
depth, depth,
prune, prune,
no_dedupe, no_dedupe,
marker_environment, markers,
} }
} }
// Depth-first traversal of the given distribution and its dependencies. /// Perform a depth-first traversal of the given distribution and its dependencies.
fn visit( fn visit(
&self, &self,
installed_dist: &InstalledDist, installed_dist: &InstalledDist,
@ -192,7 +190,7 @@ impl<'a> DisplayDependencyGraph<'a> {
path.push(package_name.clone()); path.push(package_name.clone());
visited.insert(package_name.clone()); visited.insert(package_name.clone());
let required_packages = required_with_no_extra(installed_dist, self.marker_environment); let required_packages = required_with_no_extra(installed_dist, self.markers);
for (index, required_package) in required_packages.iter().enumerate() { for (index, required_package) in required_packages.iter().enumerate() {
// Skip if the current package is not one of the installed distributions. // Skip if the current package is not one of the installed distributions.
if !self if !self