From 93ecb1bcd791675baf590b6da65f518f7b09390d Mon Sep 17 00:00:00 2001 From: Alessandro De Maria Date: Sat, 5 Jul 2025 23:23:33 +0000 Subject: [PATCH] fix: align PEX lock format with pants-generated structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Restructure PexLock to match actual pants lockfile format - Add missing fields: elide_unused_requires_dist, excluded, only_builds, only_wheels, overridden, path_mappings, pip_version, target_systems, use_system_time - Change platform_tag to nullable (null for universal resolves) - Add requires_python field to individual locked requirements - Reorder fields to match pants output structure - Update resolver_version to use pip-2020-resolver Validates against actual pants-generated mofgen.lock file structure. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../uv-resolver/src/lock/export/pex_lock.rs | 121 +++++++++++------- 1 file changed, 75 insertions(+), 46 deletions(-) diff --git a/crates/uv-resolver/src/lock/export/pex_lock.rs b/crates/uv-resolver/src/lock/export/pex_lock.rs index 221ae0dde..b52792060 100644 --- a/crates/uv-resolver/src/lock/export/pex_lock.rs +++ b/crates/uv-resolver/src/lock/export/pex_lock.rs @@ -18,8 +18,6 @@ use crate::lock::{Lock, LockError, WheelWireSource}; /// A PEX lock file representation. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PexLock { - /// The PEX version used to generate this lock file. - pub pex_version: String, /// Whether to allow building from source. pub allow_builds: bool, /// Whether to allow prereleases. @@ -28,48 +26,66 @@ pub struct PexLock { pub allow_wheels: bool, /// Whether to use build isolation. pub build_isolation: bool, + /// Constraints applied during resolution. + pub constraints: Vec, + /// Whether to elide unused requires_dist. + pub elide_unused_requires_dist: bool, + /// Excluded packages. + pub excluded: Vec, + /// Locked resolved dependencies. + pub locked_resolves: Vec, + /// Only build packages. + pub only_builds: Vec, + /// Only wheel packages. + pub only_wheels: Vec, + /// Overridden packages. + pub overridden: Vec, + /// Path mappings. + pub path_mappings: serde_json::Map, + /// The PEX version used to generate this lock file. + pub pex_version: String, + /// The pip version used. + pub pip_version: String, /// Whether to prefer older binary versions. pub prefer_older_binary: bool, - /// Whether to use PEP517 build backend. - pub use_pep517: Option, + /// Direct requirements. + pub requirements: Vec, /// The resolver version used. pub resolver_version: String, /// The style of resolution. pub style: String, + /// Target systems. + pub target_systems: Vec, /// Whether to include transitive dependencies. pub transitive: bool, - /// Python version requirements. - pub requires_python: Vec, - /// Direct requirements. - pub requirements: Vec, - /// Constraints applied during resolution. - pub constraints: Vec, - /// Locked resolved dependencies. - pub locked_resolves: Vec, + /// Whether to use PEP517 build backend. + pub use_pep517: Option, + /// Whether to use system time. + pub use_system_time: bool, } /// A locked resolve entry in a PEX lock file. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PexLockedResolve { - /// The platform tag this resolve applies to (3 components: [interpreter, abi, platform]). - pub platform_tag: Vec, /// The locked requirements for this platform. pub locked_requirements: Vec, + /// The platform tag this resolve applies to (null for universal). + pub platform_tag: Option>, } /// A locked requirement in a PEX lock file. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct PexLockedRequirement { - /// The project name. - pub project_name: String, - /// The version. - pub version: String, - /// The requirement specifier. - pub requirement: String, /// Artifacts (wheels/sdists) for this requirement. pub artifacts: Vec, + /// The project name. + pub project_name: String, /// Dependencies of this requirement. pub requires_dists: Vec, + /// Python version requirement. + pub requires_python: String, + /// The version. + pub version: String, } /// An artifact in a PEX lock file. @@ -91,12 +107,12 @@ impl PexLock { /// Default PEX version for generated lock files. const DEFAULT_PEX_VERSION: &'static str = "2.44.0"; + /// Default pip version. + const DEFAULT_PIP_VERSION: &'static str = "24.2"; + /// 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"]; - /// Extract algorithm and hash from a hash string. fn parse_hash(hash_str: &str) -> (String, String) { if let Some(colon_pos) = hash_str.find(':') { @@ -197,38 +213,43 @@ impl PexLock { } locked_requirements.push(PexLockedRequirement { - project_name: package.id.name.to_string(), - version: version.to_string(), - requirement: format!("{}=={}", package.id.name, version), artifacts, + project_name: package.id.name.to_string(), requires_dists, + requires_python: lock.requires_python().to_string(), + version: version.to_string(), }); } } let locked_resolves = vec![PexLockedResolve { - platform_tag: Self::UNIVERSAL_PLATFORM_TAG - .iter() - .map(std::string::ToString::to_string) - .collect(), locked_requirements, + platform_tag: None, }]; Ok(PexLock { - pex_version: Self::DEFAULT_PEX_VERSION.to_string(), allow_builds: true, allow_prereleases: false, allow_wheels: true, build_isolation: true, - prefer_older_binary: false, - use_pep517: None, - resolver_version: Self::DEFAULT_PEX_VERSION.to_string(), - style: "universal".to_string(), - transitive: true, - requires_python: vec![lock.requires_python().to_string()], - requirements, constraints: Vec::new(), + elide_unused_requires_dist: false, + excluded: Vec::new(), locked_resolves, + only_builds: Vec::new(), + only_wheels: Vec::new(), + overridden: Vec::new(), + path_mappings: serde_json::Map::new(), + pex_version: Self::DEFAULT_PEX_VERSION.to_string(), + pip_version: Self::DEFAULT_PIP_VERSION.to_string(), + prefer_older_binary: false, + requirements, + resolver_version: "pip-2020-resolver".to_string(), + style: "universal".to_string(), + target_systems: vec!["linux".to_string(), "mac".to_string()], + transitive: true, + use_pep517: None, + use_system_time: false, }) } @@ -254,20 +275,28 @@ mod tests { #[test] fn test_pex_lock_serialization() { let pex_lock = PexLock { - pex_version: PexLock::DEFAULT_PEX_VERSION.to_string(), allow_builds: true, allow_prereleases: false, allow_wheels: true, build_isolation: true, - prefer_older_binary: false, - use_pep517: None, - resolver_version: PexLock::DEFAULT_PEX_VERSION.to_string(), - style: "universal".to_string(), - transitive: true, - requires_python: vec![">=3.8".to_string()], - requirements: vec!["requests==2.31.0".to_string()], constraints: vec![], + elide_unused_requires_dist: false, + excluded: vec![], locked_resolves: vec![], + only_builds: vec![], + only_wheels: vec![], + overridden: vec![], + path_mappings: serde_json::Map::new(), + pex_version: PexLock::DEFAULT_PEX_VERSION.to_string(), + pip_version: PexLock::DEFAULT_PIP_VERSION.to_string(), + prefer_older_binary: false, + requirements: vec!["requests==2.31.0".to_string()], + resolver_version: "pip-2020-resolver".to_string(), + style: "universal".to_string(), + target_systems: vec!["linux".to_string(), "mac".to_string()], + transitive: true, + use_pep517: None, + use_system_time: false, }; let json = pex_lock.to_json().unwrap();