mirror of
				https://github.com/astral-sh/uv.git
				synced 2025-10-29 19:17:26 +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.
 | ||||
|         // TODO(charlie): If the resolution contains any mutable metadata (like a path or URL
 | ||||
|         // dependency), skip this step.
 | ||||
|         let resolution_hash = { | ||||
|             let distributions = resolution.distributions().collect::<Vec<_>>(); | ||||
|         let resolution_hash = hash_digest(&distributions); | ||||
|             hash_digest(&distributions) | ||||
|         }; | ||||
| 
 | ||||
|         // Hash the interpreter based on its path.
 | ||||
|         // TODO(charlie): Come up with a robust hash for the interpreter.
 | ||||
|  | @ -84,18 +86,20 @@ impl CachedEnvironment { | |||
|         // Search in the content-addressed cache.
 | ||||
|         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?; | ||||
|         let _lock = LockedFile::acquire( | ||||
|             cache_entry.dir().join(".lock"), | ||||
|             cache_entry.dir().user_display(), | ||||
|         )?; | ||||
| 
 | ||||
|         // If the receipt exists, return the environment.
 | ||||
|         let ok = cache_entry.path().join(".ok"); | ||||
| 
 | ||||
|         if settings.reinstall.is_none() { | ||||
|             // If the receipt exists, return the environment.
 | ||||
|             if ok.is_file() { | ||||
|                 debug!( | ||||
|                 "Found existing cached environment at: `{}`", | ||||
|                     "Reusing cached environment at: `{}`", | ||||
|                     cache_entry.path().display() | ||||
|                 ); | ||||
|                 return Ok(Self(PythonEnvironment::from_root( | ||||
|  | @ -103,6 +107,19 @@ impl CachedEnvironment { | |||
|                     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!( | ||||
|             "Creating cached environment at: `{}`", | ||||
|  | @ -117,8 +134,6 @@ impl CachedEnvironment { | |||
|             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( | ||||
|             venv, | ||||
|             &resolution, | ||||
|  |  | |||
|  | @ -508,6 +508,63 @@ fn tool_run_cache() { | |||
|     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.
 | ||||
|     uv_snapshot!(context.filters(), context.tool_run() | ||||
|         .arg("-p") | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Charlie Marsh
						Charlie Marsh