diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index 10b33772b..6096a0bab 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -7186,7 +7186,11 @@ pub struct WorkspaceDirArgs { } #[derive(Args, Debug)] -pub struct WorkspaceListArgs; +pub struct WorkspaceListArgs { + /// Show paths instead of names. + #[arg(long)] + pub paths: bool, +} /// See [PEP 517](https://peps.python.org/pep-0517/) and /// [PEP 660](https://peps.python.org/pep-0660/) for specifications of the parameters. diff --git a/crates/uv/src/commands/workspace/list.rs b/crates/uv/src/commands/workspace/list.rs index 4689d6f38..5ad074984 100644 --- a/crates/uv/src/commands/workspace/list.rs +++ b/crates/uv/src/commands/workspace/list.rs @@ -4,6 +4,7 @@ use std::path::Path; use anyhow::Result; use owo_colors::OwoColorize; +use uv_fs::Simplified; use uv_preview::{Preview, PreviewFeatures}; use uv_warnings::warn_user; use uv_workspace::{DiscoveryOptions, Workspace, WorkspaceCache}; @@ -14,6 +15,7 @@ use crate::printer::Printer; /// List workspace members pub(crate) async fn list( project_dir: &Path, + paths: bool, preview: Preview, printer: Printer, ) -> Result { @@ -28,8 +30,16 @@ pub(crate) async fn list( let workspace = Workspace::discover(project_dir, &DiscoveryOptions::default(), &workspace_cache).await?; - for name in workspace.packages().keys() { - writeln!(printer.stdout(), "{}", name.cyan())?; + for (name, member) in workspace.packages() { + if paths { + writeln!( + printer.stdout(), + "{}", + member.root().simplified_display().cyan() + )?; + } else { + writeln!(printer.stdout(), "{}", name.cyan())?; + } } Ok(ExitStatus::Success) diff --git a/crates/uv/src/lib.rs b/crates/uv/src/lib.rs index 84f6411a7..f6c93fa91 100644 --- a/crates/uv/src/lib.rs +++ b/crates/uv/src/lib.rs @@ -1746,8 +1746,8 @@ async fn run(mut cli: Cli) -> Result { WorkspaceCommand::Dir(args) => { commands::dir(args.package, &project_dir, globals.preview, printer).await } - WorkspaceCommand::List(_args) => { - commands::list(&project_dir, globals.preview, printer).await + WorkspaceCommand::List(args) => { + commands::list(&project_dir, args.paths, globals.preview, printer).await } }, Commands::BuildBackend { command } => spawn_blocking(move || match command { diff --git a/crates/uv/tests/it/workspace_list.rs b/crates/uv/tests/it/workspace_list.rs index 1bccac994..5716c286d 100644 --- a/crates/uv/tests/it/workspace_list.rs +++ b/crates/uv/tests/it/workspace_list.rs @@ -24,6 +24,17 @@ fn workspace_list_simple() { warning: The `uv workspace list` command is experimental and may change without warning. Pass `--preview-features workspace-list` to disable this warning. " ); + + uv_snapshot!(context.filters(), context.workspace_list().arg("--paths").current_dir(&workspace), @r" + success: true + exit_code: 0 + ----- stdout ----- + [TEMP_DIR]/foo + + ----- stderr ----- + warning: The `uv workspace list` command is experimental and may change without warning. Pass `--preview-features workspace-list` to disable this warning. + " + ); } /// Test list output for a root workspace (workspace with a root package). @@ -152,6 +163,19 @@ fn workspace_list_multiple_members() { warning: The `uv workspace list` command is experimental and may change without warning. Pass `--preview-features workspace-list` to disable this warning. " ); + + uv_snapshot!(context.filters(), context.workspace_list().arg("--paths").current_dir(&workspace_root), @r" + success: true + exit_code: 0 + ----- stdout ----- + [TEMP_DIR]/pkg-a + [TEMP_DIR]/pkg-a/pkg-b + [TEMP_DIR]/pkg-a/pkg-c + + ----- stderr ----- + warning: The `uv workspace list` command is experimental and may change without warning. Pass `--preview-features workspace-list` to disable this warning. + " + ); } /// Test list output for a single project (not a workspace).