diff --git a/crates/uv-resolver/src/lock/export/mod.rs b/crates/uv-resolver/src/lock/export/mod.rs index b7dc49a52..639a4a3a7 100644 --- a/crates/uv-resolver/src/lock/export/mod.rs +++ b/crates/uv-resolver/src/lock/export/mod.rs @@ -16,16 +16,16 @@ use uv_pep508::MarkerTree; use uv_pypi_types::ConflictItem; use crate::graph_ops::{Reachable, marker_reachability}; +pub use crate::lock::export::pex_lock::PexLock; pub(crate) use crate::lock::export::pylock_toml::PylockTomlPackage; pub use crate::lock::export::pylock_toml::{PylockToml, PylockTomlErrorKind}; pub use crate::lock::export::requirements_txt::RequirementsTxtExport; -pub use crate::lock::export::pex_lock::PexLock; use crate::universal_marker::resolve_conflicts; use crate::{Installable, Package}; +mod pex_lock; mod pylock_toml; mod requirements_txt; -mod pex_lock; /// A flat requirement, with its associated marker. #[derive(Debug, Clone, PartialEq, Eq)] diff --git a/crates/uv-resolver/src/lock/export/pex_lock.rs b/crates/uv-resolver/src/lock/export/pex_lock.rs index 978b2f131..7efffe46f 100644 --- a/crates/uv-resolver/src/lock/export/pex_lock.rs +++ b/crates/uv-resolver/src/lock/export/pex_lock.rs @@ -88,10 +88,10 @@ pub struct PexArtifact { impl PexLock { /// Default PEX version for generated lock files. const DEFAULT_PEX_VERSION: &'static str = "2.44.0"; - + /// Default hash algorithm when none is specified. const DEFAULT_HASH_ALGORITHM: &'static str = "sha256"; - + /// Universal platform tag components: [interpreter, abi, platform]. const UNIVERSAL_PLATFORM_TAG: [&'static str; 3] = ["py", "none", "any"]; @@ -102,7 +102,10 @@ impl PexLock { let hash_value = hash_str[colon_pos + 1..].to_string(); (algorithm, hash_value) } else { - (Self::DEFAULT_HASH_ALGORITHM.to_string(), hash_str.to_string()) + ( + Self::DEFAULT_HASH_ALGORITHM.to_string(), + hash_str.to_string(), + ) } } @@ -110,11 +113,13 @@ impl PexLock { pub fn from_lock(lock: &Lock) -> Result { let mut requirements = Vec::new(); let mut locked_requirements = Vec::new(); - + // Collect root requirements if let Some(root) = lock.root() { for dep in &root.dependencies { - if let Some(version) = lock.packages().iter() + if let Some(version) = lock + .packages() + .iter() .find(|pkg| pkg.id.name == dep.package_id.name) .and_then(|pkg| pkg.id.version.as_ref()) { @@ -125,10 +130,9 @@ impl PexLock { // Process all packages for locked requirements for package in lock.packages() { - // Create locked requirement let mut artifacts = Vec::new(); - + // Add wheels for wheel in &package.wheels { let wheel_url = match &wheel.url { @@ -136,13 +140,13 @@ impl PexLock { WheelWireSource::Path { path } => format!("file://{}", path.to_string_lossy()), WheelWireSource::Filename { filename } => filename.to_string(), }; - + let (algorithm, hash) = if let Some(h) = wheel.hash.as_ref() { Self::parse_hash(&h.to_string()) } else { continue; }; - + artifacts.push(PexArtifact { url: wheel_url, filename: wheel.filename.to_string(), @@ -151,7 +155,7 @@ impl PexLock { is_wheel: true, }); } - + // Add source distributions if let Some(sdist) = &package.sdist { let Some(sdist_url) = sdist.url().map(|u| u.to_string()) else { @@ -160,13 +164,13 @@ impl PexLock { let Some(sdist_filename) = sdist.filename().map(|f| f.to_string()) else { continue; }; - + let (algorithm, hash) = if let Some(h) = sdist.hash() { Self::parse_hash(&h.to_string()) } else { continue; }; - + artifacts.push(PexArtifact { url: sdist_url, filename: sdist_filename, @@ -175,7 +179,7 @@ impl PexLock { is_wheel: false, }); } - + if let Some(version) = &package.id.version { locked_requirements.push(PexLockedRequirement { project_name: package.id.name.to_string(), @@ -185,12 +189,15 @@ impl PexLock { }); } } - + let locked_resolves = vec![PexLockedResolve { - platform_tag: Self::UNIVERSAL_PLATFORM_TAG.iter().map(|s| s.to_string()).collect(), + platform_tag: Self::UNIVERSAL_PLATFORM_TAG + .iter() + .map(|s| s.to_string()) + .collect(), locked_requirements, }]; - + Ok(PexLock { pex_version: Self::DEFAULT_PEX_VERSION.to_string(), allow_builds: true, @@ -208,7 +215,7 @@ impl PexLock { locked_resolves, }) } - + /// Serialize the PEX lock to JSON. pub fn to_json(&self) -> Result { serde_json::to_string_pretty(self) @@ -227,7 +234,7 @@ impl fmt::Display for PexLock { #[cfg(test)] mod tests { use super::*; - + #[test] fn test_pex_lock_serialization() { let pex_lock = PexLock { @@ -246,9 +253,9 @@ mod tests { constraints: vec![], locked_resolves: vec![], }; - + let json = pex_lock.to_json().unwrap(); assert!(json.contains("\"pex_version\": \"2.44.0\"")); assert!(json.contains("\"allow_builds\": true")); } -} \ No newline at end of file +} diff --git a/crates/uv/src/commands/pip/compile.rs b/crates/uv/src/commands/pip/compile.rs index 28db2943a..5805a30c0 100644 --- a/crates/uv/src/commands/pip/compile.rs +++ b/crates/uv/src/commands/pip/compile.rs @@ -697,7 +697,9 @@ pub(crate) async fn pip_compile( write!(writer, "{}", export.to_toml()?)?; } ExportFormat::PexLock => { - return Err(anyhow::anyhow!("PEX lock format is not supported in pip compile")); + return Err(anyhow::anyhow!( + "PEX lock format is not supported in pip compile" + )); } } diff --git a/crates/uv/src/commands/project/export.rs b/crates/uv/src/commands/project/export.rs index 48972bc51..54c9e56c4 100644 --- a/crates/uv/src/commands/project/export.rs +++ b/crates/uv/src/commands/project/export.rs @@ -14,7 +14,7 @@ use uv_configuration::{ use uv_normalize::{DefaultExtras, DefaultGroups, PackageName}; use uv_python::{PythonDownloads, PythonPreference, PythonRequest}; use uv_requirements::is_pylock_toml; -use uv_resolver::{PexLock, PylockToml, RequirementsTxtExport, Installable}; +use uv_resolver::{Installable, PexLock, PylockToml, RequirementsTxtExport}; use uv_scripts::{Pep723ItemRef, Pep723Script}; use uv_settings::PythonInstallMirrors; use uv_workspace::{DiscoveryOptions, MemberDiscovery, VirtualProject, Workspace, WorkspaceCache}; diff --git a/crates/uv/tests/it/export.rs b/crates/uv/tests/it/export.rs index 5dd0b1bb7..b48536f2e 100644 --- a/crates/uv/tests/it/export.rs +++ b/crates/uv/tests/it/export.rs @@ -4433,4 +4433,3 @@ fn pep_751_https_credentials() -> Result<()> { Ok(()) } -