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
787 changes: 459 additions & 328 deletions examples/pypi-wheel-packages/pixi.lock

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions examples/pypi-wheel-packages/pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ platforms = [
]

[dependencies]
python = "3.11.*"
python = "3.12.*"
pip = ">=25.0.1,<26"

[pypi-dependencies]
ordered-enum = ">=0.0.9,<0.0.10"

[target.linux-64.pypi-dependencies]
numpy = { url = "https://files.pythonhosted.org/packages/3a/d0/edc009c27b406c4f9cbc79274d6e46d634d139075492ad055e3d68445925/numpy-1.26.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }
numpy = { url = "https://files.pythonhosted.org/packages/0f/50/de23fde84e45f5c4fda2488c759b69990fd4512387a8632860f3ac9cd225/numpy-1.26.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" }
my-webserver = { path = "../webserver/my_webserver-0.1.0-py3-none-any.whl" }
87 changes: 55 additions & 32 deletions src/pack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ pub async fn pack(options: PackOptions) -> Result<()> {
package,
&pypi_directory,
options.cache_dir.as_deref(),
&options.manifest_path,
)
.await?;
bar.pb.inc(1);
Expand Down Expand Up @@ -797,48 +798,70 @@ async fn download_pypi_package(
package: &PypiPackageData,
output_dir: &Path,
cache_dir: Option<&Path>,
manifest_path: &Path,
) -> Result<()> {
create_dir_all(output_dir)
.await
.map_err(|e| anyhow!("could not create download directory: {}", e))?;

let url = match &package.location {
UrlOrPath::Url(url) => url
.as_ref()
.strip_prefix("direct+")
.and_then(|str| Url::parse(str).ok())
.unwrap_or(url.clone()),
UrlOrPath::Path(path) => anyhow::bail!("Path not supported: {}", path),
};

// Use `RemoteSource::filename()` from `uv_distribution_types` to decode filename
// Because it may be percent-encoded
let file_name = url.filename()?.to_string();
let output_path = output_dir.join(&file_name);

if let Some(cache_dir) = cache_dir {
let cache_path = cache_dir.join(PYPI_DIRECTORY_NAME).join(&file_name);
if cache_path.exists() {
tracing::debug!("Using cached package from {}", cache_path.display());
fs::copy(&cache_path, &output_path).await?;
return Ok(());
match &package.location {
UrlOrPath::Path(path) => {
let file_name = path
.file_name()
.ok_or_else(|| anyhow!("Path does not contain file name: {}", path))?
.to_string();
let lockfile_dir = if !manifest_path.is_dir() {
manifest_path
.parent()
.ok_or(anyhow!("could not get parent directory"))?
} else {
manifest_path
};

let source_path = lockfile_dir.join(path.to_string());
let output_path = output_dir.join(file_name);
tracing::debug!("Copy from {}", path);
fs::copy(source_path, output_path)
.map_err(|e| anyhow!("could not copy local wheel file: {}", e))
.await?;
}
}
UrlOrPath::Url(url) => {
let url = url
.as_ref()
.strip_prefix("direct+")
.and_then(|str| Url::parse(str).ok())
.unwrap_or(url.clone());

// Use `RemoteSource::filename()` from `uv_distribution_types` to decode filename
// Because it may be percent-encoded
let file_name = url.filename()?.to_string();
let output_path = output_dir.join(&file_name);

if let Some(cache_dir) = cache_dir {
let cache_path = cache_dir.join(PYPI_DIRECTORY_NAME).join(&file_name);
if cache_path.exists() {
tracing::debug!("Using cached package from {}", cache_path.display());
fs::copy(&cache_path, &output_path).await?;
return Ok(());
}
}

let mut dest = File::create(&output_path).await?;
tracing::debug!("Fetching package {}", url);
let mut dest = File::create(&output_path).await?;
tracing::debug!("Fetching package {}", url);

let mut response = client.get(url.clone()).send().await?.error_for_status()?;
let mut response = client.get(url.clone()).send().await?.error_for_status()?;

while let Some(chunk) = response.chunk().await? {
dest.write_all(&chunk).await?;
}
while let Some(chunk) = response.chunk().await? {
dest.write_all(&chunk).await?;
}

if let Some(cache_dir) = cache_dir {
let cache_subdir = cache_dir.join(PYPI_DIRECTORY_NAME);
create_dir_all(&cache_subdir).await?;
let cache_path = cache_subdir.join(&file_name);
fs::copy(&output_path, &cache_path).await?;
if let Some(cache_dir) = cache_dir {
let cache_subdir = cache_dir.join(PYPI_DIRECTORY_NAME);
create_dir_all(&cache_subdir).await?;
let cache_path = cache_subdir.join(&file_name);
fs::copy(&output_path, &cache_path).await?;
}
}
}

Ok(())
Expand Down
8 changes: 4 additions & 4 deletions tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ fn required_fs_objects(#[default(false)] use_pypi: bool) -> Vec<&'static str> {
_ => panic!("Unsupported platform"),
};
let ordered_enum_required_file = match Platform::current() {
Platform::Linux64 => "lib/python3.11/site-packages/ordered_enum-0.0.9.dist-info",
Platform::LinuxAarch64 => "lib/python3.11/site-packages/ordered_enum-0.0.9.dist-info",
Platform::OsxArm64 => "lib/python3.11/site-packages/ordered_enum-0.0.9.dist-info",
Platform::Osx64 => "lib/python3.11/site-packages/ordered_enum-0.0.9.dist-info",
Platform::Linux64 => "lib/python3.12/site-packages/ordered_enum-0.0.9.dist-info",
Platform::LinuxAarch64 => "lib/python3.12/site-packages/ordered_enum-0.0.9.dist-info",
Platform::OsxArm64 => "lib/python3.12/site-packages/ordered_enum-0.0.9.dist-info",
Platform::Osx64 => "lib/python3.12/site-packages/ordered_enum-0.0.9.dist-info",
Platform::Win64 => "lib/site-packages/ordered_enum-0.0.9.dist-info",
_ => panic!("Unsupported platform"),
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 425
expression: "&sha256_digest"
---
5126F06DB2ACC35E965BCEACBA234E1DC0F498D255F16DA087D1D1D32708949D
1ADF8EFBFC73ABB81AFBE72DAB6415A3CA5CE7C42FA4A24CFFF3CA54A41733B2
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 402
expression: "&sha256_digest"
---
101C7E2D6AA8888281B1118929B0E876E7C0D244F86035B65D5A4C6D698C5C44
BE9383458B6D9BFE0652FEA0D9A4431FC88CA2B7A11B3147E94B2426194D07AC
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 425
expression: "&sha256_digest"
---
878550316C27711A4F8B2A67AB722306137D410DCD09E2A538CCC78A6D0BB135
5A293287A8DBBB6A0F67BF287E30C6E33EB24E49757A7CB32C878F569AF9278B
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 402
expression: "&sha256_digest"
---
07A73D4C05634BF4CDB2FBC2A3E48D76D987C20F5BEC4071F26A3DB10D987645
85B122EB7951B8B15ADA88B220B7318639CDBDF205A31E11C30A9C642CD80FDE
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 402
expression: "&sha256_digest"
---
BA61E63A0147C2E25B9327AD87894448758B5965F8BF1A78E9497AFB3B47F083
A86354773B86D7C7ED8686E5C3E4C5DEE615BBC6301A6639C576B6E1760A943E
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 425
expression: "&sha256_digest"
---
F6AF2C70E6A2A200EFFC7E67B67561EE3F12265A9F06F16EB57F964604273B43
17241E9D21EF37ECFB75BF561C9C1EF448A49B6DC830B74191CAB1CB3C4F3D9F
3 changes: 2 additions & 1 deletion tests/snapshots/integration_test__sha256-osx-64-pypi.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 402
expression: "&sha256_digest"
---
9FD0391EE2BBC4B486A04184E8B611F4BFFC379A56A2BE301BDA2B983C0F97C7
F692D3EF33D0A1C18E140C9AA26FB56D3E7CA4C0BD8F58F94A234E03115EA489
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 425
expression: "&sha256_digest"
---
E2451DA3F5B93A8C3EC57391B2B5050D4914AEFB38A4FA2AF2FD5D02E708F580
646306FDAAF9FAA8081A403A7611435C4F24B35F6A4BFC2859F90E2678EB6690
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 402
expression: "&sha256_digest"
---
E8612A515EDD6720B94DAF18AED68E7918872F3DF1FA12B1A747F71DC7393AD5
04528EDD9AE7AB2B61933F1361D1C268C82FFC3B2C9B909D2D398C02B816F0E9
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 425
expression: "&sha256_digest"
---
5354B79D251E152912CFDD65407A2EE8ECB0115A030E5A05196FDBE0649708FA
49428F64988C3EE609E127591F6FEE2DF7220F3DA6B67D1825459D823A0C19A6
3 changes: 2 additions & 1 deletion tests/snapshots/integration_test__sha256-win-64-pypi.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: tests/integration_test.rs
assertion_line: 402
expression: "&sha256_digest"
---
3A063104622736F3910ED0BF31EA8B769EF936DA10B5CFB10BD48DA782CC001B
C1A4993A6A500F3B165DE7D39A04B494ADF12C26C0B9016E43A7BF619260E795
Loading