mirror of
				https://github.com/astral-sh/uv.git
				synced 2025-11-04 05:34:28 +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