Skip to content

Commit

Permalink
Introduce Resolver vs. Installer vs. Complete
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Jun 13, 2024
1 parent a809ec6 commit 3e83554
Show file tree
Hide file tree
Showing 12 changed files with 516 additions and 315 deletions.
10 changes: 5 additions & 5 deletions crates/uv-workspace/src/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use uv_configuration::{ConfigSettings, IndexStrategy, KeyringProviderType, Targe
use uv_resolver::{AnnotationStyle, ExcludeNewer, PreReleaseMode, ResolutionMode};
use uv_toolchain::PythonVersion;

use crate::{GlobalOptions, InstallerOptions, Options, PipOptions, Workspace};
use crate::{CompleteOptions, GlobalOptions, Options, PipOptions, Workspace};

pub trait Combine {
/// Combine two values, preferring the values in `self`.
Expand Down Expand Up @@ -42,7 +42,7 @@ impl Combine for Options {
fn combine(self, other: Options) -> Options {
Options {
globals: self.globals.combine(other.globals),
installer: self.installer.combine(other.installer),
top_level: self.top_level.combine(other.top_level),
pip: self.pip.combine(other.pip),
override_dependencies: self
.override_dependencies
Expand All @@ -63,9 +63,9 @@ impl Combine for GlobalOptions {
}
}

impl Combine for InstallerOptions {
fn combine(self, other: InstallerOptions) -> InstallerOptions {
InstallerOptions {
impl Combine for CompleteOptions {
fn combine(self, other: CompleteOptions) -> CompleteOptions {
CompleteOptions {
index_url: self.index_url.combine(other.index_url),
extra_index_url: self.extra_index_url.combine(other.extra_index_url),
no_index: self.no_index.combine(other.no_index),
Expand Down
93 changes: 65 additions & 28 deletions crates/uv-workspace/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub struct Options {
#[serde(flatten)]
pub globals: GlobalOptions,
#[serde(flatten)]
pub installer: InstallerOptions,
pub top_level: CompleteOptions,
pub pip: Option<PipOptions>,
#[cfg_attr(
feature = "schemars",
Expand All @@ -60,12 +60,49 @@ pub struct GlobalOptions {
pub preview: Option<bool>,
}

/// Shared settings, relevant to all dependency management operations.
/// Settings relevant to all installer operations.
#[allow(dead_code)]
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct InstallerOptions {
pub index_url: Option<IndexUrl>,
pub extra_index_url: Option<Vec<IndexUrl>>,
pub no_index: Option<bool>,
pub find_links: Option<Vec<FlatIndexLocation>>,
pub index_strategy: Option<IndexStrategy>,
pub keyring_provider: Option<KeyringProviderType>,
pub config_settings: Option<ConfigSettings>,
pub link_mode: Option<LinkMode>,
pub compile_bytecode: Option<bool>,
}

/// Settings relevant to all resolver operations.
#[allow(dead_code)]
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct ResolverOptions {
pub index_url: Option<IndexUrl>,
pub extra_index_url: Option<Vec<IndexUrl>>,
pub no_index: Option<bool>,
pub find_links: Option<Vec<FlatIndexLocation>>,
pub index_strategy: Option<IndexStrategy>,
pub keyring_provider: Option<KeyringProviderType>,
pub resolution: Option<ResolutionMode>,
pub prerelease: Option<PreReleaseMode>,
pub config_settings: Option<ConfigSettings>,
pub exclude_newer: Option<ExcludeNewer>,
pub link_mode: Option<LinkMode>,
}

/// Shared settings, relevant to all operations that must resolve and install dependencies. The
/// union of [`InstallerOptions`] and [`ResolverOptions`].
#[allow(dead_code)]
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct CompleteOptions {
pub index_url: Option<IndexUrl>,
pub extra_index_url: Option<Vec<IndexUrl>>,
pub no_index: Option<bool>,
Expand Down Expand Up @@ -185,33 +222,33 @@ impl Options {
concurrent_installs,
} = self.pip.unwrap_or_default();

let InstallerOptions {
index_url: resolver_index_url,
extra_index_url: resolver_extra_index_url,
no_index: resolver_no_index,
find_links: resolver_find_links,
index_strategy: resolver_index_strategy,
keyring_provider: resolver_keyring_provider,
resolution: resolver_resolution,
prerelease: resolver_prerelease,
config_settings: resolver_config_settings,
exclude_newer: resolver_exclude_newer,
link_mode: resolver_link_mode,
compile_bytecode: resolver_compile_bytecode,
} = self.installer;
let CompleteOptions {
index_url: top_level_index_url,
extra_index_url: top_level_extra_index_url,
no_index: top_level_no_index,
find_links: top_level_find_links,
index_strategy: top_level_index_strategy,
keyring_provider: top_level_keyring_provider,
resolution: top_level_resolution,
prerelease: top_level_prerelease,
config_settings: top_level_config_settings,
exclude_newer: top_level_exclude_newer,
link_mode: top_level_link_mode,
compile_bytecode: top_level_compile_bytecode,
} = self.top_level;

PipOptions {
python,
system,
break_system_packages,
target,
prefix,
index_url: index_url.or(resolver_index_url),
extra_index_url: extra_index_url.or(resolver_extra_index_url),
no_index: no_index.or(resolver_no_index),
find_links: find_links.or(resolver_find_links),
index_strategy: index_strategy.or(resolver_index_strategy),
keyring_provider: keyring_provider.or(resolver_keyring_provider),
index_url: index_url.or(top_level_index_url),
extra_index_url: extra_index_url.or(top_level_extra_index_url),
no_index: no_index.or(top_level_no_index),
find_links: find_links.or(top_level_find_links),
index_strategy: index_strategy.or(top_level_index_strategy),
keyring_provider: keyring_provider.or(top_level_keyring_provider),
no_build,
no_binary,
only_binary,
Expand All @@ -220,27 +257,27 @@ impl Options {
extra,
all_extras,
no_deps,
resolution: resolution.or(resolver_resolution),
prerelease: prerelease.or(resolver_prerelease),
resolution: resolution.or(top_level_resolution),
prerelease: prerelease.or(top_level_prerelease),
output_file,
no_strip_extras,
no_annotate,
no_header,
custom_compile_command,
generate_hashes,
legacy_setup_py,
config_settings: config_settings.or(resolver_config_settings),
config_settings: config_settings.or(top_level_config_settings),
python_version,
python_platform,
exclude_newer: exclude_newer.or(resolver_exclude_newer),
exclude_newer: exclude_newer.or(top_level_exclude_newer),
no_emit_package,
emit_index_url,
emit_find_links,
emit_marker_expression,
emit_index_annotation,
annotation_style,
link_mode: link_mode.or(resolver_link_mode),
compile_bytecode: compile_bytecode.or(resolver_compile_bytecode),
link_mode: link_mode.or(top_level_link_mode),
compile_bytecode: compile_bytecode.or(top_level_compile_bytecode),
require_hashes,
concurrent_builds,
concurrent_downloads,
Expand Down
34 changes: 17 additions & 17 deletions crates/uv/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,7 @@ pub(crate) struct PipCompileArgs {
pub(crate) no_all_extras: bool,

#[command(flatten)]
pub(crate) compile: CompilerArgs,
pub(crate) resolver: ResolverArgs,

/// Ignore package dependencies, instead only add those packages explicitly listed
/// on the command line to the resulting the requirements file.
Expand Down Expand Up @@ -607,7 +607,14 @@ pub(crate) struct PipSyncArgs {
pub(crate) constraint: Vec<Maybe<PathBuf>>,

#[command(flatten)]
pub(crate) sync: SyncerArgs,
pub(crate) installer: InstallerArgs,

/// Limit candidate packages to those that were uploaded prior to the given date.
///
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same
/// format (e.g., `2006-12-02`).
#[arg(long, env = "UV_EXCLUDE_NEWER")]
pub(crate) exclude_newer: Option<ExcludeNewer>,

/// Reinstall all packages, regardless of whether they're already installed.
#[arg(long, alias = "force-reinstall", overrides_with("no_reinstall"))]
Expand Down Expand Up @@ -884,7 +891,7 @@ pub(crate) struct PipInstallArgs {
pub(crate) no_all_extras: bool,

#[command(flatten)]
pub(crate) install: InstallerArgs,
pub(crate) installer: CompleteArgs,

/// Allow package upgrades.
#[arg(long, short = 'U', overrides_with("no_upgrade"))]
Expand Down Expand Up @@ -1591,7 +1598,7 @@ pub(crate) struct RunArgs {
pub(crate) upgrade_package: Vec<PackageName>,

#[command(flatten)]
pub(crate) install: InstallerArgs,
pub(crate) installer: CompleteArgs,

/// The Python interpreter to use to build the run environment.
///
Expand Down Expand Up @@ -1653,7 +1660,7 @@ pub(crate) struct SyncArgs {
pub(crate) refresh_package: Vec<PackageName>,

#[command(flatten)]
pub(crate) sync: SyncerArgs,
pub(crate) installer: InstallerArgs,

/// The Python interpreter to use to build the run environment.
///
Expand Down Expand Up @@ -1701,7 +1708,7 @@ pub(crate) struct LockArgs {
pub(crate) upgrade_package: Vec<PackageName>,

#[command(flatten)]
pub(crate) compile: CompilerArgs,
pub(crate) resolver: ResolverArgs,

/// The Python interpreter to use to build the run environment.
///
Expand Down Expand Up @@ -1797,7 +1804,7 @@ pub(crate) struct ToolRunArgs {
pub(crate) with: Vec<String>,

#[command(flatten)]
pub(crate) install: InstallerArgs,
pub(crate) installer: CompleteArgs,

/// The Python interpreter to use to build the run environment.
///
Expand Down Expand Up @@ -1898,7 +1905,7 @@ pub(crate) struct IndexArgs {

/// Arguments that are used by commands that need to install (but not resolve) packages.
#[derive(Args)]
pub(crate) struct SyncerArgs {
pub(crate) struct InstallerArgs {
#[command(flatten)]
pub(crate) index_args: IndexArgs,

Expand All @@ -1924,13 +1931,6 @@ pub(crate) struct SyncerArgs {
#[arg(long, short = 'C', alias = "config-settings")]
pub(crate) config_setting: Option<Vec<ConfigSettingEntry>>,

/// Limit candidate packages to those that were uploaded prior to the given date.
///
/// Accepts both RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`) and UTC dates in the same
/// format (e.g., `2006-12-02`).
#[arg(long, env = "UV_EXCLUDE_NEWER")]
pub(crate) exclude_newer: Option<ExcludeNewer>,

/// The method to use when installing packages from the global cache.
///
/// Defaults to `clone` (also known as Copy-on-Write) on macOS, and `hardlink` on Linux and
Expand Down Expand Up @@ -1961,7 +1961,7 @@ pub(crate) struct SyncerArgs {

/// Arguments that are used by commands that need to resolve (but not install) packages.
#[derive(Args)]
pub(crate) struct CompilerArgs {
pub(crate) struct ResolverArgs {
#[command(flatten)]
pub(crate) index_args: IndexArgs,

Expand Down Expand Up @@ -2024,7 +2024,7 @@ pub(crate) struct CompilerArgs {

/// Arguments that are used by commands that need to resolve and install packages.
#[derive(Args)]
pub(crate) struct InstallerArgs {
pub(crate) struct CompleteArgs {
#[command(flatten)]
pub(crate) index_args: IndexArgs,

Expand Down
21 changes: 17 additions & 4 deletions crates/uv/src/commands/project/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use uv_warnings::warn_user;

use crate::commands::{project, ExitStatus};
use crate::printer::Printer;
use crate::settings::InstallerSettings;
use crate::settings::{InstallerSettings, ResolverSettings};

/// Add one or more packages to the project requirements.
#[allow(clippy::too_many_arguments)]
Expand Down Expand Up @@ -49,7 +49,7 @@ pub(crate) async fn add(
let venv = project::init_environment(project.workspace(), python.as_deref(), cache, printer)?;

// Use the default settings.
let settings = InstallerSettings::default();
let settings = ResolverSettings::default();
let upgrade = Upgrade::default();

// Lock and sync the environment.
Expand All @@ -65,7 +65,14 @@ pub(crate) async fn add(
project.workspace(),
venv.interpreter(),
upgrade,
&settings,
&settings.index_locations,
&settings.index_strategy,
&settings.keyring_provider,
&settings.resolution,
&settings.prerelease,
&settings.config_setting,
settings.exclude_newer.as_ref(),
&settings.link_mode,
preview,
connectivity,
concurrency,
Expand All @@ -77,6 +84,7 @@ pub(crate) async fn add(

// Perform a full sync, because we don't know what exactly is affected by the removal.
// TODO(ibraheem): Should we accept CLI overrides for this? Should we even sync here?
let settings = InstallerSettings::default();
let extras = ExtrasSpecification::All;
let dev = true;

Expand All @@ -87,7 +95,12 @@ pub(crate) async fn add(
&lock,
extras,
dev,
&settings,
&settings.index_locations,
&settings.index_strategy,
&settings.keyring_provider,
&settings.config_setting,
&settings.link_mode,
&settings.compile_bytecode,
preview,
connectivity,
concurrency,
Expand Down
Loading

0 comments on commit 3e83554

Please sign in to comment.