Implement settings conversion traits (#4489)

## Summary

This does require cloning the settings, but I think it's fine. A better
solution would be to have owned and unowned settings structs, so that we
could convert `ResolverInstallerSettingsRef` to `InstallerSettingsRef`
without cloning, but that requires maintaining owned and unowned
variants.

Closes https://github.com/astral-sh/uv/issues/4455.
This commit is contained in:
Charlie Marsh 2024-06-24 23:08:11 +03:00 committed by GitHub
parent ff72bb9bcc
commit 8afad69b03
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 85 additions and 119 deletions

View File

@ -186,16 +186,7 @@ pub(crate) async fn add(
let lock = project::lock::do_lock( let lock = project::lock::do_lock(
project.workspace(), project.workspace(),
venv.interpreter(), venv.interpreter(),
&settings.upgrade, settings.clone().into(),
&settings.index_locations,
settings.index_strategy,
settings.keyring_provider,
settings.resolution,
settings.prerelease,
&settings.config_setting,
settings.exclude_newer,
settings.link_mode,
&settings.build_options,
preview, preview,
connectivity, connectivity,
concurrency, concurrency,
@ -218,14 +209,7 @@ pub(crate) async fn add(
extras, extras,
dev, dev,
Modifications::Sufficient, Modifications::Sufficient,
&settings.reinstall, settings.into(),
&settings.index_locations,
settings.index_strategy,
settings.keyring_provider,
&settings.config_setting,
settings.link_mode,
settings.compile_bytecode,
&settings.build_options,
preview, preview,
connectivity, connectivity,
concurrency, concurrency,

View File

@ -2,23 +2,16 @@ use std::collections::Bound;
use anstream::eprint; use anstream::eprint;
use distribution_types::{IndexLocations, UnresolvedRequirementSpecification}; use distribution_types::UnresolvedRequirementSpecification;
use install_wheel_rs::linker::LinkMode;
use pep508_rs::RequirementOrigin; use pep508_rs::RequirementOrigin;
use uv_cache::Cache; use uv_cache::Cache;
use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{ use uv_configuration::{Concurrency, ExtrasSpecification, PreviewMode, Reinstall, SetupPyStrategy};
BuildOptions, Concurrency, ConfigSettings, ExtrasSpecification, IndexStrategy,
KeyringProviderType, PreviewMode, Reinstall, SetupPyStrategy, Upgrade,
};
use uv_dispatch::BuildDispatch; use uv_dispatch::BuildDispatch;
use uv_distribution::{Workspace, DEV_DEPENDENCIES}; use uv_distribution::{Workspace, DEV_DEPENDENCIES};
use uv_git::GitResolver; use uv_git::GitResolver;
use uv_requirements::upgrade::{read_lockfile, LockedRequirements}; use uv_requirements::upgrade::{read_lockfile, LockedRequirements};
use uv_resolver::{ use uv_resolver::{FlatIndex, InMemoryIndex, Lock, OptionsBuilder, RequiresPython};
ExcludeNewer, FlatIndex, InMemoryIndex, Lock, OptionsBuilder, PreReleaseMode, RequiresPython,
ResolutionMode,
};
use uv_toolchain::{Interpreter, ToolchainPreference, ToolchainRequest}; use uv_toolchain::{Interpreter, ToolchainPreference, ToolchainRequest};
use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight}; use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight};
use uv_warnings::warn_user; use uv_warnings::warn_user;
@ -64,16 +57,7 @@ pub(crate) async fn lock(
match do_lock( match do_lock(
&workspace, &workspace,
&interpreter, &interpreter,
&settings.upgrade, settings,
&settings.index_locations,
settings.index_strategy,
settings.keyring_provider,
settings.resolution,
settings.prerelease,
&settings.config_setting,
settings.exclude_newer,
settings.link_mode,
&settings.build_options,
preview, preview,
connectivity, connectivity,
concurrency, concurrency,
@ -101,16 +85,7 @@ pub(crate) async fn lock(
pub(super) async fn do_lock( pub(super) async fn do_lock(
workspace: &Workspace, workspace: &Workspace,
interpreter: &Interpreter, interpreter: &Interpreter,
upgrade: &Upgrade, settings: ResolverSettings,
index_locations: &IndexLocations,
index_strategy: IndexStrategy,
keyring_provider: KeyringProviderType,
resolution: ResolutionMode,
prerelease: PreReleaseMode,
config_setting: &ConfigSettings,
exclude_newer: Option<ExcludeNewer>,
link_mode: LinkMode,
build_options: &BuildOptions,
preview: PreviewMode, preview: PreviewMode,
connectivity: Connectivity, connectivity: Connectivity,
concurrency: Concurrency, concurrency: Concurrency,
@ -118,6 +93,20 @@ pub(super) async fn do_lock(
cache: &Cache, cache: &Cache,
printer: Printer, printer: Printer,
) -> Result<Lock, ProjectError> { ) -> Result<Lock, ProjectError> {
// Extract the project settings.
let ResolverSettings {
index_locations,
index_strategy,
keyring_provider,
resolution,
prerelease,
config_setting,
exclude_newer,
link_mode,
upgrade,
build_options,
} = settings;
// When locking, include the project itself (as editable). // When locking, include the project itself (as editable).
let requirements = workspace let requirements = workspace
.members_as_requirements() .members_as_requirements()
@ -204,11 +193,11 @@ pub(super) async fn do_lock(
let flat_index = { let flat_index = {
let client = FlatIndexClient::new(&client, cache); let client = FlatIndexClient::new(&client, cache);
let entries = client.fetch(index_locations.flat_index()).await?; let entries = client.fetch(index_locations.flat_index()).await?;
FlatIndex::from_entries(entries, None, &hasher, build_options) FlatIndex::from_entries(entries, None, &hasher, &build_options)
}; };
// If an existing lockfile exists, build up a set of preferences. // If an existing lockfile exists, build up a set of preferences.
let LockedRequirements { preferences, git } = read_lockfile(workspace, upgrade).await?; let LockedRequirements { preferences, git } = read_lockfile(workspace, &upgrade).await?;
// Create the Git resolver. // Create the Git resolver.
let git = GitResolver::from_refs(git); let git = GitResolver::from_refs(git);
@ -218,17 +207,17 @@ pub(super) async fn do_lock(
&client, &client,
cache, cache,
interpreter, interpreter,
index_locations, &index_locations,
&flat_index, &flat_index,
&index, &index,
&git, &git,
&in_flight, &in_flight,
index_strategy, index_strategy,
setup_py, setup_py,
config_setting, &config_setting,
build_isolation, build_isolation,
link_mode, link_mode,
build_options, &build_options,
exclude_newer, exclude_newer,
concurrency, concurrency,
preview, preview,
@ -247,7 +236,7 @@ pub(super) async fn do_lock(
EmptyInstalledPackages, EmptyInstalledPackages,
&hasher, &hasher,
&Reinstall::default(), &Reinstall::default(),
upgrade, &upgrade,
interpreter, interpreter,
None, None,
None, None,

View File

@ -101,16 +101,7 @@ pub(crate) async fn remove(
let lock = project::lock::do_lock( let lock = project::lock::do_lock(
project.workspace(), project.workspace(),
venv.interpreter(), venv.interpreter(),
&settings.upgrade, settings,
&settings.index_locations,
settings.index_strategy,
settings.keyring_provider,
settings.resolution,
settings.prerelease,
&settings.config_setting,
settings.exclude_newer,
settings.link_mode,
&settings.build_options,
preview, preview,
connectivity, connectivity,
concurrency, concurrency,
@ -134,14 +125,7 @@ pub(crate) async fn remove(
extras, extras,
dev, dev,
Modifications::Exact, Modifications::Exact,
&settings.reinstall, settings,
&settings.index_locations,
settings.index_strategy,
settings.keyring_provider,
&settings.config_setting,
settings.link_mode,
settings.compile_bytecode,
&settings.build_options,
preview, preview,
connectivity, connectivity,
concurrency, concurrency,

View File

@ -78,16 +78,7 @@ pub(crate) async fn run(
let lock = project::lock::do_lock( let lock = project::lock::do_lock(
project.workspace(), project.workspace(),
venv.interpreter(), venv.interpreter(),
&settings.upgrade, settings.clone().into(),
&settings.index_locations,
settings.index_strategy,
settings.keyring_provider,
settings.resolution,
settings.prerelease,
&settings.config_setting,
settings.exclude_newer,
settings.link_mode,
&settings.build_options,
preview, preview,
connectivity, connectivity,
concurrency, concurrency,
@ -104,14 +95,7 @@ pub(crate) async fn run(
extras, extras,
dev, dev,
Modifications::Sufficient, Modifications::Sufficient,
&settings.reinstall, settings.clone().into(),
&settings.index_locations,
settings.index_strategy,
settings.keyring_provider,
&settings.config_setting,
settings.link_mode,
settings.compile_bytecode,
&settings.build_options,
preview, preview,
connectivity, connectivity,
concurrency, concurrency,

View File

@ -2,14 +2,9 @@ use std::path::Path;
use anyhow::Result; use anyhow::Result;
use distribution_types::IndexLocations;
use install_wheel_rs::linker::LinkMode;
use uv_cache::Cache; use uv_cache::Cache;
use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder}; use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{ use uv_configuration::{Concurrency, ExtrasSpecification, PreviewMode, SetupPyStrategy};
BuildOptions, Concurrency, ConfigSettings, ExtrasSpecification, IndexStrategy,
KeyringProviderType, PreviewMode, Reinstall, SetupPyStrategy,
};
use uv_dispatch::BuildDispatch; use uv_dispatch::BuildDispatch;
use uv_distribution::{ProjectWorkspace, DEV_DEPENDENCIES}; use uv_distribution::{ProjectWorkspace, DEV_DEPENDENCIES};
use uv_git::GitResolver; use uv_git::GitResolver;
@ -77,14 +72,7 @@ pub(crate) async fn sync(
extras, extras,
dev, dev,
modifications, modifications,
&settings.reinstall, settings,
&settings.index_locations,
settings.index_strategy,
settings.keyring_provider,
&settings.config_setting,
settings.link_mode,
settings.compile_bytecode,
&settings.build_options,
preview, preview,
connectivity, connectivity,
concurrency, concurrency,
@ -107,14 +95,7 @@ pub(super) async fn do_sync(
extras: ExtrasSpecification, extras: ExtrasSpecification,
dev: bool, dev: bool,
modifications: Modifications, modifications: Modifications,
reinstall: &Reinstall, settings: InstallerSettings,
index_locations: &IndexLocations,
index_strategy: IndexStrategy,
keyring_provider: KeyringProviderType,
config_setting: &ConfigSettings,
link_mode: LinkMode,
compile_bytecode: bool,
build_options: &BuildOptions,
preview: PreviewMode, preview: PreviewMode,
connectivity: Connectivity, connectivity: Connectivity,
concurrency: Concurrency, concurrency: Concurrency,
@ -122,6 +103,18 @@ pub(super) async fn do_sync(
cache: &Cache, cache: &Cache,
printer: Printer, printer: Printer,
) -> Result<(), ProjectError> { ) -> Result<(), ProjectError> {
// Extract the project settings.
let InstallerSettings {
index_locations,
index_strategy,
keyring_provider,
config_setting,
link_mode,
compile_bytecode,
reinstall,
build_options,
} = settings;
// Validate that the Python version is supported by the lockfile. // Validate that the Python version is supported by the lockfile.
if let Some(requires_python) = lock.requires_python() { if let Some(requires_python) = lock.requires_python() {
if !requires_python.contains(venv.interpreter().python_version()) { if !requires_python.contains(venv.interpreter().python_version()) {
@ -174,7 +167,7 @@ pub(super) async fn do_sync(
let flat_index = { let flat_index = {
let client = FlatIndexClient::new(&client, cache); let client = FlatIndexClient::new(&client, cache);
let entries = client.fetch(index_locations.flat_index()).await?; let entries = client.fetch(index_locations.flat_index()).await?;
FlatIndex::from_entries(entries, Some(tags), &hasher, build_options) FlatIndex::from_entries(entries, Some(tags), &hasher, &build_options)
}; };
// Create a build dispatch. // Create a build dispatch.
@ -182,17 +175,17 @@ pub(super) async fn do_sync(
&client, &client,
cache, cache,
venv.interpreter(), venv.interpreter(),
index_locations, &index_locations,
&flat_index, &flat_index,
&index, &index,
&git, &git,
&in_flight, &in_flight,
index_strategy, index_strategy,
setup_py, setup_py,
config_setting, &config_setting,
build_isolation, build_isolation,
link_mode, link_mode,
build_options, &build_options,
exclude_newer, exclude_newer,
concurrency, concurrency,
preview, preview,
@ -205,11 +198,11 @@ pub(super) async fn do_sync(
&resolution, &resolution,
site_packages, site_packages,
modifications, modifications,
reinstall, &reinstall,
build_options, &build_options,
link_mode, link_mode,
compile_bytecode, compile_bytecode,
index_locations, &index_locations,
&hasher, &hasher,
tags, tags,
&client, &client,

View File

@ -1681,6 +1681,38 @@ impl PipSettings {
} }
} }
impl From<ResolverInstallerSettings> for ResolverSettings {
fn from(settings: ResolverInstallerSettings) -> Self {
Self {
index_locations: settings.index_locations,
index_strategy: settings.index_strategy,
keyring_provider: settings.keyring_provider,
resolution: settings.resolution,
prerelease: settings.prerelease,
config_setting: settings.config_setting,
exclude_newer: settings.exclude_newer,
link_mode: settings.link_mode,
upgrade: settings.upgrade,
build_options: settings.build_options,
}
}
}
impl From<ResolverInstallerSettings> for InstallerSettings {
fn from(settings: ResolverInstallerSettings) -> Self {
Self {
index_locations: settings.index_locations,
index_strategy: settings.index_strategy,
keyring_provider: settings.keyring_provider,
config_setting: settings.config_setting,
link_mode: settings.link_mode,
compile_bytecode: settings.compile_bytecode,
reinstall: settings.reinstall,
build_options: settings.build_options,
}
}
}
// Environment variables that are not exposed as CLI arguments. // Environment variables that are not exposed as CLI arguments.
mod env { mod env {
pub(super) const CONCURRENT_DOWNLOADS: (&str, &str) = pub(super) const CONCURRENT_DOWNLOADS: (&str, &str) =