diff --git a/Cargo.lock b/Cargo.lock index 1ef938990a88..350851e2b060 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4999,6 +4999,7 @@ dependencies = [ "uv-normalize", "uv-resolver", "uv-toolchain", + "uv-warnings", ] [[package]] diff --git a/crates/uv-settings/Cargo.toml b/crates/uv-settings/Cargo.toml index a6e05c7a00bf..8dbff5fc79e0 100644 --- a/crates/uv-settings/Cargo.toml +++ b/crates/uv-settings/Cargo.toml @@ -19,10 +19,11 @@ pep508_rs = { workspace = true } pypi-types = { workspace = true } uv-configuration = { workspace = true, features = ["schemars"] } uv-fs = { workspace = true } +uv-macros = { workspace = true } uv-normalize = { workspace = true, features = ["schemars"] } uv-resolver = { workspace = true, features = ["schemars"] } uv-toolchain = { workspace = true, features = ["schemars"] } -uv-macros = { workspace = true } +uv-warnings = { workspace = true } dirs-sys = { workspace = true } fs-err = { workspace = true } diff --git a/crates/uv-settings/src/lib.rs b/crates/uv-settings/src/lib.rs index a5bfb2f5b732..a89176d3c0d0 100644 --- a/crates/uv-settings/src/lib.rs +++ b/crates/uv-settings/src/lib.rs @@ -4,6 +4,7 @@ use std::path::{Path, PathBuf}; use tracing::debug; use uv_fs::Simplified; +use uv_warnings::warn_user; pub use crate::combine::*; pub use crate::settings::*; @@ -57,22 +58,25 @@ impl FilesystemOptions { /// Find the [`FilesystemOptions`] for the given path. /// - /// The search starts at the given path and goes up the directory tree until a `uv.toml` file is - /// found. + /// The search starts at the given path and goes up the directory tree until a `uv.toml` file or + /// `pyproject.toml` file is found. pub fn find(path: impl AsRef) -> Result, Error> { for ancestor in path.as_ref().ancestors() { - // Read a `uv.toml` file in the current directory. - let path = ancestor.join("uv.toml"); - match fs_err::read_to_string(&path) { - Ok(content) => { - let options: Options = toml::from_str(&content) - .map_err(|err| Error::UvToml(path.user_display().to_string(), err))?; - - debug!("Found workspace configuration at `{}`", path.display()); - return Ok(Some(Self(options))); + match Self::from_directory(ancestor) { + Ok(Some(options)) => { + return Ok(Some(options)); + } + Ok(None) => { + // Continue traversing the directory tree. + } + Err(Error::PyprojectToml(file, _err)) => { + // If we see an invalid `pyproject.toml`, warn but continue. + warn_user!("Failed to parse `{file}` during settings discovery; skipping..."); + } + Err(err) => { + // Otherwise, warn and stop. + return Err(err); } - Err(err) if err.kind() == std::io::ErrorKind::NotFound => {} - Err(err) => return Err(err.into()), } } Ok(None) @@ -103,9 +107,17 @@ impl FilesystemOptions { let pyproject: PyProjectToml = toml::from_str(&content) .map_err(|err| Error::PyprojectToml(path.user_display().to_string(), err))?; let Some(tool) = pyproject.tool else { + debug!( + "Skipping `pyproject.toml` in `{}` (no `[tool]` section)", + dir.as_ref().display() + ); return Ok(None); }; let Some(options) = tool.uv else { + debug!( + "Skipping `pyproject.toml` in `{}` (no `[tool.uv]` section)", + dir.as_ref().display() + ); return Ok(None); }; diff --git a/crates/uv/tests/pip_compile.rs b/crates/uv/tests/pip_compile.rs index b35d921eacbb..d272f11c0ee7 100644 --- a/crates/uv/tests/pip_compile.rs +++ b/crates/uv/tests/pip_compile.rs @@ -3204,6 +3204,7 @@ fn override_dependency_from_workspace_invalid_syntax() -> Result<()> { ----- stdout ----- ----- stderr ----- + warning: Failed to parse `pyproject.toml` during settings discovery; skipping... error: Failed to parse: `pyproject.toml` Caused by: TOML parse error at line 9, column 29 | diff --git a/crates/uv/tests/pip_install.rs b/crates/uv/tests/pip_install.rs index 076af4ab9a09..5d69ec048880 100644 --- a/crates/uv/tests/pip_install.rs +++ b/crates/uv/tests/pip_install.rs @@ -143,6 +143,7 @@ fn invalid_pyproject_toml_syntax() -> Result<()> { ----- stdout ----- ----- stderr ----- + warning: Failed to parse `pyproject.toml` during settings discovery; skipping... error: Failed to parse: `pyproject.toml` Caused by: TOML parse error at line 1, column 5 |