use std::env;
use std::io::Write;
use std::path::PathBuf;
use std::str::FromStr;
use uv_preview::Preview;
use uv_static::{EnvVars, parse_boolish_environment_variable};
use anyhow::{Context, Result, bail};
use tracing::debug;
use tracing_subscriber::filter::LevelFilter;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{EnvFilter, Layer};
use uv_logging::UvFormat;
fn main() -> Result<()> {
let filter = EnvFilter::builder()
.with_default_directive(LevelFilter::OFF.into())
.from_env()
.context("Invalid RUST_LOG directives")?;
let stderr_layer = tracing_subscriber::fmt::layer()
.event_format(UvFormat::default())
.with_writer(std::sync::Mutex::new(anstream::stderr()))
.with_filter(filter);
tracing_subscriber::registry().with(stderr_layer).init();
let mut args = env::args_os();
args.next();
let command = args
.next()
.context("Missing command")?
.to_str()
.context("Invalid non-UTF8 command")?
.to_string();
let preview = if parse_boolish_environment_variable(EnvVars::UV_PREVIEW)?.unwrap_or(false) {
Preview::all()
} else if let Some(preview_features) = env::var_os(EnvVars::UV_PREVIEW_FEATURES) {
let preview_features = preview_features
.to_str()
.with_context(|| format!("Invalid UTF-8 in `{}`", EnvVars::UV_PREVIEW_FEATURES))?;
Preview::from_str(preview_features).with_context(|| {
format!(
"Invalid preview features list in `{}`",
EnvVars::UV_PREVIEW_FEATURES
)
})?
} else {
Preview::default()
};
if preview.all_enabled() {
debug!("All preview features are enabled");
} else if preview.any_enabled() {
debug!("The following preview features are enabled: {preview}");
}
uv_preview::set(preview)
.expect("Global preview features should not have been initialised already");
uv_preview::finalize().unwrap();
match command.as_str() {
"build-sdist" => {
let sdist_directory = PathBuf::from(args.next().context("Missing sdist directory")?);
let filename = uv_build_backend::build_source_dist(
&env::current_dir()?,
&sdist_directory,
uv_version::version(),
false,
)?;
writeln!(&mut std::io::stdout(), "{filename}").context("stdout is closed")?;
}
"build-wheel" => {
let wheel_directory = PathBuf::from(args.next().context("Missing wheel directory")?);
let metadata_directory = args.next().map(PathBuf::from);
let filename = uv_build_backend::build_wheel(
&env::current_dir()?,
&wheel_directory,
metadata_directory.as_deref(),
uv_version::version(),
false,
)?;
writeln!(&mut std::io::stdout(), "{filename}").context("stdout is closed")?;
}
"build-editable" => {
let wheel_directory = PathBuf::from(args.next().context("Missing wheel directory")?);
let metadata_directory = args.next().map(PathBuf::from);
let filename = uv_build_backend::build_editable(
&env::current_dir()?,
&wheel_directory,
metadata_directory.as_deref(),
uv_version::version(),
false,
)?;
writeln!(&mut std::io::stdout(), "{filename}").context("stdout is closed")?;
}
"prepare-metadata-for-build-wheel" => {
let wheel_directory = PathBuf::from(args.next().context("Missing wheel directory")?);
let filename = uv_build_backend::metadata(
&env::current_dir()?,
&wheel_directory,
uv_version::version(),
)?;
writeln!(&mut std::io::stdout(), "{filename}").context("stdout is closed")?;
}
"prepare-metadata-for-build-editable" => {
let wheel_directory = PathBuf::from(args.next().context("Missing wheel directory")?);
let filename = uv_build_backend::metadata(
&env::current_dir()?,
&wheel_directory,
uv_version::version(),
)?;
writeln!(&mut std::io::stdout(), "{filename}").context("stdout is closed")?;
}
"--help" => {
writeln!(
&mut std::io::stderr(),
"uv_build contains only the PEP 517 build backend for uv and can't be used on the CLI. \
Use `uv build` or another build frontend instead."
).context("stdout is closed")?;
}
unknown => {
bail!(
"Unknown subcommand: {} (cli: {:?})",
unknown,
env::args_os()
);
}
}
Ok(())
}