Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use a struct for install options #6561

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/uv-configuration/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@ license = { workspace = true }
workspace = true

[dependencies]
distribution-types = { workspace = true }
pep508_rs = { workspace = true, features = ["schemars"] }
platform-tags = { workspace = true }
pypi-types = { workspace = true }
uv-auth = { workspace = true }
uv-cache = { workspace = true }
uv-normalize = { workspace = true }
uv-workspace = { workspace = true }

clap = { workspace = true, features = ["derive"], optional = true }
either = { workspace = true }
Expand Down
85 changes: 85 additions & 0 deletions crates/uv-configuration/src/install_options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use rustc_hash::FxHashSet;
use tracing::debug;

use distribution_types::{Name, Resolution};
use pep508_rs::PackageName;
use uv_workspace::VirtualProject;

#[derive(Debug, Clone, Default)]
pub struct InstallOptions {
pub no_install_project: bool,
pub no_install_workspace: bool,
pub no_install_package: Vec<PackageName>,
}

impl InstallOptions {
pub fn new(
no_install_project: bool,
no_install_workspace: bool,
no_install_package: Vec<PackageName>,
) -> Self {
Self {
no_install_project,
no_install_workspace,
no_install_package,
}
}

pub fn filter_resolution(
&self,
resolution: Resolution,
project: &VirtualProject,
) -> Resolution {
// If `--no-install-project` is set, remove the project itself.
let resolution = self.apply_no_install_project(resolution, project);

// If `--no-install-workspace` is set, remove the project and any workspace members.
let resolution = self.apply_no_install_workspace(resolution, project);

// If `--no-install-package` is provided, remove the requested packages.
self.apply_no_install_package(resolution)
}

fn apply_no_install_project(
&self,
resolution: Resolution,
project: &VirtualProject,
) -> Resolution {
if !self.no_install_project {
return resolution;
}

let Some(project_name) = project.project_name() else {
debug!("Ignoring `--no-install-project` for virtual workspace");
return resolution;
};

resolution.filter(|dist| dist.name() != project_name)
}

fn apply_no_install_workspace(
&self,
resolution: Resolution,
project: &VirtualProject,
) -> Resolution {
if !self.no_install_workspace {
return resolution;
}

let workspace_packages = project.workspace().packages();
resolution.filter(|dist| {
!workspace_packages.contains_key(dist.name())
&& Some(dist.name()) != project.project_name()
})
}

fn apply_no_install_package(&self, resolution: Resolution) -> Resolution {
if self.no_install_package.is_empty() {
return resolution;
}

let no_install_packages = self.no_install_package.iter().collect::<FxHashSet<_>>();

resolution.filter(|dist| !no_install_packages.contains(dist.name()))
}
}
2 changes: 2 additions & 0 deletions crates/uv-configuration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub use config_settings::*;
pub use constraints::*;
pub use extras::*;
pub use hash::*;
pub use install_options::*;
pub use name_specifiers::*;
pub use overrides::*;
pub use package_options::*;
Expand All @@ -19,6 +20,7 @@ mod config_settings;
mod constraints;
mod extras;
mod hash;
mod install_options;
mod name_specifiers;
mod overrides;
mod package_options;
Expand Down
10 changes: 3 additions & 7 deletions crates/uv/src/commands/project/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use pypi_types::redact_git_credentials;
use uv_auth::{store_credentials_from_url, Credentials};
use uv_cache::Cache;
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{Concurrency, ExtrasSpecification, SourceStrategy};
use uv_configuration::{Concurrency, ExtrasSpecification, InstallOptions, SourceStrategy};
use uv_dispatch::BuildDispatch;
use uv_distribution::DistributionDatabase;
use uv_fs::{Simplified, CWD};
Expand Down Expand Up @@ -642,19 +642,15 @@ pub(crate) async fn add(

// Initialize any shared state.
let state = SharedState::default();
let no_install_root = false;
let no_install_workspace = false;
let no_install_package = vec![];
let install_options = InstallOptions::default();

if let Err(err) = project::sync::do_sync(
&project,
&venv,
&lock,
&extras,
dev,
no_install_root,
no_install_workspace,
no_install_package,
install_options,
Modifications::Sufficient,
settings.as_ref().into(),
&state,
Expand Down
10 changes: 3 additions & 7 deletions crates/uv/src/commands/project/remove.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use owo_colors::OwoColorize;
use pep508_rs::PackageName;
use uv_cache::Cache;
use uv_client::Connectivity;
use uv_configuration::{Concurrency, ExtrasSpecification};
use uv_configuration::{Concurrency, ExtrasSpecification, InstallOptions};
use uv_fs::{Simplified, CWD};
use uv_python::{PythonDownloads, PythonPreference, PythonRequest};
use uv_scripts::Pep723Script;
Expand Down Expand Up @@ -190,9 +190,7 @@ pub(crate) async fn remove(
// TODO(ibraheem): Should we accept CLI overrides for this? Should we even sync here?
let extras = ExtrasSpecification::All;
let dev = true;
let no_install_project = false;
let no_install_workspace = false;
let no_install_package = vec![];
let install_options = InstallOptions::default();

// Initialize any shared state.
let state = SharedState::default();
Expand All @@ -203,9 +201,7 @@ pub(crate) async fn remove(
&lock,
&extras,
dev,
no_install_project,
no_install_workspace,
no_install_package,
install_options,
Modifications::Exact,
settings.as_ref().into(),
&state,
Expand Down
10 changes: 3 additions & 7 deletions crates/uv/src/commands/project/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use tracing::{debug, warn};
use uv_cache::Cache;
use uv_cli::ExternalCommand;
use uv_client::{BaseClientBuilder, Connectivity};
use uv_configuration::{Concurrency, ExtrasSpecification};
use uv_configuration::{Concurrency, ExtrasSpecification, InstallOptions};
use uv_distribution::LoweredRequirement;
use uv_fs::{PythonExt, Simplified, CWD};
use uv_installer::{SatisfiesResult, SitePackages};
Expand Down Expand Up @@ -419,19 +419,15 @@ pub(crate) async fn run(
Err(err) => return Err(err.into()),
};

let no_install_root = false;
let no_install_workspace = false;
let no_install_package = vec![];
let install_options = InstallOptions::default();

project::sync::do_sync(
&project,
&venv,
result.lock(),
&extras,
dev,
no_install_root,
no_install_workspace,
no_install_package,
install_options,
Modifications::Sufficient,
settings.as_ref().into(),
&state,
Expand Down
72 changes: 6 additions & 66 deletions crates/uv/src/commands/project/sync.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
use anyhow::{Context, Result};
use distribution_types::Name;
use itertools::Itertools;
use pep508_rs::MarkerTree;
use rustc_hash::FxHashSet;
use tracing::debug;
use uv_auth::store_credentials_from_url;
use uv_cache::Cache;
use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{Concurrency, ExtrasSpecification, HashCheckingMode};
use uv_configuration::{Concurrency, ExtrasSpecification, HashCheckingMode, InstallOptions};
use uv_dispatch::BuildDispatch;
use uv_fs::CWD;
use uv_installer::SitePackages;
Expand All @@ -33,9 +30,7 @@ pub(crate) async fn sync(
package: Option<PackageName>,
extras: ExtrasSpecification,
dev: bool,
no_install_project: bool,
no_install_workspace: bool,
no_install_package: Vec<PackageName>,
install_options: InstallOptions,
modifications: Modifications,
python: Option<String>,
python_preference: PythonPreference,
Expand Down Expand Up @@ -108,9 +103,7 @@ pub(crate) async fn sync(
&lock,
&extras,
dev,
no_install_project,
no_install_workspace,
no_install_package,
install_options,
modifications,
settings.as_ref().into(),
&state,
Expand All @@ -134,9 +127,7 @@ pub(super) async fn do_sync(
lock: &Lock,
extras: &ExtrasSpecification,
dev: bool,
no_install_project: bool,
no_install_workspace: bool,
no_install_package: Vec<PackageName>,
install_options: InstallOptions,
modifications: Modifications,
settings: InstallerSettingsRef<'_>,
state: &SharedState,
Expand Down Expand Up @@ -203,14 +194,8 @@ pub(super) async fn do_sync(
// Read the lockfile.
let resolution = lock.to_resolution(project, &markers, tags, extras, &dev)?;

// If `--no-install-project` is set, remove the project itself.
let resolution = apply_no_install_project(no_install_project, resolution, project);

// If `--no-install-workspace` is set, remove the project and any workspace members.
let resolution = apply_no_install_workspace(no_install_workspace, resolution, project);

// If `--no-install-package` is provided, remove the requested packages.
let resolution = apply_no_install_package(&no_install_package, resolution);
// Filter resolution based on install-specific options.
let resolution = install_options.filter_resolution(resolution, project);

// Add all authenticated sources to the cache.
for url in index_locations.urls() {
Expand Down Expand Up @@ -302,48 +287,3 @@ pub(super) async fn do_sync(

Ok(())
}

fn apply_no_install_project(
no_install_project: bool,
resolution: distribution_types::Resolution,
project: &VirtualProject,
) -> distribution_types::Resolution {
if !no_install_project {
return resolution;
}

let Some(project_name) = project.project_name() else {
debug!("Ignoring `--no-install-project` for virtual workspace");
return resolution;
};

resolution.filter(|dist| dist.name() != project_name)
}

fn apply_no_install_workspace(
no_install_workspace: bool,
resolution: distribution_types::Resolution,
project: &VirtualProject,
) -> distribution_types::Resolution {
if !no_install_workspace {
return resolution;
}

let workspace_packages = project.workspace().packages();
resolution.filter(|dist| {
!workspace_packages.contains_key(dist.name()) && Some(dist.name()) != project.project_name()
})
}

fn apply_no_install_package(
no_install_package: &[PackageName],
resolution: distribution_types::Resolution,
) -> distribution_types::Resolution {
if no_install_package.is_empty() {
return resolution;
}

let no_install_packages = no_install_package.iter().collect::<FxHashSet<_>>();

resolution.filter(|dist| !no_install_packages.contains(dist.name()))
}
4 changes: 1 addition & 3 deletions crates/uv/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1107,9 +1107,7 @@ async fn run_project(
args.package,
args.extras,
args.dev,
args.no_install_project,
args.no_install_workspace,
args.no_install_package,
args.install_options,
args.modifications,
args.python,
globals.python_preference,
Expand Down
16 changes: 8 additions & 8 deletions crates/uv/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ use uv_cli::{
use uv_client::Connectivity;
use uv_configuration::{
BuildOptions, Concurrency, ConfigSettings, ExtrasSpecification, HashCheckingMode,
IndexStrategy, KeyringProviderType, NoBinary, NoBuild, PreviewMode, Reinstall, SourceStrategy,
TargetTriple, Upgrade,
IndexStrategy, InstallOptions, KeyringProviderType, NoBinary, NoBuild, PreviewMode, Reinstall,
SourceStrategy, TargetTriple, Upgrade,
};
use uv_normalize::PackageName;
use uv_python::{Prefix, PythonDownloads, PythonPreference, PythonVersion, Target};
Expand Down Expand Up @@ -630,9 +630,7 @@ pub(crate) struct SyncSettings {
pub(crate) frozen: bool,
pub(crate) extras: ExtrasSpecification,
pub(crate) dev: bool,
pub(crate) no_install_project: bool,
pub(crate) no_install_workspace: bool,
pub(crate) no_install_package: Vec<PackageName>,
pub(crate) install_options: InstallOptions,
pub(crate) modifications: Modifications,
pub(crate) package: Option<PackageName>,
pub(crate) python: Option<String>,
Expand Down Expand Up @@ -677,9 +675,11 @@ impl SyncSettings {
extra.unwrap_or_default(),
),
dev: flag(dev, no_dev).unwrap_or(true),
no_install_project,
no_install_workspace,
no_install_package,
install_options: InstallOptions::new(
no_install_project,
no_install_workspace,
no_install_package,
),
modifications: if flag(exact, inexact).unwrap_or(true) {
Modifications::Exact
} else {
Expand Down
Loading