Respect reinstalls in cached environments (#5499)

## Summary

Closes #5493.
This commit is contained in:
Charlie Marsh 2024-07-26 21:36:58 -04:00 committed by GitHub
parent 8f16f1b746
commit 3ea5e16e96
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 87 additions and 15 deletions

View file

@ -74,8 +74,10 @@ impl CachedEnvironment {
// Hash the resolution by hashing the generated lockfile. // Hash the resolution by hashing the generated lockfile.
// TODO(charlie): If the resolution contains any mutable metadata (like a path or URL // TODO(charlie): If the resolution contains any mutable metadata (like a path or URL
// dependency), skip this step. // dependency), skip this step.
let distributions = resolution.distributions().collect::<Vec<_>>(); let resolution_hash = {
let resolution_hash = hash_digest(&distributions); let distributions = resolution.distributions().collect::<Vec<_>>();
hash_digest(&distributions)
};
// Hash the interpreter based on its path. // Hash the interpreter based on its path.
// TODO(charlie): Come up with a robust hash for the interpreter. // TODO(charlie): Come up with a robust hash for the interpreter.
@ -84,24 +86,39 @@ impl CachedEnvironment {
// Search in the content-addressed cache. // Search in the content-addressed cache.
let cache_entry = cache.entry(CacheBucket::Environments, interpreter_hash, resolution_hash); let cache_entry = cache.entry(CacheBucket::Environments, interpreter_hash, resolution_hash);
// Lock the interpreter, to avoid concurrent modification across processes. // Lock at the interpreter level, to avoid concurrent modification across processes.
fs_err::tokio::create_dir_all(cache_entry.dir()).await?; fs_err::tokio::create_dir_all(cache_entry.dir()).await?;
let _lock = LockedFile::acquire( let _lock = LockedFile::acquire(
cache_entry.dir().join(".lock"), cache_entry.dir().join(".lock"),
cache_entry.dir().user_display(), cache_entry.dir().user_display(),
)?; )?;
// If the receipt exists, return the environment.
let ok = cache_entry.path().join(".ok"); let ok = cache_entry.path().join(".ok");
if ok.is_file() {
debug!( if settings.reinstall.is_none() {
"Found existing cached environment at: `{}`", // If the receipt exists, return the environment.
cache_entry.path().display() if ok.is_file() {
); debug!(
return Ok(Self(PythonEnvironment::from_root( "Reusing cached environment at: `{}`",
cache_entry.path(), cache_entry.path().display()
cache, );
)?)); return Ok(Self(PythonEnvironment::from_root(
cache_entry.path(),
cache,
)?));
}
} else {
// If the receipt exists, remove it.
match fs_err::tokio::remove_file(&ok).await {
Ok(()) => {
debug!(
"Removed receipt for environment at: `{}`",
cache_entry.path().display()
);
}
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {}
Err(err) => return Err(err.into()),
}
} }
debug!( debug!(
@ -117,8 +134,6 @@ impl CachedEnvironment {
false, false,
)?; )?;
// TODO(charlie): Rather than passing all the arguments to `sync_environment`, return a
// struct that lets us "continue" from `resolve_environment`.
let venv = sync_environment( let venv = sync_environment(
venv, venv,
&resolution, &resolution,

View file

@ -508,6 +508,63 @@ fn tool_run_cache() {
Resolved [N] packages in [TIME] Resolved [N] packages in [TIME]
"###); "###);
// Verify that `--reinstall` reinstalls everything.
uv_snapshot!(context.filters(), context.tool_run()
.arg("-p")
.arg("3.12")
.arg("--reinstall")
.arg("black")
.arg("--version")
.env("UV_TOOL_DIR", tool_dir.as_os_str())
.env("XDG_BIN_HOME", bin_dir.as_os_str()), @r###"
success: true
exit_code: 0
----- stdout -----
black, 24.3.0 (compiled: yes)
Python (CPython) 3.12.[X]
----- stderr -----
warning: `uv tool run` is experimental and may change without warning
Resolved [N] packages in [TIME]
Prepared [N] packages in [TIME]
Installed [N] packages in [TIME]
+ black==24.3.0
+ click==8.1.7
+ mypy-extensions==1.0.0
+ packaging==24.0
+ pathspec==0.12.1
+ platformdirs==4.2.0
"###);
// Verify that `--reinstall-package` reinstalls everything. We may want to change this.
uv_snapshot!(context.filters(), context.tool_run()
.arg("-p")
.arg("3.12")
.arg("--reinstall-package")
.arg("packaging")
.arg("black")
.arg("--version")
.env("UV_TOOL_DIR", tool_dir.as_os_str())
.env("XDG_BIN_HOME", bin_dir.as_os_str()), @r###"
success: true
exit_code: 0
----- stdout -----
black, 24.3.0 (compiled: yes)
Python (CPython) 3.12.[X]
----- stderr -----
warning: `uv tool run` is experimental and may change without warning
Resolved [N] packages in [TIME]
Prepared [N] packages in [TIME]
Installed [N] packages in [TIME]
+ black==24.3.0
+ click==8.1.7
+ mypy-extensions==1.0.0
+ packaging==24.0
+ pathspec==0.12.1
+ platformdirs==4.2.0
"###);
// Verify that varying the interpreter leads to a fresh environment. // Verify that varying the interpreter leads to a fresh environment.
uv_snapshot!(context.filters(), context.tool_run() uv_snapshot!(context.filters(), context.tool_run()
.arg("-p") .arg("-p")