Add uv tool dir --bin to show executable directory (#5160)
## Summary Closes https://github.com/astral-sh/uv/issues/5159.
This commit is contained in:
@@ -2067,7 +2067,7 @@ pub enum ToolCommand {
|
||||
#[command(alias = "ensurepath")]
|
||||
UpdateShell,
|
||||
/// Show the tools directory.
|
||||
Dir,
|
||||
Dir(ToolDirArgs),
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
@@ -2168,6 +2168,17 @@ pub struct ToolInstallArgs {
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct ToolListArgs;
|
||||
|
||||
#[derive(Args)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct ToolDirArgs {
|
||||
/// Show the directory into which `uv tool` will install executables.
|
||||
///
|
||||
/// By default, `uv tool dir` shows the directory into which the tool Python environments
|
||||
/// themselves are installed, rather than the directory containing the linked executables.
|
||||
#[arg(long, alias = "executable")]
|
||||
pub bin: bool,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct ToolUninstallArgs {
|
||||
|
||||
@@ -3,16 +3,23 @@ use owo_colors::OwoColorize;
|
||||
|
||||
use uv_configuration::PreviewMode;
|
||||
use uv_fs::Simplified;
|
||||
use uv_tool::InstalledTools;
|
||||
use uv_tool::{find_executable_directory, InstalledTools};
|
||||
use uv_warnings::warn_user_once;
|
||||
|
||||
/// Show the tool directory.
|
||||
pub(crate) fn dir(preview: PreviewMode) -> anyhow::Result<()> {
|
||||
pub(crate) fn dir(bin: bool, 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());
|
||||
|
||||
if bin {
|
||||
let executable_directory = find_executable_directory()?;
|
||||
anstream::println!("{}", executable_directory.simplified_display().cyan());
|
||||
} else {
|
||||
let installed_tools =
|
||||
InstalledTools::from_settings().context("Failed to initialize tools settings")?;
|
||||
anstream::println!("{}", installed_tools.root().simplified_display().cyan());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -689,9 +689,13 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
|
||||
Ok(ExitStatus::Success)
|
||||
}
|
||||
Commands::Tool(ToolNamespace {
|
||||
command: ToolCommand::Dir,
|
||||
command: ToolCommand::Dir(args),
|
||||
}) => {
|
||||
commands::tool_dir(globals.preview)?;
|
||||
// Resolve the settings from the command-line arguments and workspace configuration.
|
||||
let args = settings::ToolDirSettings::resolve(args, filesystem);
|
||||
show_settings!(args);
|
||||
|
||||
commands::tool_dir(args.bin, globals.preview)?;
|
||||
Ok(ExitStatus::Success)
|
||||
}
|
||||
Commands::Python(PythonNamespace {
|
||||
|
||||
@@ -14,8 +14,8 @@ use uv_cli::{
|
||||
AddArgs, ColorChoice, Commands, ExternalCommand, GlobalArgs, ListFormat, LockArgs, Maybe,
|
||||
PipCheckArgs, PipCompileArgs, PipFreezeArgs, PipInstallArgs, PipListArgs, PipShowArgs,
|
||||
PipSyncArgs, PipTreeArgs, PipUninstallArgs, PythonFindArgs, PythonInstallArgs, PythonListArgs,
|
||||
PythonPinArgs, PythonUninstallArgs, RemoveArgs, RunArgs, SyncArgs, ToolInstallArgs,
|
||||
ToolListArgs, ToolRunArgs, ToolUninstallArgs, TreeArgs, VenvArgs,
|
||||
PythonPinArgs, PythonUninstallArgs, RemoveArgs, RunArgs, SyncArgs, ToolDirArgs,
|
||||
ToolInstallArgs, ToolListArgs, ToolRunArgs, ToolUninstallArgs, TreeArgs, VenvArgs,
|
||||
};
|
||||
use uv_client::Connectivity;
|
||||
use uv_configuration::{
|
||||
@@ -316,6 +316,23 @@ impl ToolUninstallSettings {
|
||||
}
|
||||
}
|
||||
|
||||
/// The resolved settings to use for a `tool dir` invocation.
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct ToolDirSettings {
|
||||
pub(crate) bin: bool,
|
||||
}
|
||||
|
||||
impl ToolDirSettings {
|
||||
/// Resolve the [`ToolDirSettings`] from the CLI and filesystem configuration.
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub(crate) fn resolve(args: ToolDirArgs, _filesystem: Option<FilesystemOptions>) -> Self {
|
||||
let ToolDirArgs { bin } = args;
|
||||
|
||||
Self { bin }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub(crate) enum PythonListKinds {
|
||||
#[default]
|
||||
|
||||
@@ -24,3 +24,22 @@ fn tool_dir() {
|
||||
warning: `uv tool dir` is experimental and may change without warning.
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tool_dir_bin() {
|
||||
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().arg("--bin")
|
||||
.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]/bin
|
||||
|
||||
----- stderr -----
|
||||
warning: `uv tool dir` is experimental and may change without warning.
|
||||
"###);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user