Skip to content

Commit

Permalink
fix: use correct directory for build artifact cache (#2830)
Browse files Browse the repository at this point in the history
There was an issue were the packages in the build-cache were reused for unrelated source checkouts. This is because we bucket the caches based on the pinned source spec but for a lot of examples the pinned path source spec was simply .. This caused a lot of examples to reuse the cache entry of another source checkout causing strange behavior.

I fixed this issue by using the pinned source spec as the cache key if the source is immutable (e.g. for git checkouts) and otherwise (e.g. for path source dependencies) use the absolute path on disk as the cache key. I think this makes sense as it creates separate cache entries for packages in different locations on disk (like temporary directories).
  • Loading branch information
baszalmstra authored Jan 3, 2025
1 parent 698087b commit 8e72a49
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 13 deletions.
12 changes: 11 additions & 1 deletion src/build/cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,17 @@ use crate::build::SourceCheckout;
/// Constructs a name for a cache directory for the given source checkout.
fn source_checkout_cache_key(source: &SourceCheckout) -> String {
let mut hasher = Xxh3::new();
source.pinned.to_string().hash(&mut hasher);

// If the source is immutable we use the pinned definition of the source.
// If the source is mutable we instead hash the location of the source
// checkout on disk. This ensures that we get different cache directories
// for different source checkouts with different edits.
if source.pinned.is_immutable() {
source.pinned.to_string().hash(&mut hasher);
} else {
source.path.to_string_lossy().hash(&mut hasher);
}

let unique_key = URL_SAFE_NO_PAD.encode(hasher.finish().to_ne_bytes());
match source.path.file_name().and_then(OsStr::to_str) {
Some(name) => format!("{}-{}", name, unique_key),
Expand Down
12 changes: 0 additions & 12 deletions tests/integration_python/pixi_build/test_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ def test_source_change_trigger_rebuild(
project = "simple-pyproject"
test_data = build_data.joinpath(project)

# TODO: Setting the cache dir shouldn't be necessary!
env = {"PIXI_CACHE_DIR": str(tmp_pixi_workspace.joinpath("pixi_cache"))}

target_dir = tmp_pixi_workspace.joinpath(project)
shutil.copytree(test_data, target_dir)
manifest_path = target_dir.joinpath("pyproject.toml")
Expand All @@ -99,7 +96,6 @@ def test_source_change_trigger_rebuild(
"get-version",
],
stdout_contains="The version of simple-pyproject is 1.0.0",
env=env,
)

# Bump version from 1.0.0 to 2.0.0
Expand All @@ -116,7 +112,6 @@ def test_source_change_trigger_rebuild(
"get-version",
],
stdout_contains="The version of simple-pyproject is 2.0.0",
env=env,
)


Expand All @@ -125,11 +120,6 @@ def test_editable_pyproject(pixi: Path, build_data: Path, tmp_pixi_workspace: Pa
project = "editable-pyproject"
test_data = build_data.joinpath(project)

# TODO: Setting the cache dir shouldn't be necessary!
env = {
"PIXI_CACHE_DIR": str(tmp_pixi_workspace.joinpath("pixi_cache")),
}

target_dir = tmp_pixi_workspace.joinpath(project)
shutil.copytree(test_data, target_dir)
manifest_path = target_dir.joinpath("pyproject.toml")
Expand All @@ -141,7 +131,6 @@ def test_editable_pyproject(pixi: Path, build_data: Path, tmp_pixi_workspace: Pa
"--manifest-path",
manifest_path,
],
env=env,
)

# Verify that package is installed as editable
Expand All @@ -153,6 +142,5 @@ def test_editable_pyproject(pixi: Path, build_data: Path, tmp_pixi_workspace: Pa
manifest_path,
"check-editable",
],
env=env,
stdout_contains="The package is installed as editable.",
)

0 comments on commit 8e72a49

Please sign in to comment.