diff --git a/crates/uv/src/commands/build_frontend.rs b/crates/uv/src/commands/build_frontend.rs index 84d97b1d9344a..fdcdc349e72b7 100644 --- a/crates/uv/src/commands/build_frontend.rs +++ b/crates/uv/src/commands/build_frontend.rs @@ -39,6 +39,7 @@ use uv_requirements::RequirementsSource; use uv_resolver::{ExcludeNewer, FlatIndex}; use uv_settings::PythonInstallMirrors; use uv_types::{AnyErrorBuild, BuildContext, BuildStack, HashStrategy, SourceTreeEditablePolicy}; +use uv_warnings::warn_user; use uv_workspace::pyproject::ExtraBuildDependencies; use uv_workspace::{DiscoveryOptions, Workspace, WorkspaceCache, WorkspaceError}; @@ -372,16 +373,17 @@ async fn build_impl( }; // Build backends can include arbitrary files from the source directory in the distribution. - // Reject an active cache within the source to avoid including cache contents in the build. + // Warn if the active cache is within the source since cache contents may be included in the + // build. for source in &packages { if let Source::Directory(source_dir) = &source.source && is_path_within(cache.root(), source_dir) { - return Err(anyhow::anyhow!( - "The cache directory `{}` is inside the build source directory `{}`", + warn_user!( + "The cache directory `{}` is inside the build source directory `{}` and may be included in distributions", cache.root().user_display(), source_dir.user_display() - )); + ); } } diff --git a/crates/uv/tests/build/cache.rs b/crates/uv/tests/build/cache.rs index 30ce8ad9ff3cf..f3e09fef53c6f 100644 --- a/crates/uv/tests/build/cache.rs +++ b/crates/uv/tests/build/cache.rs @@ -7,10 +7,10 @@ use std::process::Command; use uv_fs::create_symlink; use uv_test::{get_bin, uv_snapshot}; -/// When the active cache directory is inside an explicit build source, we should error before -/// invoking the build backend or creating the output directory. +/// When the active cache directory is inside an explicit build source, we should warn and continue +/// the build. #[test] -fn build_rejects_cache_inside_source() -> Result<()> { +fn build_warns_cache_inside_source() -> Result<()> { let mut context = uv_test::test_context!("3.12"); let project = context.temp_dir.child("project"); @@ -31,24 +31,28 @@ fn build_rejects_cache_inside_source() -> Result<()> { context.cache_dir = project.child(".uv-cache"); uv_snapshot!(context.filters(), context.build().arg("--sdist").arg("project"), @" - success: false - exit_code: 2 + success: true + exit_code: 0 ----- stdout ----- ----- stderr ----- - error: The cache directory `project/.uv-cache` is inside the build source directory `project` + warning: The cache directory `project/.uv-cache` is inside the build source directory `project` and may be included in distributions + Building source distribution (uv build backend)... + Successfully built project/dist/project-0.1.0.tar.gz "); - project.child("dist").assert(predicate::path::missing()); + project + .child("dist/project-0.1.0.tar.gz") + .assert(predicate::path::is_file()); Ok(()) } -/// When the canonical cache directory is inside an explicit build source, we should error even if +/// When the canonical cache directory is inside an explicit build source, we should warn even if /// the configured cache path itself is outside the source. #[test] #[cfg(unix)] -fn build_rejects_symlinked_cache_inside_source() -> Result<()> { +fn build_warns_symlinked_cache_inside_source() -> Result<()> { let context = uv_test::test_context!("3.12"); let project = context.temp_dir.child("project"); @@ -82,15 +86,19 @@ fn build_rejects_symlinked_cache_inside_source() -> Result<()> { command.current_dir(context.temp_dir.path()); uv_snapshot!(context.filters(), command, @" - success: false - exit_code: 2 + success: true + exit_code: 0 ----- stdout ----- ----- stderr ----- - error: The cache directory `cache-link` is inside the build source directory `project` + warning: The cache directory `cache-link` is inside the build source directory `project` and may be included in distributions + Building source distribution (uv build backend)... + Successfully built project/dist/project-0.1.0.tar.gz "); - project.child("dist").assert(predicate::path::missing()); + project + .child("dist/project-0.1.0.tar.gz") + .assert(predicate::path::is_file()); Ok(()) }