Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
Signed-off-by: Kemal Akkoyun <kakkoyun@gmail.com>
  • Loading branch information
kakkoyun committed Sep 26, 2024
1 parent 405115f commit 4a765e6
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 78 deletions.
13 changes: 2 additions & 11 deletions crates/uv/src/commands/tool/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@ pub(crate) async fn list(
printer: Printer,
) -> Result<ExitStatus> {
let installed_tools = InstalledTools::from_settings()?;
let no_tools_installed_msg =
"No tools installed.\n\nSee `uv tool install --help` for more information.";
let _lock = match installed_tools.lock().await {
Ok(lock) => lock,
Err(uv_tool::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => {
writeln!(printer.stderr(), "{no_tools_installed_msg}")?;
writeln!(printer.stderr(), "No tools installed")?;
return Ok(ExitStatus::Success);
}
Err(err) => return Err(err.into()),
Expand All @@ -35,16 +33,10 @@ pub(crate) async fn list(
tools.sort_by_key(|(name, _)| name.clone());

if tools.is_empty() {
writeln!(printer.stderr(), "{no_tools_installed_msg}")?;
writeln!(printer.stderr(), "No tools installed")?;
return Ok(ExitStatus::Success);
}

writeln!(
printer.stdout(),
"Provide a command to invoke with `uvx <command>` or `uvx --from <package> <command>`.\n\n\
The following tools are already installed:\n"
)?;

for (name, tool) in tools {
// Skip invalid tools
let Ok(tool) = tool else {
Expand Down Expand Up @@ -107,6 +99,5 @@ pub(crate) async fn list(
}
}

writeln!(printer.stdout(), "\nSee `uvx --help` for more information.")?;
Ok(ExitStatus::Success)
}
80 changes: 75 additions & 5 deletions crates/uv/src/commands/tool/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ use crate::commands::pip::operations;
use crate::commands::project::{resolve_names, EnvironmentSpecification, ProjectError};
use crate::commands::reporters::PythonDownloadReporter;
use crate::commands::tool::Target;
use crate::commands::{
project::environment::CachedEnvironment, tool::common::matching_packages, tool_list,
};
use crate::commands::{project::environment::CachedEnvironment, tool::common::matching_packages};
use crate::commands::{ExitStatus, SharedState};
use crate::printer::Printer;
use crate::settings::ResolverInstallerSettings;
Expand Down Expand Up @@ -79,9 +77,10 @@ pub(crate) async fn run(
cache: Cache,
printer: Printer,
) -> anyhow::Result<ExitStatus> {
// treat empty command as `uv tool list`
// treat empty command similar to `uv tool list`, list available tools
// but without propagating malformed tool errors.
let Some(command) = command else {
return tool_list(false, false, &cache, printer).await;
return list_available_tools(invocation_source, &cache, printer).await;
};

let (target, args) = command.split();
Expand Down Expand Up @@ -262,6 +261,77 @@ fn get_entrypoints(
)?)
}

/// Display a list of tools that provide the executable.
///
/// If there is no package providing the executable, we will display a message to how to install a package.
async fn list_available_tools(
invocation_source: ToolRunCommand,
cache: &Cache,
printer: Printer,
) -> anyhow::Result<ExitStatus> {
writeln!(
printer.stdout(),
"Provide a command to invoke with `{invocation_source} <command>` \
or `{invocation_source} --from <package> <command>`.\n"
)?;

let installed_tools = InstalledTools::from_settings()?;
let no_tools_installed_msg =
"No tools installed. See `uv tool install --help` for more information.";
let _lock = match installed_tools.lock().await {
Ok(lock) => lock,
Err(uv_tool::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => {
writeln!(printer.stdout(), "{no_tools_installed_msg}")?;
return Ok(ExitStatus::Success);
}
Err(err) => return Err(err.into()),
};

let mut tools = installed_tools.tools()?.into_iter().collect::<Vec<_>>();
tools.sort_by_key(|(name, _)| name.clone());

if tools.is_empty() {
writeln!(printer.stdout(), "{no_tools_installed_msg}")?;
return Ok(ExitStatus::Success);
}

let mut buf = String::new();
for (name, tool) in tools {
// Skip invalid tools.
let Ok(tool) = tool else {
continue;
};

// Output tool name and version.
let Ok(version) = installed_tools.version(&name, cache) else {
continue;
};
writeln!(buf, "{}", format!("{name} v{version}").bold())?;

// Output tool entrypoints.
for entrypoint in tool.entrypoints() {
writeln!(buf, "- {}", entrypoint.name)?;
}
}

// Installed tools were malformed or failed fetching versions.
if buf.is_empty() {
writeln!(printer.stderr(), "{no_tools_installed_msg}")?;
return Ok(ExitStatus::Success);
}

writeln!(
printer.stdout(),
"The following tools are already installed:\n"
)?;
writeln!(printer.stdout(), "{buf}")?;
writeln!(
printer.stdout(),
"See `{invocation_source} --help` for more information."
)?;
Ok(ExitStatus::Success)
}

/// Display a warning if an executable is not provided by package.
///
/// If found in a dependency of the requested package instead of the requested package itself, we will hint to use that instead.
Expand Down
52 changes: 1 addition & 51 deletions crates/uv/tests/tool_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,10 @@ fn tool_list() {
success: true
exit_code: 0
----- stdout -----
Provide a command to invoke with `uvx <command>` or `uvx --from <package> <command>`.
The following tools are already installed:
black v24.2.0
- black
- blackd
See `uvx --help` for more information.
----- stderr -----
"###);
}
Expand All @@ -65,16 +59,10 @@ fn tool_list_paths() {
success: true
exit_code: 0
----- stdout -----
Provide a command to invoke with `uvx <command>` or `uvx --from <package> <command>`.
The following tools are already installed:
black v24.2.0 ([TEMP_DIR]/tools/black)
- black ([TEMP_DIR]/bin/black)
- blackd ([TEMP_DIR]/bin/blackd)
See `uvx --help` for more information.
----- stderr -----
"###);
}
Expand All @@ -93,9 +81,7 @@ fn tool_list_empty() {
----- stdout -----
----- stderr -----
No tools installed.
See `uv tool install --help` for more information.
No tools installed
"###);
}

Expand All @@ -122,12 +108,6 @@ fn tool_list_missing_receipt() {
success: true
exit_code: 0
----- stdout -----
Provide a command to invoke with `uvx <command>` or `uvx --from <package> <command>`.
The following tools are already installed:
See `uvx --help` for more information.
----- stderr -----
warning: Ignoring malformed tool `black` (run `uv tool uninstall black` to remove)
Expand Down Expand Up @@ -175,15 +155,9 @@ fn tool_list_bad_environment() -> Result<()> {
success: true
exit_code: 0
----- stdout -----
Provide a command to invoke with `uvx <command>` or `uvx --from <package> <command>`.
The following tools are already installed:
ruff v0.3.4
- ruff
See `uvx --help` for more information.
----- stderr -----
Invalid environment at `tools/black`: missing Python executable at `tools/black/[BIN]/python`
"###
Expand Down Expand Up @@ -244,16 +218,10 @@ fn tool_list_deprecated() -> Result<()> {
success: true
exit_code: 0
----- stdout -----
Provide a command to invoke with `uvx <command>` or `uvx --from <package> <command>`.
The following tools are already installed:
black v24.2.0
- black
- blackd
See `uvx --help` for more information.
----- stderr -----
"###);

Expand All @@ -277,12 +245,6 @@ fn tool_list_deprecated() -> Result<()> {
success: true
exit_code: 0
----- stdout -----
Provide a command to invoke with `uvx <command>` or `uvx --from <package> <command>`.
The following tools are already installed:
See `uvx --help` for more information.
----- stderr -----
warning: Ignoring malformed tool `black` (run `uv tool uninstall black` to remove)
Expand Down Expand Up @@ -312,16 +274,10 @@ fn tool_list_show_version_specifiers() {
success: true
exit_code: 0
----- stdout -----
Provide a command to invoke with `uvx <command>` or `uvx --from <package> <command>`.
The following tools are already installed:
black v24.2.0 [required: <24.3.0]
- black
- blackd
See `uvx --help` for more information.
----- stderr -----
"###);

Expand All @@ -332,16 +288,10 @@ fn tool_list_show_version_specifiers() {
success: true
exit_code: 0
----- stdout -----
Provide a command to invoke with `uvx <command>` or `uvx --from <package> <command>`.
The following tools are already installed:
black v24.2.0 [required: <24.3.0] ([TEMP_DIR]/tools/black)
- black ([TEMP_DIR]/bin/black)
- blackd ([TEMP_DIR]/bin/blackd)
See `uvx --help` for more information.
----- stderr -----
"###);
}
10 changes: 5 additions & 5 deletions crates/uv/tests/tool_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -753,11 +753,11 @@ fn tool_run_list_installed() {
success: true
exit_code: 0
----- stdout -----
Provide a command to invoke with `uv tool run <command>` or `uv tool run --from <package> <command>`.
----- stderr -----
No tools installed.
No tools installed. See `uv tool install --help` for more information.
See `uv tool install --help` for more information.
----- stderr -----
"###);

// Install `black`.
Expand All @@ -776,15 +776,15 @@ fn tool_run_list_installed() {
success: true
exit_code: 0
----- stdout -----
Provide a command to invoke with `uvx <command>` or `uvx --from <package> <command>`.
Provide a command to invoke with `uv tool run <command>` or `uv tool run --from <package> <command>`.
The following tools are already installed:
black v24.2.0
- black
- blackd
See `uvx --help` for more information.
See `uv tool run --help` for more information.
----- stderr -----
"###);
Expand Down
8 changes: 2 additions & 6 deletions crates/uv/tests/tool_uninstall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ fn tool_uninstall() {
----- stdout -----
----- stderr -----
No tools installed.
See `uv tool install --help` for more information.
No tools installed
"###);

// After uninstalling the tool, we should be able to reinstall it.
Expand Down Expand Up @@ -113,9 +111,7 @@ fn tool_uninstall_multiple_names() {
----- stdout -----
----- stderr -----
No tools installed.
See `uv tool install --help` for more information.
No tools installed
"###);
}

Expand Down

0 comments on commit 4a765e6

Please sign in to comment.