mirror of
https://github.com/astral-sh/uv.git
synced 2025-11-02 21:02:37 +00:00
Add --package support to uv build (#6990)
## Summary This PR adds `--package` support to `uv build`, such that you can use `--package` from anywhere in a workspace to build any member. If a source directory is provided, we use that as the workspace root. If a file is provided, we error. For now, `uv build` only builds the current package, making it semantically identical to `uv sync`.
This commit is contained in:
parent
05ed4bc11d
commit
7aed94bed2
6 changed files with 321 additions and 21 deletions
|
|
@ -1955,6 +1955,15 @@ pub struct BuildArgs {
|
||||||
#[arg(value_parser = parse_file_path)]
|
#[arg(value_parser = parse_file_path)]
|
||||||
pub src: Option<PathBuf>,
|
pub src: Option<PathBuf>,
|
||||||
|
|
||||||
|
/// Build a specific package in the workspace.
|
||||||
|
///
|
||||||
|
/// The workspace will be discovered from the provided source directory, or the current
|
||||||
|
/// directory if no source directory is provided.
|
||||||
|
///
|
||||||
|
/// If the workspace member does not exist, uv will exit with an error.
|
||||||
|
#[arg(long)]
|
||||||
|
pub package: Option<PackageName>,
|
||||||
|
|
||||||
/// The output directory to which distributions should be written.
|
/// The output directory to which distributions should be written.
|
||||||
///
|
///
|
||||||
/// Defaults to the `dist` subdirectory within the source directory, or the
|
/// Defaults to the `dist` subdirectory within the source directory, or the
|
||||||
|
|
|
||||||
|
|
@ -15,19 +15,20 @@ use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClient
|
||||||
use uv_configuration::{BuildKind, BuildOutput, Concurrency};
|
use uv_configuration::{BuildKind, BuildOutput, Concurrency};
|
||||||
use uv_dispatch::BuildDispatch;
|
use uv_dispatch::BuildDispatch;
|
||||||
use uv_fs::{Simplified, CWD};
|
use uv_fs::{Simplified, CWD};
|
||||||
|
use uv_normalize::PackageName;
|
||||||
use uv_python::{
|
use uv_python::{
|
||||||
EnvironmentPreference, PythonDownloads, PythonEnvironment, PythonInstallation,
|
EnvironmentPreference, PythonDownloads, PythonEnvironment, PythonInstallation,
|
||||||
PythonPreference, PythonRequest, PythonVersionFile, VersionRequest,
|
PythonPreference, PythonRequest, PythonVersionFile, VersionRequest,
|
||||||
};
|
};
|
||||||
use uv_resolver::{FlatIndex, RequiresPython};
|
use uv_resolver::{FlatIndex, RequiresPython};
|
||||||
use uv_types::{BuildContext, BuildIsolation, HashStrategy};
|
use uv_types::{BuildContext, BuildIsolation, HashStrategy};
|
||||||
use uv_warnings::warn_user_once;
|
use uv_workspace::{DiscoveryOptions, Workspace};
|
||||||
use uv_workspace::{DiscoveryOptions, VirtualProject, WorkspaceError};
|
|
||||||
|
|
||||||
/// Build source distributions and wheels.
|
/// Build source distributions and wheels.
|
||||||
#[allow(clippy::fn_params_excessive_bools)]
|
#[allow(clippy::fn_params_excessive_bools)]
|
||||||
pub(crate) async fn build(
|
pub(crate) async fn build(
|
||||||
src: Option<PathBuf>,
|
src: Option<PathBuf>,
|
||||||
|
package: Option<PackageName>,
|
||||||
output_dir: Option<PathBuf>,
|
output_dir: Option<PathBuf>,
|
||||||
sdist: bool,
|
sdist: bool,
|
||||||
wheel: bool,
|
wheel: bool,
|
||||||
|
|
@ -44,6 +45,7 @@ pub(crate) async fn build(
|
||||||
) -> Result<ExitStatus> {
|
) -> Result<ExitStatus> {
|
||||||
let assets = build_impl(
|
let assets = build_impl(
|
||||||
src.as_deref(),
|
src.as_deref(),
|
||||||
|
package.as_ref(),
|
||||||
output_dir.as_deref(),
|
output_dir.as_deref(),
|
||||||
sdist,
|
sdist,
|
||||||
wheel,
|
wheel,
|
||||||
|
|
@ -82,6 +84,7 @@ pub(crate) async fn build(
|
||||||
#[allow(clippy::fn_params_excessive_bools)]
|
#[allow(clippy::fn_params_excessive_bools)]
|
||||||
async fn build_impl(
|
async fn build_impl(
|
||||||
src: Option<&Path>,
|
src: Option<&Path>,
|
||||||
|
package: Option<&PackageName>,
|
||||||
output_dir: Option<&Path>,
|
output_dir: Option<&Path>,
|
||||||
sdist: bool,
|
sdist: bool,
|
||||||
wheel: bool,
|
wheel: bool,
|
||||||
|
|
@ -118,6 +121,7 @@ async fn build_impl(
|
||||||
.connectivity(connectivity)
|
.connectivity(connectivity)
|
||||||
.native_tls(native_tls);
|
.native_tls(native_tls);
|
||||||
|
|
||||||
|
// Determine the source to build.
|
||||||
let src = if let Some(src) = src {
|
let src = if let Some(src) = src {
|
||||||
let src = std::path::absolute(src)?;
|
let src = std::path::absolute(src)?;
|
||||||
let metadata = match fs_err::tokio::metadata(&src).await {
|
let metadata = match fs_err::tokio::metadata(&src).await {
|
||||||
|
|
@ -139,9 +143,37 @@ async fn build_impl(
|
||||||
Source::Directory(Cow::Borrowed(&*CWD))
|
Source::Directory(Cow::Borrowed(&*CWD))
|
||||||
};
|
};
|
||||||
|
|
||||||
let src_dir = match src {
|
// Attempt to discover the workspace; on failure, save the error for later.
|
||||||
Source::Directory(ref src) => src,
|
let workspace = Workspace::discover(src.directory(), &DiscoveryOptions::default()).await;
|
||||||
Source::File(ref src) => src.parent().unwrap(),
|
|
||||||
|
// If a `--package` was provided, adjust the source directory.
|
||||||
|
let src = if let Some(package) = package {
|
||||||
|
if matches!(src, Source::File(_)) {
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"Cannot specify a `--package` when building from a file"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let workspace = match workspace {
|
||||||
|
Ok(ref workspace) => workspace,
|
||||||
|
Err(err) => {
|
||||||
|
return Err(
|
||||||
|
anyhow::anyhow!("`--package` was provided, but no workspace was found")
|
||||||
|
.context(err),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let project = workspace
|
||||||
|
.packages()
|
||||||
|
.get(package)
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("Package `{}` not found in workspace", package))?
|
||||||
|
.root()
|
||||||
|
.clone();
|
||||||
|
|
||||||
|
Source::Directory(Cow::Owned(project))
|
||||||
|
} else {
|
||||||
|
src
|
||||||
};
|
};
|
||||||
|
|
||||||
let output_dir = if let Some(output_dir) = output_dir {
|
let output_dir = if let Some(output_dir) = output_dir {
|
||||||
|
|
@ -158,26 +190,15 @@ async fn build_impl(
|
||||||
|
|
||||||
// (2) Request from `.python-version`
|
// (2) Request from `.python-version`
|
||||||
if interpreter_request.is_none() {
|
if interpreter_request.is_none() {
|
||||||
interpreter_request = PythonVersionFile::discover(&src_dir, no_config, false)
|
interpreter_request = PythonVersionFile::discover(src.directory(), no_config, false)
|
||||||
.await?
|
.await?
|
||||||
.and_then(PythonVersionFile::into_version);
|
.and_then(PythonVersionFile::into_version);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (3) `Requires-Python` in `pyproject.toml`
|
// (3) `Requires-Python` in `pyproject.toml`
|
||||||
if interpreter_request.is_none() {
|
if interpreter_request.is_none() {
|
||||||
let project = match VirtualProject::discover(src_dir, &DiscoveryOptions::default()).await {
|
if let Ok(ref workspace) = workspace {
|
||||||
Ok(project) => Some(project),
|
interpreter_request = find_requires_python(workspace)?
|
||||||
Err(WorkspaceError::MissingProject(_)) => None,
|
|
||||||
Err(WorkspaceError::MissingPyprojectToml) => None,
|
|
||||||
Err(WorkspaceError::NonWorkspace(_)) => None,
|
|
||||||
Err(err) => {
|
|
||||||
warn_user_once!("{err}");
|
|
||||||
None
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(project) = project {
|
|
||||||
interpreter_request = find_requires_python(project.workspace())?
|
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(RequiresPython::specifiers)
|
.map(RequiresPython::specifiers)
|
||||||
.map(|specifiers| {
|
.map(|specifiers| {
|
||||||
|
|
@ -463,8 +484,15 @@ enum Source<'a> {
|
||||||
impl<'a> Source<'a> {
|
impl<'a> Source<'a> {
|
||||||
fn path(&self) -> &Path {
|
fn path(&self) -> &Path {
|
||||||
match self {
|
match self {
|
||||||
Source::File(path) => path.as_ref(),
|
Self::File(path) => path.as_ref(),
|
||||||
Source::Directory(path) => path.as_ref(),
|
Self::Directory(path) => path.as_ref(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn directory(&self) -> &Path {
|
||||||
|
match self {
|
||||||
|
Self::File(path) => path.parent().unwrap(),
|
||||||
|
Self::Directory(path) => path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -672,6 +672,7 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
|
||||||
|
|
||||||
commands::build(
|
commands::build(
|
||||||
args.src,
|
args.src,
|
||||||
|
args.package,
|
||||||
args.out_dir,
|
args.out_dir,
|
||||||
args.sdist,
|
args.sdist,
|
||||||
args.wheel,
|
args.wheel,
|
||||||
|
|
|
||||||
|
|
@ -1616,6 +1616,7 @@ impl PipCheckSettings {
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct BuildSettings {
|
pub(crate) struct BuildSettings {
|
||||||
pub(crate) src: Option<PathBuf>,
|
pub(crate) src: Option<PathBuf>,
|
||||||
|
pub(crate) package: Option<PackageName>,
|
||||||
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,
|
||||||
|
|
@ -1630,6 +1631,7 @@ impl BuildSettings {
|
||||||
let BuildArgs {
|
let BuildArgs {
|
||||||
src,
|
src,
|
||||||
out_dir,
|
out_dir,
|
||||||
|
package,
|
||||||
sdist,
|
sdist,
|
||||||
wheel,
|
wheel,
|
||||||
python,
|
python,
|
||||||
|
|
@ -1640,6 +1642,7 @@ impl BuildSettings {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
src,
|
src,
|
||||||
|
package,
|
||||||
out_dir,
|
out_dir,
|
||||||
sdist,
|
sdist,
|
||||||
wheel,
|
wheel,
|
||||||
|
|
|
||||||
|
|
@ -893,3 +893,256 @@ fn fail() -> Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn workspace() -> Result<()> {
|
||||||
|
let context = TestContext::new("3.12");
|
||||||
|
let filters = context
|
||||||
|
.filters()
|
||||||
|
.into_iter()
|
||||||
|
.chain([
|
||||||
|
(r"exit code: 1", "exit status: 1"),
|
||||||
|
(r"bdist\.[^/\\\s]+-[^/\\\s]+", "bdist.linux-x86_64"),
|
||||||
|
(r"\\\.", ""),
|
||||||
|
])
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let project = context.temp_dir.child("project");
|
||||||
|
|
||||||
|
let pyproject_toml = project.child("pyproject.toml");
|
||||||
|
pyproject_toml.write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "project"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = ["anyio==3.7.0"]
|
||||||
|
|
||||||
|
[tool.uv.workspace]
|
||||||
|
members = ["packages/*"]
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=42"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
project.child("src").child("__init__.py").touch()?;
|
||||||
|
project.child("README").touch()?;
|
||||||
|
|
||||||
|
let member = project.child("packages").child("member");
|
||||||
|
fs_err::create_dir_all(member.path())?;
|
||||||
|
|
||||||
|
member.child("pyproject.toml").write_str(
|
||||||
|
r#"
|
||||||
|
[project]
|
||||||
|
name = "member"
|
||||||
|
version = "0.1.0"
|
||||||
|
requires-python = ">=3.12"
|
||||||
|
dependencies = ["iniconfig"]
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=42"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
"#,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
member.child("src").child("__init__.py").touch()?;
|
||||||
|
member.child("README").touch()?;
|
||||||
|
|
||||||
|
// Build the member.
|
||||||
|
uv_snapshot!(&filters, context.build().arg("--package").arg("member").current_dir(&project), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Building source distribution...
|
||||||
|
running egg_info
|
||||||
|
creating src/member.egg-info
|
||||||
|
writing src/member.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/member.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/member.egg-info/requires.txt
|
||||||
|
writing top-level names to src/member.egg-info/top_level.txt
|
||||||
|
writing manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
reading manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
running sdist
|
||||||
|
running egg_info
|
||||||
|
writing src/member.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/member.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/member.egg-info/requires.txt
|
||||||
|
writing top-level names to src/member.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
running check
|
||||||
|
creating member-0.1.0
|
||||||
|
creating member-0.1.0/src
|
||||||
|
creating member-0.1.0/src/member.egg-info
|
||||||
|
copying files to member-0.1.0...
|
||||||
|
copying README -> member-0.1.0
|
||||||
|
copying pyproject.toml -> member-0.1.0
|
||||||
|
copying src/__init__.py -> member-0.1.0/src
|
||||||
|
copying src/member.egg-info/PKG-INFO -> member-0.1.0/src/member.egg-info
|
||||||
|
copying src/member.egg-info/SOURCES.txt -> member-0.1.0/src/member.egg-info
|
||||||
|
copying src/member.egg-info/dependency_links.txt -> member-0.1.0/src/member.egg-info
|
||||||
|
copying src/member.egg-info/requires.txt -> member-0.1.0/src/member.egg-info
|
||||||
|
copying src/member.egg-info/top_level.txt -> member-0.1.0/src/member.egg-info
|
||||||
|
copying src/member.egg-info/SOURCES.txt -> member-0.1.0/src/member.egg-info
|
||||||
|
Writing member-0.1.0/setup.cfg
|
||||||
|
Creating tar archive
|
||||||
|
removing 'member-0.1.0' (and everything under it)
|
||||||
|
Building wheel from source distribution...
|
||||||
|
running egg_info
|
||||||
|
writing src/member.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/member.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/member.egg-info/requires.txt
|
||||||
|
writing top-level names to src/member.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
running bdist_wheel
|
||||||
|
running build
|
||||||
|
running build_py
|
||||||
|
creating build
|
||||||
|
creating build/lib
|
||||||
|
copying src/__init__.py -> build/lib
|
||||||
|
running egg_info
|
||||||
|
writing src/member.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/member.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/member.egg-info/requires.txt
|
||||||
|
writing top-level names to src/member.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
installing to build/bdist.linux-x86_64/wheel
|
||||||
|
running install
|
||||||
|
running install_lib
|
||||||
|
creating build/bdist.linux-x86_64
|
||||||
|
creating build/bdist.linux-x86_64/wheel
|
||||||
|
copying build/lib/__init__.py -> build/bdist.linux-x86_64/wheel
|
||||||
|
running install_egg_info
|
||||||
|
Copying src/member.egg-info to build/bdist.linux-x86_64/wheel/member-0.1.0-py3.12.egg-info
|
||||||
|
running install_scripts
|
||||||
|
creating build/bdist.linux-x86_64/wheel/member-0.1.0.dist-info/WHEEL
|
||||||
|
creating '[TEMP_DIR]/project/packages/member/dist/[TMP]/wheel' to it
|
||||||
|
adding '__init__.py'
|
||||||
|
adding 'member-0.1.0.dist-info/METADATA'
|
||||||
|
adding 'member-0.1.0.dist-info/WHEEL'
|
||||||
|
adding 'member-0.1.0.dist-info/top_level.txt'
|
||||||
|
adding 'member-0.1.0.dist-info/RECORD'
|
||||||
|
removing build/bdist.linux-x86_64/wheel
|
||||||
|
Successfully built packages/member/dist/member-0.1.0.tar.gz and packages/member/dist/member-0.1.0-py3-none-any.whl
|
||||||
|
"###);
|
||||||
|
|
||||||
|
member
|
||||||
|
.child("dist")
|
||||||
|
.child("member-0.1.0.tar.gz")
|
||||||
|
.assert(predicate::path::is_file());
|
||||||
|
member
|
||||||
|
.child("dist")
|
||||||
|
.child("member-0.1.0-py3-none-any.whl")
|
||||||
|
.assert(predicate::path::is_file());
|
||||||
|
|
||||||
|
// If a source is provided, discover the workspace from the source.
|
||||||
|
uv_snapshot!(&filters, context.build().arg("./project").arg("--package").arg("member"), @r###"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Building source distribution...
|
||||||
|
running egg_info
|
||||||
|
writing src/member.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/member.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/member.egg-info/requires.txt
|
||||||
|
writing top-level names to src/member.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
running sdist
|
||||||
|
running egg_info
|
||||||
|
writing src/member.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/member.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/member.egg-info/requires.txt
|
||||||
|
writing top-level names to src/member.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
running check
|
||||||
|
creating member-0.1.0
|
||||||
|
creating member-0.1.0/src
|
||||||
|
creating member-0.1.0/src/member.egg-info
|
||||||
|
copying files to member-0.1.0...
|
||||||
|
copying README -> member-0.1.0
|
||||||
|
copying pyproject.toml -> member-0.1.0
|
||||||
|
copying src/__init__.py -> member-0.1.0/src
|
||||||
|
copying src/member.egg-info/PKG-INFO -> member-0.1.0/src/member.egg-info
|
||||||
|
copying src/member.egg-info/SOURCES.txt -> member-0.1.0/src/member.egg-info
|
||||||
|
copying src/member.egg-info/dependency_links.txt -> member-0.1.0/src/member.egg-info
|
||||||
|
copying src/member.egg-info/requires.txt -> member-0.1.0/src/member.egg-info
|
||||||
|
copying src/member.egg-info/top_level.txt -> member-0.1.0/src/member.egg-info
|
||||||
|
copying src/member.egg-info/SOURCES.txt -> member-0.1.0/src/member.egg-info
|
||||||
|
Writing member-0.1.0/setup.cfg
|
||||||
|
Creating tar archive
|
||||||
|
removing 'member-0.1.0' (and everything under it)
|
||||||
|
Building wheel from source distribution...
|
||||||
|
running egg_info
|
||||||
|
writing src/member.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/member.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/member.egg-info/requires.txt
|
||||||
|
writing top-level names to src/member.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
running bdist_wheel
|
||||||
|
running build
|
||||||
|
running build_py
|
||||||
|
creating build
|
||||||
|
creating build/lib
|
||||||
|
copying src/__init__.py -> build/lib
|
||||||
|
running egg_info
|
||||||
|
writing src/member.egg-info/PKG-INFO
|
||||||
|
writing dependency_links to src/member.egg-info/dependency_links.txt
|
||||||
|
writing requirements to src/member.egg-info/requires.txt
|
||||||
|
writing top-level names to src/member.egg-info/top_level.txt
|
||||||
|
reading manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
writing manifest file 'src/member.egg-info/SOURCES.txt'
|
||||||
|
installing to build/bdist.linux-x86_64/wheel
|
||||||
|
running install
|
||||||
|
running install_lib
|
||||||
|
creating build/bdist.linux-x86_64
|
||||||
|
creating build/bdist.linux-x86_64/wheel
|
||||||
|
copying build/lib/__init__.py -> build/bdist.linux-x86_64/wheel
|
||||||
|
running install_egg_info
|
||||||
|
Copying src/member.egg-info to build/bdist.linux-x86_64/wheel/member-0.1.0-py3.12.egg-info
|
||||||
|
running install_scripts
|
||||||
|
creating build/bdist.linux-x86_64/wheel/member-0.1.0.dist-info/WHEEL
|
||||||
|
creating '[TEMP_DIR]/project/packages/member/dist/[TMP]/wheel' to it
|
||||||
|
adding '__init__.py'
|
||||||
|
adding 'member-0.1.0.dist-info/METADATA'
|
||||||
|
adding 'member-0.1.0.dist-info/WHEEL'
|
||||||
|
adding 'member-0.1.0.dist-info/top_level.txt'
|
||||||
|
adding 'member-0.1.0.dist-info/RECORD'
|
||||||
|
removing build/bdist.linux-x86_64/wheel
|
||||||
|
Successfully built project/packages/member/dist/member-0.1.0.tar.gz and project/packages/member/dist/member-0.1.0-py3-none-any.whl
|
||||||
|
"###);
|
||||||
|
|
||||||
|
// Fail when `--package` is provided without a workspace.
|
||||||
|
uv_snapshot!(&filters, context.build().arg("--package").arg("member"), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: No `pyproject.toml` found in current directory or any parent directory
|
||||||
|
Caused by: `--package` was provided, but no workspace was found
|
||||||
|
"###);
|
||||||
|
|
||||||
|
// Fail when `--package` is a non-existent member without a workspace.
|
||||||
|
uv_snapshot!(&filters, context.build().arg("--package").arg("fail").current_dir(&project), @r###"
|
||||||
|
success: false
|
||||||
|
exit_code: 2
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
error: Package `fail` not found in workspace
|
||||||
|
"###);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6374,6 +6374,12 @@ uv build [OPTIONS] [SRC]
|
||||||
|
|
||||||
<p>Defaults to the <code>dist</code> subdirectory within the source directory, or the directory containing the source distribution archive.</p>
|
<p>Defaults to the <code>dist</code> subdirectory within the source directory, or the directory containing the source distribution archive.</p>
|
||||||
|
|
||||||
|
</dd><dt><code>--package</code> <i>package</i></dt><dd><p>Build a specific package in the workspace.</p>
|
||||||
|
|
||||||
|
<p>The workspace will be discovered from the provided source directory, or the current directory if no source directory is provided.</p>
|
||||||
|
|
||||||
|
<p>If the workspace member does not exist, uv will exit with an error.</p>
|
||||||
|
|
||||||
</dd><dt><code>--prerelease</code> <i>prerelease</i></dt><dd><p>The strategy to use when considering pre-release versions.</p>
|
</dd><dt><code>--prerelease</code> <i>prerelease</i></dt><dd><p>The strategy to use when considering pre-release versions.</p>
|
||||||
|
|
||||||
<p>By default, uv will accept pre-releases for packages that <em>only</em> publish pre-releases, along with first-party requirements that contain an explicit pre-release marker in the declared specifiers (<code>if-necessary-or-explicit</code>).</p>
|
<p>By default, uv will accept pre-releases for packages that <em>only</em> publish pre-releases, along with first-party requirements that contain an explicit pre-release marker in the declared specifiers (<code>if-necessary-or-explicit</code>).</p>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue