From a2d97ae9b1c0ca3ffd02a60a26d8cde98322bb50 Mon Sep 17 00:00:00 2001 From: Jorge Hermo Date: Fri, 22 Aug 2025 18:27:34 +0200 Subject: [PATCH] Respect `--project` in `uv format` (#15438) Closes https://github.com/astral-sh/uv/issues/15431 This is my first contribution, so I'm sorry if I miss something! Didn't update any documentation nor added tests. Tell me if this is needed for this feature :smile: I will try to address https://github.com/astral-sh/uv/issues/15430 in another PR --- crates/uv/src/commands/project/format.rs | 3 ++ crates/uv/src/lib.rs | 1 + crates/uv/tests/it/format.rs | 69 ++++++++++++++++++++++++ 3 files changed, 73 insertions(+) diff --git a/crates/uv/src/commands/project/format.rs b/crates/uv/src/commands/project/format.rs index 96ddd59bd..bf8f852c9 100644 --- a/crates/uv/src/commands/project/format.rs +++ b/crates/uv/src/commands/project/format.rs @@ -1,3 +1,4 @@ +use std::path::Path; use std::str::FromStr; use anyhow::{Context, Result}; @@ -18,6 +19,7 @@ use crate::settings::NetworkSettings; /// Run the formatter. pub(crate) async fn format( + project_dir: &Path, check: bool, diff: bool, extra_args: Vec, @@ -53,6 +55,7 @@ pub(crate) async fn format( .context("Failed to install ruff {version}")?; let mut command = Command::new(&ruff_path); + command.current_dir(project_dir); command.arg("format"); if check { diff --git a/crates/uv/src/lib.rs b/crates/uv/src/lib.rs index 5aa42e2d4..6b5b36d5e 100644 --- a/crates/uv/src/lib.rs +++ b/crates/uv/src/lib.rs @@ -2193,6 +2193,7 @@ async fn run_project( let cache = cache.init()?; Box::pin(commands::format( + project_dir, args.check, args.diff, args.extra_args, diff --git a/crates/uv/tests/it/format.rs b/crates/uv/tests/it/format.rs index 6898fc3aa..5a4e830e8 100644 --- a/crates/uv/tests/it/format.rs +++ b/crates/uv/tests/it/format.rs @@ -55,6 +55,75 @@ fn format_project() -> Result<()> { Ok(()) } +#[test] +fn format_relative_project() -> Result<()> { + let context = TestContext::new_with_versions(&[]); + + let pyproject_toml = context.temp_dir.child("project").child("pyproject.toml"); + pyproject_toml.write_str(indoc! {r#" + [project] + name = "project" + version = "0.1.0" + requires-python = ">=3.12" + dependencies = [] + "#})?; + + // Create an unformatted Python file in the relative project + let relative_project_main_py = context.temp_dir.child("project").child("main.py"); + relative_project_main_py.write_str(indoc! {r#" + import sys + def hello(): + print( "Hello, World!" ) + if __name__=="__main__": + hello( ) + "#})?; + + // Create another unformatted Python file in the root directory + let root_main_py = context.temp_dir.child("main.py"); + root_main_py.write_str(indoc! {r#" + import sys + def hello(): + print( "Hello, World!" ) + if __name__=="__main__": + hello( ) + "#})?; + + uv_snapshot!(context.filters(), context.format().arg("--project").arg("project"), @r" + success: true + exit_code: 0 + ----- stdout ----- + 1 file reformatted + + ----- stderr ----- + warning: `uv format` is experimental and may change without warning. Pass `--preview-features format` to disable this warning. + "); + + // Check that the relative project file was formatted + let relative_project_content = fs_err::read_to_string(&relative_project_main_py)?; + assert_snapshot!(relative_project_content, @r#" + import sys + + + def hello(): + print("Hello, World!") + + + if __name__ == "__main__": + hello() + "#); + + // Check that the root file was not formatted + let root_content = fs_err::read_to_string(&root_main_py)?; + assert_snapshot!(root_content, @r#" + import sys + def hello(): + print( "Hello, World!" ) + if __name__=="__main__": + hello( ) + "#); + Ok(()) +} + #[test] fn format_check() -> Result<()> { let context = TestContext::new_with_versions(&[]);