mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Allow uv
crate to be used as a library (#4642)
This is pulled out of #4632 — a user noted that it would be useful to use the `uv` crate from Rust. This makes it way easier to invoke `uv` from Rust with arbitrary arguments as well as use various functionality in the `uv` crate. Note this is no longer needed for #4632 and is not particularly urgent.
This commit is contained in:
parent
e0fae8e6f4
commit
c14de2a92a
2 changed files with 93 additions and 72 deletions
7
crates/uv/src/bin/uv.rs
Normal file
7
crates/uv/src/bin/uv.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
use std::process::ExitCode;
|
||||||
|
|
||||||
|
use uv::main as uv_main;
|
||||||
|
|
||||||
|
fn main() -> ExitCode {
|
||||||
|
uv_main(std::env::args_os())
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::ffi::OsString;
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
use std::io::stdout;
|
use std::io::stdout;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -48,76 +49,15 @@ static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
|
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
|
||||||
|
|
||||||
mod commands;
|
pub(crate) mod commands;
|
||||||
mod logging;
|
pub(crate) mod logging;
|
||||||
mod printer;
|
pub(crate) mod printer;
|
||||||
mod settings;
|
pub(crate) mod settings;
|
||||||
mod shell;
|
pub(crate) mod shell;
|
||||||
mod version;
|
pub(crate) mod version;
|
||||||
|
|
||||||
#[instrument]
|
|
||||||
async fn run() -> Result<ExitStatus> {
|
|
||||||
let cli = match Cli::try_parse() {
|
|
||||||
Ok(cli) => cli,
|
|
||||||
Err(mut err) => {
|
|
||||||
if let Some(ContextValue::String(subcommand)) = err.get(ContextKind::InvalidSubcommand)
|
|
||||||
{
|
|
||||||
match subcommand.as_str() {
|
|
||||||
"compile" | "lock" => {
|
|
||||||
err.insert(
|
|
||||||
ContextKind::SuggestedSubcommand,
|
|
||||||
ContextValue::String("uv pip compile".to_string()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"sync" => {
|
|
||||||
err.insert(
|
|
||||||
ContextKind::SuggestedSubcommand,
|
|
||||||
ContextValue::String("uv pip sync".to_string()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"install" | "add" => {
|
|
||||||
err.insert(
|
|
||||||
ContextKind::SuggestedSubcommand,
|
|
||||||
ContextValue::String("uv pip install".to_string()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"uninstall" | "remove" => {
|
|
||||||
err.insert(
|
|
||||||
ContextKind::SuggestedSubcommand,
|
|
||||||
ContextValue::String("uv pip uninstall".to_string()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"freeze" => {
|
|
||||||
err.insert(
|
|
||||||
ContextKind::SuggestedSubcommand,
|
|
||||||
ContextValue::String("uv pip freeze".to_string()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"list" => {
|
|
||||||
err.insert(
|
|
||||||
ContextKind::SuggestedSubcommand,
|
|
||||||
ContextValue::String("uv pip list".to_string()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"show" => {
|
|
||||||
err.insert(
|
|
||||||
ContextKind::SuggestedSubcommand,
|
|
||||||
ContextValue::String("uv pip show".to_string()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
"tree" => {
|
|
||||||
err.insert(
|
|
||||||
ContextKind::SuggestedSubcommand,
|
|
||||||
ContextValue::String("uv pip tree".to_string()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err.exit()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
#[instrument(skip_all)]
|
||||||
|
async fn run(cli: Cli) -> Result<ExitStatus> {
|
||||||
// enable flag to pick up warnings generated by workspace loading.
|
// enable flag to pick up warnings generated by workspace loading.
|
||||||
if !cli.global_args.quiet {
|
if !cli.global_args.quiet {
|
||||||
uv_warnings::enable();
|
uv_warnings::enable();
|
||||||
|
@ -1030,7 +970,81 @@ async fn run_project(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> ExitCode {
|
/// The main entry point for a uv invocation.
|
||||||
|
///
|
||||||
|
/// WARNING: This entry point is not recommended for external consumption, the
|
||||||
|
/// `uv` binary interface is the official public API. When using this entry
|
||||||
|
/// point, uv assumes it is running in a process it controls and that the
|
||||||
|
/// entire process lifetime is managed by uv. Unexpected behavior may be
|
||||||
|
/// encountered if this entry pointis called multiple times in a single process.
|
||||||
|
pub fn main<I, T>(args: I) -> ExitCode
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = T>,
|
||||||
|
T: Into<OsString> + Clone,
|
||||||
|
{
|
||||||
|
// `std::env::args` is not `Send` so we parse before passing to our runtime
|
||||||
|
// https://github.com/rust-lang/rust/pull/48005
|
||||||
|
let cli = match Cli::try_parse_from(args) {
|
||||||
|
Ok(cli) => cli,
|
||||||
|
Err(mut err) => {
|
||||||
|
if let Some(ContextValue::String(subcommand)) = err.get(ContextKind::InvalidSubcommand)
|
||||||
|
{
|
||||||
|
match subcommand.as_str() {
|
||||||
|
"compile" | "lock" => {
|
||||||
|
err.insert(
|
||||||
|
ContextKind::SuggestedSubcommand,
|
||||||
|
ContextValue::String("uv pip compile".to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"sync" => {
|
||||||
|
err.insert(
|
||||||
|
ContextKind::SuggestedSubcommand,
|
||||||
|
ContextValue::String("uv pip sync".to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"install" | "add" => {
|
||||||
|
err.insert(
|
||||||
|
ContextKind::SuggestedSubcommand,
|
||||||
|
ContextValue::String("uv pip install".to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"uninstall" | "remove" => {
|
||||||
|
err.insert(
|
||||||
|
ContextKind::SuggestedSubcommand,
|
||||||
|
ContextValue::String("uv pip uninstall".to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"freeze" => {
|
||||||
|
err.insert(
|
||||||
|
ContextKind::SuggestedSubcommand,
|
||||||
|
ContextValue::String("uv pip freeze".to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"list" => {
|
||||||
|
err.insert(
|
||||||
|
ContextKind::SuggestedSubcommand,
|
||||||
|
ContextValue::String("uv pip list".to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"show" => {
|
||||||
|
err.insert(
|
||||||
|
ContextKind::SuggestedSubcommand,
|
||||||
|
ContextValue::String("uv pip show".to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
"tree" => {
|
||||||
|
err.insert(
|
||||||
|
ContextKind::SuggestedSubcommand,
|
||||||
|
ContextValue::String("uv pip tree".to_string()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err.exit()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Windows has a default stack size of 1MB, which is lower than the linux and mac default.
|
// Windows has a default stack size of 1MB, which is lower than the linux and mac default.
|
||||||
// https://learn.microsoft.com/en-us/cpp/build/reference/stack-stack-allocations?view=msvc-170
|
// https://learn.microsoft.com/en-us/cpp/build/reference/stack-stack-allocations?view=msvc-170
|
||||||
// We support increasing the stack size to avoid stack overflows in debug mode on Windows. In
|
// We support increasing the stack size to avoid stack overflows in debug mode on Windows. In
|
||||||
|
@ -1045,7 +1059,7 @@ fn main() -> ExitCode {
|
||||||
.build()
|
.build()
|
||||||
.expect("Failed building the Runtime");
|
.expect("Failed building the Runtime");
|
||||||
// Box the large main future to avoid stack overflows.
|
// Box the large main future to avoid stack overflows.
|
||||||
let result = runtime.block_on(Box::pin(run()));
|
let result = runtime.block_on(Box::pin(run(cli)));
|
||||||
// Avoid waiting for pending tasks to complete.
|
// Avoid waiting for pending tasks to complete.
|
||||||
//
|
//
|
||||||
// The resolver may have kicked off HTTP requests during resolution that
|
// The resolver may have kicked off HTTP requests during resolution that
|
||||||
|
@ -1066,7 +1080,7 @@ fn main() -> ExitCode {
|
||||||
.build()
|
.build()
|
||||||
.expect("Failed building the Runtime");
|
.expect("Failed building the Runtime");
|
||||||
// Box the large main future to avoid stack overflows.
|
// Box the large main future to avoid stack overflows.
|
||||||
let result = runtime.block_on(Box::pin(run()));
|
let result = runtime.block_on(Box::pin(run(cli)));
|
||||||
runtime.shutdown_background();
|
runtime.shutdown_background();
|
||||||
result
|
result
|
||||||
};
|
};
|
Loading…
Add table
Add a link
Reference in a new issue