From dc705211b71ac2973d7c132e16af5c77e3dd3a18 Mon Sep 17 00:00:00 2001 From: Alexander Gherm Date: Sun, 20 Oct 2024 22:05:09 +0200 Subject: [PATCH 1/3] Modify pip list and tree to print to stdout regardless of the --quiet flag --- crates/uv/src/commands/pip/list.rs | 15 +++--- crates/uv/src/commands/project/tree.rs | 5 +- crates/uv/tests/it/pip_list.rs | 74 ++++++++++++++++++++++++++ crates/uv/tests/it/pip_tree.rs | 39 ++++++++++++++ 4 files changed, 122 insertions(+), 11 deletions(-) diff --git a/crates/uv/src/commands/pip/list.rs b/crates/uv/src/commands/pip/list.rs index 7401ed0a7268..ff4b52fc30b5 100644 --- a/crates/uv/src/commands/pip/list.rs +++ b/crates/uv/src/commands/pip/list.rs @@ -18,7 +18,7 @@ use uv_python::{EnvironmentPreference, PythonEnvironment}; use crate::commands::pip::operations::report_target_environment; use crate::commands::ExitStatus; -use crate::printer::Printer; +use crate::printer::{Printer, Stdout}; /// Enumerate the installed packages in the current environment. #[allow(clippy::fn_params_excessive_bools)] @@ -52,11 +52,13 @@ pub(crate) fn pip_list( .sorted_unstable_by(|a, b| a.name().cmp(b.name()).then(a.version().cmp(b.version()))) .collect_vec(); + // We force output to stdout specifically for `pip list` command (#8379) + let mut forced_stdout = Stdout::Enabled; match format { ListFormat::Json => { let rows = results.iter().copied().map(Entry::from).collect_vec(); let output = serde_json::to_string(&rows)?; - writeln!(printer.stdout(), "{output}")?; + writeln!(forced_stdout, "{output}")?; } ListFormat::Columns if results.is_empty() => {} ListFormat::Columns => { @@ -97,18 +99,13 @@ pub(crate) fn pip_list( } for elems in MultiZip(columns.iter().map(Column::fmt).collect_vec()) { - writeln!(printer.stdout(), "{}", elems.join(" ").trim_end())?; + writeln!(forced_stdout, "{}", elems.join(" ").trim_end())?; } } ListFormat::Freeze if results.is_empty() => {} ListFormat::Freeze => { for dist in &results { - writeln!( - printer.stdout(), - "{}=={}", - dist.name().bold(), - dist.version() - )?; + writeln!(forced_stdout, "{}=={}", dist.name().bold(), dist.version())?; } } } diff --git a/crates/uv/src/commands/project/tree.rs b/crates/uv/src/commands/project/tree.rs index 32063d4f4e43..893b0cfc889d 100644 --- a/crates/uv/src/commands/project/tree.rs +++ b/crates/uv/src/commands/project/tree.rs @@ -14,7 +14,7 @@ use crate::commands::pip::loggers::DefaultResolveLogger; use crate::commands::pip::resolution_markers; use crate::commands::project::ProjectInterpreter; use crate::commands::{project, ExitStatus, SharedState}; -use crate::printer::Printer; +use crate::printer::{Printer, Stdout}; use crate::settings::ResolverSettings; /// Run a command. @@ -100,7 +100,8 @@ pub(crate) async fn tree( invert, ); - write!(printer.stdout(), "{tree}")?; + // Making an exclusion specifically for tree subcommand (#8379) + write!(Stdout::Enabled, "{tree}")?; Ok(ExitStatus::Success) } diff --git a/crates/uv/tests/it/pip_list.rs b/crates/uv/tests/it/pip_list.rs index 5f749706b8a8..8152578c91a1 100644 --- a/crates/uv/tests/it/pip_list.rs +++ b/crates/uv/tests/it/pip_list.rs @@ -525,3 +525,77 @@ Version: 0.1-bulbasaur Ok(()) } + +#[test] +fn list_ignores_quiet_flag_format_freeze() { + let context = TestContext::new("3.12"); + + // Install the editable package. + uv_snapshot!(context.filters(), context + .pip_install() + .arg("-e") + .arg(context.workspace_root.join("scripts/packages/poetry_editable")), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 4 packages in [TIME] + Prepared 4 packages in [TIME] + Installed 4 packages in [TIME] + + anyio==4.3.0 + + idna==3.6 + + poetry-editable==0.1.0 (from file://[WORKSPACE]/scripts/packages/poetry_editable) + + sniffio==1.3.1 + "### + ); + + let filters = context + .filters() + .into_iter() + .chain(vec![(r"\-\-\-\-\-\-+.*", "[UNDERLINE]"), (" +", " ")]) + .collect::>(); + + uv_snapshot!(filters, context.pip_list() + .arg("--format=freeze") + .arg("--quiet"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + anyio==4.3.0 + idna==3.6 + poetry-editable==0.1.0 + sniffio==1.3.1 + + ----- stderr ----- + "### + ); + + uv_snapshot!(filters, context.pip_list() + .arg("--format=freeze") + .arg("--editable") + .arg("--quiet"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + poetry-editable==0.1.0 + + ----- stderr ----- + "### + ); + + uv_snapshot!(filters, context.pip_list() + .arg("--format=freeze") + .arg("--exclude-editable") + .arg("--quiet"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + anyio==4.3.0 + idna==3.6 + sniffio==1.3.1 + + ----- stderr ----- + "### + ); +} diff --git a/crates/uv/tests/it/pip_tree.rs b/crates/uv/tests/it/pip_tree.rs index b169a38cc651..038fa22e86be 100644 --- a/crates/uv/tests/it/pip_tree.rs +++ b/crates/uv/tests/it/pip_tree.rs @@ -1744,3 +1744,42 @@ fn show_version_specifiers_with_package() { "### ); } + +#[test] +fn print_output_even_with_quite_flag() { + let context = TestContext::new("3.12"); + + let requirements_txt = context.temp_dir.child("requirements.txt"); + requirements_txt.write_str("requests==2.31.0").unwrap(); + + uv_snapshot!(context + .pip_install() + .arg("-r") + .arg("requirements.txt") + .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 + "### + ); + + context.assert_command("import requests").success(); + uv_snapshot!(context.filters(), context.pip_tree().arg("--quiet"), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + "### + ); +} From 3b41ab0e9efc742a59c75309222935a6fd3a020a Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 20 Oct 2024 18:52:35 -0400 Subject: [PATCH 2/3] Inline --- crates/uv/src/commands/pip/list.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/uv/src/commands/pip/list.rs b/crates/uv/src/commands/pip/list.rs index ff4b52fc30b5..ff1c85da3c46 100644 --- a/crates/uv/src/commands/pip/list.rs +++ b/crates/uv/src/commands/pip/list.rs @@ -53,12 +53,11 @@ pub(crate) fn pip_list( .collect_vec(); // We force output to stdout specifically for `pip list` command (#8379) - let mut forced_stdout = Stdout::Enabled; match format { ListFormat::Json => { let rows = results.iter().copied().map(Entry::from).collect_vec(); let output = serde_json::to_string(&rows)?; - writeln!(forced_stdout, "{output}")?; + writeln!(Stdout::Enabled, "{output}")?; } ListFormat::Columns if results.is_empty() => {} ListFormat::Columns => { @@ -99,13 +98,18 @@ pub(crate) fn pip_list( } for elems in MultiZip(columns.iter().map(Column::fmt).collect_vec()) { - writeln!(forced_stdout, "{}", elems.join(" ").trim_end())?; + writeln!(Stdout::Enabled, "{}", elems.join(" ").trim_end())?; } } ListFormat::Freeze if results.is_empty() => {} ListFormat::Freeze => { for dist in &results { - writeln!(forced_stdout, "{}=={}", dist.name().bold(), dist.version())?; + writeln!( + Stdout::Enabled, + "{}=={}", + dist.name().bold(), + dist.version() + )?; } } } From 4dd57ef549623aa578099df3bfb464bbe205f6fc Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 20 Oct 2024 19:06:14 -0400 Subject: [PATCH 3/3] Fixtures --- crates/uv/src/commands/project/tree.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/uv/src/commands/project/tree.rs b/crates/uv/src/commands/project/tree.rs index 862266703b96..c767aca51fc7 100644 --- a/crates/uv/src/commands/project/tree.rs +++ b/crates/uv/src/commands/project/tree.rs @@ -1,6 +1,6 @@ use std::path::Path; -use anstream::println; +use anstream::print; use anyhow::Result; use uv_cache::Cache; @@ -101,7 +101,7 @@ pub(crate) async fn tree( invert, ); - println!("{tree}"); + print!("{tree}"); Ok(ExitStatus::Success) }