mirror of https://github.com/astral-sh/uv
Build backend: Add `--list` option (#9610)
Add the `uv build --list`, a "subcommand" to list the files that would be included when building a distribution. It does not build the distribution, except when a source dist is required for source dist -> wheel. This is an important debugging tool for the include and exclude options: Did i actually include the files I wanted, or am i shipping a broken distribution? Are there any temporary files I still need to exclude? Cargo offers this as `cargo package --list`. `--list` is preview-exclusive, since it requires the fast path, which I also put into preview. Examples:    I'll fix the error handling in a follow-up. Tagging as enhancement because it changes the stable output slightly (two lines instead of one). CC @charliermarsh for uv-wide consistency in the stdout/stderr handling.
This commit is contained in:
parent
d7b74f964e
commit
7d82cbff01
|
|
@ -2175,6 +2175,18 @@ pub struct BuildArgs {
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub wheel: bool,
|
pub wheel: bool,
|
||||||
|
|
||||||
|
/// When using the uv build backend, list the files that would be included when building.
|
||||||
|
///
|
||||||
|
/// Skips building the actual distribution, except when the source distribution is needed to
|
||||||
|
/// build the wheel. The file list is collected directly without a PEP 517 environment. It only
|
||||||
|
/// works with the uv build backend, there is no PEP 517 file list build hook.
|
||||||
|
///
|
||||||
|
/// This option can be combined with `--sdist` and `--wheel` for inspecting different build
|
||||||
|
/// paths.
|
||||||
|
// Hidden while in preview.
|
||||||
|
#[arg(long, hide = true)]
|
||||||
|
pub list: bool,
|
||||||
|
|
||||||
#[arg(long, overrides_with("no_build_logs"), hide = true)]
|
#[arg(long, overrides_with("no_build_logs"), hide = true)]
|
||||||
pub build_logs: bool,
|
pub build_logs: bool,
|
||||||
|
|
||||||
|
|
@ -2187,7 +2199,7 @@ pub struct BuildArgs {
|
||||||
/// By default, uv won't create a PEP 517 build environment for packages using the uv build
|
/// By default, uv won't create a PEP 517 build environment for packages using the uv build
|
||||||
/// backend, but use a fast path that calls into the build backend directly. This option forces
|
/// backend, but use a fast path that calls into the build backend directly. This option forces
|
||||||
/// always using PEP 517.
|
/// always using PEP 517.
|
||||||
#[arg(long)]
|
#[arg(long, conflicts_with = "list")]
|
||||||
pub force_pep517: bool,
|
pub force_pep517: bool,
|
||||||
|
|
||||||
/// Constrain build dependencies using the given requirements files when building
|
/// Constrain build dependencies using the given requirements files when building
|
||||||
|
|
|
||||||
|
|
@ -4,13 +4,9 @@ use std::io;
|
||||||
use std::io::Write as _;
|
use std::io::Write as _;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::{bail, Context, Result};
|
||||||
|
|
||||||
use owo_colors::OwoColorize;
|
use owo_colors::OwoColorize;
|
||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
use uv_distribution_filename::SourceDistExtension;
|
|
||||||
use uv_distribution_types::{DependencyMetadata, Index, IndexLocations, SourceDist};
|
|
||||||
use uv_install_wheel::linker::LinkMode;
|
|
||||||
|
|
||||||
use uv_auth::store_credentials;
|
use uv_auth::store_credentials;
|
||||||
use uv_build_backend::PyProjectToml;
|
use uv_build_backend::PyProjectToml;
|
||||||
|
|
@ -18,10 +14,14 @@ use uv_cache::{Cache, CacheBucket};
|
||||||
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
|
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
|
||||||
use uv_configuration::{
|
use uv_configuration::{
|
||||||
BuildKind, BuildOptions, BuildOutput, Concurrency, ConfigSettings, Constraints,
|
BuildKind, BuildOptions, BuildOutput, Concurrency, ConfigSettings, Constraints,
|
||||||
HashCheckingMode, IndexStrategy, KeyringProviderType, LowerBound, SourceStrategy, TrustedHost,
|
HashCheckingMode, IndexStrategy, KeyringProviderType, LowerBound, PreviewMode, SourceStrategy,
|
||||||
|
TrustedHost,
|
||||||
};
|
};
|
||||||
use uv_dispatch::{BuildDispatch, SharedState};
|
use uv_dispatch::{BuildDispatch, SharedState};
|
||||||
use uv_fs::Simplified;
|
use uv_distribution_filename::SourceDistExtension;
|
||||||
|
use uv_distribution_types::{DependencyMetadata, Index, IndexLocations, SourceDist};
|
||||||
|
use uv_fs::{relative_to, Simplified};
|
||||||
|
use uv_install_wheel::linker::LinkMode;
|
||||||
use uv_normalize::PackageName;
|
use uv_normalize::PackageName;
|
||||||
use uv_python::{
|
use uv_python::{
|
||||||
EnvironmentPreference, PythonDownloads, PythonEnvironment, PythonInstallation,
|
EnvironmentPreference, PythonDownloads, PythonEnvironment, PythonInstallation,
|
||||||
|
|
@ -51,6 +51,7 @@ pub(crate) async fn build_frontend(
|
||||||
output_dir: Option<PathBuf>,
|
output_dir: Option<PathBuf>,
|
||||||
sdist: bool,
|
sdist: bool,
|
||||||
wheel: bool,
|
wheel: bool,
|
||||||
|
list: bool,
|
||||||
build_logs: bool,
|
build_logs: bool,
|
||||||
force_pep517: bool,
|
force_pep517: bool,
|
||||||
build_constraints: Vec<RequirementsSource>,
|
build_constraints: Vec<RequirementsSource>,
|
||||||
|
|
@ -67,6 +68,7 @@ pub(crate) async fn build_frontend(
|
||||||
allow_insecure_host: &[TrustedHost],
|
allow_insecure_host: &[TrustedHost],
|
||||||
cache: &Cache,
|
cache: &Cache,
|
||||||
printer: Printer,
|
printer: Printer,
|
||||||
|
preview: PreviewMode,
|
||||||
) -> Result<ExitStatus> {
|
) -> Result<ExitStatus> {
|
||||||
let build_result = build_impl(
|
let build_result = build_impl(
|
||||||
project_dir,
|
project_dir,
|
||||||
|
|
@ -76,6 +78,7 @@ pub(crate) async fn build_frontend(
|
||||||
output_dir.as_deref(),
|
output_dir.as_deref(),
|
||||||
sdist,
|
sdist,
|
||||||
wheel,
|
wheel,
|
||||||
|
list,
|
||||||
build_logs,
|
build_logs,
|
||||||
force_pep517,
|
force_pep517,
|
||||||
&build_constraints,
|
&build_constraints,
|
||||||
|
|
@ -92,6 +95,7 @@ pub(crate) async fn build_frontend(
|
||||||
allow_insecure_host,
|
allow_insecure_host,
|
||||||
cache,
|
cache,
|
||||||
printer,
|
printer,
|
||||||
|
preview,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
@ -119,6 +123,7 @@ async fn build_impl(
|
||||||
output_dir: Option<&Path>,
|
output_dir: Option<&Path>,
|
||||||
sdist: bool,
|
sdist: bool,
|
||||||
wheel: bool,
|
wheel: bool,
|
||||||
|
list: bool,
|
||||||
build_logs: bool,
|
build_logs: bool,
|
||||||
force_pep517: bool,
|
force_pep517: bool,
|
||||||
build_constraints: &[RequirementsSource],
|
build_constraints: &[RequirementsSource],
|
||||||
|
|
@ -135,7 +140,17 @@ async fn build_impl(
|
||||||
allow_insecure_host: &[TrustedHost],
|
allow_insecure_host: &[TrustedHost],
|
||||||
cache: &Cache,
|
cache: &Cache,
|
||||||
printer: Printer,
|
printer: Printer,
|
||||||
|
preview: PreviewMode,
|
||||||
) -> Result<BuildResult> {
|
) -> Result<BuildResult> {
|
||||||
|
if list && preview.is_disabled() {
|
||||||
|
// We need the fast path for list and that is preview only.
|
||||||
|
writeln!(
|
||||||
|
printer.stderr(),
|
||||||
|
"The `--list` option is only available in preview mode; add the `--preview` flag to use `--list`"
|
||||||
|
)?;
|
||||||
|
return Ok(BuildResult::Failure);
|
||||||
|
}
|
||||||
|
|
||||||
// Extract the resolver settings.
|
// Extract the resolver settings.
|
||||||
let ResolverSettingsRef {
|
let ResolverSettingsRef {
|
||||||
index_locations,
|
index_locations,
|
||||||
|
|
@ -286,9 +301,11 @@ async fn build_impl(
|
||||||
build_options,
|
build_options,
|
||||||
sdist,
|
sdist,
|
||||||
wheel,
|
wheel,
|
||||||
|
list,
|
||||||
dependency_metadata,
|
dependency_metadata,
|
||||||
link_mode,
|
link_mode,
|
||||||
config_setting,
|
config_setting,
|
||||||
|
preview,
|
||||||
);
|
);
|
||||||
async {
|
async {
|
||||||
let result = future.await;
|
let result = future.await;
|
||||||
|
|
@ -300,30 +317,11 @@ async fn build_impl(
|
||||||
let mut success = true;
|
let mut success = true;
|
||||||
for (source, result) in results {
|
for (source, result) in results {
|
||||||
match result {
|
match result {
|
||||||
Ok(assets) => match assets {
|
Ok(messages) => {
|
||||||
BuiltDistributions::Wheel(wheel) => {
|
for message in messages {
|
||||||
writeln!(
|
message.print(printer)?;
|
||||||
printer.stderr(),
|
|
||||||
"Successfully built {}",
|
|
||||||
wheel.user_display().bold().cyan()
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
BuiltDistributions::Sdist(sdist) => {
|
}
|
||||||
writeln!(
|
|
||||||
printer.stderr(),
|
|
||||||
"Successfully built {}",
|
|
||||||
sdist.user_display().bold().cyan()
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
BuiltDistributions::Both(sdist, wheel) => {
|
|
||||||
writeln!(
|
|
||||||
printer.stderr(),
|
|
||||||
"Successfully built {} and {}",
|
|
||||||
sdist.user_display().bold().cyan(),
|
|
||||||
wheel.user_display().bold().cyan()
|
|
||||||
)?;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
#[derive(Debug, miette::Diagnostic, thiserror::Error)]
|
#[derive(Debug, miette::Diagnostic, thiserror::Error)]
|
||||||
#[error("Failed to build `{source}`", source = source.cyan())]
|
#[error("Failed to build `{source}`", source = source.cyan())]
|
||||||
|
|
@ -383,10 +381,12 @@ async fn build_package(
|
||||||
build_options: &BuildOptions,
|
build_options: &BuildOptions,
|
||||||
sdist: bool,
|
sdist: bool,
|
||||||
wheel: bool,
|
wheel: bool,
|
||||||
|
list: bool,
|
||||||
dependency_metadata: &DependencyMetadata,
|
dependency_metadata: &DependencyMetadata,
|
||||||
link_mode: LinkMode,
|
link_mode: LinkMode,
|
||||||
config_setting: &ConfigSettings,
|
config_setting: &ConfigSettings,
|
||||||
) -> Result<BuiltDistributions> {
|
preview: PreviewMode,
|
||||||
|
) -> Result<Vec<BuildMessage>> {
|
||||||
let output_dir = if let Some(output_dir) = output_dir {
|
let output_dir = if let Some(output_dir) = output_dir {
|
||||||
Cow::Owned(std::path::absolute(output_dir)?)
|
Cow::Owned(std::path::absolute(output_dir)?)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -538,7 +538,22 @@ async fn build_package(
|
||||||
|
|
||||||
// Check if the build backend is matching uv version that allows calling in the uv build backend
|
// Check if the build backend is matching uv version that allows calling in the uv build backend
|
||||||
// directly.
|
// directly.
|
||||||
let fast_path = !force_pep517 && check_fast_path(source.path());
|
let build_action = if list {
|
||||||
|
if force_pep517 {
|
||||||
|
bail!("Can't use `--force-pep517` with `--list`");
|
||||||
|
}
|
||||||
|
|
||||||
|
if !check_fast_path(source.path()) {
|
||||||
|
// TODO(konsti): Provide more context on what mismatched
|
||||||
|
bail!("Can only use `--list` with the uv backend");
|
||||||
|
}
|
||||||
|
|
||||||
|
BuildAction::List
|
||||||
|
} else if preview.is_enabled() && !force_pep517 && check_fast_path(source.path()) {
|
||||||
|
BuildAction::FastPath
|
||||||
|
} else {
|
||||||
|
BuildAction::Pep517
|
||||||
|
};
|
||||||
|
|
||||||
// Prepare some common arguments for the build.
|
// Prepare some common arguments for the build.
|
||||||
let dist = None;
|
let dist = None;
|
||||||
|
|
@ -556,15 +571,36 @@ async fn build_package(
|
||||||
Printer::Quiet => BuildOutput::Quiet,
|
Printer::Quiet => BuildOutput::Quiet,
|
||||||
};
|
};
|
||||||
|
|
||||||
let assets = match plan {
|
let mut build_results = Vec::new();
|
||||||
|
match plan {
|
||||||
BuildPlan::SdistToWheel => {
|
BuildPlan::SdistToWheel => {
|
||||||
let sdist = build_sdist(
|
// Even when listing files, we still need to build the source distribution for the wheel
|
||||||
|
// build.
|
||||||
|
if list {
|
||||||
|
let sdist_list = build_sdist(
|
||||||
|
source.path(),
|
||||||
|
&output_dir,
|
||||||
|
build_action,
|
||||||
|
&source,
|
||||||
|
printer,
|
||||||
|
"source distribution",
|
||||||
|
&build_dispatch,
|
||||||
|
sources,
|
||||||
|
dist,
|
||||||
|
subdirectory,
|
||||||
|
version_id,
|
||||||
|
build_output,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
build_results.push(sdist_list);
|
||||||
|
}
|
||||||
|
let sdist_build = build_sdist(
|
||||||
source.path(),
|
source.path(),
|
||||||
&output_dir,
|
&output_dir,
|
||||||
fast_path,
|
build_action.force_build(),
|
||||||
&source,
|
&source,
|
||||||
printer,
|
printer,
|
||||||
"Building source distribution",
|
"source distribution",
|
||||||
&build_dispatch,
|
&build_dispatch,
|
||||||
sources,
|
sources,
|
||||||
dist,
|
dist,
|
||||||
|
|
@ -573,9 +609,10 @@ async fn build_package(
|
||||||
build_output,
|
build_output,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
build_results.push(sdist_build.clone());
|
||||||
|
|
||||||
// Extract the source distribution into a temporary directory.
|
// Extract the source distribution into a temporary directory.
|
||||||
let path = output_dir.join(&sdist);
|
let path = output_dir.join(sdist_build.filename());
|
||||||
let reader = fs_err::tokio::File::open(&path).await?;
|
let reader = fs_err::tokio::File::open(&path).await?;
|
||||||
let ext = SourceDistExtension::from_path(path.as_path()).map_err(|err| {
|
let ext = SourceDistExtension::from_path(path.as_path()).map_err(|err| {
|
||||||
anyhow::anyhow!("`{}` is not a valid source distribution, as it ends with an unsupported extension. Expected one of: {err}.", path.user_display())
|
anyhow::anyhow!("`{}` is not a valid source distribution, as it ends with an unsupported extension. Expected one of: {err}.", path.user_display())
|
||||||
|
|
@ -590,13 +627,13 @@ async fn build_package(
|
||||||
Err(err) => return Err(err.into()),
|
Err(err) => return Err(err.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let wheel = build_wheel(
|
let wheel_build = build_wheel(
|
||||||
&extracted,
|
&extracted,
|
||||||
&output_dir,
|
&output_dir,
|
||||||
fast_path,
|
build_action,
|
||||||
&source,
|
&source,
|
||||||
printer,
|
printer,
|
||||||
"Building wheel from source distribution",
|
"wheel from source distribution",
|
||||||
&build_dispatch,
|
&build_dispatch,
|
||||||
sources,
|
sources,
|
||||||
dist,
|
dist,
|
||||||
|
|
@ -605,17 +642,16 @@ async fn build_package(
|
||||||
build_output,
|
build_output,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
build_results.push(wheel_build);
|
||||||
BuiltDistributions::Both(output_dir.join(sdist), output_dir.join(wheel))
|
|
||||||
}
|
}
|
||||||
BuildPlan::Sdist => {
|
BuildPlan::Sdist => {
|
||||||
let sdist = build_sdist(
|
let sdist_build = build_sdist(
|
||||||
source.path(),
|
source.path(),
|
||||||
&output_dir,
|
&output_dir,
|
||||||
fast_path,
|
build_action,
|
||||||
&source,
|
&source,
|
||||||
printer,
|
printer,
|
||||||
"Building source distribution",
|
"source distribution",
|
||||||
&build_dispatch,
|
&build_dispatch,
|
||||||
sources,
|
sources,
|
||||||
dist,
|
dist,
|
||||||
|
|
@ -624,17 +660,16 @@ async fn build_package(
|
||||||
build_output,
|
build_output,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
build_results.push(sdist_build);
|
||||||
BuiltDistributions::Sdist(output_dir.join(sdist))
|
|
||||||
}
|
}
|
||||||
BuildPlan::Wheel => {
|
BuildPlan::Wheel => {
|
||||||
let wheel = build_wheel(
|
let wheel_build = build_wheel(
|
||||||
source.path(),
|
source.path(),
|
||||||
&output_dir,
|
&output_dir,
|
||||||
fast_path,
|
build_action,
|
||||||
&source,
|
&source,
|
||||||
printer,
|
printer,
|
||||||
"Building wheel",
|
"wheel",
|
||||||
&build_dispatch,
|
&build_dispatch,
|
||||||
sources,
|
sources,
|
||||||
dist,
|
dist,
|
||||||
|
|
@ -643,17 +678,16 @@ async fn build_package(
|
||||||
build_output,
|
build_output,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
build_results.push(wheel_build);
|
||||||
BuiltDistributions::Wheel(output_dir.join(wheel))
|
|
||||||
}
|
}
|
||||||
BuildPlan::SdistAndWheel => {
|
BuildPlan::SdistAndWheel => {
|
||||||
let sdist = build_sdist(
|
let sdist_build = build_sdist(
|
||||||
source.path(),
|
source.path(),
|
||||||
&output_dir,
|
&output_dir,
|
||||||
fast_path,
|
build_action,
|
||||||
&source,
|
&source,
|
||||||
printer,
|
printer,
|
||||||
"Building source distribution",
|
"source distribution",
|
||||||
&build_dispatch,
|
&build_dispatch,
|
||||||
sources,
|
sources,
|
||||||
dist,
|
dist,
|
||||||
|
|
@ -662,14 +696,15 @@ async fn build_package(
|
||||||
build_output,
|
build_output,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
build_results.push(sdist_build);
|
||||||
|
|
||||||
let wheel = build_wheel(
|
let wheel_build = build_wheel(
|
||||||
source.path(),
|
source.path(),
|
||||||
&output_dir,
|
&output_dir,
|
||||||
fast_path,
|
build_action,
|
||||||
&source,
|
&source,
|
||||||
printer,
|
printer,
|
||||||
"Building wheel",
|
"wheel",
|
||||||
&build_dispatch,
|
&build_dispatch,
|
||||||
sources,
|
sources,
|
||||||
dist,
|
dist,
|
||||||
|
|
@ -678,8 +713,7 @@ async fn build_package(
|
||||||
build_output,
|
build_output,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
build_results.push(wheel_build);
|
||||||
BuiltDistributions::Both(output_dir.join(&sdist), output_dir.join(&wheel))
|
|
||||||
}
|
}
|
||||||
BuildPlan::WheelFromSdist => {
|
BuildPlan::WheelFromSdist => {
|
||||||
// Extract the source distribution into a temporary directory.
|
// Extract the source distribution into a temporary directory.
|
||||||
|
|
@ -700,13 +734,13 @@ async fn build_package(
|
||||||
Err(err) => return Err(err.into()),
|
Err(err) => return Err(err.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
let wheel = build_wheel(
|
let wheel_build = build_wheel(
|
||||||
&extracted,
|
&extracted,
|
||||||
&output_dir,
|
&output_dir,
|
||||||
fast_path,
|
build_action,
|
||||||
&source,
|
&source,
|
||||||
printer,
|
printer,
|
||||||
"Building wheel from source distribution",
|
"wheel from source distribution",
|
||||||
&build_dispatch,
|
&build_dispatch,
|
||||||
sources,
|
sources,
|
||||||
dist,
|
dist,
|
||||||
|
|
@ -715,12 +749,33 @@ async fn build_package(
|
||||||
build_output,
|
build_output,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
build_results.push(wheel_build);
|
||||||
BuiltDistributions::Wheel(output_dir.join(wheel))
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
Ok(assets)
|
Ok(build_results)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, PartialEq, Eq)]
|
||||||
|
enum BuildAction {
|
||||||
|
/// Only list the files that would be included, don't actually build.
|
||||||
|
List,
|
||||||
|
/// Build by calling directly into the build backend.
|
||||||
|
FastPath,
|
||||||
|
/// Build through the PEP 517 hooks.
|
||||||
|
Pep517,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildAction {
|
||||||
|
/// If in list mode, still build the distribution.
|
||||||
|
fn force_build(self) -> Self {
|
||||||
|
match self {
|
||||||
|
// List is only available for the uv build backend
|
||||||
|
Self::List => Self::FastPath,
|
||||||
|
Self::FastPath => Self::FastPath,
|
||||||
|
Self::Pep517 => Self::Pep517,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a source distribution, either through PEP 517 or through the fast path.
|
/// Build a source distribution, either through PEP 517 or through the fast path.
|
||||||
|
|
@ -728,10 +783,10 @@ async fn build_package(
|
||||||
async fn build_sdist(
|
async fn build_sdist(
|
||||||
source_tree: &Path,
|
source_tree: &Path,
|
||||||
output_dir: &Path,
|
output_dir: &Path,
|
||||||
fast_path: bool,
|
action: BuildAction,
|
||||||
source: &AnnotatedSource<'_>,
|
source: &AnnotatedSource<'_>,
|
||||||
printer: Printer,
|
printer: Printer,
|
||||||
message: &str,
|
build_kind_message: &str,
|
||||||
// Below is only used with PEP 517 builds
|
// Below is only used with PEP 517 builds
|
||||||
build_dispatch: &BuildDispatch<'_>,
|
build_dispatch: &BuildDispatch<'_>,
|
||||||
sources: SourceStrategy,
|
sources: SourceStrategy,
|
||||||
|
|
@ -739,46 +794,80 @@ async fn build_sdist(
|
||||||
subdirectory: Option<&Path>,
|
subdirectory: Option<&Path>,
|
||||||
version_id: Option<&str>,
|
version_id: Option<&str>,
|
||||||
build_output: BuildOutput,
|
build_output: BuildOutput,
|
||||||
) -> Result<String> {
|
) -> Result<BuildMessage> {
|
||||||
let sdist = if fast_path {
|
let build_result = match action {
|
||||||
writeln!(
|
BuildAction::List => {
|
||||||
printer.stderr(),
|
let source_tree_ = source_tree.to_path_buf();
|
||||||
"{}",
|
let (filename, file_list) = tokio::task::spawn_blocking(move || {
|
||||||
format!(
|
uv_build_backend::list_source_dist(&source_tree_, uv_version::version())
|
||||||
"{}{} (uv build backend)...",
|
})
|
||||||
source.message_prefix(),
|
.await??;
|
||||||
message
|
|
||||||
)
|
BuildMessage::List {
|
||||||
.bold()
|
filename: filename.to_string(),
|
||||||
)?;
|
source_tree: source_tree.to_path_buf(),
|
||||||
let source_tree = source_tree.to_path_buf();
|
file_list,
|
||||||
let output_dir = output_dir.to_path_buf();
|
}
|
||||||
tokio::task::spawn_blocking(move || {
|
}
|
||||||
uv_build_backend::build_source_dist(&source_tree, &output_dir, uv_version::version())
|
BuildAction::FastPath => {
|
||||||
})
|
writeln!(
|
||||||
.await??
|
printer.stderr(),
|
||||||
.to_string()
|
"{}",
|
||||||
} else {
|
format!(
|
||||||
writeln!(
|
"{}Building {} (uv build backend)...",
|
||||||
printer.stderr(),
|
source.message_prefix(),
|
||||||
"{}",
|
build_kind_message
|
||||||
format!("{}{}...", source.message_prefix(), message).bold()
|
)
|
||||||
)?;
|
.bold()
|
||||||
let builder = build_dispatch
|
)?;
|
||||||
.setup_build(
|
let source_tree = source_tree.to_path_buf();
|
||||||
source_tree,
|
let output_dir_ = output_dir.to_path_buf();
|
||||||
subdirectory,
|
let filename = tokio::task::spawn_blocking(move || {
|
||||||
source.path(),
|
uv_build_backend::build_source_dist(
|
||||||
version_id.map(ToString::to_string),
|
&source_tree,
|
||||||
dist,
|
&output_dir_,
|
||||||
sources,
|
uv_version::version(),
|
||||||
BuildKind::Sdist,
|
)
|
||||||
build_output,
|
})
|
||||||
)
|
.await??
|
||||||
.await?;
|
.to_string();
|
||||||
builder.build(output_dir).await?
|
|
||||||
|
BuildMessage::Build {
|
||||||
|
filename,
|
||||||
|
output_dir: output_dir.to_path_buf(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BuildAction::Pep517 => {
|
||||||
|
writeln!(
|
||||||
|
printer.stderr(),
|
||||||
|
"{}",
|
||||||
|
format!(
|
||||||
|
"{}Building {}...",
|
||||||
|
source.message_prefix(),
|
||||||
|
build_kind_message
|
||||||
|
)
|
||||||
|
.bold()
|
||||||
|
)?;
|
||||||
|
let builder = build_dispatch
|
||||||
|
.setup_build(
|
||||||
|
source_tree,
|
||||||
|
subdirectory,
|
||||||
|
source.path(),
|
||||||
|
version_id.map(ToString::to_string),
|
||||||
|
dist,
|
||||||
|
sources,
|
||||||
|
BuildKind::Sdist,
|
||||||
|
build_output,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let filename = builder.build(output_dir).await?;
|
||||||
|
BuildMessage::Build {
|
||||||
|
filename,
|
||||||
|
output_dir: output_dir.to_path_buf(),
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ok(sdist)
|
Ok(build_result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a wheel, either through PEP 517 or through the fast path.
|
/// Build a wheel, either through PEP 517 or through the fast path.
|
||||||
|
|
@ -786,10 +875,10 @@ async fn build_sdist(
|
||||||
async fn build_wheel(
|
async fn build_wheel(
|
||||||
source_tree: &Path,
|
source_tree: &Path,
|
||||||
output_dir: &Path,
|
output_dir: &Path,
|
||||||
fast_path: bool,
|
action: BuildAction,
|
||||||
source: &AnnotatedSource<'_>,
|
source: &AnnotatedSource<'_>,
|
||||||
printer: Printer,
|
printer: Printer,
|
||||||
message: &str,
|
build_kind_message: &str,
|
||||||
// Below is only used with PEP 517 builds
|
// Below is only used with PEP 517 builds
|
||||||
build_dispatch: &BuildDispatch<'_>,
|
build_dispatch: &BuildDispatch<'_>,
|
||||||
sources: SourceStrategy,
|
sources: SourceStrategy,
|
||||||
|
|
@ -797,46 +886,80 @@ async fn build_wheel(
|
||||||
subdirectory: Option<&Path>,
|
subdirectory: Option<&Path>,
|
||||||
version_id: Option<&str>,
|
version_id: Option<&str>,
|
||||||
build_output: BuildOutput,
|
build_output: BuildOutput,
|
||||||
) -> Result<String> {
|
) -> Result<BuildMessage> {
|
||||||
let wheel = if fast_path {
|
let build_message = match action {
|
||||||
writeln!(
|
BuildAction::List => {
|
||||||
printer.stderr(),
|
let source_tree_ = source_tree.to_path_buf();
|
||||||
"{}",
|
let (name, file_list) = tokio::task::spawn_blocking(move || {
|
||||||
format!(
|
uv_build_backend::list_wheel(&source_tree_, uv_version::version())
|
||||||
"{}{} (uv build backend)...",
|
})
|
||||||
source.message_prefix(),
|
.await??;
|
||||||
message
|
BuildMessage::List {
|
||||||
)
|
filename: name.to_string(),
|
||||||
.bold()
|
source_tree: source_tree.to_path_buf(),
|
||||||
)?;
|
file_list,
|
||||||
let source_tree = source_tree.to_path_buf();
|
}
|
||||||
let output_dir = output_dir.to_path_buf();
|
}
|
||||||
tokio::task::spawn_blocking(move || {
|
BuildAction::FastPath => {
|
||||||
uv_build_backend::build_wheel(&source_tree, &output_dir, None, uv_version::version())
|
writeln!(
|
||||||
})
|
printer.stderr(),
|
||||||
.await??
|
"{}",
|
||||||
.to_string()
|
format!(
|
||||||
} else {
|
"{}Building {} (uv build backend)...",
|
||||||
writeln!(
|
source.message_prefix(),
|
||||||
printer.stderr(),
|
build_kind_message
|
||||||
"{}",
|
)
|
||||||
format!("{}{}...", source.message_prefix(), message).bold()
|
.bold()
|
||||||
)?;
|
)?;
|
||||||
let builder = build_dispatch
|
let source_tree = source_tree.to_path_buf();
|
||||||
.setup_build(
|
let output_dir_ = output_dir.to_path_buf();
|
||||||
source_tree,
|
let filename = tokio::task::spawn_blocking(move || {
|
||||||
subdirectory,
|
uv_build_backend::build_wheel(
|
||||||
source.path(),
|
&source_tree,
|
||||||
version_id.map(ToString::to_string),
|
&output_dir_,
|
||||||
dist,
|
None,
|
||||||
sources,
|
uv_version::version(),
|
||||||
BuildKind::Wheel,
|
)
|
||||||
build_output,
|
})
|
||||||
)
|
.await??
|
||||||
.await?;
|
.to_string();
|
||||||
builder.build(output_dir).await?
|
|
||||||
|
BuildMessage::Build {
|
||||||
|
filename,
|
||||||
|
output_dir: output_dir.to_path_buf(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BuildAction::Pep517 => {
|
||||||
|
writeln!(
|
||||||
|
printer.stderr(),
|
||||||
|
"{}",
|
||||||
|
format!(
|
||||||
|
"{}Building {}...",
|
||||||
|
source.message_prefix(),
|
||||||
|
build_kind_message
|
||||||
|
)
|
||||||
|
.bold()
|
||||||
|
)?;
|
||||||
|
let builder = build_dispatch
|
||||||
|
.setup_build(
|
||||||
|
source_tree,
|
||||||
|
subdirectory,
|
||||||
|
source.path(),
|
||||||
|
version_id.map(ToString::to_string),
|
||||||
|
dist,
|
||||||
|
sources,
|
||||||
|
BuildKind::Wheel,
|
||||||
|
build_output,
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
let filename = builder.build(output_dir).await?;
|
||||||
|
BuildMessage::Build {
|
||||||
|
filename,
|
||||||
|
output_dir: output_dir.to_path_buf(),
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Ok(wheel)
|
Ok(build_message)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create the output directory and add a `.gitignore`.
|
/// Create the output directory and add a `.gitignore`.
|
||||||
|
|
@ -926,14 +1049,76 @@ impl<'a> Source<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// We run all builds in parallel, so we wait until all builds are done to show the success messages
|
||||||
|
/// in order.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
enum BuiltDistributions {
|
enum BuildMessage {
|
||||||
/// A built wheel.
|
/// A built wheel or source distribution.
|
||||||
Wheel(PathBuf),
|
Build {
|
||||||
/// A built source distribution.
|
/// The name of the built distribution.
|
||||||
Sdist(PathBuf),
|
filename: String,
|
||||||
/// A built source distribution and wheel.
|
/// The location of the built distribution.
|
||||||
Both(PathBuf, PathBuf),
|
output_dir: PathBuf,
|
||||||
|
},
|
||||||
|
/// Show the list of files that would be included in a distribution.
|
||||||
|
List {
|
||||||
|
/// The name of the build distribution.
|
||||||
|
filename: String,
|
||||||
|
// All source files are relative to the source tree.
|
||||||
|
source_tree: PathBuf,
|
||||||
|
// Included file and source file, if not generated.
|
||||||
|
file_list: Vec<(String, Option<PathBuf>)>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BuildMessage {
|
||||||
|
/// The filename of the wheel or source distribution.
|
||||||
|
fn filename(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
BuildMessage::Build { filename: name, .. } => name,
|
||||||
|
BuildMessage::List { filename: name, .. } => name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print(&self, printer: Printer) -> Result<()> {
|
||||||
|
match self {
|
||||||
|
BuildMessage::Build {
|
||||||
|
filename,
|
||||||
|
output_dir,
|
||||||
|
} => {
|
||||||
|
writeln!(
|
||||||
|
printer.stderr(),
|
||||||
|
"Successfully built {}",
|
||||||
|
output_dir.join(filename).user_display().bold().cyan()
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
BuildMessage::List {
|
||||||
|
filename,
|
||||||
|
file_list,
|
||||||
|
source_tree,
|
||||||
|
} => {
|
||||||
|
writeln!(
|
||||||
|
printer.stdout(),
|
||||||
|
"{}",
|
||||||
|
format!("Building {filename} will include the following files:").bold()
|
||||||
|
)?;
|
||||||
|
for (file, source) in file_list {
|
||||||
|
if let Some(source) = source {
|
||||||
|
writeln!(
|
||||||
|
printer.stdout(),
|
||||||
|
"{file} ({})",
|
||||||
|
relative_to(source, source_tree)
|
||||||
|
.context("Included files must be relative to source tree")?
|
||||||
|
.display()
|
||||||
|
)?;
|
||||||
|
} else {
|
||||||
|
writeln!(printer.stdout(), "{file} (generated)")?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ pub(crate) async fn install(
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
|
|
||||||
if default && !preview.is_enabled() {
|
if default && !preview.is_enabled() {
|
||||||
writeln!(printer.stderr(), "The `--default` flag is only available in preview mode; add the `--preview` flag to use `--default")?;
|
writeln!(printer.stderr(), "The `--default` flag is only available in preview mode; add the `--preview` flag to use `--default`")?;
|
||||||
return Ok(ExitStatus::Failure);
|
return Ok(ExitStatus::Failure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -733,6 +733,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
args.out_dir,
|
args.out_dir,
|
||||||
args.sdist,
|
args.sdist,
|
||||||
args.wheel,
|
args.wheel,
|
||||||
|
args.list,
|
||||||
args.build_logs,
|
args.build_logs,
|
||||||
args.force_pep517,
|
args.force_pep517,
|
||||||
build_constraints,
|
build_constraints,
|
||||||
|
|
@ -749,6 +750,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
||||||
&globals.allow_insecure_host,
|
&globals.allow_insecure_host,
|
||||||
&cache,
|
&cache,
|
||||||
printer,
|
printer,
|
||||||
|
globals.preview,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2030,6 +2030,7 @@ pub(crate) struct BuildSettings {
|
||||||
pub(crate) out_dir: Option<PathBuf>,
|
pub(crate) out_dir: Option<PathBuf>,
|
||||||
pub(crate) sdist: bool,
|
pub(crate) sdist: bool,
|
||||||
pub(crate) wheel: bool,
|
pub(crate) wheel: bool,
|
||||||
|
pub(crate) list: bool,
|
||||||
pub(crate) build_logs: bool,
|
pub(crate) build_logs: bool,
|
||||||
pub(crate) force_pep517: bool,
|
pub(crate) force_pep517: bool,
|
||||||
pub(crate) build_constraints: Vec<PathBuf>,
|
pub(crate) build_constraints: Vec<PathBuf>,
|
||||||
|
|
@ -2050,6 +2051,7 @@ impl BuildSettings {
|
||||||
all_packages,
|
all_packages,
|
||||||
sdist,
|
sdist,
|
||||||
wheel,
|
wheel,
|
||||||
|
list,
|
||||||
force_pep517,
|
force_pep517,
|
||||||
build_constraints,
|
build_constraints,
|
||||||
require_hashes,
|
require_hashes,
|
||||||
|
|
@ -2076,6 +2078,7 @@ impl BuildSettings {
|
||||||
out_dir,
|
out_dir,
|
||||||
sdist,
|
sdist,
|
||||||
wheel,
|
wheel,
|
||||||
|
list,
|
||||||
build_logs: flag(build_logs, no_build_logs).unwrap_or(true),
|
build_logs: flag(build_logs, no_build_logs).unwrap_or(true),
|
||||||
build_constraints: build_constraints
|
build_constraints: build_constraints
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,8 @@ fn build() -> Result<()> {
|
||||||
adding 'project-0.1.0.dist-info/top_level.txt'
|
adding 'project-0.1.0.dist-info/top_level.txt'
|
||||||
adding 'project-0.1.0.dist-info/RECORD'
|
adding 'project-0.1.0.dist-info/RECORD'
|
||||||
removing build/bdist.linux-x86_64/wheel
|
removing build/bdist.linux-x86_64/wheel
|
||||||
Successfully built project/dist/project-0.1.0.tar.gz and project/dist/project-0.1.0-py3-none-any.whl
|
Successfully built project/dist/project-0.1.0.tar.gz
|
||||||
|
Successfully built project/dist/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
project
|
project
|
||||||
|
|
@ -213,7 +214,8 @@ fn build() -> Result<()> {
|
||||||
adding 'project-0.1.0.dist-info/top_level.txt'
|
adding 'project-0.1.0.dist-info/top_level.txt'
|
||||||
adding 'project-0.1.0.dist-info/RECORD'
|
adding 'project-0.1.0.dist-info/RECORD'
|
||||||
removing build/bdist.linux-x86_64/wheel
|
removing build/bdist.linux-x86_64/wheel
|
||||||
Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
|
Successfully built dist/project-0.1.0.tar.gz
|
||||||
|
Successfully built dist/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
project
|
project
|
||||||
|
|
@ -317,7 +319,8 @@ fn build() -> Result<()> {
|
||||||
adding 'project-0.1.0.dist-info/top_level.txt'
|
adding 'project-0.1.0.dist-info/top_level.txt'
|
||||||
adding 'project-0.1.0.dist-info/RECORD'
|
adding 'project-0.1.0.dist-info/RECORD'
|
||||||
removing build/bdist.linux-x86_64/wheel
|
removing build/bdist.linux-x86_64/wheel
|
||||||
Successfully built out/project-0.1.0.tar.gz and out/project-0.1.0-py3-none-any.whl
|
Successfully built out/project-0.1.0.tar.gz
|
||||||
|
Successfully built out/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
project
|
project
|
||||||
|
|
@ -630,7 +633,8 @@ fn sdist_wheel() -> Result<()> {
|
||||||
adding 'project-0.1.0.dist-info/top_level.txt'
|
adding 'project-0.1.0.dist-info/top_level.txt'
|
||||||
adding 'project-0.1.0.dist-info/RECORD'
|
adding 'project-0.1.0.dist-info/RECORD'
|
||||||
removing build/bdist.linux-x86_64/wheel
|
removing build/bdist.linux-x86_64/wheel
|
||||||
Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
|
Successfully built dist/project-0.1.0.tar.gz
|
||||||
|
Successfully built dist/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
project
|
project
|
||||||
|
|
@ -1052,7 +1056,8 @@ fn workspace() -> Result<()> {
|
||||||
adding 'member-0.1.0.dist-info/top_level.txt'
|
adding 'member-0.1.0.dist-info/top_level.txt'
|
||||||
adding 'member-0.1.0.dist-info/RECORD'
|
adding 'member-0.1.0.dist-info/RECORD'
|
||||||
removing build/bdist.linux-x86_64/wheel
|
removing build/bdist.linux-x86_64/wheel
|
||||||
Successfully built dist/member-0.1.0.tar.gz and dist/member-0.1.0-py3-none-any.whl
|
Successfully built dist/member-0.1.0.tar.gz
|
||||||
|
Successfully built dist/member-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
project
|
project
|
||||||
|
|
@ -1075,8 +1080,10 @@ fn workspace() -> Result<()> {
|
||||||
[PKG] Building source distribution...
|
[PKG] Building source distribution...
|
||||||
[PKG] Building wheel from source distribution...
|
[PKG] Building wheel from source distribution...
|
||||||
[PKG] Building wheel from source distribution...
|
[PKG] Building wheel from source distribution...
|
||||||
Successfully built dist/member-0.1.0.tar.gz and dist/member-0.1.0-py3-none-any.whl
|
Successfully built dist/member-0.1.0.tar.gz
|
||||||
Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
|
Successfully built dist/member-0.1.0-py3-none-any.whl
|
||||||
|
Successfully built dist/project-0.1.0.tar.gz
|
||||||
|
Successfully built dist/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
project
|
project
|
||||||
|
|
@ -1174,7 +1181,8 @@ fn workspace() -> Result<()> {
|
||||||
adding 'member-0.1.0.dist-info/top_level.txt'
|
adding 'member-0.1.0.dist-info/top_level.txt'
|
||||||
adding 'member-0.1.0.dist-info/RECORD'
|
adding 'member-0.1.0.dist-info/RECORD'
|
||||||
removing build/bdist.linux-x86_64/wheel
|
removing build/bdist.linux-x86_64/wheel
|
||||||
Successfully built project/dist/member-0.1.0.tar.gz and project/dist/member-0.1.0-py3-none-any.whl
|
Successfully built project/dist/member-0.1.0.tar.gz
|
||||||
|
Successfully built project/dist/member-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// If a source is provided, discover the workspace from the source.
|
// If a source is provided, discover the workspace from the source.
|
||||||
|
|
@ -1188,8 +1196,10 @@ fn workspace() -> Result<()> {
|
||||||
[PKG] Building source distribution...
|
[PKG] Building source distribution...
|
||||||
[PKG] Building wheel from source distribution...
|
[PKG] Building wheel from source distribution...
|
||||||
[PKG] Building wheel from source distribution...
|
[PKG] Building wheel from source distribution...
|
||||||
Successfully built project/dist/member-0.1.0.tar.gz and project/dist/member-0.1.0-py3-none-any.whl
|
Successfully built project/dist/member-0.1.0.tar.gz
|
||||||
Successfully built project/dist/project-0.1.0.tar.gz and project/dist/project-0.1.0-py3-none-any.whl
|
Successfully built project/dist/member-0.1.0-py3-none-any.whl
|
||||||
|
Successfully built project/dist/project-0.1.0.tar.gz
|
||||||
|
Successfully built project/dist/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// Fail when `--package` is provided without a workspace.
|
// Fail when `--package` is provided without a workspace.
|
||||||
|
|
@ -1331,10 +1341,12 @@ fn build_all_with_failure() -> Result<()> {
|
||||||
[PKG] Building source distribution...
|
[PKG] Building source distribution...
|
||||||
[PKG] Building wheel from source distribution...
|
[PKG] Building wheel from source distribution...
|
||||||
[PKG] Building wheel from source distribution...
|
[PKG] Building wheel from source distribution...
|
||||||
Successfully built dist/member_a-0.1.0.tar.gz and dist/member_a-0.1.0-py3-none-any.whl
|
Successfully built dist/member_a-0.1.0.tar.gz
|
||||||
|
Successfully built dist/member_a-0.1.0-py3-none-any.whl
|
||||||
× Failed to build `member-b @ [TEMP_DIR]/project/packages/member_b`
|
× Failed to build `member-b @ [TEMP_DIR]/project/packages/member_b`
|
||||||
╰─▶ Build backend failed to determine requirements with `build_sdist()` (exit status: 1)
|
╰─▶ Build backend failed to determine requirements with `build_sdist()` (exit status: 1)
|
||||||
Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
|
Successfully built dist/project-0.1.0.tar.gz
|
||||||
|
Successfully built dist/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// project and member_a should be built, regardless of member_b build failure
|
// project and member_a should be built, regardless of member_b build failure
|
||||||
|
|
@ -1628,7 +1640,8 @@ fn sha() -> Result<()> {
|
||||||
adding 'project-0.1.0.dist-info/top_level.txt'
|
adding 'project-0.1.0.dist-info/top_level.txt'
|
||||||
adding 'project-0.1.0.dist-info/RECORD'
|
adding 'project-0.1.0.dist-info/RECORD'
|
||||||
removing build/bdist.linux-x86_64/wheel
|
removing build/bdist.linux-x86_64/wheel
|
||||||
Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
|
Successfully built dist/project-0.1.0.tar.gz
|
||||||
|
Successfully built dist/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
project
|
project
|
||||||
|
|
@ -1710,7 +1723,8 @@ fn build_no_build_logs() -> Result<()> {
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
Building source distribution...
|
Building source distribution...
|
||||||
Building wheel from source distribution...
|
Building wheel from source distribution...
|
||||||
Successfully built project/dist/project-0.1.0.tar.gz and project/dist/project-0.1.0-py3-none-any.whl
|
Successfully built project/dist/project-0.1.0.tar.gz
|
||||||
|
Successfully built project/dist/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -1867,7 +1881,8 @@ fn tool_uv_sources() -> Result<()> {
|
||||||
adding 'project-0.1.0.dist-info/top_level.txt'
|
adding 'project-0.1.0.dist-info/top_level.txt'
|
||||||
adding 'project-0.1.0.dist-info/RECORD'
|
adding 'project-0.1.0.dist-info/RECORD'
|
||||||
removing build/bdist.linux-x86_64/wheel
|
removing build/bdist.linux-x86_64/wheel
|
||||||
Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
|
Successfully built dist/project-0.1.0.tar.gz
|
||||||
|
Successfully built dist/project-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
project
|
project
|
||||||
|
|
@ -1915,7 +1930,8 @@ fn git_boundary_in_dist_build() -> Result<()> {
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
Building source distribution...
|
Building source distribution...
|
||||||
Building wheel from source distribution...
|
Building wheel from source distribution...
|
||||||
Successfully built dist/demo-0.1.0.tar.gz and dist/demo-0.1.0-py3-none-any.whl
|
Successfully built dist/demo-0.1.0.tar.gz
|
||||||
|
Successfully built dist/demo-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// Check that the source file is included
|
// Check that the source file is included
|
||||||
|
|
@ -2048,6 +2064,7 @@ fn build_fast_path() -> Result<()> {
|
||||||
let built_by_uv = current_dir()?.join("../../scripts/packages/built-by-uv");
|
let built_by_uv = current_dir()?.join("../../scripts/packages/built-by-uv");
|
||||||
|
|
||||||
uv_snapshot!(context.build()
|
uv_snapshot!(context.build()
|
||||||
|
.arg("--preview")
|
||||||
.arg(&built_by_uv)
|
.arg(&built_by_uv)
|
||||||
.arg("--out-dir")
|
.arg("--out-dir")
|
||||||
.arg(context.temp_dir.join("output1")), @r###"
|
.arg(context.temp_dir.join("output1")), @r###"
|
||||||
|
|
@ -2058,7 +2075,8 @@ fn build_fast_path() -> Result<()> {
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
Building source distribution (uv build backend)...
|
Building source distribution (uv build backend)...
|
||||||
Building wheel from source distribution (uv build backend)...
|
Building wheel from source distribution (uv build backend)...
|
||||||
Successfully built output1/built_by_uv-0.1.0.tar.gz and output1/built_by_uv-0.1.0-py3-none-any.whl
|
Successfully built output1/built_by_uv-0.1.0.tar.gz
|
||||||
|
Successfully built output1/built_by_uv-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
context
|
context
|
||||||
.temp_dir
|
.temp_dir
|
||||||
|
|
@ -2072,6 +2090,7 @@ fn build_fast_path() -> Result<()> {
|
||||||
.assert(predicate::path::is_file());
|
.assert(predicate::path::is_file());
|
||||||
|
|
||||||
uv_snapshot!(context.build()
|
uv_snapshot!(context.build()
|
||||||
|
.arg("--preview")
|
||||||
.arg(&built_by_uv)
|
.arg(&built_by_uv)
|
||||||
.arg("--out-dir")
|
.arg("--out-dir")
|
||||||
.arg(context.temp_dir.join("output2"))
|
.arg(context.temp_dir.join("output2"))
|
||||||
|
|
@ -2091,6 +2110,7 @@ fn build_fast_path() -> Result<()> {
|
||||||
.assert(predicate::path::is_file());
|
.assert(predicate::path::is_file());
|
||||||
|
|
||||||
uv_snapshot!(context.build()
|
uv_snapshot!(context.build()
|
||||||
|
.arg("--preview")
|
||||||
.arg(&built_by_uv)
|
.arg(&built_by_uv)
|
||||||
.arg("--out-dir")
|
.arg("--out-dir")
|
||||||
.arg(context.temp_dir.join("output3"))
|
.arg(context.temp_dir.join("output3"))
|
||||||
|
|
@ -2110,6 +2130,7 @@ fn build_fast_path() -> Result<()> {
|
||||||
.assert(predicate::path::is_file());
|
.assert(predicate::path::is_file());
|
||||||
|
|
||||||
uv_snapshot!(context.build()
|
uv_snapshot!(context.build()
|
||||||
|
.arg("--preview")
|
||||||
.arg(&built_by_uv)
|
.arg(&built_by_uv)
|
||||||
.arg("--out-dir")
|
.arg("--out-dir")
|
||||||
.arg(context.temp_dir.join("output4"))
|
.arg(context.temp_dir.join("output4"))
|
||||||
|
|
@ -2122,7 +2143,8 @@ fn build_fast_path() -> Result<()> {
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
Building source distribution (uv build backend)...
|
Building source distribution (uv build backend)...
|
||||||
Building wheel (uv build backend)...
|
Building wheel (uv build backend)...
|
||||||
Successfully built output4/built_by_uv-0.1.0.tar.gz and output4/built_by_uv-0.1.0-py3-none-any.whl
|
Successfully built output4/built_by_uv-0.1.0.tar.gz
|
||||||
|
Successfully built output4/built_by_uv-0.1.0-py3-none-any.whl
|
||||||
"###);
|
"###);
|
||||||
context
|
context
|
||||||
.temp_dir
|
.temp_dir
|
||||||
|
|
@ -2137,3 +2159,172 @@ fn build_fast_path() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Test the `--list` option.
|
||||||
|
#[test]
|
||||||
|
fn list_files() -> Result<()> {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
|
let built_by_uv = current_dir()?.join("../../scripts/packages/built-by-uv");
|
||||||
|
|
||||||
|
// By default, we build the wheel from the source dist, which we need to do even for the list
|
||||||
|
// task.
|
||||||
|
uv_snapshot!(context.build()
|
||||||
|
.arg("--preview")
|
||||||
|
.arg(&built_by_uv)
|
||||||
|
.arg("--out-dir")
|
||||||
|
.arg(context.temp_dir.join("output1"))
|
||||||
|
.arg("--list"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
Building built_by_uv-0.1.0.tar.gz will include the following files:
|
||||||
|
built_by_uv-0.1.0/LICENSE-APACHE (LICENSE-APACHE)
|
||||||
|
built_by_uv-0.1.0/LICENSE-MIT (LICENSE-MIT)
|
||||||
|
built_by_uv-0.1.0/PKG-INFO (generated)
|
||||||
|
built_by_uv-0.1.0/README.md (README.md)
|
||||||
|
built_by_uv-0.1.0/assets/data.csv (assets/data.csv)
|
||||||
|
built_by_uv-0.1.0/header/built_by_uv.h (header/built_by_uv.h)
|
||||||
|
built_by_uv-0.1.0/pyproject.toml (pyproject.toml)
|
||||||
|
built_by_uv-0.1.0/scripts/whoami.sh (scripts/whoami.sh)
|
||||||
|
built_by_uv-0.1.0/src/built_by_uv/__init__.py (src/built_by_uv/__init__.py)
|
||||||
|
built_by_uv-0.1.0/src/built_by_uv/arithmetic/__init__.py (src/built_by_uv/arithmetic/__init__.py)
|
||||||
|
built_by_uv-0.1.0/src/built_by_uv/arithmetic/circle.py (src/built_by_uv/arithmetic/circle.py)
|
||||||
|
built_by_uv-0.1.0/src/built_by_uv/arithmetic/pi.txt (src/built_by_uv/arithmetic/pi.txt)
|
||||||
|
built_by_uv-0.1.0/src/built_by_uv/build-only.h (src/built_by_uv/build-only.h)
|
||||||
|
built_by_uv-0.1.0/third-party-licenses/PEP-401.txt (third-party-licenses/PEP-401.txt)
|
||||||
|
Building built_by_uv-0.1.0-py3-none-any.whl will include the following files:
|
||||||
|
built_by_uv-0.1.0.data/data/data.csv (assets/data.csv)
|
||||||
|
built_by_uv-0.1.0.data/headers/built_by_uv.h (header/built_by_uv.h)
|
||||||
|
built_by_uv-0.1.0.data/scripts/whoami.sh (scripts/whoami.sh)
|
||||||
|
built_by_uv-0.1.0.dist-info/METADATA (generated)
|
||||||
|
built_by_uv-0.1.0.dist-info/WHEEL (generated)
|
||||||
|
built_by_uv-0.1.0.dist-info/licenses/LICENSE-APACHE (LICENSE-APACHE)
|
||||||
|
built_by_uv-0.1.0.dist-info/licenses/LICENSE-MIT (LICENSE-MIT)
|
||||||
|
built_by_uv-0.1.0.dist-info/licenses/third-party-licenses/PEP-401.txt (third-party-licenses/PEP-401.txt)
|
||||||
|
built_by_uv/__init__.py (src/built_by_uv/__init__.py)
|
||||||
|
built_by_uv/arithmetic/__init__.py (src/built_by_uv/arithmetic/__init__.py)
|
||||||
|
built_by_uv/arithmetic/circle.py (src/built_by_uv/arithmetic/circle.py)
|
||||||
|
built_by_uv/arithmetic/pi.txt (src/built_by_uv/arithmetic/pi.txt)
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Building source distribution (uv build backend)...
|
||||||
|
Successfully built output1/built_by_uv-0.1.0.tar.gz
|
||||||
|
"###);
|
||||||
|
context
|
||||||
|
.temp_dir
|
||||||
|
.child("output1")
|
||||||
|
.child("built_by_uv-0.1.0.tar.gz")
|
||||||
|
.assert(predicate::path::is_file());
|
||||||
|
context
|
||||||
|
.temp_dir
|
||||||
|
.child("output1")
|
||||||
|
.child("built_by_uv-0.1.0-py3-none-any.whl")
|
||||||
|
.assert(predicate::path::missing());
|
||||||
|
|
||||||
|
uv_snapshot!(context.build()
|
||||||
|
.arg("--preview")
|
||||||
|
.arg(&built_by_uv)
|
||||||
|
.arg("--out-dir")
|
||||||
|
.arg(context.temp_dir.join("output2"))
|
||||||
|
.arg("--list")
|
||||||
|
.arg("--sdist")
|
||||||
|
.arg("--wheel"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
Building built_by_uv-0.1.0.tar.gz will include the following files:
|
||||||
|
built_by_uv-0.1.0/LICENSE-APACHE (LICENSE-APACHE)
|
||||||
|
built_by_uv-0.1.0/LICENSE-MIT (LICENSE-MIT)
|
||||||
|
built_by_uv-0.1.0/PKG-INFO (generated)
|
||||||
|
built_by_uv-0.1.0/README.md (README.md)
|
||||||
|
built_by_uv-0.1.0/assets/data.csv (assets/data.csv)
|
||||||
|
built_by_uv-0.1.0/header/built_by_uv.h (header/built_by_uv.h)
|
||||||
|
built_by_uv-0.1.0/pyproject.toml (pyproject.toml)
|
||||||
|
built_by_uv-0.1.0/scripts/whoami.sh (scripts/whoami.sh)
|
||||||
|
built_by_uv-0.1.0/src/built_by_uv/__init__.py (src/built_by_uv/__init__.py)
|
||||||
|
built_by_uv-0.1.0/src/built_by_uv/arithmetic/__init__.py (src/built_by_uv/arithmetic/__init__.py)
|
||||||
|
built_by_uv-0.1.0/src/built_by_uv/arithmetic/circle.py (src/built_by_uv/arithmetic/circle.py)
|
||||||
|
built_by_uv-0.1.0/src/built_by_uv/arithmetic/pi.txt (src/built_by_uv/arithmetic/pi.txt)
|
||||||
|
built_by_uv-0.1.0/src/built_by_uv/build-only.h (src/built_by_uv/build-only.h)
|
||||||
|
built_by_uv-0.1.0/third-party-licenses/PEP-401.txt (third-party-licenses/PEP-401.txt)
|
||||||
|
Building built_by_uv-0.1.0-py3-none-any.whl will include the following files:
|
||||||
|
built_by_uv-0.1.0.data/data/data.csv (assets/data.csv)
|
||||||
|
built_by_uv-0.1.0.data/headers/built_by_uv.h (header/built_by_uv.h)
|
||||||
|
built_by_uv-0.1.0.data/scripts/whoami.sh (scripts/whoami.sh)
|
||||||
|
built_by_uv-0.1.0.dist-info/METADATA (generated)
|
||||||
|
built_by_uv-0.1.0.dist-info/WHEEL (generated)
|
||||||
|
built_by_uv-0.1.0.dist-info/licenses/LICENSE-APACHE (LICENSE-APACHE)
|
||||||
|
built_by_uv-0.1.0.dist-info/licenses/LICENSE-MIT (LICENSE-MIT)
|
||||||
|
built_by_uv-0.1.0.dist-info/licenses/third-party-licenses/PEP-401.txt (third-party-licenses/PEP-401.txt)
|
||||||
|
built_by_uv/__init__.py (src/built_by_uv/__init__.py)
|
||||||
|
built_by_uv/arithmetic/__init__.py (src/built_by_uv/arithmetic/__init__.py)
|
||||||
|
built_by_uv/arithmetic/circle.py (src/built_by_uv/arithmetic/circle.py)
|
||||||
|
built_by_uv/arithmetic/pi.txt (src/built_by_uv/arithmetic/pi.txt)
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
"###);
|
||||||
|
context
|
||||||
|
.temp_dir
|
||||||
|
.child("output2")
|
||||||
|
.child("built_by_uv-0.1.0.tar.gz")
|
||||||
|
.assert(predicate::path::missing());
|
||||||
|
context
|
||||||
|
.temp_dir
|
||||||
|
.child("output2")
|
||||||
|
.child("built_by_uv-0.1.0-py3-none-any.whl")
|
||||||
|
.assert(predicate::path::missing());
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test `--list` option errors.
|
||||||
|
#[test]
|
||||||
|
fn list_files_errors() -> Result<()> {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
|
||||||
|
let built_by_uv = current_dir()?.join("../../scripts/packages/built-by-uv");
|
||||||
|
|
||||||
|
let mut filters = context.filters();
|
||||||
|
// In CI, we run with link mode settings.
|
||||||
|
filters.push(("--link-mode <LINK_MODE> ", ""));
|
||||||
|
uv_snapshot!(filters, context.build()
|
||||||
|
.arg("--preview")
|
||||||
|
.arg(&built_by_uv)
|
||||||
|
.arg("--out-dir")
|
||||||
|
.arg(context.temp_dir.join("output1"))
|
||||||
|
.arg("--list")
|
||||||
|
.arg("--force-pep517"), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: the argument '--list' cannot be used with '--force-pep517'
|
||||||
|
|
||||||
|
Usage: uv build --cache-dir [CACHE_DIR] --out-dir <OUT_DIR> --exclude-newer <EXCLUDE_NEWER> <SRC>
|
||||||
|
|
||||||
|
For more information, try '--help'.
|
||||||
|
"###);
|
||||||
|
|
||||||
|
// Not a uv build backend package, we can't list it.
|
||||||
|
let anyio_local = current_dir()?.join("../../scripts/packages/anyio_local");
|
||||||
|
let mut filters = context.filters();
|
||||||
|
// Windows normalization
|
||||||
|
filters.push(("/crates/uv/../../", "/"));
|
||||||
|
uv_snapshot!(filters, context.build()
|
||||||
|
.arg("--preview")
|
||||||
|
.arg(&anyio_local)
|
||||||
|
.arg("--out-dir")
|
||||||
|
.arg(context.temp_dir.join("output2"))
|
||||||
|
.arg("--list"), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
× Failed to build `[WORKSPACE]/scripts/packages/anyio_local`
|
||||||
|
╰─▶ Can only use `--list` with the uv backend
|
||||||
|
"###);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -543,7 +543,7 @@ fn python_install_default() {
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
The `--default` flag is only available in preview mode; add the `--preview` flag to use `--default
|
The `--default` flag is only available in preview mode; add the `--preview` flag to use `--default`
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
// Install a specific version
|
// Install a specific version
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue