Skip to content

Commit

Permalink
refactor: use a struct for install options (#6561)
Browse files Browse the repository at this point in the history
## Summary

Closes #6545.

## Test Plan

Relying on existing tests.
  • Loading branch information
mkniewallner authored Aug 27, 2024
1 parent 680dcc3 commit 6a988ac
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 98 deletions.
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

0 comments on commit 6a988ac

Please sign in to comment.