Skip to content

Commit c23023c

Browse files
committed
Build backend: Add source tree -> source dist -> wheel tests
1 parent 02a7bb4 commit c23023c

File tree

19 files changed

+301
-55
lines changed

19 files changed

+301
-55
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/uv-build-backend/src/tests.rs

+30-32
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,26 @@ fn test_wheel() {
2828
#[test]
2929
fn test_record() {
3030
let record = vec![RecordEntry {
31-
path: "uv_backend/__init__.py".to_string(),
31+
path: "built_by_uv/__init__.py".to_string(),
3232
hash: "89f869e53a3a0061a52c0233e6442d4d72de80a8a2d3406d9ea0bfd397ed7865".to_string(),
3333
size: 37,
3434
}];
3535

3636
let mut writer = Vec::new();
37-
write_record(&mut writer, "uv_backend-0.1.0", record).unwrap();
37+
write_record(&mut writer, "built_by_uv-0.1.0", record).unwrap();
3838
assert_snapshot!(String::from_utf8(writer).unwrap(), @r"
39-
uv_backend/__init__.py,sha256=89f869e53a3a0061a52c0233e6442d4d72de80a8a2d3406d9ea0bfd397ed7865,37
40-
uv_backend-0.1.0/RECORD,,
39+
built_by_uv/__init__.py,sha256=89f869e53a3a0061a52c0233e6442d4d72de80a8a2d3406d9ea0bfd397ed7865,37
40+
built_by_uv-0.1.0/RECORD,,
4141
");
4242
}
4343

4444
/// Check that we write deterministic wheels.
4545
#[test]
4646
fn test_determinism() {
4747
let temp1 = TempDir::new().unwrap();
48-
let uv_backend = Path::new("../../scripts/packages/uv_backend");
48+
let built_by_uv = Path::new("../../scripts/packages/built-by-uv");
4949
build_wheel(
50-
uv_backend,
50+
built_by_uv,
5151
temp1.path(),
5252
None,
5353
WheelSettings::default(),
@@ -57,22 +57,22 @@ fn test_determinism() {
5757

5858
// Touch the file to check that we don't serialize the last modified date.
5959
fs_err::write(
60-
uv_backend.join("src/uv_backend/__init__.py"),
60+
built_by_uv.join("src/built_by_uv/__init__.py"),
6161
"def greet():\n print(\"Hello 👋\")\n",
6262
)
6363
.unwrap();
6464

6565
let temp2 = TempDir::new().unwrap();
6666
build_wheel(
67-
uv_backend,
67+
built_by_uv,
6868
temp2.path(),
6969
None,
7070
WheelSettings::default(),
7171
"1.0.0+test",
7272
)
7373
.unwrap();
7474

75-
let wheel_filename = "uv_backend-0.1.0-py3-none-any.whl";
75+
let wheel_filename = "built_by_uv-0.1.0-py3-none-any.whl";
7676
assert_eq!(
7777
fs_err::read(temp1.path().join(wheel_filename)).unwrap(),
7878
fs_err::read(temp2.path().join(wheel_filename)).unwrap()
@@ -83,8 +83,8 @@ fn test_determinism() {
8383
#[test]
8484
fn test_prepare_metadata() {
8585
let metadata_dir = TempDir::new().unwrap();
86-
let uv_backend = Path::new("../../scripts/packages/uv_backend");
87-
metadata(uv_backend, metadata_dir.path(), "1.0.0+test").unwrap();
86+
let built_by_uv = Path::new("../../scripts/packages/built-by-uv");
87+
metadata(built_by_uv, metadata_dir.path(), "1.0.0+test").unwrap();
8888

8989
let mut files: Vec<_> = WalkDir::new(metadata_dir.path())
9090
.into_iter()
@@ -101,38 +101,36 @@ fn test_prepare_metadata() {
101101
.collect();
102102
files.sort();
103103
assert_snapshot!(files.join("\n"), @r"
104-
uv_backend-0.1.0.dist-info
105-
uv_backend-0.1.0.dist-info/METADATA
106-
uv_backend-0.1.0.dist-info/RECORD
107-
uv_backend-0.1.0.dist-info/WHEEL
104+
built_by_uv-0.1.0.dist-info
105+
built_by_uv-0.1.0.dist-info/METADATA
106+
built_by_uv-0.1.0.dist-info/RECORD
107+
built_by_uv-0.1.0.dist-info/WHEEL
108108
");
109109

110110
let metadata_file = metadata_dir
111111
.path()
112-
.join("uv_backend-0.1.0.dist-info/METADATA");
112+
.join("built_by_uv-0.1.0.dist-info/METADATA");
113113
assert_snapshot!(fs_err::read_to_string(metadata_file).unwrap(), @r###"
114-
Metadata-Version: 2.3
115-
Name: uv-backend
116-
Version: 0.1.0
117-
Summary: Add your description here
118-
Requires-Python: >=3.12
119-
Description-Content-Type: text/markdown
120-
121-
# uv_backend
122-
123-
A simple package to be built with the uv build backend.
124-
"###);
114+
Metadata-Version: 2.3
115+
Name: built-by-uv
116+
Version: 0.1.0
117+
Summary: A package to be built with the uv build backend that uses all features exposed by the build backend
118+
Requires-Dist: anyio>=4,<5
119+
Requires-Python: >=3.12
120+
"###);
125121

126122
let record_file = metadata_dir
127123
.path()
128-
.join("uv_backend-0.1.0.dist-info/RECORD");
124+
.join("built_by_uv-0.1.0.dist-info/RECORD");
129125
assert_snapshot!(fs_err::read_to_string(record_file).unwrap(), @r###"
130-
uv_backend-0.1.0.dist-info/WHEEL,sha256=3da1bfa0e8fd1b6cc246aa0b2b44a35815596c600cb485c39a6f8c106c3d5a8d,83
131-
uv_backend-0.1.0.dist-info/METADATA,sha256=e4a0d390317d7182f65ea978254c71ed283e0a4242150cf1c99a694b113ff68d,224
132-
uv_backend-0.1.0.dist-info/RECORD,,
126+
built_by_uv-0.1.0.dist-info/WHEEL,sha256=3da1bfa0e8fd1b6cc246aa0b2b44a35815596c600cb485c39a6f8c106c3d5a8d,83
127+
built_by_uv-0.1.0.dist-info/METADATA,sha256=ec36b5ae8830bdd248e90aaf581483ffb057f9a2d0f41e19e585531e7d07c9dc,215
128+
built_by_uv-0.1.0.dist-info/RECORD,,
133129
"###);
134130

135-
let wheel_file = metadata_dir.path().join("uv_backend-0.1.0.dist-info/WHEEL");
131+
let wheel_file = metadata_dir
132+
.path()
133+
.join("built_by_uv-0.1.0.dist-info/WHEEL");
136134
assert_snapshot!(fs_err::read_to_string(wheel_file).unwrap(), @r###"
137135
Wheel-Version: 1.0
138136
Generator: uv 1.0.0+test

crates/uv/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,15 @@ base64 = { version = "0.22.1" }
105105
byteorder = { version = "1.5.0" }
106106
etcetera = { workspace = true }
107107
filetime = { version = "0.2.25" }
108+
flate2 = { workspace = true }
108109
ignore = { version = "0.4.23" }
109110
indoc = { version = "2.0.5" }
110111
insta = { version = "1.40.0", features = ["filters", "json"] }
111112
predicates = { version = "3.1.2" }
112113
regex = { workspace = true }
113114
reqwest = { workspace = true, features = ["blocking"], default-features = false }
114115
similar = { version = "2.6.0" }
116+
tar = { workspace = true }
115117
tempfile = { workspace = true }
116118
zip = { workspace = true }
117119

crates/uv/tests/it/build_backend.rs

+96-6
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,141 @@
11
use crate::common::{uv_snapshot, TestContext};
22
use anyhow::Result;
33
use assert_cmd::assert::OutputAssertExt;
4+
use flate2::bufread::GzDecoder;
5+
use fs_err::File;
6+
use indoc::indoc;
47
use std::env;
8+
use std::io::BufReader;
59
use std::path::Path;
610
use tempfile::TempDir;
711
use uv_static::EnvVars;
812

13+
const BUILT_BY_UV_TEST_SCRIPT: &str = indoc! {r#"
14+
from built_by_uv import greet
15+
from built_by_uv.arithmetic.circle import area
16+
17+
print(greet())
18+
print(f"Area of a circle with r=2: {area(2)}")
19+
"#};
20+
921
/// Test that build backend works if we invoke it directly.
1022
///
1123
/// We can't test end-to-end here including the PEP 517 bridge code since we don't have a uv wheel.
1224
#[test]
13-
fn uv_backend_direct() -> Result<()> {
25+
fn built_by_uv_direct_wheel() -> Result<()> {
1426
let context = TestContext::new("3.12");
15-
let uv_backend = Path::new("../../scripts/packages/uv_backend");
27+
let built_by_uv = Path::new("../../scripts/packages/built-by-uv");
1628

1729
let temp_dir = TempDir::new()?;
1830

1931
uv_snapshot!(context
2032
.build_backend()
2133
.arg("build-wheel")
2234
.arg(temp_dir.path())
23-
.current_dir(uv_backend), @r###"
35+
.current_dir(built_by_uv), @r###"
36+
success: true
37+
exit_code: 0
38+
----- stdout -----
39+
built_by_uv-0.1.0-py3-none-any.whl
40+
41+
----- stderr -----
42+
"###);
43+
44+
context
45+
.pip_install()
46+
.arg(temp_dir.path().join("built_by_uv-0.1.0-py3-none-any.whl"))
47+
.assert()
48+
.success();
49+
50+
uv_snapshot!(context
51+
.run()
52+
.arg("python")
53+
.arg("-c")
54+
.arg(BUILT_BY_UV_TEST_SCRIPT)
55+
// Python on windows
56+
.env(EnvVars::PYTHONUTF8, "1"), @r###"
57+
success: true
58+
exit_code: 0
59+
----- stdout -----
60+
Hello 👋
61+
Area of a circle with r=2: 12.56636
62+
63+
----- stderr -----
64+
"###);
65+
66+
Ok(())
67+
}
68+
69+
/// Test that source tree -> source dist -> wheel works.
70+
///
71+
/// We can't test end-to-end here including the PEP 517 bridge code since we don't have a uv wheel,
72+
/// so we call the build backend directly.
73+
#[test]
74+
fn built_by_uv_direct() -> Result<()> {
75+
let context = TestContext::new("3.12");
76+
let built_by_uv = Path::new("../../scripts/packages/built-by-uv");
77+
78+
let sdist_dir = TempDir::new()?;
79+
80+
uv_snapshot!(context
81+
.build_backend()
82+
.arg("build-sdist")
83+
.arg(sdist_dir.path())
84+
.current_dir(built_by_uv), @r###"
2485
success: true
2586
exit_code: 0
2687
----- stdout -----
27-
uv_backend-0.1.0-py3-none-any.whl
88+
built_by_uv-0.1.0.tar.gz
2889
2990
----- stderr -----
3091
"###);
3192

93+
let sdist_tree = TempDir::new()?;
94+
95+
let sdist_reader = BufReader::new(File::open(
96+
sdist_dir.path().join("built_by_uv-0.1.0.tar.gz"),
97+
)?);
98+
tar::Archive::new(GzDecoder::new(sdist_reader)).unpack(sdist_tree.path())?;
99+
100+
drop(sdist_dir);
101+
102+
let wheel_dir = TempDir::new()?;
103+
104+
uv_snapshot!(context
105+
.build_backend()
106+
.arg("build-wheel")
107+
.arg(wheel_dir.path())
108+
.current_dir(sdist_tree.path().join("built-by-uv-0.1.0")), @r###"
109+
success: true
110+
exit_code: 0
111+
----- stdout -----
112+
built_by_uv-0.1.0-py3-none-any.whl
113+
114+
----- stderr -----
115+
"###);
116+
117+
drop(sdist_tree);
118+
32119
context
33120
.pip_install()
34-
.arg(temp_dir.path().join("uv_backend-0.1.0-py3-none-any.whl"))
121+
.arg(wheel_dir.path().join("built_by_uv-0.1.0-py3-none-any.whl"))
35122
.assert()
36123
.success();
37124

125+
drop(wheel_dir);
126+
38127
uv_snapshot!(context
39128
.run()
40129
.arg("python")
41130
.arg("-c")
42-
.arg("import uv_backend\nuv_backend.greet()")
131+
.arg(BUILT_BY_UV_TEST_SCRIPT)
43132
// Python on windows
44133
.env(EnvVars::PYTHONUTF8, "1"), @r###"
45134
success: true
46135
exit_code: 0
47136
----- stdout -----
48137
Hello 👋
138+
Area of a circle with r=2: 12.56636
49139
50140
----- stderr -----
51141
"###);
+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/dist/
2+
/build-root/
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# built_by_uv
2+
3+
A package to be built with the uv build backend that uses all features exposed by the build backend.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
We don't want this file in the source dist or wheel.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[project]
2+
name = "built-by-uv"
3+
version = "0.1.0"
4+
description = "A package to be built with the uv build backend that uses all features exposed by the build backend"
5+
#rreadme = "README.md"
6+
requires-python = ">=3.12"
7+
dependencies = ["anyio>=4,<5"]
8+
9+
[build-system]
10+
requires = ["uv>=0.4.15,<5"]
11+
build-backend = "uv"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def greet() -> str:
2+
return "Hello 👋"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .circle import area as circle_area
2+
3+
__all__ = ["circle_area"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from functools import lru_cache
2+
from pathlib import Path
3+
4+
5+
@lru_cache(maxsize=1)
6+
def pi() -> float:
7+
return float(Path(__file__).parent.joinpath("pi.txt").read_text().strip())
8+
9+
10+
def area(radius: float) -> float:
11+
"""Use a non-Python file (`pi.txt`)."""
12+
return radius**2 * pi()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.14159

scripts/packages/built-by-uv/test.sh

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
# Test source tree -> source dist -> wheel and run pytest after.
3+
# We can't test this through the build backend setting directly since we want
4+
# to use the debug build of uv, so we use the internal API instead.
5+
6+
set -e
7+
8+
cargo build
9+
uv venv -p 3.12 -q
10+
mkdir -p dist
11+
rm -f dist/*
12+
../../../target/debug/uv build-backend build-sdist dist/
13+
rm -rf build-root
14+
mkdir build-root
15+
cd build-root
16+
tar -tvf ../dist/built_by_uv-0.1.0.tar.gz
17+
tar xf ../dist/built_by_uv-0.1.0.tar.gz
18+
cd built-by-uv-0.1.0
19+
../../../../../target/debug/uv build-backend build-wheel ../../dist
20+
unzip -l ../../dist/built_by_uv-0.1.0-py3-none-any.whl
21+
cd ../..
22+
uv pip install -q pytest dist/built_by_uv-0.1.0-py3-none-any.whl
23+
pytest
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import pytest
2+
from built_by_uv import greet
3+
from built_by_uv.arithmetic.circle import area
4+
5+
6+
def test_circle():
7+
assert area(2) == pytest.approx(12.56636)
8+
9+
10+
def test_greet():
11+
assert greet() == "Hello 👋"

0 commit comments

Comments
 (0)