mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-03 18:38:21 +00:00
Filter uv tree
to current platform by default (#5763)
## Summary `uv tree` will now filter to the current platform by default. You can pass `--universal` to show the entire tree. Closes https://github.com/astral-sh/uv/issues/5760.
This commit is contained in:
parent
865f9eeef7
commit
3156fccc85
7 changed files with 64 additions and 15 deletions
|
@ -1709,6 +1709,10 @@ pub struct PipShowArgs {
|
|||
#[derive(Args)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct PipTreeArgs {
|
||||
/// Show the version constraint(s) imposed on each package.
|
||||
#[arg(long)]
|
||||
pub show_version_specifiers: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
pub tree: DisplayTreeArgs,
|
||||
|
||||
|
@ -2344,6 +2348,11 @@ pub struct RemoveArgs {
|
|||
#[derive(Args)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct TreeArgs {
|
||||
/// Show the resolved package versions for all Python versions and platforms, rather than
|
||||
/// filtering to those that are relevant for the current environment.
|
||||
#[arg(long)]
|
||||
pub universal: bool,
|
||||
|
||||
#[command(flatten)]
|
||||
pub tree: DisplayTreeArgs,
|
||||
|
||||
|
@ -3054,8 +3063,4 @@ pub struct DisplayTreeArgs {
|
|||
/// Show the reverse dependencies for the given package. This flag will invert the tree and display the packages that depend on the given package.
|
||||
#[arg(long, alias = "reverse")]
|
||||
pub invert: bool,
|
||||
|
||||
/// Show the version constraint(s) imposed on each package.
|
||||
#[arg(long)]
|
||||
pub show_version_specifiers: bool,
|
||||
}
|
||||
|
|
|
@ -2650,6 +2650,7 @@ impl<'env> TreeDisplay<'env> {
|
|||
/// Create a new [`DisplayDependencyGraph`] for the set of installed distributions.
|
||||
pub fn new(
|
||||
lock: &'env Lock,
|
||||
markers: Option<&'env MarkerEnvironment>,
|
||||
depth: usize,
|
||||
prune: Vec<PackageName>,
|
||||
package: Vec<PackageName>,
|
||||
|
@ -2676,6 +2677,15 @@ impl<'env> TreeDisplay<'env> {
|
|||
// Mark the dependency as a non-root node.
|
||||
non_roots.insert(child);
|
||||
|
||||
// Skip dependencies that don't apply to the current environment.
|
||||
if let Some(environment_markers) = markers {
|
||||
if let Some(dependency_markers) = dependency.marker.as_ref() {
|
||||
if !dependency_markers.evaluate(environment_markers, &[]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
edges.entry(parent).or_default().push(child);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,12 +24,12 @@ use crate::printer::Printer;
|
|||
/// Display the installed packages in the current environment as a dependency tree.
|
||||
#[allow(clippy::fn_params_excessive_bools)]
|
||||
pub(crate) fn pip_tree(
|
||||
show_version_specifiers: bool,
|
||||
depth: u8,
|
||||
prune: Vec<PackageName>,
|
||||
package: Vec<PackageName>,
|
||||
no_dedupe: bool,
|
||||
invert: bool,
|
||||
show_version_specifiers: bool,
|
||||
strict: bool,
|
||||
python: Option<&str>,
|
||||
system: bool,
|
||||
|
|
|
@ -24,6 +24,7 @@ use super::SharedState;
|
|||
pub(crate) async fn tree(
|
||||
locked: bool,
|
||||
frozen: bool,
|
||||
universal: bool,
|
||||
depth: u8,
|
||||
prune: Vec<PackageName>,
|
||||
package: Vec<PackageName>,
|
||||
|
@ -79,7 +80,15 @@ pub(crate) async fn tree(
|
|||
.await?;
|
||||
|
||||
// Render the tree.
|
||||
let tree = TreeDisplay::new(&lock.lock, depth.into(), prune, package, no_dedupe, invert);
|
||||
let tree = TreeDisplay::new(
|
||||
&lock.lock,
|
||||
(!universal).then(|| interpreter.markers()),
|
||||
depth.into(),
|
||||
prune,
|
||||
package,
|
||||
no_dedupe,
|
||||
invert,
|
||||
);
|
||||
|
||||
write!(printer.stdout(), "{tree}")?;
|
||||
|
||||
|
|
|
@ -562,12 +562,12 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
|
|||
let cache = cache.init()?;
|
||||
|
||||
commands::pip_tree(
|
||||
args.show_version_specifiers,
|
||||
args.depth,
|
||||
args.prune,
|
||||
args.package,
|
||||
args.no_dedupe,
|
||||
args.invert,
|
||||
args.show_version_specifiers,
|
||||
args.shared.strict,
|
||||
args.shared.python.as_deref(),
|
||||
args.shared.system,
|
||||
|
@ -1121,6 +1121,7 @@ async fn run_project(
|
|||
commands::tree(
|
||||
args.locked,
|
||||
args.frozen,
|
||||
args.universal,
|
||||
args.depth,
|
||||
args.prune,
|
||||
args.package,
|
||||
|
|
|
@ -769,6 +769,7 @@ impl RemoveSettings {
|
|||
pub(crate) struct TreeSettings {
|
||||
pub(crate) locked: bool,
|
||||
pub(crate) frozen: bool,
|
||||
pub(crate) universal: bool,
|
||||
pub(crate) depth: u8,
|
||||
pub(crate) prune: Vec<PackageName>,
|
||||
pub(crate) package: Vec<PackageName>,
|
||||
|
@ -783,6 +784,7 @@ impl TreeSettings {
|
|||
pub(crate) fn resolve(args: TreeArgs, filesystem: Option<FilesystemOptions>) -> Self {
|
||||
let TreeArgs {
|
||||
tree,
|
||||
universal,
|
||||
locked,
|
||||
frozen,
|
||||
build,
|
||||
|
@ -793,6 +795,7 @@ impl TreeSettings {
|
|||
Self {
|
||||
locked,
|
||||
frozen,
|
||||
universal,
|
||||
depth: tree.depth,
|
||||
prune: tree.prune,
|
||||
package: tree.package,
|
||||
|
@ -1357,12 +1360,12 @@ impl PipShowSettings {
|
|||
#[allow(clippy::struct_excessive_bools)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct PipTreeSettings {
|
||||
pub(crate) show_version_specifiers: bool,
|
||||
pub(crate) depth: u8,
|
||||
pub(crate) prune: Vec<PackageName>,
|
||||
pub(crate) package: Vec<PackageName>,
|
||||
pub(crate) no_dedupe: bool,
|
||||
pub(crate) invert: bool,
|
||||
pub(crate) show_version_specifiers: bool,
|
||||
// CLI-only settings.
|
||||
pub(crate) shared: PipSettings,
|
||||
}
|
||||
|
@ -1371,6 +1374,7 @@ impl PipTreeSettings {
|
|||
/// Resolve the [`PipTreeSettings`] from the CLI and workspace configuration.
|
||||
pub(crate) fn resolve(args: PipTreeArgs, filesystem: Option<FilesystemOptions>) -> Self {
|
||||
let PipTreeArgs {
|
||||
show_version_specifiers,
|
||||
tree,
|
||||
strict,
|
||||
no_strict,
|
||||
|
@ -1381,11 +1385,11 @@ impl PipTreeSettings {
|
|||
} = args;
|
||||
|
||||
Self {
|
||||
show_version_specifiers,
|
||||
depth: tree.depth,
|
||||
prune: tree.prune,
|
||||
no_dedupe: tree.no_dedupe,
|
||||
invert: tree.invert,
|
||||
show_version_specifiers: tree.show_version_specifiers,
|
||||
package: tree.package,
|
||||
// Shared settings.
|
||||
shared: PipSettings::combine(
|
||||
|
|
|
@ -26,7 +26,7 @@ fn nested_dependencies() -> Result<()> {
|
|||
"#,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.tree(), @r###"
|
||||
uv_snapshot!(context.filters(), context.tree().arg("--universal"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
@ -132,7 +132,7 @@ fn frozen() -> Result<()> {
|
|||
"#,
|
||||
)?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.tree(), @r###"
|
||||
uv_snapshot!(context.filters(), context.tree().arg("--universal"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
@ -200,12 +200,31 @@ fn platform_dependencies() -> Result<()> {
|
|||
"#,
|
||||
)?;
|
||||
|
||||
// Should include `colorama`, even though it's only included on Windows.
|
||||
// When `--universal` is _not_ provided, `colorama` should _not_ be included.
|
||||
#[cfg(not(windows))]
|
||||
uv_snapshot!(context.filters(), context.tree(), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
project v0.1.0
|
||||
└── black v24.3.0
|
||||
├── click v8.1.7
|
||||
├── mypy-extensions v1.0.0
|
||||
├── packaging v24.0
|
||||
├── pathspec v0.12.1
|
||||
└── platformdirs v4.2.0
|
||||
|
||||
----- stderr -----
|
||||
warning: `uv tree` is experimental and may change without warning
|
||||
Resolved 8 packages in [TIME]
|
||||
"###);
|
||||
|
||||
// Should include `colorama`, even though it's only included on Windows.
|
||||
uv_snapshot!(context.filters(), context.tree().arg("--universal"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
project v0.1.0
|
||||
└── black v24.3.0
|
||||
├── click v8.1.7
|
||||
│ └── colorama v0.4.6
|
||||
|
@ -247,7 +266,7 @@ fn repeated_dependencies() -> Result<()> {
|
|||
)?;
|
||||
|
||||
// Should include both versions of `anyio`, which have different dependencies.
|
||||
uv_snapshot!(context.filters(), context.tree(), @r###"
|
||||
uv_snapshot!(context.filters(), context.tree().arg("--universal"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
@ -321,7 +340,7 @@ fn repeated_version() -> Result<()> {
|
|||
Url::from_file_path(context.temp_dir.join("v2")).unwrap(),
|
||||
})?;
|
||||
|
||||
uv_snapshot!(context.filters(), context.tree(), @r###"
|
||||
uv_snapshot!(context.filters(), context.tree().arg("--universal"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
@ -361,13 +380,14 @@ fn dev_dependencies() -> Result<()> {
|
|||
# ...
|
||||
requires-python = ">=3.12"
|
||||
dependencies = ["iniconfig"]
|
||||
|
||||
[tool.uv]
|
||||
dev-dependencies = ["anyio"]
|
||||
"#,
|
||||
)?;
|
||||
|
||||
// Dev dependencies should be omitted.
|
||||
uv_snapshot!(context.filters(), context.tree(), @r###"
|
||||
uv_snapshot!(context.filters(), context.tree().arg("--universal"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue