Check subdirectory existence after cache heal (#11719)

## Summary

Closes https://github.com/astral-sh/uv/issues/11703.
This commit is contained in:
Charlie Marsh 2025-02-22 14:13:29 -10:00 committed by GitHub
parent c124bd250b
commit 3c541e2368
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 71 additions and 20 deletions

View File

@ -415,16 +415,6 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
let cache_shard = cache_shard.shard(revision.id()); let cache_shard = cache_shard.shard(revision.id());
let source_dist_entry = cache_shard.entry(SOURCE); let source_dist_entry = cache_shard.entry(SOURCE);
// Validate that the subdirectory exists.
if let Some(subdirectory) = subdirectory {
if !source_dist_entry.path().join(subdirectory).is_dir() {
return Err(Error::MissingSubdirectory(
url.clone(),
subdirectory.to_path_buf(),
));
}
}
// If there are build settings, we need to scope to a cache shard. // If there are build settings, we need to scope to a cache shard.
let config_settings = self.build_context.config_settings(); let config_settings = self.build_context.config_settings();
let cache_shard = if config_settings.is_empty() { let cache_shard = if config_settings.is_empty() {
@ -456,6 +446,16 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
.await? .await?
}; };
// Validate that the subdirectory exists.
if let Some(subdirectory) = subdirectory {
if !source_dist_entry.path().join(subdirectory).is_dir() {
return Err(Error::MissingSubdirectory(
url.clone(),
subdirectory.to_path_buf(),
));
}
}
let task = self let task = self
.reporter .reporter
.as_ref() .as_ref()
@ -528,16 +528,6 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
let cache_shard = cache_shard.shard(revision.id()); let cache_shard = cache_shard.shard(revision.id());
let source_dist_entry = cache_shard.entry(SOURCE); let source_dist_entry = cache_shard.entry(SOURCE);
// Validate that the subdirectory exists.
if let Some(subdirectory) = subdirectory {
if !source_dist_entry.path().join(subdirectory).is_dir() {
return Err(Error::MissingSubdirectory(
url.clone(),
subdirectory.to_path_buf(),
));
}
}
// If the metadata is static, return it. // If the metadata is static, return it.
let dynamic = let dynamic =
match StaticMetadata::read(source, source_dist_entry.path(), subdirectory).await? { match StaticMetadata::read(source, source_dist_entry.path(), subdirectory).await? {
@ -586,6 +576,16 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
.await? .await?
}; };
// Validate that the subdirectory exists.
if let Some(subdirectory) = subdirectory {
if !source_dist_entry.path().join(subdirectory).is_dir() {
return Err(Error::MissingSubdirectory(
url.clone(),
subdirectory.to_path_buf(),
));
}
}
// If there are build settings, we need to scope to a cache shard. // If there are build settings, we need to scope to a cache shard.
let config_settings = self.build_context.config_settings(); let config_settings = self.build_context.config_settings();
let cache_shard = if config_settings.is_empty() { let cache_shard = if config_settings.is_empty() {

View File

@ -7808,3 +7808,54 @@ fn multiple_group_conflicts() -> Result<()> {
Ok(()) Ok(())
} }
/// See: <https://github.com/astral-sh/uv/issues/11703>
#[test]
fn prune_cache_url_subdirectory() -> Result<()> {
let context = TestContext::new("3.12");
let pyproject_toml = context.temp_dir.child("pyproject.toml");
pyproject_toml.write_str(indoc! {r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
"root",
]
[tool.uv.sources]
root = { url = "https://github.com/user-attachments/files/18216295/subdirectory-test.tar.gz", subdirectory = "packages/root" }
"#})?;
// Lock the project.
uv_snapshot!(context.filters(), context.lock(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 5 packages in [TIME]
"###);
// Prune the cache.
context.prune().arg("--ci").assert().success();
// Install the project.
uv_snapshot!(context.filters(), context.sync(), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 5 packages in [TIME]
Prepared 4 packages in [TIME]
Installed 4 packages in [TIME]
+ anyio==4.3.0
+ idna==3.6
+ root==0.0.1 (from https://github.com/user-attachments/files/18216295/subdirectory-test.tar.gz#subdirectory=packages/root)
+ sniffio==1.3.1
"###);
Ok(())
}