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

Support no-build-isolation-package #5894

Merged
merged 4 commits into from
Aug 8, 2024
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
15 changes: 9 additions & 6 deletions crates/uv-build/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,22 +434,25 @@ impl SourceBuild {
Self::extract_pep517_backend(&source_tree, setup_py, &default_backend)
.map_err(|err| *err)?;

let package_name = project.clone().map(|p| p.name);

// Create a virtual environment, or install into the shared environment if requested.
let venv = match build_isolation {
BuildIsolation::Isolated => uv_virtualenv::create_venv(
let venv = if let Some(venv) = build_isolation.shared_environment(package_name.as_ref()) {
venv.clone()
} else {
uv_virtualenv::create_venv(
temp_dir.path(),
interpreter.clone(),
uv_virtualenv::Prompt::None,
false,
false,
false,
)?,
BuildIsolation::Shared(venv) => venv.clone(),
)?
};

// Setup the build environment. If build isolation is disabled, we assume the build
// environment is already setup.
if build_isolation.is_isolated() {
if build_isolation.is_isolated(package_name.as_ref()) {
let resolved_requirements = Self::get_resolved_requirements(
build_context,
source_build_context,
Expand Down Expand Up @@ -499,7 +502,7 @@ impl SourceBuild {
// Create the PEP 517 build environment. If build isolation is disabled, we assume the build
// environment is already setup.
let runner = PythonRunner::new(concurrent_builds);
if build_isolation.is_isolated() {
if build_isolation.is_isolated(package_name.as_ref()) {
if let Some(pep517_backend) = &pep517_backend {
create_pep517_build_environment(
&runner,
Expand Down
12 changes: 12 additions & 0 deletions crates/uv-cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3034,6 +3034,12 @@ pub struct ResolverArgs {
)]
pub no_build_isolation: bool,

/// Disable isolation when building source distributions for a specific package.
///
/// Assumes that the packages' build dependencies specified by PEP 518 are already installed.
#[arg(long, help_heading = "Build options")]
pub no_build_isolation_package: Vec<PackageName>,

#[arg(
long,
overrides_with("no_build_isolation"),
Expand Down Expand Up @@ -3199,6 +3205,12 @@ pub struct ResolverInstallerArgs {
)]
pub no_build_isolation: bool,

/// Disable isolation when building source distributions for a specific package.
///
/// Assumes that the packages' build dependencies specified by PEP 518 are already installed.
#[arg(long, help_heading = "Build options")]
pub no_build_isolation_package: Vec<PackageName>,

#[arg(
long,
overrides_with("no_build_isolation"),
Expand Down
8 changes: 8 additions & 0 deletions crates/uv-cli/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ impl From<ResolverArgs> for PipOptions {
pre,
config_setting,
no_build_isolation,
no_build_isolation_package,
build_isolation,
exclude_newer,
link_mode,
Expand All @@ -63,6 +64,7 @@ impl From<ResolverArgs> for PipOptions {
config_settings: config_setting
.map(|config_settings| config_settings.into_iter().collect::<ConfigSettings>()),
no_build_isolation: flag(no_build_isolation, build_isolation),
no_build_isolation_package: Some(no_build_isolation_package),
exclude_newer,
link_mode,
no_sources: if no_sources { Some(true) } else { None },
Expand Down Expand Up @@ -124,6 +126,7 @@ impl From<ResolverInstallerArgs> for PipOptions {
pre,
config_setting,
no_build_isolation,
no_build_isolation_package,
build_isolation,
exclude_newer,
link_mode,
Expand All @@ -148,6 +151,7 @@ impl From<ResolverInstallerArgs> for PipOptions {
config_settings: config_setting
.map(|config_settings| config_settings.into_iter().collect::<ConfigSettings>()),
no_build_isolation: flag(no_build_isolation, build_isolation),
no_build_isolation_package: Some(no_build_isolation_package),
exclude_newer,
link_mode,
compile_bytecode: flag(compile_bytecode, no_compile_bytecode),
Expand Down Expand Up @@ -195,6 +199,7 @@ pub fn resolver_options(resolver_args: ResolverArgs, build_args: BuildArgs) -> R
pre,
config_setting,
no_build_isolation,
no_build_isolation_package,
build_isolation,
exclude_newer,
link_mode,
Expand Down Expand Up @@ -237,6 +242,7 @@ pub fn resolver_options(resolver_args: ResolverArgs, build_args: BuildArgs) -> R
config_settings: config_setting
.map(|config_settings| config_settings.into_iter().collect::<ConfigSettings>()),
no_build_isolation: flag(no_build_isolation, build_isolation),
no_build_isolation_package: Some(no_build_isolation_package),
exclude_newer,
link_mode,
no_build: flag(no_build, build),
Expand Down Expand Up @@ -267,6 +273,7 @@ pub fn resolver_installer_options(
pre,
config_setting,
no_build_isolation,
no_build_isolation_package,
build_isolation,
exclude_newer,
link_mode,
Expand Down Expand Up @@ -313,6 +320,7 @@ pub fn resolver_installer_options(
config_settings: config_setting
.map(|config_settings| config_settings.into_iter().collect::<ConfigSettings>()),
no_build_isolation: flag(no_build_isolation, build_isolation),
no_build_isolation_package: Some(no_build_isolation_package),
exclude_newer,
link_mode,
compile_bytecode: flag(compile_bytecode, no_compile_bytecode),
Expand Down
25 changes: 25 additions & 0 deletions crates/uv-settings/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ pub struct ResolverOptions {
pub no_binary: Option<bool>,
pub no_binary_package: Option<Vec<PackageName>>,
pub no_build_isolation: Option<bool>,
pub no_build_isolation_package: Option<Vec<PackageName>>,
pub no_sources: Option<bool>,
}

Expand Down Expand Up @@ -350,6 +351,18 @@ pub struct ResolverInstallerOptions {
"#
)]
pub no_build_isolation: Option<bool>,
/// Disable isolation when building source distributions for a specific package.
///
/// Assumes that the packages' build dependencies specified by [PEP 518](https://peps.python.org/pep-0518/)
/// are already installed.
#[option(
default = "[]",
value_type = "Vec<PackageName>",
example = r#"
no-build-isolation-package = ["package1", "package2"]
"#
)]
pub no_build_isolation_package: Option<Vec<PackageName>>,
/// Limit candidate packages to those that were uploaded prior to the given date.
///
/// Accepts both [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) timestamps (e.g.,
Expand Down Expand Up @@ -717,6 +730,18 @@ pub struct PipOptions {
"#
)]
pub no_build_isolation: Option<bool>,
/// Disable isolation when building source distributions for a specific package.
///
/// Assumes that the packages' build dependencies specified by [PEP 518](https://peps.python.org/pep-0518/)
/// are already installed.
#[option(
default = "[]",
value_type = "Vec<PackageName>",
example = r#"
no-build-isolation-package = ["package1", "package2"]
"#
)]
pub no_build_isolation_package: Option<Vec<PackageName>>,
/// Validate the Python environment, to detect packages with missing dependencies and other
/// issues.
#[option(
Expand Down
29 changes: 26 additions & 3 deletions crates/uv-types/src/builds.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use pep508_rs::PackageName;
use uv_python::PythonEnvironment;

/// Whether to enforce build isolation when building source distributions.
Expand All @@ -6,11 +7,33 @@ pub enum BuildIsolation<'a> {
#[default]
Isolated,
Shared(&'a PythonEnvironment),
SharedPackage(&'a PythonEnvironment, &'a [PackageName]),
}

impl<'a> BuildIsolation<'a> {
/// Returns `true` if build isolation is enforced.
pub fn is_isolated(&self) -> bool {
matches!(self, Self::Isolated)
/// Returns `true` if build isolation is enforced for the given package name.
pub fn is_isolated(&self, package: Option<&PackageName>) -> bool {
match self {
Self::Isolated => true,
Self::Shared(_) => false,
Self::SharedPackage(_, packages) => {
package.map_or(true, |package| !packages.iter().any(|p| p == package))
}
}
}

/// Returns the shared environment for a given package, if build isolation is not enforced.
pub fn shared_environment(&self, package: Option<&PackageName>) -> Option<&PythonEnvironment> {
match self {
Self::Isolated => None,
Self::Shared(env) => Some(env),
Self::SharedPackage(env, packages) => {
if package.is_some_and(|package| packages.iter().any(|p| p == package)) {
Some(env)
} else {
None
}
}
}
}
}
6 changes: 5 additions & 1 deletion crates/uv/src/commands/pip/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ pub(crate) async fn pip_compile(
config_settings: ConfigSettings,
connectivity: Connectivity,
no_build_isolation: bool,
no_build_isolation_package: Vec<PackageName>,
build_options: BuildOptions,
python_version: Option<PythonVersion>,
python_platform: Option<TargetTriple>,
Expand Down Expand Up @@ -303,8 +304,11 @@ pub(crate) async fn pip_compile(
let build_isolation = if no_build_isolation {
environment = PythonEnvironment::from_interpreter(interpreter.clone());
BuildIsolation::Shared(&environment)
} else {
} else if no_build_isolation_package.is_empty() {
BuildIsolation::Isolated
} else {
environment = PythonEnvironment::from_interpreter(interpreter.clone());
BuildIsolation::SharedPackage(&environment, &no_build_isolation_package)
};

let build_dispatch = BuildDispatch::new(
Expand Down
6 changes: 5 additions & 1 deletion crates/uv/src/commands/pip/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::fmt::Write;
use anstream::eprint;
use itertools::Itertools;
use owo_colors::OwoColorize;
use pep508_rs::PackageName;
use tracing::{debug, enabled, Level};

use distribution_types::{IndexLocations, Resolution, UnresolvedRequirementSpecification};
Expand Down Expand Up @@ -59,6 +60,7 @@ pub(crate) async fn pip_install(
connectivity: Connectivity,
config_settings: &ConfigSettings,
no_build_isolation: bool,
no_build_isolation_package: Vec<PackageName>,
build_options: BuildOptions,
python_version: Option<PythonVersion>,
python_platform: Option<TargetTriple>,
Expand Down Expand Up @@ -289,8 +291,10 @@ pub(crate) async fn pip_install(
// Determine whether to enable build isolation.
let build_isolation = if no_build_isolation {
BuildIsolation::Shared(&environment)
} else {
} else if no_build_isolation_package.is_empty() {
BuildIsolation::Isolated
} else {
BuildIsolation::SharedPackage(&environment, &no_build_isolation_package)
};

// Initialize any shared state.
Expand Down
6 changes: 5 additions & 1 deletion crates/uv/src/commands/pip/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::fmt::Write;
use anstream::eprint;
use anyhow::Result;
use owo_colors::OwoColorize;
use pep508_rs::PackageName;
use tracing::debug;

use distribution_types::{IndexLocations, Resolution};
Expand Down Expand Up @@ -51,6 +52,7 @@ pub(crate) async fn pip_sync(
connectivity: Connectivity,
config_settings: &ConfigSettings,
no_build_isolation: bool,
no_build_isolation_package: Vec<PackageName>,
build_options: BuildOptions,
python_version: Option<PythonVersion>,
python_platform: Option<TargetTriple>,
Expand Down Expand Up @@ -229,8 +231,10 @@ pub(crate) async fn pip_sync(
// Determine whether to enable build isolation.
let build_isolation = if no_build_isolation {
BuildIsolation::Shared(&environment)
} else {
} else if no_build_isolation_package.is_empty() {
BuildIsolation::Isolated
} else {
BuildIsolation::SharedPackage(&environment, &no_build_isolation_package)
};

// Initialize any shared state.
Expand Down
6 changes: 5 additions & 1 deletion crates/uv/src/commands/project/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ async fn do_lock(
prerelease,
config_setting,
no_build_isolation,
no_build_isolation_package,
exclude_newer,
link_mode,
upgrade,
Expand Down Expand Up @@ -292,8 +293,11 @@ async fn do_lock(
let build_isolation = if no_build_isolation {
environment = PythonEnvironment::from_interpreter(interpreter.clone());
BuildIsolation::Shared(&environment)
} else {
} else if no_build_isolation_package.is_empty() {
BuildIsolation::Isolated
} else {
environment = PythonEnvironment::from_interpreter(interpreter.clone());
BuildIsolation::SharedPackage(&environment, no_build_isolation_package)
};

let options = OptionsBuilder::new()
Expand Down
17 changes: 14 additions & 3 deletions crates/uv/src/commands/project/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ pub(crate) async fn resolve_names(
prerelease: _,
config_setting,
no_build_isolation,
no_build_isolation_package,
exclude_newer,
link_mode,
compile_bytecode: _,
Expand Down Expand Up @@ -436,8 +437,11 @@ pub(crate) async fn resolve_names(
let build_isolation = if *no_build_isolation {
environment = PythonEnvironment::from_interpreter(interpreter.clone());
BuildIsolation::Shared(&environment)
} else {
} else if no_build_isolation_package.is_empty() {
BuildIsolation::Isolated
} else {
environment = PythonEnvironment::from_interpreter(interpreter.clone());
BuildIsolation::SharedPackage(&environment, no_build_isolation_package)
};

// TODO(charlie): These are all default values. We should consider whether we want to make them
Expand Down Expand Up @@ -505,6 +509,7 @@ pub(crate) async fn resolve_environment<'a>(
prerelease,
config_setting,
no_build_isolation,
no_build_isolation_package,
exclude_newer,
link_mode,
upgrade: _,
Expand Down Expand Up @@ -548,8 +553,11 @@ pub(crate) async fn resolve_environment<'a>(
let build_isolation = if no_build_isolation {
environment = PythonEnvironment::from_interpreter(interpreter.clone());
BuildIsolation::Shared(&environment)
} else {
} else if no_build_isolation_package.is_empty() {
BuildIsolation::Isolated
} else {
environment = PythonEnvironment::from_interpreter(interpreter.clone());
BuildIsolation::SharedPackage(&environment, no_build_isolation_package)
};

let options = OptionsBuilder::new()
Expand Down Expand Up @@ -780,6 +788,7 @@ pub(crate) async fn update_environment(
prerelease,
config_setting,
no_build_isolation,
no_build_isolation_package,
exclude_newer,
link_mode,
compile_bytecode,
Expand Down Expand Up @@ -848,8 +857,10 @@ pub(crate) async fn update_environment(
// Determine whether to enable build isolation.
let build_isolation = if *no_build_isolation {
BuildIsolation::Shared(&venv)
} else {
} else if no_build_isolation_package.is_empty() {
BuildIsolation::Isolated
} else {
BuildIsolation::SharedPackage(&venv, no_build_isolation_package)
};

let options = OptionsBuilder::new()
Expand Down
Loading
Loading