From 081f092781568a4fcc01ac1c0447dddebb9f4478 Mon Sep 17 00:00:00 2001 From: Ahmed Ilyas Date: Mon, 1 Jul 2024 16:51:59 +0200 Subject: [PATCH] Add `tool dir` and `toolchain dir` commands (#4695) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Resolves #4483 Resolves #4484 ## Test Plan `cargo test` ```sh ❯ cargo run -- toolchain dir warning: `uv toolchain dir` is experimental and may change without warning. /Users/ahmedilyas/Library/Application Support/uv/toolchains ❯ cargo run -- tool dir warning: `uv tool dir` is experimental and may change without warning. /Users/ahmedilyas/Library/Application Support/uv/tools ``` --- crates/uv-cli/src/lib.rs | 5 +++++ crates/uv/src/commands/cache_dir.rs | 2 +- crates/uv/src/commands/mod.rs | 2 ++ crates/uv/src/commands/tool/dir.rs | 17 +++++++++++++++++ crates/uv/src/commands/tool/mod.rs | 1 + crates/uv/src/commands/toolchain/dir.rs | 20 ++++++++++++++++++++ crates/uv/src/commands/toolchain/mod.rs | 1 + crates/uv/src/main.rs | 12 ++++++++++++ crates/uv/tests/common/mod.rs | 16 ++++++++++++++++ crates/uv/tests/tool_dir.rs | 25 +++++++++++++++++++++++++ crates/uv/tests/toolchain_dir.rs | 23 +++++++++++++++++++++++ 11 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 crates/uv/src/commands/tool/dir.rs create mode 100644 crates/uv/src/commands/toolchain/dir.rs create mode 100644 crates/uv/tests/tool_dir.rs create mode 100644 crates/uv/tests/toolchain_dir.rs diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index 96f65a6f2346..fd0db6a8a63b 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -1889,6 +1889,8 @@ pub enum ToolCommand { List(ToolListArgs), /// Uninstall a tool. Uninstall(ToolUninstallArgs), + /// Show the tools directory. + Dir, } #[derive(Args)] @@ -2013,6 +2015,9 @@ pub enum ToolchainCommand { /// Search for a toolchain #[command(disable_version_flag = true)] Find(ToolchainFindArgs), + + /// Show the toolchains directory. + Dir, } #[derive(Args)] diff --git a/crates/uv/src/commands/cache_dir.rs b/crates/uv/src/commands/cache_dir.rs index 6347ec314a95..2ff7977339a2 100644 --- a/crates/uv/src/commands/cache_dir.rs +++ b/crates/uv/src/commands/cache_dir.rs @@ -4,5 +4,5 @@ use uv_fs::Simplified; /// Show the cache directory. pub(crate) fn cache_dir(cache: &Cache) { - anstream::println!("{}", cache.root().user_display().cyan()); + anstream::println!("{}", cache.root().simplified_display().cyan()); } diff --git a/crates/uv/src/commands/mod.rs b/crates/uv/src/commands/mod.rs index 56cca196e2e8..9e454b47c465 100644 --- a/crates/uv/src/commands/mod.rs +++ b/crates/uv/src/commands/mod.rs @@ -24,10 +24,12 @@ pub(crate) use project::run::run; pub(crate) use project::sync::sync; #[cfg(feature = "self-update")] pub(crate) use self_update::self_update; +pub(crate) use tool::dir::dir as tool_dir; pub(crate) use tool::install::install as tool_install; pub(crate) use tool::list::list as tool_list; pub(crate) use tool::run::run as tool_run; pub(crate) use tool::uninstall::uninstall as tool_uninstall; +pub(crate) use toolchain::dir::dir as toolchain_dir; pub(crate) use toolchain::find::find as toolchain_find; pub(crate) use toolchain::install::install as toolchain_install; pub(crate) use toolchain::list::list as toolchain_list; diff --git a/crates/uv/src/commands/tool/dir.rs b/crates/uv/src/commands/tool/dir.rs new file mode 100644 index 000000000000..72396f833aa4 --- /dev/null +++ b/crates/uv/src/commands/tool/dir.rs @@ -0,0 +1,17 @@ +use anyhow::Context; +use owo_colors::OwoColorize; +use uv_configuration::PreviewMode; +use uv_fs::Simplified; +use uv_tool::InstalledTools; +use uv_warnings::warn_user_once; + +/// Show the tool directory. +pub(crate) fn dir(preview: PreviewMode) -> anyhow::Result<()> { + if preview.is_disabled() { + warn_user_once!("`uv tool dir` is experimental and may change without warning."); + } + let installed_tools = + InstalledTools::from_settings().context("Failed to initialize tools settings")?; + anstream::println!("{}", installed_tools.root().simplified_display().cyan()); + Ok(()) +} diff --git a/crates/uv/src/commands/tool/mod.rs b/crates/uv/src/commands/tool/mod.rs index 1939e48896d6..987798216477 100644 --- a/crates/uv/src/commands/tool/mod.rs +++ b/crates/uv/src/commands/tool/mod.rs @@ -1,3 +1,4 @@ +pub(crate) mod dir; pub(crate) mod install; pub(crate) mod list; pub(crate) mod run; diff --git a/crates/uv/src/commands/toolchain/dir.rs b/crates/uv/src/commands/toolchain/dir.rs new file mode 100644 index 000000000000..c716896a4beb --- /dev/null +++ b/crates/uv/src/commands/toolchain/dir.rs @@ -0,0 +1,20 @@ +use anyhow::Context; +use owo_colors::OwoColorize; +use uv_configuration::PreviewMode; +use uv_fs::Simplified; +use uv_toolchain::managed::InstalledToolchains; +use uv_warnings::warn_user_once; + +/// Show the toolchain directory. +pub(crate) fn dir(preview: PreviewMode) -> anyhow::Result<()> { + if preview.is_disabled() { + warn_user_once!("`uv toolchain dir` is experimental and may change without warning."); + } + let installed_toolchains = + InstalledToolchains::from_settings().context("Failed to initialize toolchain settings")?; + anstream::println!( + "{}", + installed_toolchains.root().simplified_display().cyan() + ); + Ok(()) +} diff --git a/crates/uv/src/commands/toolchain/mod.rs b/crates/uv/src/commands/toolchain/mod.rs index 772c9c26e96f..370274394837 100644 --- a/crates/uv/src/commands/toolchain/mod.rs +++ b/crates/uv/src/commands/toolchain/mod.rs @@ -1,3 +1,4 @@ +pub(crate) mod dir; pub(crate) mod find; pub(crate) mod install; pub(crate) mod list; diff --git a/crates/uv/src/main.rs b/crates/uv/src/main.rs index 1254cb7cfdd9..d4fdd0d858ed 100644 --- a/crates/uv/src/main.rs +++ b/crates/uv/src/main.rs @@ -847,6 +847,12 @@ async fn run() -> Result { commands::tool_uninstall(args.name, globals.preview, printer).await } + Commands::Tool(ToolNamespace { + command: ToolCommand::Dir, + }) => { + commands::tool_dir(globals.preview)?; + Ok(ExitStatus::Success) + } Commands::Toolchain(ToolchainNamespace { command: ToolchainCommand::List(args), }) => { @@ -907,6 +913,12 @@ async fn run() -> Result { ) .await } + Commands::Toolchain(ToolchainNamespace { + command: ToolchainCommand::Dir, + }) => { + commands::toolchain_dir(globals.preview)?; + Ok(ExitStatus::Success) + } } } diff --git a/crates/uv/tests/common/mod.rs b/crates/uv/tests/common/mod.rs index 99096807aa4d..c78d6cc880db 100644 --- a/crates/uv/tests/common/mod.rs +++ b/crates/uv/tests/common/mod.rs @@ -376,6 +376,14 @@ impl TestContext { command } + /// Create a `uv toolchain dir` command with options shared across scenarios. + pub fn toolchain_dir(&self) -> Command { + let mut command = Command::new(get_bin()); + command.arg("toolchain").arg("dir"); + self.add_shared_args(&mut command); + command + } + /// Create a `uv run` command with options shared across scenarios. pub fn run(&self) -> Command { let mut command = Command::new(get_bin()); @@ -420,6 +428,14 @@ impl TestContext { command } + /// Create a `uv tool dir` command with options shared across scenarios. + pub fn tool_dir(&self) -> Command { + let mut command = Command::new(get_bin()); + command.arg("tool").arg("dir"); + self.add_shared_args(&mut command); + command + } + /// Create a `uv tool uninstall` command with options shared across scenarios. pub fn tool_uninstall(&self) -> std::process::Command { let mut command = std::process::Command::new(get_bin()); diff --git a/crates/uv/tests/tool_dir.rs b/crates/uv/tests/tool_dir.rs new file mode 100644 index 000000000000..eb72ca314d51 --- /dev/null +++ b/crates/uv/tests/tool_dir.rs @@ -0,0 +1,25 @@ +#![cfg(all(feature = "python", feature = "pypi"))] + +use assert_fs::fixture::PathChild; +use common::{uv_snapshot, TestContext}; + +mod common; + +#[test] +fn tool_dir() { + let context = TestContext::new("3.12"); + let tool_dir = context.temp_dir.child("tools"); + let bin_dir = context.temp_dir.child("bin"); + + uv_snapshot!(context.filters(), context.tool_dir() + .env("UV_TOOL_DIR", tool_dir.as_os_str()) + .env("XDG_BIN_HOME", bin_dir.as_os_str()), @r###" + success: true + exit_code: 0 + ----- stdout ----- + [TEMP_DIR]/tools + + ----- stderr ----- + warning: `uv tool dir` is experimental and may change without warning. + "###); +} diff --git a/crates/uv/tests/toolchain_dir.rs b/crates/uv/tests/toolchain_dir.rs new file mode 100644 index 000000000000..b2c8773570bd --- /dev/null +++ b/crates/uv/tests/toolchain_dir.rs @@ -0,0 +1,23 @@ +#![cfg(all(feature = "python", feature = "pypi"))] + +use assert_fs::fixture::PathChild; +use common::{uv_snapshot, TestContext}; + +mod common; + +#[test] +fn toolchain_dir() { + let context = TestContext::new("3.12"); + + let toolchain_dir = context.temp_dir.child("toolchains"); + uv_snapshot!(context.filters(), context.toolchain_dir() + .env("UV_TOOLCHAIN_DIR", toolchain_dir.as_os_str()), @r###" + success: true + exit_code: 0 + ----- stdout ----- + [TEMP_DIR]/toolchains + + ----- stderr ----- + warning: `uv toolchain dir` is experimental and may change without warning. + "###); +}