mirror of
				https://github.com/astral-sh/uv.git
				synced 2025-10-31 03:55:33 +00:00 
			
		
		
		
	Add a --require-hashes command-line setting (#2824)
				
					
				
			## Summary I'll likely only merge this once the PR chain is further along, but this PR wires up the setting fro the CLI.
This commit is contained in:
		
							parent
							
								
									520cd4689b
								
							
						
					
					
						commit
						a9d554fa90
					
				
					 4 changed files with 53 additions and 0 deletions
				
			
		|  | @ -9,6 +9,7 @@ pub struct Options { | |||
|     pub prerelease_mode: PreReleaseMode, | ||||
|     pub dependency_mode: DependencyMode, | ||||
|     pub exclude_newer: Option<DateTime<Utc>>, | ||||
|     pub require_hashes: bool, | ||||
| } | ||||
| 
 | ||||
| /// Builder for [`Options`].
 | ||||
|  | @ -18,6 +19,7 @@ pub struct OptionsBuilder { | |||
|     prerelease_mode: PreReleaseMode, | ||||
|     dependency_mode: DependencyMode, | ||||
|     exclude_newer: Option<DateTime<Utc>>, | ||||
|     require_hashes: bool, | ||||
| } | ||||
| 
 | ||||
| impl OptionsBuilder { | ||||
|  | @ -54,6 +56,13 @@ impl OptionsBuilder { | |||
|         self | ||||
|     } | ||||
| 
 | ||||
|     /// Sets the `--requires-hash` flag.
 | ||||
|     #[must_use] | ||||
|     pub fn require_hashes(mut self, require_hashes: bool) -> Self { | ||||
|         self.require_hashes = require_hashes; | ||||
|         self | ||||
|     } | ||||
| 
 | ||||
|     /// Builds the options.
 | ||||
|     pub fn build(self) -> Options { | ||||
|         Options { | ||||
|  | @ -61,6 +70,7 @@ impl OptionsBuilder { | |||
|             prerelease_mode: self.prerelease_mode, | ||||
|             dependency_mode: self.dependency_mode, | ||||
|             exclude_newer: self.exclude_newer, | ||||
|             require_hashes: self.require_hashes, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -67,6 +67,7 @@ pub(crate) async fn pip_install( | |||
|     reinstall: Reinstall, | ||||
|     link_mode: LinkMode, | ||||
|     compile: bool, | ||||
|     require_hashes: bool, | ||||
|     setup_py: SetupPyStrategy, | ||||
|     connectivity: Connectivity, | ||||
|     config_settings: &ConfigSettings, | ||||
|  | @ -84,6 +85,11 @@ pub(crate) async fn pip_install( | |||
|     printer: Printer, | ||||
| ) -> Result<ExitStatus> { | ||||
|     let start = std::time::Instant::now(); | ||||
| 
 | ||||
|     if require_hashes { | ||||
|         warn_user!("Hash-checking mode (via `--require-hashes`) is not yet supported."); | ||||
|     } | ||||
| 
 | ||||
|     let client_builder = BaseClientBuilder::new() | ||||
|         .connectivity(connectivity) | ||||
|         .native_tls(native_tls) | ||||
|  | @ -292,6 +298,7 @@ pub(crate) async fn pip_install( | |||
|         .prerelease_mode(prerelease_mode) | ||||
|         .dependency_mode(dependency_mode) | ||||
|         .exclude_newer(exclude_newer) | ||||
|         .require_hashes(require_hashes) | ||||
|         .build(); | ||||
| 
 | ||||
|     // Resolve the requirements.
 | ||||
|  |  | |||
|  | @ -45,6 +45,7 @@ pub(crate) async fn pip_sync( | |||
|     reinstall: &Reinstall, | ||||
|     link_mode: LinkMode, | ||||
|     compile: bool, | ||||
|     require_hashes: bool, | ||||
|     index_locations: IndexLocations, | ||||
|     index_strategy: IndexStrategy, | ||||
|     keyring_provider: KeyringProvider, | ||||
|  | @ -64,6 +65,10 @@ pub(crate) async fn pip_sync( | |||
| ) -> Result<ExitStatus> { | ||||
|     let start = std::time::Instant::now(); | ||||
| 
 | ||||
|     if require_hashes { | ||||
|         warn_user!("Hash-checking mode (via `--require-hashes`) is not yet supported."); | ||||
|     } | ||||
| 
 | ||||
|     let client_builder = BaseClientBuilder::new() | ||||
|         .connectivity(connectivity) | ||||
|         .native_tls(native_tls) | ||||
|  | @ -289,6 +294,7 @@ pub(crate) async fn pip_sync( | |||
|         // Resolve with `--no-deps`.
 | ||||
|         let options = OptionsBuilder::new() | ||||
|             .dependency_mode(DependencyMode::Direct) | ||||
|             .require_hashes(require_hashes) | ||||
|             .build(); | ||||
| 
 | ||||
|         // Create a bound on the progress bar, since we know the number of packages upfront.
 | ||||
|  |  | |||
|  | @ -593,6 +593,20 @@ struct PipSyncArgs { | |||
|     #[clap(long, default_value_t, value_enum, env = "UV_INDEX_STRATEGY")] | ||||
|     index_strategy: IndexStrategy, | ||||
| 
 | ||||
|     /// Require a matching hash for each requirement.
 | ||||
|     ///
 | ||||
|     /// Hash-checking mode is all or nothing. If enabled, _all_ requirements must be provided
 | ||||
|     /// with a corresponding hash or set of hashes. Additionally, if enabled, _all_ requirements
 | ||||
|     /// must either be pinned to exact versions (e.g., `==1.0.0`), or be specified via direct URL.
 | ||||
|     ///
 | ||||
|     /// Hash-checking mode introduces a number of additional constraints:
 | ||||
|     /// - Git dependencies are not supported.
 | ||||
|     /// - Editable installs are not supported.
 | ||||
|     /// - Local dependencies are not supported, unless they point to a specific wheel (`.whl`) or
 | ||||
|     ///   source archive (`.zip`, `.tar.gz`), as opposed to a directory.
 | ||||
|     #[clap(long, hide = true)] | ||||
|     require_hashes: bool, | ||||
| 
 | ||||
|     /// Attempt to use `keyring` for authentication for index urls
 | ||||
|     ///
 | ||||
|     /// Function's similar to `pip`'s `--keyring-provider subprocess` argument,
 | ||||
|  | @ -867,6 +881,20 @@ struct PipInstallArgs { | |||
|     #[clap(long, default_value_t, value_enum, env = "UV_INDEX_STRATEGY")] | ||||
|     index_strategy: IndexStrategy, | ||||
| 
 | ||||
|     /// Require a matching hash for each requirement.
 | ||||
|     ///
 | ||||
|     /// Hash-checking mode is all or nothing. If enabled, _all_ requirements must be provided
 | ||||
|     /// with a corresponding hash or set of hashes. Additionally, if enabled, _all_ requirements
 | ||||
|     /// must either be pinned to exact versions (e.g., `==1.0.0`), or be specified via direct URL.
 | ||||
|     ///
 | ||||
|     /// Hash-checking mode introduces a number of additional constraints:
 | ||||
|     /// - Git dependencies are not supported.
 | ||||
|     /// - Editable installs are not supported.
 | ||||
|     /// - Local dependencies are not supported, unless they point to a specific wheel (`.whl`) or
 | ||||
|     ///   source archive (`.zip`, `.tar.gz`), as opposed to a directory.
 | ||||
|     #[clap(long, hide = true)] | ||||
|     require_hashes: bool, | ||||
| 
 | ||||
|     /// Attempt to use `keyring` for authentication for index urls
 | ||||
|     ///
 | ||||
|     /// Due to not having Python imports, only `--keyring-provider subprocess` argument is currently
 | ||||
|  | @ -1650,6 +1678,7 @@ async fn run() -> Result<ExitStatus> { | |||
|                 &reinstall, | ||||
|                 args.link_mode, | ||||
|                 args.compile, | ||||
|                 args.require_hashes, | ||||
|                 index_urls, | ||||
|                 args.index_strategy, | ||||
|                 args.keyring_provider, | ||||
|  | @ -1750,6 +1779,7 @@ async fn run() -> Result<ExitStatus> { | |||
|                 reinstall, | ||||
|                 args.link_mode, | ||||
|                 args.compile, | ||||
|                 args.require_hashes, | ||||
|                 setup_py, | ||||
|                 if args.offline { | ||||
|                     Connectivity::Offline | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Charlie Marsh
						Charlie Marsh