diff --git a/crates/uv/src/commands/project/init.rs b/crates/uv/src/commands/project/init.rs index a44625453b3d..a811b6cc2504 100644 --- a/crates/uv/src/commands/project/init.rs +++ b/crates/uv/src/commands/project/init.rs @@ -1,7 +1,7 @@ use std::fmt::Write; use std::path::PathBuf; -use anyhow::Result; +use anyhow::{Context, Result}; use owo_colors::OwoColorize; use pep508_rs::PackageName; @@ -34,19 +34,6 @@ pub(crate) async fn init( Some(ref path) => PathBuf::from(path), }; - // Default to the directory name if a name was not provided. - let name = match name { - Some(name) => name, - None => { - let name = path - .file_name() - .and_then(|path| path.to_str()) - .expect("Invalid package name"); - - PackageName::new(name.to_string())? - } - }; - // Make sure a project does not already exist in the given directory. if path.join("pyproject.toml").exists() { let path = path @@ -62,6 +49,19 @@ pub(crate) async fn init( // Canonicalize the path to the project. let path = absolutize_path(&path)?; + // Default to the directory name if a name was not provided. + let name = match name { + Some(name) => name, + None => { + let name = path + .file_name() + .and_then(|path| path.to_str()) + .context("Missing directory name")?; + + PackageName::new(name.to_string())? + } + }; + // Create the `pyproject.toml`. let pyproject = indoc::formatdoc! {r#" [project] diff --git a/crates/uv/tests/init.rs b/crates/uv/tests/init.rs index c2654f28bc35..3cb16c27eb41 100644 --- a/crates/uv/tests/init.rs +++ b/crates/uv/tests/init.rs @@ -175,6 +175,72 @@ fn current_dir() -> Result<()> { Ok(()) } +#[test] +fn init_dot_args() -> Result<()> { + let context = TestContext::new("3.12"); + + let dir = context.temp_dir.join("foo"); + fs_err::create_dir(&dir)?; + + uv_snapshot!(context.filters(), context.init().current_dir(&dir).arg("."), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv init` is experimental and may change without warning + Initialized project `foo` at `[TEMP_DIR]/foo` + "###); + + let pyproject = fs_err::read_to_string(dir.join("pyproject.toml"))?; + let init_py = fs_err::read_to_string(dir.join("src/foo/__init__.py"))?; + let _ = fs_err::read_to_string(dir.join("README.md")).unwrap(); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + pyproject, @r###" + [project] + name = "foo" + version = "0.1.0" + description = "Add your description here" + readme = "README.md" + dependencies = [] + + [tool.uv] + dev-dependencies = [] + "### + ); + }); + + insta::with_settings!({ + filters => context.filters(), + }, { + assert_snapshot!( + init_py, @r###" + def hello() -> str: + return "Hello from foo!" + "### + ); + }); + + // Run `uv lock` in the new project. + uv_snapshot!(context.filters(), context.lock().current_dir(&dir), @r###" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + warning: `uv lock` is experimental and may change without warning + Using Python 3.12.[X] interpreter at: [PYTHON-3.12] + warning: No `requires-python` field found in the workspace. Defaulting to `>=3.12`. + Resolved 1 package in [TIME] + "###); + + Ok(()) +} + #[test] fn init_workspace() -> Result<()> { let context = TestContext::new("3.12");