Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions crates/uv-build-frontend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ impl SourceBuild {
pub async fn setup(
source: &Path,
subdirectory: Option<&Path>,
install_path: &Path,
fallback_package_name: Option<&PackageName>,
fallback_package_version: Option<&Version>,
interpreter: &Interpreter,
Expand Down Expand Up @@ -273,6 +274,7 @@ impl SourceBuild {
// Check if we have a PEP 517 build backend.
let (pep517_backend, project) = Self::extract_pep517_backend(
&source_tree,
install_path,
fallback_package_name,
locations,
source_strategy,
Expand Down Expand Up @@ -368,6 +370,7 @@ impl SourceBuild {
create_pep517_build_environment(
&runner,
&source_tree,
install_path,
&venv,
&pep517_backend,
build_context,
Expand Down Expand Up @@ -436,6 +439,7 @@ impl SourceBuild {
/// Extract the PEP 517 backend from the `pyproject.toml` or `setup.py` file.
async fn extract_pep517_backend(
source_tree: &Path,
install_path: &Path,
package_name: Option<&PackageName>,
locations: &IndexLocations,
source_strategy: SourceStrategy,
Expand Down Expand Up @@ -469,7 +473,7 @@ impl SourceBuild {
};
let requires_dist = RequiresDist::from_project_maybe_workspace(
requires_dist,
source_tree,
install_path,
locations,
source_strategy,
LowerBound::Allow,
Expand Down Expand Up @@ -803,6 +807,7 @@ fn escape_path_for_python(path: &Path) -> String {
async fn create_pep517_build_environment(
runner: &PythonRunner,
source_tree: &Path,
install_path: &Path,
venv: &PythonEnvironment,
pep517_backend: &Pep517Backend,
build_context: &impl BuildContext,
Expand Down Expand Up @@ -921,7 +926,7 @@ async fn create_pep517_build_environment(
};
let requires_dist = RequiresDist::from_project_maybe_workspace(
requires_dist,
source_tree,
install_path,
locations,
source_strategy,
LowerBound::Allow,
Expand Down
2 changes: 2 additions & 0 deletions crates/uv-dispatch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ impl<'a> BuildContext for BuildDispatch<'a> {
&'data self,
source: &'data Path,
subdirectory: Option<&'data Path>,
install_path: &'data Path,
version_id: Option<String>,
dist: Option<&'data SourceDist>,
sources: SourceStrategy,
Expand Down Expand Up @@ -352,6 +353,7 @@ impl<'a> BuildContext for BuildDispatch<'a> {
let builder = SourceBuild::setup(
source,
subdirectory,
install_path,
dist_name,
dist_version,
self.interpreter,
Expand Down
2 changes: 2 additions & 0 deletions crates/uv-distribution/src/source/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1712,6 +1712,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
.setup_build(
source_root,
subdirectory,
source_root,
Some(source.to_string()),
source.as_dist(),
source_strategy,
Expand Down Expand Up @@ -1756,6 +1757,7 @@ impl<'a, T: BuildContext> SourceDistributionBuilder<'a, T> {
.setup_build(
source_root,
subdirectory,
source_root,
Some(source.to_string()),
source.as_dist(),
source_strategy,
Expand Down
1 change: 1 addition & 0 deletions crates/uv-types/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ pub trait BuildContext {
&'a self,
source: &'a Path,
subdirectory: Option<&'a Path>,
install_path: &'a Path,
version_id: Option<String>,
dist: Option<&'a SourceDist>,
sources: SourceStrategy,
Expand Down
9 changes: 8 additions & 1 deletion crates/uv/src/commands/build_frontend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,9 +535,9 @@ async fn build_package(
};

// Prepare some common arguments for the build.
let dist = None;
let subdirectory = None;
let version_id = source.path().file_name().and_then(|name| name.to_str());
let dist = None;

let build_output = match printer {
Printer::Default | Printer::NoProgress | Printer::Verbose => {
Expand All @@ -563,6 +563,7 @@ async fn build_package(
.setup_build(
source.path(),
subdirectory,
source.path(),
version_id.map(ToString::to_string),
dist,
sources,
Expand Down Expand Up @@ -601,6 +602,7 @@ async fn build_package(
.setup_build(
&extracted,
subdirectory,
source.path(),
version_id.map(ToString::to_string),
dist,
sources,
Expand All @@ -623,6 +625,7 @@ async fn build_package(
.setup_build(
source.path(),
subdirectory,
source.path(),
version_id.map(ToString::to_string),
dist,
sources,
Expand All @@ -645,6 +648,7 @@ async fn build_package(
.setup_build(
source.path(),
subdirectory,
source.path(),
version_id.map(ToString::to_string),
dist,
sources,
Expand All @@ -666,6 +670,7 @@ async fn build_package(
.setup_build(
source.path(),
subdirectory,
source.path(),
version_id.map(ToString::to_string),
dist,
sources,
Expand All @@ -684,6 +689,7 @@ async fn build_package(
.setup_build(
source.path(),
subdirectory,
source.path(),
version_id.map(ToString::to_string),
dist,
sources,
Expand Down Expand Up @@ -724,6 +730,7 @@ async fn build_package(
.setup_build(
&extracted,
subdirectory,
source.path(),
version_id.map(ToString::to_string),
dist,
sources,
Expand Down
154 changes: 154 additions & 0 deletions crates/uv/tests/it/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::common::{uv_snapshot, TestContext};
use anyhow::Result;
use assert_fs::prelude::*;
use fs_err::File;
use indoc::indoc;
use insta::assert_snapshot;
use predicates::prelude::predicate;
use zip::ZipArchive;
Expand Down Expand Up @@ -1766,6 +1767,159 @@ fn build_no_build_logs() -> Result<()> {
Ok(())
}

#[test]
fn tool_uv_sources() -> 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 build = context.temp_dir.child("backend");
build.child("pyproject.toml").write_str(
r#"
[project]
name = "backend"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["typing-extensions>=3.10"]

[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"
"#,
)?;

build
.child("src")
.child("backend")
.child("__init__.py")
.write_str(indoc! { r#"
def hello() -> str:
return "Hello, world!"
"#})?;
build.child("README.md").touch()?;

let project = context.temp_dir.child("project");

project.child("pyproject.toml").write_str(
r#"
[project]
name = "project"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = ["iniconfig>1"]

[build-system]
requires = ["setuptools>=42", "backend==0.1.0"]
build-backend = "setuptools.build_meta"

[tool.uv.sources]
backend = { path = "../backend" }
"#,
)?;

project.child("setup.py").write_str(indoc! {r"
from setuptools import setup

from backend import hello

hello()

setup()
",
})?;

uv_snapshot!(filters, context.build().current_dir(project.path()), @r###"
success: true
exit_code: 0
----- stdout -----

----- stderr -----
Building source distribution...
running egg_info
creating project.egg-info
writing project.egg-info/PKG-INFO
writing dependency_links to project.egg-info/dependency_links.txt
writing requirements to project.egg-info/requires.txt
writing top-level names to project.egg-info/top_level.txt
writing manifest file 'project.egg-info/SOURCES.txt'
reading manifest file 'project.egg-info/SOURCES.txt'
writing manifest file 'project.egg-info/SOURCES.txt'
running sdist
running egg_info
writing project.egg-info/PKG-INFO
writing dependency_links to project.egg-info/dependency_links.txt
writing requirements to project.egg-info/requires.txt
writing top-level names to project.egg-info/top_level.txt
reading manifest file 'project.egg-info/SOURCES.txt'
writing manifest file 'project.egg-info/SOURCES.txt'
warning: sdist: standard file not found: should have one of README, README.rst, README.txt, README.md

running check
creating project-0.1.0
creating project-0.1.0/project.egg-info
copying files to project-0.1.0...
copying pyproject.toml -> project-0.1.0
copying setup.py -> project-0.1.0
copying project.egg-info/PKG-INFO -> project-0.1.0/project.egg-info
copying project.egg-info/SOURCES.txt -> project-0.1.0/project.egg-info
copying project.egg-info/dependency_links.txt -> project-0.1.0/project.egg-info
copying project.egg-info/requires.txt -> project-0.1.0/project.egg-info
copying project.egg-info/top_level.txt -> project-0.1.0/project.egg-info
copying project.egg-info/SOURCES.txt -> project-0.1.0/project.egg-info
Writing project-0.1.0/setup.cfg
Creating tar archive
removing 'project-0.1.0' (and everything under it)
Building wheel from source distribution...
running egg_info
writing project.egg-info/PKG-INFO
writing dependency_links to project.egg-info/dependency_links.txt
writing requirements to project.egg-info/requires.txt
writing top-level names to project.egg-info/top_level.txt
reading manifest file 'project.egg-info/SOURCES.txt'
writing manifest file 'project.egg-info/SOURCES.txt'
running bdist_wheel
running build
installing to build/bdist.linux-x86_64/wheel
running install
running install_egg_info
running egg_info
writing project.egg-info/PKG-INFO
writing dependency_links to project.egg-info/dependency_links.txt
writing requirements to project.egg-info/requires.txt
writing top-level names to project.egg-info/top_level.txt
reading manifest file 'project.egg-info/SOURCES.txt'
writing manifest file 'project.egg-info/SOURCES.txt'
Copying project.egg-info to build/bdist.linux-x86_64/wheel/project-0.1.0-py3.12.egg-info
running install_scripts
creating build/bdist.linux-x86_64/wheel/project-0.1.0.dist-info/WHEEL
creating '[TEMP_DIR]/project/dist/[TMP]/wheel' to it
adding 'project-0.1.0.dist-info/METADATA'
adding 'project-0.1.0.dist-info/WHEEL'
adding 'project-0.1.0.dist-info/top_level.txt'
adding 'project-0.1.0.dist-info/RECORD'
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
"###);

project
.child("dist")
.child("project-0.1.0.tar.gz")
.assert(predicate::path::is_file());
project
.child("dist")
.child("project-0.1.0-py3-none-any.whl")
.assert(predicate::path::is_file());

Ok(())
}

/// Check that we have a working git boundary for builds from source dist to wheel in `dist/`.
#[test]
fn git_boundary_in_dist_build() -> Result<()> {
Expand Down