mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-28 10:50:29 +00:00
Respect reinstalls in cached environments (#5499)
## Summary Closes #5493.
This commit is contained in:
parent
8f16f1b746
commit
3ea5e16e96
2 changed files with 87 additions and 15 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue