mirror of https://github.com/astral-sh/uv
Build backend: Add template to uv init (#9661)
Add a preview option `uv init --build-backend uv --preview` that uses the uv build backend when generating the project. The uv build backend is in preview, so the option is also guarded by preview and hidden from the help message and docs. For https://github.com/astral-sh/uv/issues/3957#issuecomment-2518757563
This commit is contained in:
parent
77df01f4bf
commit
dc82a84841
|
|
@ -4,6 +4,10 @@
|
|||
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
|
||||
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
|
||||
pub enum ProjectBuildBackend {
|
||||
#[cfg_attr(feature = "clap", value(hide = true))]
|
||||
#[cfg_attr(feature = "schemars", value(hide = true))]
|
||||
/// Use uv as the project build backend.
|
||||
Uv,
|
||||
#[default]
|
||||
#[serde(alias = "hatchling")]
|
||||
#[cfg_attr(feature = "clap", value(alias = "hatchling"))]
|
||||
|
|
|
|||
|
|
@ -315,6 +315,7 @@ fn emit_possible_options(opt: &clap::Arg, output: &mut String) {
|
|||
"\nPossible values:\n{}",
|
||||
values
|
||||
.into_iter()
|
||||
.filter(|value| !value.is_hide_set())
|
||||
.map(|value| {
|
||||
let name = value.get_name();
|
||||
value.get_help().map_or_else(
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
use anyhow::{anyhow, Context, Result};
|
||||
use owo_colors::OwoColorize;
|
||||
use std::fmt::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use owo_colors::OwoColorize;
|
||||
use std::str::FromStr;
|
||||
|
||||
use tracing::{debug, warn};
|
||||
use uv_cache::Cache;
|
||||
use uv_cli::AuthorFrom;
|
||||
use uv_client::{BaseClientBuilder, Connectivity};
|
||||
use uv_configuration::{
|
||||
ProjectBuildBackend, TrustedHost, VersionControlError, VersionControlSystem,
|
||||
PreviewMode, ProjectBuildBackend, TrustedHost, VersionControlError, VersionControlSystem,
|
||||
};
|
||||
use uv_fs::{Simplified, CWD};
|
||||
use uv_git::GIT;
|
||||
|
|
@ -57,7 +57,11 @@ pub(crate) async fn init(
|
|||
no_config: bool,
|
||||
cache: &Cache,
|
||||
printer: Printer,
|
||||
preview: PreviewMode,
|
||||
) -> Result<ExitStatus> {
|
||||
if build_backend == Some(ProjectBuildBackend::Uv) && preview.is_disabled() {
|
||||
warn_user_once!("The uv build backend is experimental and may change without warning");
|
||||
}
|
||||
match init_kind {
|
||||
InitKind::Script => {
|
||||
let Some(path) = explicit_path.as_deref() else {
|
||||
|
|
@ -864,6 +868,21 @@ fn pyproject_project(
|
|||
fn pyproject_build_system(package: &PackageName, build_backend: ProjectBuildBackend) -> String {
|
||||
let module_name = package.as_dist_info_name();
|
||||
match build_backend {
|
||||
ProjectBuildBackend::Uv => {
|
||||
// Limit to the stable version range.
|
||||
let min_version = Version::from_str(uv_version::version()).unwrap();
|
||||
debug_assert!(
|
||||
min_version.release()[0] == 0,
|
||||
"migrate to major version bumps"
|
||||
);
|
||||
let max_version = Version::new([0, min_version.release()[1] + 1]);
|
||||
indoc::formatdoc! {r#"
|
||||
[build-system]
|
||||
requires = ["uv>={min_version},<{max_version}"]
|
||||
build-backend = "uv"
|
||||
"#}
|
||||
}
|
||||
.to_string(),
|
||||
// Pure-python backends
|
||||
ProjectBuildBackend::Hatch => indoc::indoc! {r#"
|
||||
[build-system]
|
||||
|
|
|
|||
|
|
@ -1320,6 +1320,7 @@ async fn run_project(
|
|||
no_config,
|
||||
&cache,
|
||||
printer,
|
||||
globals.preview,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3193,3 +3193,81 @@ fn init_lib_build_backend_scikit() -> Result<()> {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Run `uv init --app --package --build-backend uv` to create a packaged application project
|
||||
#[test]
|
||||
fn init_application_package_uv() -> Result<()> {
|
||||
let context = TestContext::new("3.12");
|
||||
|
||||
let child = context.temp_dir.child("foo");
|
||||
child.create_dir_all()?;
|
||||
|
||||
let pyproject_toml = child.join("pyproject.toml");
|
||||
let init_py = child.join("src").join("foo").join("__init__.py");
|
||||
|
||||
uv_snapshot!(context.filters(), context.init().current_dir(&child).arg("--app").arg("--package").arg("--build-backend").arg("uv"), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
warning: The uv build backend is experimental and may change without warning
|
||||
Initialized project `foo`
|
||||
"###);
|
||||
|
||||
let pyproject = fs_err::read_to_string(&pyproject_toml)?;
|
||||
let mut filters = context.filters();
|
||||
filters.push((r#"\["uv>=.*,<.*"\]"#, r#"["uv[SPECIFIERS]"]"#));
|
||||
insta::with_settings!({
|
||||
filters => filters,
|
||||
}, {
|
||||
assert_snapshot!(
|
||||
pyproject, @r###"
|
||||
[project]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
description = "Add your description here"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.12"
|
||||
dependencies = []
|
||||
|
||||
[project.scripts]
|
||||
foo = "foo:main"
|
||||
|
||||
[build-system]
|
||||
requires = ["uv[SPECIFIERS]"]
|
||||
build-backend = "uv"
|
||||
"###
|
||||
);
|
||||
});
|
||||
|
||||
let init = fs_err::read_to_string(init_py)?;
|
||||
insta::with_settings!({
|
||||
filters => context.filters(),
|
||||
}, {
|
||||
assert_snapshot!(
|
||||
init, @r###"
|
||||
def main() -> None:
|
||||
print("Hello from foo!")
|
||||
"###
|
||||
);
|
||||
});
|
||||
|
||||
// Use preview to go through the fast path.
|
||||
uv_snapshot!(context.filters(), context.run().arg("--preview").arg("foo").current_dir(&child).env_remove(EnvVars::VIRTUAL_ENV), @r###"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Hello from foo!
|
||||
|
||||
----- stderr -----
|
||||
Using CPython 3.12.[X] interpreter at: [PYTHON-3.12]
|
||||
Creating virtual environment at: .venv
|
||||
Resolved 1 package in [TIME]
|
||||
Prepared 1 package in [TIME]
|
||||
Installed 1 package in [TIME]
|
||||
+ foo==0.1.0 (from file://[TEMP_DIR]/foo)
|
||||
"###);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue