mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Move venv command to miette (#162)
This commit is contained in:
parent
370771b28c
commit
9bcc7fe77a
7 changed files with 62 additions and 19 deletions
|
@ -38,11 +38,11 @@ enum AddError {
|
||||||
InvalidRequirement(String, #[source] pep508_rs::Pep508Error),
|
InvalidRequirement(String, #[source] pep508_rs::Pep508Error),
|
||||||
|
|
||||||
#[error("Failed to parse `pyproject.toml` at: `{0}`")]
|
#[error("Failed to parse `pyproject.toml` at: `{0}`")]
|
||||||
#[diagnostic(code(puffin::add::parse_error))]
|
#[diagnostic(code(puffin::add::parse))]
|
||||||
ParseError(PathBuf, #[source] WorkspaceError),
|
ParseError(PathBuf, #[source] WorkspaceError),
|
||||||
|
|
||||||
#[error("Failed to write `pyproject.toml` to: `{0}`")]
|
#[error("Failed to write `pyproject.toml` to: `{0}`")]
|
||||||
#[diagnostic(code(puffin::add::write_error))]
|
#[diagnostic(code(puffin::add::write))]
|
||||||
WriteError(PathBuf, #[source] WorkspaceError),
|
WriteError(PathBuf, #[source] WorkspaceError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,15 +34,15 @@ enum RemoveError {
|
||||||
WorkspaceNotFound,
|
WorkspaceNotFound,
|
||||||
|
|
||||||
#[error("Failed to parse `pyproject.toml` at: `{0}`")]
|
#[error("Failed to parse `pyproject.toml` at: `{0}`")]
|
||||||
#[diagnostic(code(puffin::remove::parse_error))]
|
#[diagnostic(code(puffin::remove::parse))]
|
||||||
ParseError(PathBuf, #[source] WorkspaceError),
|
ParseError(PathBuf, #[source] WorkspaceError),
|
||||||
|
|
||||||
#[error("Failed to write `pyproject.toml` to: `{0}`")]
|
#[error("Failed to write `pyproject.toml` to: `{0}`")]
|
||||||
#[diagnostic(code(puffin::remove::write_error))]
|
#[diagnostic(code(puffin::remove::write))]
|
||||||
WriteError(PathBuf, #[source] WorkspaceError),
|
WriteError(PathBuf, #[source] WorkspaceError),
|
||||||
|
|
||||||
#[error("Failed to remove `{0}` from `pyproject.toml`")]
|
#[error("Failed to remove `{0}` from `pyproject.toml`")]
|
||||||
#[diagnostic(code(puffin::remove::parse_error))]
|
#[diagnostic(code(puffin::remove::parse))]
|
||||||
RemovalError(String, #[source] WorkspaceError),
|
RemovalError(String, #[source] WorkspaceError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,43 +3,86 @@ use std::path::Path;
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use fs_err::tokio as fs;
|
use fs_err as fs;
|
||||||
|
use miette::{Diagnostic, IntoDiagnostic};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::commands::ExitStatus;
|
use crate::commands::ExitStatus;
|
||||||
use crate::printer::Printer;
|
use crate::printer::Printer;
|
||||||
|
|
||||||
/// Create a virtual environment.
|
/// Create a virtual environment.
|
||||||
pub(crate) async fn venv(
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
|
pub(crate) fn venv(
|
||||||
|
path: &Path,
|
||||||
|
base_python: Option<&Path>,
|
||||||
|
printer: Printer,
|
||||||
|
) -> Result<ExitStatus> {
|
||||||
|
match venv_impl(path, base_python, printer) {
|
||||||
|
Ok(status) => Ok(status),
|
||||||
|
Err(err) => {
|
||||||
|
#[allow(clippy::print_stderr)]
|
||||||
|
{
|
||||||
|
eprint!("{err:?}");
|
||||||
|
}
|
||||||
|
Ok(ExitStatus::Failure)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Error, Debug, Diagnostic)]
|
||||||
|
enum VenvError {
|
||||||
|
#[error("Unable to find a Python interpreter")]
|
||||||
|
#[diagnostic(code(puffin::venv::python_not_found))]
|
||||||
|
PythonNotFound,
|
||||||
|
|
||||||
|
#[error("Failed to extract Python interpreter info")]
|
||||||
|
#[diagnostic(code(puffin::venv::interpreter))]
|
||||||
|
InterpreterError(#[source] gourgeist::Error),
|
||||||
|
|
||||||
|
#[error("Failed to create virtual environment")]
|
||||||
|
#[diagnostic(code(puffin::venv::creation))]
|
||||||
|
CreationError(#[source] gourgeist::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a virtual environment.
|
||||||
|
fn venv_impl(
|
||||||
path: &Path,
|
path: &Path,
|
||||||
base_python: Option<&Path>,
|
base_python: Option<&Path>,
|
||||||
mut printer: Printer,
|
mut printer: Printer,
|
||||||
) -> Result<ExitStatus> {
|
) -> miette::Result<ExitStatus> {
|
||||||
// Locate the Python interpreter.
|
// Locate the Python interpreter.
|
||||||
// TODO(charlie): Look at how Maturin discovers and ranks all the available Python interpreters.
|
// TODO(charlie): Look at how Maturin discovers and ranks all the available Python interpreters.
|
||||||
let base_python = if let Some(base_python) = base_python {
|
let base_python = if let Some(base_python) = base_python {
|
||||||
base_python.to_path_buf()
|
base_python.to_path_buf()
|
||||||
} else {
|
} else {
|
||||||
which::which("python3").or_else(|_| which::which("python"))?
|
which::which("python3")
|
||||||
|
.or_else(|_| which::which("python"))
|
||||||
|
.map_err(|_| VenvError::PythonNotFound)?
|
||||||
};
|
};
|
||||||
let interpreter_info = gourgeist::get_interpreter_info(&base_python)?;
|
let interpreter_info =
|
||||||
|
gourgeist::get_interpreter_info(&base_python).map_err(VenvError::InterpreterError)?;
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
printer,
|
printer,
|
||||||
"Using Python interpreter: {}",
|
"Using Python interpreter: {}",
|
||||||
format!("{}", base_python.display()).cyan()
|
format!("{}", base_python.display()).cyan()
|
||||||
)?;
|
)
|
||||||
|
.into_diagnostic()?;
|
||||||
|
|
||||||
// If the path already exists, remove it.
|
// If the path already exists, remove it.
|
||||||
fs::remove_file(path).await.ok();
|
fs::remove_file(path).ok();
|
||||||
fs::remove_dir_all(path).await.ok();
|
fs::remove_dir_all(path).ok();
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
printer,
|
printer,
|
||||||
"Creating virtual environment at: {}",
|
"Creating virtual environment at: {}",
|
||||||
format!("{}", path.display()).cyan()
|
format!("{}", path.display()).cyan()
|
||||||
)?;
|
)
|
||||||
|
.into_diagnostic()?;
|
||||||
|
|
||||||
// Create the virtual environment.
|
// Create the virtual environment.
|
||||||
gourgeist::create_venv(path, &base_python, &interpreter_info, true)?;
|
gourgeist::create_venv(path, &base_python, &interpreter_info, true)
|
||||||
|
.map_err(VenvError::CreationError)?;
|
||||||
|
|
||||||
Ok(ExitStatus::Success)
|
Ok(ExitStatus::Success)
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,7 @@ async fn main() -> ExitCode {
|
||||||
}
|
}
|
||||||
Commands::Clean => commands::clean(cache_dir, printer),
|
Commands::Clean => commands::clean(cache_dir, printer),
|
||||||
Commands::Freeze => commands::freeze(cache_dir, printer),
|
Commands::Freeze => commands::freeze(cache_dir, printer),
|
||||||
Commands::Venv(args) => commands::venv(&args.name, args.python.as_deref(), printer).await,
|
Commands::Venv(args) => commands::venv(&args.name, args.python.as_deref(), printer),
|
||||||
Commands::Add(args) => commands::add(&args.name, printer),
|
Commands::Add(args) => commands::add(&args.name, printer),
|
||||||
Commands::Remove(args) => commands::remove(&args.name, printer),
|
Commands::Remove(args) => commands::remove(&args.name, printer),
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,7 +11,7 @@ exit_code: 1
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
puffin::remove::parse_error
|
puffin::remove::parse
|
||||||
|
|
||||||
× Failed to remove `flask` from `pyproject.toml`
|
× Failed to remove `flask` from `pyproject.toml`
|
||||||
╰─▶ no `[project.dependencies]` array found in `pyproject.toml`
|
╰─▶ no `[project.dependencies]` array found in `pyproject.toml`
|
||||||
|
|
|
@ -11,7 +11,7 @@ exit_code: 1
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
puffin::remove::parse_error
|
puffin::remove::parse
|
||||||
|
|
||||||
× Failed to remove `requests` from `pyproject.toml`
|
× Failed to remove `requests` from `pyproject.toml`
|
||||||
╰─▶ unable to find package: `requests`
|
╰─▶ unable to find package: `requests`
|
||||||
|
|
|
@ -11,7 +11,7 @@ exit_code: 1
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
puffin::remove::parse_error
|
puffin::remove::parse
|
||||||
|
|
||||||
× Failed to remove `flask` from `pyproject.toml`
|
× Failed to remove `flask` from `pyproject.toml`
|
||||||
╰─▶ no `[project]` table found in `pyproject.toml`
|
╰─▶ no `[project]` table found in `pyproject.toml`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue