Skip to content

Commit

Permalink
Add a --require-hashes command-line setting
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Apr 5, 2024
1 parent 2ac562b commit ec16897
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 0 deletions.
10 changes: 10 additions & 0 deletions crates/uv-resolver/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`].
Expand All @@ -18,6 +19,7 @@ pub struct OptionsBuilder {
prerelease_mode: PreReleaseMode,
dependency_mode: DependencyMode,
exclude_newer: Option<DateTime<Utc>>,
require_hashes: bool,
}

impl OptionsBuilder {
Expand Down Expand Up @@ -54,13 +56,21 @@ 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 {
resolution_mode: self.resolution_mode,
prerelease_mode: self.prerelease_mode,
dependency_mode: self.dependency_mode,
exclude_newer: self.exclude_newer,
require_hashes: self.require_hashes,
}
}
}
7 changes: 7 additions & 0 deletions crates/uv/src/commands/pip_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,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,
Expand All @@ -83,6 +84,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)
Expand Down Expand Up @@ -291,6 +297,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.
Expand Down
6 changes: 6 additions & 0 deletions crates/uv/src/commands/pip_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,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,
Expand All @@ -63,6 +64,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)
Expand Down Expand Up @@ -288,6 +293,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.
Expand Down
30 changes: 30 additions & 0 deletions crates/uv/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,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,
Expand Down Expand Up @@ -862,6 +876,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
Expand Down Expand Up @@ -1644,6 +1672,7 @@ async fn run() -> Result<ExitStatus> {
&reinstall,
args.link_mode,
args.compile,
args.require_hashes,
index_urls,
args.index_strategy,
args.keyring_provider,
Expand Down Expand Up @@ -1744,6 +1773,7 @@ async fn run() -> Result<ExitStatus> {
reinstall,
args.link_mode,
args.compile,
args.require_hashes,
setup_py,
if args.offline {
Connectivity::Offline
Expand Down

0 comments on commit ec16897

Please sign in to comment.