diff --git a/Cargo.lock b/Cargo.lock index 123a855199..2e675a5772 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,9 +34,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] @@ -481,9 +481,9 @@ dependencies = [ [[package]] name = "aws-sdk-s3" -version = "1.108.0" +version = "1.109.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200be4aed61e3c0669f7268bacb768f283f1c32a7014ce57225e1160be2f6ccb" +checksum = "3c6d81b75f8ff78882e70c5909804b44553d56136899fb4015a0a68ecc870e0e" dependencies = [ "aws-credential-types", "aws-runtime", @@ -515,9 +515,9 @@ dependencies = [ [[package]] name = "aws-sdk-sso" -version = "1.86.0" +version = "1.87.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0abbfab841446cce6e87af853a3ba2cc1bc9afcd3f3550dd556c43d434c86d" +checksum = "f4af747ffcb5aa8da8be8f0679ef6940f1afdb8c2e10c36738c9ebeb8d17b95e" dependencies = [ "aws-credential-types", "aws-runtime", @@ -559,9 +559,9 @@ dependencies = [ [[package]] name = "aws-sdk-sts" -version = "1.88.0" +version = "1.89.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d30990923f4f675523c51eb1c0dec9b752fb267b36a61e83cbc219c9d86da715" +checksum = "928e87698cd916cf1efd5268148347269e6d2911028742c0061ff6261e639e3c" dependencies = [ "aws-credential-types", "aws-runtime", @@ -621,9 +621,9 @@ dependencies = [ [[package]] name = "aws-smithy-checksums" -version = "0.63.9" +version = "0.63.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "165d8583d8d906e2fb5511d29201d447cc710864f075debcdd9c31c265412806" +checksum = "bb9a26b2831e728924ec0089e92697a78a2f9cdcf90d81e8cfcc6a6c85080369" dependencies = [ "aws-smithy-http", "aws-smithy-types", @@ -641,9 +641,9 @@ dependencies = [ [[package]] name = "aws-smithy-eventstream" -version = "0.60.12" +version = "0.60.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9656b85088f8d9dc7ad40f9a6c7228e1e8447cdf4b046c87e152e0805dea02fa" +checksum = "e29a304f8319781a39808847efb39561351b1bb76e933da7aa90232673638658" dependencies = [ "aws-smithy-types", "bytes", @@ -652,9 +652,9 @@ dependencies = [ [[package]] name = "aws-smithy-http" -version = "0.62.4" +version = "0.62.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3feafd437c763db26aa04e0cc7591185d0961e64c61885bece0fb9d50ceac671" +checksum = "445d5d720c99eed0b4aa674ed00d835d9b1427dd73e04adaf2f94c6b2d6f9fca" dependencies = [ "aws-smithy-eventstream", "aws-smithy-runtime-api", @@ -662,6 +662,7 @@ dependencies = [ "bytes", "bytes-utils", "futures-core", + "futures-util", "http 0.2.12", "http 1.3.1", "http-body 0.4.6", @@ -673,9 +674,9 @@ dependencies = [ [[package]] name = "aws-smithy-http-client" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1053b5e587e6fa40ce5a79ea27957b04ba660baa02b28b7436f64850152234f1" +checksum = "623254723e8dfd535f566ee7b2381645f8981da086b5c4aa26c0c41582bb1d2c" dependencies = [ "aws-smithy-async", "aws-smithy-runtime-api", @@ -697,9 +698,9 @@ dependencies = [ [[package]] name = "aws-smithy-json" -version = "0.61.6" +version = "0.61.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff418fc8ec5cadf8173b10125f05c2e7e1d46771406187b2c878557d4503390" +checksum = "2db31f727935fc63c6eeae8b37b438847639ec330a9161ece694efba257e0c54" dependencies = [ "aws-smithy-types", ] @@ -725,9 +726,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime" -version = "1.9.3" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ab99739082da5347660c556689256438defae3bcefd66c52b095905730e404" +checksum = "0bbe9d018d646b96c7be063dd07987849862b0e6d07c778aad7d93d1be6c1ef0" dependencies = [ "aws-smithy-async", "aws-smithy-http", @@ -748,9 +749,9 @@ dependencies = [ [[package]] name = "aws-smithy-runtime-api" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3683c5b152d2ad753607179ed71988e8cfd52964443b4f74fd8e552d0bbfeb46" +checksum = "ec7204f9fd94749a7c53b26da1b961b4ac36bf070ef1e0b94bb09f79d4f6c193" dependencies = [ "aws-smithy-async", "aws-smithy-types", @@ -765,9 +766,9 @@ dependencies = [ [[package]] name = "aws-smithy-types" -version = "1.3.3" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f5b3a7486f6690ba25952cabf1e7d75e34d69eaff5081904a47bc79074d6457" +checksum = "25f535879a207fce0db74b679cfc3e91a3159c8144d717d55f5832aea9eef46e" dependencies = [ "base64-simd", "bytes", @@ -791,9 +792,9 @@ dependencies = [ [[package]] name = "aws-smithy-xml" -version = "0.60.11" +version = "0.60.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c34127e8c624bc2999f3b657e749c1393bedc9cd97b92a804db8ced4d2e163" +checksum = "eab77cdd036b11056d2a30a7af7b775789fb024bf216acc13884c6c97752ae56" dependencies = [ "xmlparser", ] @@ -988,6 +989,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + [[package]] name = "blocking" version = "1.6.2" @@ -1256,9 +1266,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.50" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" +checksum = "4c26d721170e0295f191a69bd9a1f93efcdb0aff38684b61ab5750468972e5f5" dependencies = [ "clap_builder", "clap_derive", @@ -1266,9 +1276,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.50" +version = "4.5.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" +checksum = "75835f0c7bf681bfd05abe44e965760fea999a5286c6eb2d59883634fd02011a" dependencies = [ "anstream", "anstyle", @@ -1279,9 +1289,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.59" +version = "4.5.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2348487adcd4631696ced64ccdb40d38ac4d31cae7f2eec8817fcea1b9d1c43c" +checksum = "8e602857739c5a4291dfa33b5a298aeac9006185229a700e5810a3ef7272d971" dependencies = [ "clap", ] @@ -1324,6 +1334,15 @@ dependencies = [ "tokio", ] +[[package]] +name = "coalesced_map" +version = "0.1.2" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" +dependencies = [ + "dashmap", + "tokio", +] + [[package]] name = "colorchoice" version = "1.0.4" @@ -1613,11 +1632,11 @@ dependencies = [ [[package]] name = "ctrlc" -version = "3.5.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881c5d0a13b2f1498e2306e82cbada78390e152d4b1378fb28a84f4dcd0dc4f3" +checksum = "73736a89c4aff73035ba2ed2e565061954da00d4970fc9ac25dcc85a2a20d790" dependencies = [ - "dispatch", + "dispatch2", "nix 0.30.1", "windows-sys 0.61.2", ] @@ -1765,9 +1784,9 @@ dependencies = [ [[package]] name = "deno_path_util" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4f70f7cbc884556f08781aaa75aef177d15bfee99e4fc40c25fa74514c678c0" +checksum = "78c7e98943f0d068928906db0c7bde89de684fa32c6a8018caacc4cee2cdd72b" dependencies = [ "deno_error", "percent-encoding", @@ -1901,10 +1920,16 @@ dependencies = [ ] [[package]] -name = "dispatch" -version = "0.2.0" +name = "dispatch2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags", + "block2", + "libc", + "objc2", +] [[package]] name = "displaydoc" @@ -2162,8 +2187,7 @@ dependencies = [ [[package]] name = "file_url" version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765662dc0b26e038099a5a1529f5d48443111eea45377c312be892997651710e" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "itertools 0.14.0", "percent-encoding", @@ -3040,9 +3064,9 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", @@ -3053,9 +3077,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -3066,11 +3090,10 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "displaydoc", "icu_collections", "icu_normalizer_data", "icu_properties", @@ -3081,42 +3104,38 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "e93fcd3157766c0c8da2f8cff6ce651a31f0810eaa1c51ec363ef790bbb5fb99" dependencies = [ - "displaydoc", "icu_collections", "icu_locale_core", "icu_properties_data", "icu_provider", - "potential_utf", "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "02845b3647bb045f1100ecd6480ff52f34c35f82d9880e029d329c21d1054899" [[package]] name = "icu_provider" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", - "stable_deref_trait", - "tinystr", "writeable", "yoke", "zerofrom", @@ -3153,9 +3172,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.24" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81776e6f9464432afcc28d03e52eb101c93b6f0566f52aef2427663e700f0403" +checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" dependencies = [ "crossbeam-deque", "globset", @@ -3577,9 +3596,9 @@ dependencies = [ [[package]] name = "lazy-regex" -version = "3.4.1" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60c7310b93682b36b98fa7ea4de998d3463ccbebd94d935d6b48ba5b6ffa7126" +checksum = "191898e17ddee19e60bccb3945aa02339e81edd4a8c50e21fd4d48cdecda7b29" dependencies = [ "lazy-regex-proc_macros", "once_cell", @@ -3588,9 +3607,9 @@ dependencies = [ [[package]] name = "lazy-regex-proc_macros" -version = "3.4.1" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ba01db5ef81e17eb10a5e0f2109d1b3a3e29bac3070fdbd7d156bf7dbd206a1" +checksum = "c35dc8b0da83d1a9507e12122c80dea71a9c7c613014347392483a83ea593e04" dependencies = [ "proc-macro2", "quote", @@ -3685,9 +3704,9 @@ checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" @@ -4151,6 +4170,15 @@ dependencies = [ "libc", ] +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", +] + [[package]] name = "objc2-core-foundation" version = "0.3.2" @@ -4160,6 +4188,12 @@ dependencies = [ "bitflags", ] +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + [[package]] name = "objc2-io-kit" version = "0.3.2" @@ -4373,8 +4407,7 @@ checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" [[package]] name = "path_resolver" version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3604448dbdd00c6884479c066f040f503bf26f6b58de5358b5d2376ef4e78d11" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "ahash", "fs-err", @@ -4811,7 +4844,7 @@ dependencies = [ "async-fd-lock", "base64 0.22.1", "chrono", - "coalesced_map", + "coalesced_map 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "derive_more", "dirs", "dunce", @@ -4851,7 +4884,6 @@ dependencies = [ "rattler_virtual_packages", "serde", "serde_json", - "serde_with", "simple_spawn_blocking", "slotmap", "strsim", @@ -5295,6 +5327,7 @@ dependencies = [ name = "pixi_record" version = "0.1.0" dependencies = [ + "chrono", "file_url", "miette 7.6.0", "pixi_git", @@ -5600,9 +5633,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -6026,8 +6059,7 @@ dependencies = [ [[package]] name = "rattler" version = "0.38.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a2c731b4989ca74615b05f308a63664b6e7592a621a58fb5267b51a8239273" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "anyhow", "clap", @@ -6071,8 +6103,7 @@ dependencies = [ [[package]] name = "rattler_cache" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e25b6c05b42228a55cd58a11d91af92819b03c9c604cbc7a83568ced7e2db2" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "ahash", "anyhow", @@ -6104,8 +6135,7 @@ dependencies = [ [[package]] name = "rattler_conda_types" version = "0.40.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4a129c8b0f43f700b43af71fcbf17fae058e0840c8a610d354355a552eb36e" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "ahash", "chrono", @@ -6146,8 +6176,7 @@ dependencies = [ [[package]] name = "rattler_digest" version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "886e9a6254e74a830c2b8555e14862d6b2f4cc498b43767d4adf1c71421a4796" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "blake2", "digest", @@ -6165,8 +6194,7 @@ dependencies = [ [[package]] name = "rattler_lock" version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f11b1ee4ef6fe117b214bb6614127bfeaf0b3301d8347d7dc65c5133e2ab20" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "ahash", "chrono", @@ -6191,8 +6219,7 @@ dependencies = [ [[package]] name = "rattler_macros" version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "988d5d7ace4fb1d7549008236cf08de95e8ea2f1f80754109324a08c31e6dc6a" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "quote", "syn", @@ -6201,8 +6228,7 @@ dependencies = [ [[package]] name = "rattler_menuinst" version = "0.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84487b67092b6624ade384f4a22adb287fee9042d2e18c50714ca947d69d3879" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "chrono", "configparser", @@ -6231,8 +6257,7 @@ dependencies = [ [[package]] name = "rattler_networking" version = "0.25.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6937ea4ebf9b46051a96fc061199e7a81e1debfd6a7558e110f400bf8dc054b" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "anyhow", "async-once-cell", @@ -6263,8 +6288,7 @@ dependencies = [ [[package]] name = "rattler_package_streaming" version = "0.23.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0778a02ff0cddc56836f325bd5365cdf3d7357570a8b9f21f6fd590452b39814" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "bzip2 0.6.1", "chrono", @@ -6293,8 +6317,7 @@ dependencies = [ [[package]] name = "rattler_pty" version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86a84e6b351c46c7588bb8f5c90994be23d5c3c31cf87f9ec903cd91d9fc4246" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "libc", "nix 0.30.1", @@ -6305,8 +6328,7 @@ dependencies = [ [[package]] name = "rattler_redaction" version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3aa5057629aeb20861919e9ae56875985d58028f3c6f433a20b5ded086e1cec5" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "reqwest", "reqwest-middleware", @@ -6316,8 +6338,7 @@ dependencies = [ [[package]] name = "rattler_repodata_gateway" version = "0.24.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410e796a90104cb4416f24955816dd2cdd9727b08b18972a32dde730e13264b3" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "anyhow", "async-compression", @@ -6328,7 +6349,7 @@ dependencies = [ "cache_control", "cfg-if", "chrono", - "coalesced_map", + "coalesced_map 0.1.2 (git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7)", "dashmap", "dirs", "file_url", @@ -6376,8 +6397,7 @@ dependencies = [ [[package]] name = "rattler_shell" version = "0.25.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1ebf3ab404de7616429f74f5d5fca00eaaf9df535706613bab42b44bdacd13" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "anyhow", "enum_dispatch", @@ -6397,8 +6417,7 @@ dependencies = [ [[package]] name = "rattler_solve" version = "3.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44ebabdec0f11bfe534f6a63f5d49cd4e7647ea029c751821c2ab36e558a97a0" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "chrono", "futures", @@ -6415,8 +6434,7 @@ dependencies = [ [[package]] name = "rattler_virtual_packages" version = "2.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2debe854ed9ecdf446b976ceac16c4cce14b8c69dd0731a5d9579ee59ec731b7" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "archspec", "libloading", @@ -7025,9 +7043,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.7" +version = "0.103.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" +checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" dependencies = [ "ring", "rustls-pki-types", @@ -7592,8 +7610,7 @@ checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] name = "simple_spawn_blocking" version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55c0b0b683828aa9d4f5c0e59b0c856a12c30a65b5f1ca4292664734d76fa9c2" +source = "git+https://github.com/baszalmstra/rattler?branch=rattler-lock%2Fv7#e14020ceea4a5f8afe2e676d39fc8255726b216b" dependencies = [ "tokio", ] @@ -8077,9 +8094,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -8485,9 +8502,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-linebreak" @@ -8497,9 +8514,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-normalization" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" dependencies = [ "tinyvec", ] @@ -10657,9 +10674,9 @@ dependencies = [ [[package]] name = "writeable" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "wyz" @@ -10713,11 +10730,10 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "serde", "stable_deref_trait", "yoke-derive", "zerofrom", @@ -10725,9 +10741,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", @@ -10916,9 +10932,9 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -10927,9 +10943,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.4" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -10938,9 +10954,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", @@ -10992,9 +11008,9 @@ checksum = "2f06ae92f42f5e5c42443fd094f245eb656abf56dd7cce9b8b263236565e00f2" [[package]] name = "zopfli" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfc5ee405f504cd4984ecc6f14d02d55cfda60fa4b689434ef4102aae150cd7" +checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" dependencies = [ "bumpalo", "crc32fast", diff --git a/Cargo.toml b/Cargo.toml index 35ec37edc8..39183e3ead 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -215,6 +215,24 @@ zstd = { version = "0.13.3", default-features = false } reqwest-middleware = { git = "https://github.com/astral-sh/reqwest-middleware", rev = "7650ed76215a962a96d94a79be71c27bffde7ab2" } reqwest-retry = { git = "https://github.com/astral-sh/reqwest-middleware", rev = "7650ed76215a962a96d94a79be71c27bffde7ab2" } version-ranges = { git = "https://github.com/astral-sh/pubgrub", rev = "d8efd77673c9a90792da9da31b6c0da7ea8a324b" } +# +# pixi-rattler-patches - START +file_url = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_cache = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_conda_types = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_digest = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_lock = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_menuinst = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_networking = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_package_streaming = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_repodata_gateway = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_shell = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_solve = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +rattler_virtual_packages = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +simple_spawn_blocking = { git = "https://github.com/baszalmstra/rattler", branch = "rattler-lock/v7" } +# pixi-rattler-patches - END +# [profile.ci] codegen-units = 16 diff --git a/crates/pixi/tests/integration_rust/common/mod.rs b/crates/pixi/tests/integration_rust/common/mod.rs index 9aefb83659..7aaa2ddcbf 100644 --- a/crates/pixi/tests/integration_rust/common/mod.rs +++ b/crates/pixi/tests/integration_rust/common/mod.rs @@ -137,7 +137,7 @@ impl LockFileExt for LockFile { .into_iter() .flatten() .filter_map(LockedPackageRef::as_conda) - .any(|package| package.record().name.as_normalized() == name) + .any(|package| package.name().as_normalized() == name) } fn contains_pypi_package(&self, environment: &str, platform: Platform, name: &str) -> bool { let Some(env) = self.environment(environment) else { diff --git a/crates/pixi/tests/integration_rust/solve_group_tests.rs b/crates/pixi/tests/integration_rust/solve_group_tests.rs index d0fc153fcb..d04305bf1f 100644 --- a/crates/pixi/tests/integration_rust/solve_group_tests.rs +++ b/crates/pixi/tests/integration_rust/solve_group_tests.rs @@ -117,8 +117,8 @@ async fn test_purl_are_added_for_pypi() { .packages(Platform::current()) .unwrap() .for_each(|dep| { - if dep.as_conda().unwrap().record().name == PackageName::from_str("boltons").unwrap() { - assert!(dep.as_conda().unwrap().record().purls.is_none()); + if dep.as_conda().unwrap().name() == &PackageName::from_str("boltons").unwrap() { + assert!(dep.as_conda().unwrap().purls().is_none()); } }); @@ -138,13 +138,11 @@ async fn test_purl_are_added_for_pypi() { .packages(Platform::current()) .unwrap() .for_each(|dep| { - if dep.as_conda().unwrap().record().name == PackageName::from_str("boltons").unwrap() { + if dep.as_conda().unwrap().name() == &PackageName::from_str("boltons").unwrap() { assert_eq!( dep.as_conda() .unwrap() - .record() - .purls - .as_ref() + .purls() .unwrap() .first() .unwrap() diff --git a/crates/pixi_build_types/src/lib.rs b/crates/pixi_build_types/src/lib.rs index e71082713d..5cdd672bb1 100644 --- a/crates/pixi_build_types/src/lib.rs +++ b/crates/pixi_build_types/src/lib.rs @@ -4,6 +4,7 @@ mod channel_configuration; mod conda_package_metadata; pub mod procedures; mod project_model; +mod variant; use std::{fmt::Display, sync::LazyLock}; @@ -20,6 +21,7 @@ use rattler_conda_types::{ version_spec::{LogicalOperator, RangeOperator}, }; use serde::{Deserialize, Serialize}; +pub use variant::VariantValue; // Version 0: Initial version (removed) // Version 1: Added conda/outputs and conda/build_v1 diff --git a/crates/pixi_build_types/src/procedures/conda_build_v1.rs b/crates/pixi_build_types/src/procedures/conda_build_v1.rs index 364737eed1..d38232f72f 100644 --- a/crates/pixi_build_types/src/procedures/conda_build_v1.rs +++ b/crates/pixi_build_types/src/procedures/conda_build_v1.rs @@ -16,6 +16,8 @@ use rattler_conda_types::{ use serde::{Deserialize, Serialize}; use serde_with::{DefaultOnError, DisplayFromStr, serde_as}; +use crate::variant::VariantValue; + pub const METHOD_NAME: &str = "conda/build_v1"; /// Parameters for the `conda/build_v1` request. @@ -174,7 +176,7 @@ pub struct CondaBuildV1Output { pub subdir: Platform, /// The variant configuration for the package. - pub variant: BTreeMap, + pub variant: BTreeMap, } /// Contains the result of the `conda/build_v1` request. diff --git a/crates/pixi_build_types/src/procedures/conda_outputs.rs b/crates/pixi_build_types/src/procedures/conda_outputs.rs index de51d0a52c..bb97cb0fcb 100644 --- a/crates/pixi_build_types/src/procedures/conda_outputs.rs +++ b/crates/pixi_build_types/src/procedures/conda_outputs.rs @@ -152,7 +152,7 @@ pub struct CondaOutputMetadata { pub python_site_packages_path: Option, /// The variants that were used for this output. - pub variant: BTreeMap, + pub variant: BTreeMap, } /// Describes dependencies, constraints and source dependencies for a particular diff --git a/crates/pixi_build_types/src/variant.rs b/crates/pixi_build_types/src/variant.rs new file mode 100644 index 0000000000..1508eb5647 --- /dev/null +++ b/crates/pixi_build_types/src/variant.rs @@ -0,0 +1,52 @@ +use std::cmp::Ordering; +use std::fmt::Display; + +use serde::{Deserialize, Serialize}; + +/// Represents a conda-build variant value. +/// +/// Variants are used in conda-build to specify different build configurations. +/// They can be strings (e.g., "3.11" for python version), integers (e.g., 1 for feature flags), +/// or booleans (e.g., true/false for optional features). +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(untagged)] +pub enum VariantValue { + /// String variant value (most common, e.g., python version "3.11") + String(String), + /// Integer variant value (e.g., for numeric feature flags) + Int(i64), + /// Boolean variant value (e.g., for on/off features) + Bool(bool), +} + +impl PartialOrd for VariantValue { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for VariantValue { + fn cmp(&self, other: &Self) -> Ordering { + #[allow(clippy::match_same_arms)] + match (self, other) { + (VariantValue::String(a), VariantValue::String(b)) => a.cmp(b), + (VariantValue::Int(a), VariantValue::Int(b)) => a.cmp(b), + (VariantValue::Bool(a), VariantValue::Bool(b)) => a.cmp(b), + // Define ordering between different types for deterministic sorting + (VariantValue::String(_), _) => Ordering::Less, + (_, VariantValue::String(_)) => Ordering::Greater, + (VariantValue::Int(_), VariantValue::Bool(_)) => Ordering::Less, + (VariantValue::Bool(_), VariantValue::Int(_)) => Ordering::Greater, + } + } +} + +impl Display for VariantValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VariantValue::String(s) => write!(f, "{s}"), + VariantValue::Int(i) => write!(f, "{i}"), + VariantValue::Bool(b) => write!(f, "{b}"), + } + } +} diff --git a/crates/pixi_cli/src/build.rs b/crates/pixi_cli/src/build.rs index fd647e3ce8..5150d372fb 100644 --- a/crates/pixi_cli/src/build.rs +++ b/crates/pixi_cli/src/build.rs @@ -76,7 +76,7 @@ pub async fn execute(args: Args) -> miette::Result<()> { // Determine the variant configuration for the build. let VariantConfig { - variants, + variants: variant_config, variant_files, } = workspace.variants(args.target_platform)?; @@ -149,7 +149,7 @@ pub async fn execute(args: Args) -> miette::Result<()> { channels: channels.clone(), channel_config: channel_config.clone(), build_environment: build_environment.clone(), - variants: Some(variants.clone()), + variants: Some(variant_config.clone()), variant_files: Some(variant_files.clone()), enabled_protocols: Default::default(), pin_override: None, @@ -177,10 +177,11 @@ pub async fn execute(args: Args) -> miette::Result<()> { .context("failed to create temporary output directory for build artifacts")?; // Build the individual packages - for package in packages { + for (package_name, package_variant) in packages { let built_package = command_dispatcher .source_build(SourceBuildSpec { - package, + package_name, + package_variant, // Build into a temporary directory first output_directory: Some(temp_output_dir.path().to_path_buf()), manifest_source: manifest_source.clone(), @@ -188,7 +189,7 @@ pub async fn execute(args: Args) -> miette::Result<()> { channels: channels.clone(), channel_config: channel_config.clone(), build_environment: build_environment.clone(), - variants: Some(variants.clone()), + variant_config: Some(variant_config.clone()), variant_files: Some(variant_files.clone()), enabled_protocols: Default::default(), work_directory: None, diff --git a/crates/pixi_cli/src/global/tree.rs b/crates/pixi_cli/src/global/tree.rs index 812db29829..43251e9cf4 100644 --- a/crates/pixi_cli/src/global/tree.rs +++ b/crates/pixi_cli/src/global/tree.rs @@ -66,12 +66,14 @@ pub async fn execute(args: Args) -> miette::Result<()> { .to_string(); let package = Package { name: name.clone(), - version: record - .repodata_record - .package_record - .version - .version() - .to_string(), + version: Some( + record + .repodata_record + .package_record + .version + .version() + .to_string(), + ), dependencies: record .repodata_record .package_record diff --git a/crates/pixi_cli/src/list.rs b/crates/pixi_cli/src/list.rs index 318a787b8c..efa6e5cee1 100644 --- a/crates/pixi_cli/src/list.rs +++ b/crates/pixi_cli/src/list.rs @@ -113,7 +113,7 @@ impl FancyDisplay for KindPackage { #[derive(Serialize)] struct PackageToOutput { name: String, - version: String, + version: Option, build: Option, size_bytes: Option, kind: KindPackage, @@ -163,16 +163,16 @@ impl PackageExt { /// Returns the name of the package. pub fn name(&self) -> Cow<'_, str> { match self { - Self::Conda(value) => value.record().name.as_normalized().into(), + Self::Conda(value) => value.name().as_normalized().into(), Self::PyPI(value, _) => value.name.as_dist_info_name(), } } /// Returns the version string of the package - pub fn version(&self) -> Cow<'_, str> { + pub fn version(&self) -> Option> { match self { - Self::Conda(value) => value.record().version.as_str(), - Self::PyPI(value, _) => value.version.to_string().into(), + Self::Conda(value) => Some(value.version()?.as_str()), + Self::PyPI(value, _) => Some(value.version.to_string().into()), } } } @@ -216,10 +216,12 @@ pub async fn execute(args: Args) -> miette::Result<()> { .into_diagnostic()?; // Get the python record from the lock file - let mut conda_records = locked_deps_ext.iter().filter_map(|d| d.as_conda()); + let conda_records = locked_deps_ext.iter().filter_map(|d| d.as_conda()); // Construct the registry index if we have a python record - let python_record = conda_records.find(|r| is_python_record(r)); + let python_record = conda_records + .filter_map(CondaPackageData::as_binary) + .find(|r| is_python_record(&r.package_record)); let tags; let uv_context; let index_locations; @@ -237,7 +239,7 @@ pub async fn execute(args: Args) -> miette::Result<()> { tags = get_pypi_tags( platform, &environment.system_requirements(), - python_record.record(), + &python_record.package_record, )?; Some(RegistryWheelIndex::new( &uv_context.cache, @@ -376,7 +378,7 @@ fn print_packages_as_table(packages: &Vec) -> io::Result<()> { writeln!( writer, "\t{}\t{}\t{}\t{}\t{}{}", - &package.version, + package.version.as_deref().unwrap_or(""), package.build.as_deref().unwrap_or(""), size_human, &package.kind.fancy_display(), @@ -420,22 +422,22 @@ fn create_package_to_output<'a, 'b>( registry_index: Option<&'a mut RegistryWheelIndex<'b>>, ) -> miette::Result { let name = package.name().to_string(); - let version = package.version().into_owned(); + let version = package.version().map(|v| v.into_owned()); let kind = KindPackage::from(package); let build = match package { - PackageExt::Conda(pkg) => Some(pkg.record().build.clone()), + PackageExt::Conda(pkg) => pkg.build().map(ToOwned::to_owned), PackageExt::PyPI(_, _) => None, }; let (size_bytes, source) = match package { - PackageExt::Conda(pkg) => ( - pkg.record().size, - match pkg { - CondaPackageData::Source(source) => Some(source.location.to_string()), - CondaPackageData::Binary(binary) => binary.channel.as_ref().map(|c| c.to_string()), - }, - ), + PackageExt::Conda(pkg) => match pkg { + CondaPackageData::Source(source) => (None, Some(source.location.to_string())), + CondaPackageData::Binary(binary) => ( + binary.package_record.size, + binary.channel.as_ref().map(|c| c.to_string()), + ), + }, PackageExt::PyPI(p, name) => { // Check the hash to avoid non index packages to be handled by the registry // index as wheels diff --git a/crates/pixi_cli/src/shared/tree.rs b/crates/pixi_cli/src/shared/tree.rs index 63c1825abd..5dda5acf02 100644 --- a/crates/pixi_cli/src/shared/tree.rs +++ b/crates/pixi_cli/src/shared/tree.rs @@ -18,7 +18,7 @@ pub enum PackageSource { #[derive(Debug, Clone)] pub struct Package { pub name: String, - pub version: String, + pub version: Option, pub dependencies: Vec, pub needed_by: Vec, pub source: PackageSource, @@ -214,7 +214,7 @@ fn print_dependency_node( &format!("{prefix}{symbol} "), &Package { name: dep_name.to_owned(), - version: String::from(""), + version: None, dependencies: Vec::new(), needed_by: Vec::new(), source: PackageSource::Conda, @@ -256,8 +256,10 @@ pub fn print_package( console::style(&package.name) }, match package.source { - PackageSource::Conda => console::style(&package.version).fg(Color::Yellow), - PackageSource::Pypi => console::style(&package.version).fg(Color::Blue), + PackageSource::Conda => + console::style(package.version.as_deref().unwrap_or_default()).fg(Color::Yellow), + PackageSource::Pypi => + console::style(package.version.as_deref().unwrap_or_default()).fg(Color::Blue), }, if visited { "(*)" } else { "" } ) diff --git a/crates/pixi_cli/src/tree.rs b/crates/pixi_cli/src/tree.rs index 7a2ed0acce..d58f9aa52d 100644 --- a/crates/pixi_cli/src/tree.rs +++ b/crates/pixi_cli/src/tree.rs @@ -120,11 +120,10 @@ pub(crate) fn extract_package_info( package: rattler_lock::LockedPackageRef<'_>, ) -> Option { if let Some(conda_package) = package.as_conda() { - let name = conda_package.record().name.as_normalized().to_string(); + let name = conda_package.name().as_normalized().to_string(); let dependencies: Vec = conda_package - .record() - .depends + .depends() .iter() .map(|d| { d.split_once(' ') @@ -179,9 +178,9 @@ pub fn generate_dependency_map(locked_deps: &[LockedPackageRef<'_>]) -> HashMap< name: package_info.name, version: match package { LockedPackageRef::Conda(conda_data) => { - conda_data.record().version.to_string() + conda_data.version().map(|v| v.to_string()) } - LockedPackageRef::Pypi(pypi_data, _) => pypi_data.version.to_string(), + LockedPackageRef::Pypi(pypi_data, _) => Some(pypi_data.version.to_string()), }, dependencies: package_info .dependencies diff --git a/crates/pixi_command_dispatcher/Cargo.toml b/crates/pixi_command_dispatcher/Cargo.toml index 8160eb2e95..a160685bab 100644 --- a/crates/pixi_command_dispatcher/Cargo.toml +++ b/crates/pixi_command_dispatcher/Cargo.toml @@ -27,7 +27,6 @@ pin-project-lite = { workspace = true } rand = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } -serde_with = { workspace = true } slotmap = { workspace = true } strsim = { workspace = true } thiserror = { workspace = true } diff --git a/crates/pixi_command_dispatcher/src/backend_source_build/mod.rs b/crates/pixi_command_dispatcher/src/backend_source_build/mod.rs index 70aaf4e503..ae5d3f99c3 100644 --- a/crates/pixi_command_dispatcher/src/backend_source_build/mod.rs +++ b/crates/pixi_command_dispatcher/src/backend_source_build/mod.rs @@ -1,19 +1,15 @@ //! See [`BackendSourceBuildSpec`] -use std::{ - collections::{BTreeMap, BTreeSet}, - fmt::Display, - path::PathBuf, -}; +use std::{collections::BTreeSet, path::PathBuf}; use futures::{SinkExt, channel::mpsc::UnboundedSender}; -use itertools::{Either, Itertools}; +use itertools::Either; use miette::Diagnostic; use pixi_build_frontend::{Backend, json_rpc::CommunicationError}; use pixi_build_types::procedures::conda_build_v1::{ CondaBuildV1Dependency, CondaBuildV1DependencyRunExportSource, CondaBuildV1DependencySource, CondaBuildV1Output, CondaBuildV1Params, CondaBuildV1Prefix, CondaBuildV1PrefixPackage, - CondaBuildV1Result, CondaBuildV1RunExports, + CondaBuildV1RunExports, }; use pixi_record::PinnedSourceSpec; use pixi_spec::{BinarySpec, PixiSpec, SpecConversionError}; @@ -21,10 +17,9 @@ use rattler_conda_types::{ ChannelConfig, ChannelUrl, MatchSpec, PackageName, Platform, RepoDataRecord, }; use serde::Serialize; -use thiserror::Error; use crate::{ - CommandDispatcherError, PackageIdentifier, + CommandDispatcherError, build::{Dependencies, DependencySource, PixiRunExports, WithSource}, }; @@ -40,8 +35,11 @@ pub struct BackendSourceBuildSpec { #[serde(skip)] pub backend: Backend, - /// The package that we are building. - pub package: PackageIdentifier, + /// The name of the package to build + pub package_name: PackageName, + + /// The platform to build the package for + pub platform: Platform, /// The source location of the package that we are building. pub source: PinnedSourceSpec, @@ -82,7 +80,7 @@ pub struct BackendSourceBuildV1Method { /// TODO: This should move to the `SourceRecord` in the future. The variant /// is an essential part to identity a particular output of a source /// package. - pub variant: BTreeMap, + pub variant: crate::SelectedVariant, /// The directory where to place the built package. This is used as a hint /// for the backend, it may still place the package elsewhere. @@ -128,7 +126,8 @@ impl BackendSourceBuildSpec { BackendSourceBuildMethod::BuildV1(params) => { Self::build_v1( self.backend, - self.package, + self.package_name, + self.platform, params, self.work_directory, self.channels, @@ -140,9 +139,11 @@ impl BackendSourceBuildSpec { } } + #[allow(clippy::too_many_arguments)] async fn build_v1( backend: Backend, - record: PackageIdentifier, + package_name: PackageName, + platform: Platform, params: BackendSourceBuildV1Method, work_directory: PathBuf, channels: Vec, @@ -244,14 +245,11 @@ impl BackendSourceBuildSpec { .collect(), }), output: CondaBuildV1Output { - name: record.name.clone(), - version: Some(record.version.clone()), - build: Some(record.build.clone()), - subdir: record - .subdir - .parse() - .expect("found a package record with an unparsable subdir"), - variant: params.variant, + name: package_name, + version: None, + build: None, + subdir: platform, + variant: params.variant.into(), }, work_directory: work_directory.clone(), output_directory: params.output_directory, @@ -265,25 +263,6 @@ impl BackendSourceBuildSpec { .map_err(BackendSourceBuildError::BuildError) .map_err(CommandDispatcherError::Failed)?; - // Make sure that the built package matches the expected output. - if v1_built_package_matches_requested(&built_package, &record) { - return Err(CommandDispatcherError::Failed( - BackendSourceBuildError::UnexpectedPackage(UnexpectedPackageError { - subdir: record.subdir.clone(), - name: record.name.as_normalized().to_string(), - version: record.version.to_string(), - build: record.build.clone(), - packages: vec![format!( - "{}/{}={}={}", - built_package.subdir, - built_package.name, - built_package.version, - built_package.build - )], - }), - )); - }; - Ok(BackendBuiltSource { input_globs: built_package.input_globs, output_file: built_package.output_file, @@ -291,18 +270,6 @@ impl BackendSourceBuildSpec { } } -/// Returns true if the requested package matches the one that was built by a -/// backend. -fn v1_built_package_matches_requested( - built_package: &CondaBuildV1Result, - record: &PackageIdentifier, -) -> bool { - built_package.name != record.name.as_normalized() - || built_package.version != record.version - || built_package.build != record.build - || built_package.subdir.as_str() != record.subdir -} - fn dependencies_to_protocol( dependencies: impl IntoIterator)>, channel_config: &ChannelConfig, @@ -370,44 +337,4 @@ pub enum BackendSourceBuildError { #[error(transparent)] #[diagnostic(transparent)] BuildError(#[from] CommunicationError), - - #[error(transparent)] - UnexpectedPackage(UnexpectedPackageError), -} - -/// An error that can occur when the build backend did not return the expected -/// package. -#[derive(Debug, Error)] -pub struct UnexpectedPackageError { - pub subdir: String, - pub name: String, - pub version: String, - pub build: String, - pub packages: Vec, -} - -impl Display for UnexpectedPackageError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self.packages.len() { - 0 => write!( - f, - "The build backend did not return any packages for {}/{}={}={}.", - self.subdir, self.name, self.version, self.build - ), - 1 => write!( - f, - "The build backend did not return the expected package: {}/{}={}={}. Instead the build backend returned {}.", - self.subdir, self.name, self.version, self.build, self.packages[0] - ), - _ => write!( - f, - "The build backend did not return the expected package: {}/{}={}={}. Instead the following packages were returned:\n- {}", - self.subdir, - self.name, - self.version, - self.build, - self.packages.iter().format("\n- ") - ), - } - } } diff --git a/crates/pixi_command_dispatcher/src/build/build_cache.rs b/crates/pixi_command_dispatcher/src/build/build_cache.rs index c76324df6f..2a0f6e5685 100644 --- a/crates/pixi_command_dispatcher/src/build/build_cache.rs +++ b/crates/pixi_command_dispatcher/src/build/build_cache.rs @@ -1,5 +1,6 @@ use std::{ collections::BTreeSet, + fmt::Display, hash::{Hash, Hasher}, io::SeekFrom, path::{Path, PathBuf}, @@ -7,6 +8,7 @@ use std::{ use async_fd_lock::{LockWrite, RwLockWriteGuard}; use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD}; +use itertools::Itertools; use ordermap::OrderMap; use pixi_build_discovery::{BackendInitializationParams, DiscoveredBackend}; use pixi_build_types::{ProjectModelV1, TargetSelectorV1}; @@ -14,7 +16,6 @@ use pixi_record::PinnedSourceSpec; use pixi_stable_hash::{StableHashBuilder, json::StableJson, map::StableMap}; use rattler_conda_types::{ChannelUrl, GenericVirtualPackage, Platform, RepoDataRecord}; use serde::{Deserialize, Serialize}; -use serde_with::serde_as; use thiserror::Error; use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; use xxhash_rust::xxh3::Xxh3; @@ -43,14 +44,8 @@ pub struct BuildInput { /// The name of the package pub name: String, - /// The version of the package to build - pub version: String, - - /// The build string of the package to build - pub build: String, - - /// The platform for which the metadata was computed. - pub subdir: String, + /// The specific variant of the package (from the lock file) + pub package_variant: crate::SelectedVariant, /// The host platform pub host_platform: Platform, @@ -70,9 +65,7 @@ impl BuildInput { let BuildInput { channel_urls, name, - version, - build, - subdir, + package_variant, host_platform, host_virtual_packages, build_virtual_packages, @@ -80,14 +73,14 @@ impl BuildInput { // Hash some of the keys let mut hasher = Xxh3::new(); - build.hash(&mut hasher); + package_variant.hash(&mut hasher); channel_urls.hash(&mut hasher); host_platform.hash(&mut hasher); host_virtual_packages.hash(&mut hasher); build_virtual_packages.hash(&mut hasher); let hash = URL_SAFE_NO_PAD.encode(hasher.finish().to_ne_bytes()); - format!("{name}-{version}-{subdir}-{hash}",) + format!("{name}-{hash}",) } } @@ -118,10 +111,8 @@ impl BuildCache { source = %source, input_key = %input_key, name = %input.name, - version = %input.version, - subdir = %input.subdir, + package_variant = ?input.package_variant, host_platform = %input.host_platform, - build = %input.build, channel_urls = ?input.channel_urls, host_virtual_packages = ?input.host_virtual_packages, build_virtual_packages = ?input.build_virtual_packages, @@ -234,22 +225,41 @@ pub struct CachedBuildSourceInfo { pub package_build_input_hash: Option, } -#[serde_as] #[derive(Clone, Default, Debug, Serialize, Deserialize)] pub struct BuildHostEnvironment { /// Describes the packages that were installed in the host environment. pub packages: Vec, } -#[serde_as] #[derive(Clone, Debug, Serialize, Deserialize)] pub struct BuildHostPackage { - /// The repodata record of the package. #[serde(flatten)] pub repodata_record: RepoDataRecord, - /// The source location from which the package was built. - pub source: Option, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub source: Option, +} + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct BuildHostSourcePackage { + /// The location of the source code. + pub source: PinnedSourceSpec, + + /// The package variant to build the package + pub package_variant: crate::SelectedVariant, +} + +impl Display for BuildHostSourcePackage { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}({})", + self.source, + self.package_variant + .iter() + .format_with(",", |(key, value), f| f(&format_args!("{key}={value}"))) + ) + } } /// A cache entry returned by [`BuildCache::entry`] which enables diff --git a/crates/pixi_command_dispatcher/src/build/conversion.rs b/crates/pixi_command_dispatcher/src/build/conversion.rs index bea7b35a49..b85d86e096 100644 --- a/crates/pixi_command_dispatcher/src/build/conversion.rs +++ b/crates/pixi_command_dispatcher/src/build/conversion.rs @@ -1,9 +1,6 @@ -use pixi_build_types::{ - BinaryPackageSpecV1, CondaPackageMetadata, PackageSpecV1, SourcePackageSpecV1, -}; -use pixi_record::{InputHash, PinnedSourceSpec, SourceRecord}; +use pixi_build_types::{BinaryPackageSpecV1, PackageSpecV1, SourcePackageSpecV1}; use pixi_spec::{BinarySpec, DetailedSpec, SourceLocationSpec, UrlBinarySpec}; -use rattler_conda_types::{NamedChannelOrUrl, PackageName, PackageRecord}; +use rattler_conda_types::NamedChannelOrUrl; /// Converts a [`SourcePackageSpecV1`] to a [`pixi_spec::SourceSpec`]. pub fn from_source_spec_v1(source: SourcePackageSpecV1) -> pixi_spec::SourceSpec { @@ -96,71 +93,3 @@ pub fn from_package_spec_v1(source: PackageSpecV1) -> pixi_spec::PixiSpec { PackageSpecV1::Binary(binary) => from_binary_spec_v1(*binary).into(), } } - -pub(crate) fn package_metadata_to_source_records( - manifest_source: &PinnedSourceSpec, - build_source: Option<&PinnedSourceSpec>, - packages: &[CondaPackageMetadata], - package: &PackageName, - input_hash: &Option, -) -> Vec { - // Convert the metadata to repodata - - packages - .iter() - .filter(|pkg| pkg.name == *package) - .map(|p| { - SourceRecord { - input_hash: input_hash.clone(), - manifest_source: manifest_source.clone(), - build_source: build_source.cloned(), - sources: p - .sources - .iter() - .map(|(name, source)| (name.clone(), from_source_spec_v1(source.clone()))) - .collect(), - package_record: PackageRecord { - // We cannot now these values from the metadata because no actual package - // was built yet. - size: None, - sha256: None, - md5: None, - - // TODO(baszalmstra): Decide if it makes sense to include the current - // timestamp here. - timestamp: None, - - // These values are derived from the build backend values. - platform: p.subdir.only_platform().map(ToString::to_string), - arch: p.subdir.arch().as_ref().map(ToString::to_string), - - // These values are passed by the build backend - name: p.name.clone(), - build: p.build.clone(), - version: p.version.clone(), - build_number: p.build_number, - license: p.license.clone(), - subdir: p.subdir.to_string(), - license_family: p.license_family.clone(), - noarch: p.noarch, - constrains: p.constraints.iter().map(|c| c.to_string()).collect(), - depends: p.depends.iter().map(|c| c.to_string()).collect(), - - // These are deprecated and no longer used. - features: None, - track_features: vec![], - legacy_bz2_md5: None, - legacy_bz2_size: None, - python_site_packages_path: None, - - // TODO(baszalmstra): Add support for these. - purls: None, - - // These are not important at this point. - run_exports: None, - experimental_extra_depends: Default::default(), - }, - } - }) - .collect() -} diff --git a/crates/pixi_command_dispatcher/src/build/dependencies.rs b/crates/pixi_command_dispatcher/src/build/dependencies.rs index abfea9c4d4..92c84e34c2 100644 --- a/crates/pixi_command_dispatcher/src/build/dependencies.rs +++ b/crates/pixi_command_dispatcher/src/build/dependencies.rs @@ -7,7 +7,7 @@ use pixi_build_types::{ CondaOutputDependencies, CondaOutputIgnoreRunExports, CondaOutputRunExports, }, }; -use pixi_record::PixiRecord; +use pixi_record::PixiPackageRecord; use pixi_spec::{BinarySpec, DetailedSpec, PixiSpec, SourceAnchor, UrlBinarySpec}; use pixi_spec_containers::DependencyMap; use rattler_conda_types::{ @@ -215,7 +215,7 @@ impl Dependencies { /// Extract run exports from the solved environments. pub async fn extract_run_exports( &self, - records: &mut [PixiRecord], + records: &mut [PixiPackageRecord], ignore: &CondaOutputIgnoreRunExports, gateway: &Gateway, reporter: Option>, @@ -226,19 +226,16 @@ impl Dependencies { let mut relevant_records = records .iter_mut() // Only record run exports for packages that are direct dependencies. - .filter(|r| self.dependencies.contains_key(&r.package_record().name)) + .filter(|r| self.dependencies.contains_key(r.name())) // Filter based on whether we want to ignore run exports for a particular // package. - .filter(|r| !ignore.from_package.contains(&r.package_record().name)) + .filter(|r| !ignore.from_package.contains(r.name())) .collect::>(); // Determine the records that have missing run exports. let records_missing_run_exports = relevant_records .iter_mut() - .flat_map(|r| match *r { - PixiRecord::Binary(repo_data_record) => Some(repo_data_record), - PixiRecord::Source(_source_record) => None, - }) + .flat_map(|r| r.as_binary_mut()) .filter(|r| r.package_record.run_exports.is_none()); gateway .ensure_run_exports(records_missing_run_exports.into_iter(), reporter) @@ -246,21 +243,18 @@ impl Dependencies { for record in relevant_records { // Only record run exports for packages that are direct dependencies. - if !self - .dependencies - .contains_key(&record.package_record().name) - { + if !self.dependencies.contains_key(record.name()) { continue; } // Filter based on whether we want to ignore run exports for a particular // package. - if ignore.from_package.contains(&record.package_record().name) { + if ignore.from_package.contains(record.name()) { continue; } // Make sure we have valid run exports. - let Some(run_exports) = &record.package_record().run_exports else { + let Some(run_exports) = record.run_exports() else { // No run-exports found continue; }; diff --git a/crates/pixi_command_dispatcher/src/build/mod.rs b/crates/pixi_command_dispatcher/src/build/mod.rs index 38d5b68d79..56d6025385 100644 --- a/crates/pixi_command_dispatcher/src/build/mod.rs +++ b/crates/pixi_command_dispatcher/src/build/mod.rs @@ -13,7 +13,7 @@ use std::hash::{Hash, Hasher}; use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD}; pub use build_cache::{ BuildCache, BuildCacheEntry, BuildCacheError, BuildHostEnvironment, BuildHostPackage, - BuildInput, CachedBuild, CachedBuildSourceInfo, PackageBuildInputHash, + BuildHostSourcePackage, BuildInput, CachedBuild, CachedBuildSourceInfo, PackageBuildInputHash, PackageBuildInputHashBuilder, }; pub use build_environment::BuildEnvironment; diff --git a/crates/pixi_command_dispatcher/src/build/source_metadata_cache.rs b/crates/pixi_command_dispatcher/src/build/source_metadata_cache.rs index 2ebbd51098..2f9d0981c7 100644 --- a/crates/pixi_command_dispatcher/src/build/source_metadata_cache.rs +++ b/crates/pixi_command_dispatcher/src/build/source_metadata_cache.rs @@ -8,14 +8,14 @@ use std::{ use async_fd_lock::{LockWrite, RwLockWriteGuard}; use base64::{Engine, engine::general_purpose::URL_SAFE_NO_PAD}; use pixi_build_discovery::EnabledProtocols; -use pixi_build_types::{CondaPackageMetadata, procedures::conda_outputs::CondaOutput}; +use pixi_build_types::procedures::conda_outputs::CondaOutput; use pixi_record::{InputHash, PinnedSourceSpec}; use rattler_conda_types::ChannelUrl; use serde::{Deserialize, Serialize}; use thiserror::Error; use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; -use crate::{BuildEnvironment, PackageIdentifier, build::source_checkout_cache_key}; +use crate::{BuildEnvironment, build::source_checkout_cache_key}; /// A cache for caching the metadata of a source checkout. /// @@ -218,43 +218,22 @@ pub struct CachedCondaMetadata { #[serde(default, skip_serializing_if = "Option::is_none")] pub input_hash: Option, - #[serde(flatten)] - pub metadata: MetadataKind, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(tag = "type", rename_all = "snake_case")] -pub enum MetadataKind { - /// The result of calling `conda/getMetadata` on a build backend. - GetMetadata { packages: Vec }, - - /// The result of calling `conda/outputs` on a build backend. - Outputs { outputs: Vec }, + /// The outputs described by this metadata. + pub outputs: Vec, } impl CachedCondaMetadata { /// Returns the unique package identifiers for the packages in this /// metadata. - pub fn outputs(&self) -> Vec { - match &self.metadata { - MetadataKind::GetMetadata { packages } => packages - .iter() - .map(|pkg| PackageIdentifier { - name: pkg.name.clone(), - version: pkg.version.clone(), - build: pkg.build.clone(), - subdir: pkg.subdir.to_string(), - }) - .collect(), - MetadataKind::Outputs { outputs } => outputs - .iter() - .map(|output| PackageIdentifier { - name: output.metadata.name.clone(), - version: output.metadata.version.clone(), - build: output.metadata.build.clone(), - subdir: output.metadata.subdir.to_string(), - }) - .collect(), - } + pub fn outputs(&self) -> Vec<(rattler_conda_types::PackageName, crate::SelectedVariant)> { + self.outputs + .iter() + .map(|output| { + let package_name = output.metadata.name.clone(); + let selected_variant = + crate::SelectedVariant::from(output.metadata.variant.clone()); + (package_name, selected_variant) + }) + .collect() } } diff --git a/crates/pixi_command_dispatcher/src/build_backend_metadata/mod.rs b/crates/pixi_command_dispatcher/src/build_backend_metadata/mod.rs index 88e5224893..a0fc4c7245 100644 --- a/crates/pixi_command_dispatcher/src/build_backend_metadata/mod.rs +++ b/crates/pixi_command_dispatcher/src/build_backend_metadata/mod.rs @@ -26,7 +26,7 @@ use crate::{ InstantiateBackendError, InstantiateBackendSpec, SourceCheckout, SourceCheckoutError, build::{ SourceRecordOrCheckout, WorkDirKey, - source_metadata_cache::{self, CachedCondaMetadata, MetadataKind, SourceMetadataKey}, + source_metadata_cache::{self, CachedCondaMetadata, SourceMetadataKey}, }, }; use pixi_build_discovery::BackendSpec; @@ -317,12 +317,7 @@ impl BuildBackendMetadataSpec { return Ok(None); }; - let metadata_kind = match metadata.metadata { - MetadataKind::GetMetadata { .. } => "conda/getMetadata", - MetadataKind::Outputs { .. } => { - pixi_build_types::procedures::conda_outputs::METHOD_NAME - } - }; + let metadata_kind = pixi_build_types::procedures::conda_outputs::METHOD_NAME; let Some(input_globs) = &metadata.input_hash else { // No input hash so just assume it is still valid. @@ -421,9 +416,7 @@ impl BuildBackendMetadataSpec { Ok(CachedCondaMetadata { id: random(), input_hash: input_hash.clone(), - metadata: MetadataKind::Outputs { - outputs: outputs.outputs, - }, + outputs: outputs.outputs, }) } diff --git a/crates/pixi_command_dispatcher/src/command_dispatcher/mod.rs b/crates/pixi_command_dispatcher/src/command_dispatcher/mod.rs index 5523a8196b..2438f5d09c 100644 --- a/crates/pixi_command_dispatcher/src/command_dispatcher/mod.rs +++ b/crates/pixi_command_dispatcher/src/command_dispatcher/mod.rs @@ -19,7 +19,7 @@ use pixi_build_discovery::{DiscoveredBackend, EnabledProtocols}; use pixi_build_frontend::BackendOverride; use pixi_git::resolver::GitResolver; use pixi_glob::GlobHashCache; -use pixi_record::{PinnedPathSpec, PinnedSourceSpec, PixiRecord}; +use pixi_record::{PinnedPathSpec, PinnedSourceSpec, PixiPackageRecord}; use pixi_spec::SourceLocationSpec; use rattler::package_cache::PackageCache; use rattler_conda_types::{ChannelConfig, GenericVirtualPackage, Platform}; @@ -245,7 +245,7 @@ pub(crate) enum ForegroundMessage { /// pixi environment. pub(crate) type SolvePixiEnvironmentTask = Task; impl TaskSpec for PixiEnvironmentSpec { - type Output = Vec; + type Output = Vec; type Error = SolvePixiEnvironmentError; } @@ -261,7 +261,7 @@ impl TaskSpec for InstallPixiEnvironmentSpec { /// conda environment. pub(crate) type SolveCondaEnvironmentTask = Task; impl TaskSpec for SolveCondaEnvironmentSpec { - type Output = Vec; + type Output = Vec; type Error = SolveCondaEnvironmentError; } @@ -510,7 +510,7 @@ impl CommandDispatcher { pub async fn solve_pixi_environment( &self, spec: PixiEnvironmentSpec, - ) -> Result, CommandDispatcherError> { + ) -> Result, CommandDispatcherError> { self.execute_task(spec).await } @@ -540,7 +540,7 @@ impl CommandDispatcher { pub async fn solve_conda_environment( &self, spec: SolveCondaEnvironmentSpec, - ) -> Result, CommandDispatcherError> { + ) -> Result, CommandDispatcherError> { self.execute_task(spec).await } diff --git a/crates/pixi_command_dispatcher/src/command_dispatcher_processor/mod.rs b/crates/pixi_command_dispatcher/src/command_dispatcher_processor/mod.rs index e7c1e3d112..c934cdae5e 100644 --- a/crates/pixi_command_dispatcher/src/command_dispatcher_processor/mod.rs +++ b/crates/pixi_command_dispatcher/src/command_dispatcher_processor/mod.rs @@ -31,7 +31,7 @@ use crate::{ use futures::{StreamExt, future::LocalBoxFuture}; use itertools::Itertools; use pixi_git::{GitError, resolver::RepositoryReference, source::Fetch}; -use pixi_record::PixiRecord; +use pixi_record::PixiPackageRecord; use tokio::sync::{mpsc, oneshot}; use tokio_util::sync::CancellationToken; @@ -149,11 +149,11 @@ type BoxedDispatcherResult = Box>>; enum TaskResult { SolveCondaEnvironment( SolveCondaEnvironmentId, - BoxedDispatcherResult, SolveCondaEnvironmentError>, + BoxedDispatcherResult, SolveCondaEnvironmentError>, ), SolvePixiEnvironment( SolvePixiEnvironmentId, - BoxedDispatcherResult, SolvePixiEnvironmentError>, + BoxedDispatcherResult, SolvePixiEnvironmentError>, ), BuildBackendMetadata( BuildBackendMetadataId, @@ -205,7 +205,7 @@ enum PendingGitCheckout { /// background task to keep track of which command_dispatcher is awaiting the /// result. struct PendingSolveCondaEnvironment { - tx: oneshot::Sender, SolveCondaEnvironmentError>>, + tx: oneshot::Sender, SolveCondaEnvironmentError>>, reporter_id: Option, } @@ -218,7 +218,7 @@ struct PendingBackendSourceBuild { /// background task to keep track of which command_dispatcher is awaiting the /// result. struct PendingPixiEnvironment { - tx: oneshot::Sender, SolvePixiEnvironmentError>>, + tx: oneshot::Sender, SolvePixiEnvironmentError>>, reporter_id: Option, } diff --git a/crates/pixi_command_dispatcher/src/command_dispatcher_processor/solve_conda.rs b/crates/pixi_command_dispatcher/src/command_dispatcher_processor/solve_conda.rs index a9e391d245..c91b053900 100644 --- a/crates/pixi_command_dispatcher/src/command_dispatcher_processor/solve_conda.rs +++ b/crates/pixi_command_dispatcher/src/command_dispatcher_processor/solve_conda.rs @@ -1,5 +1,5 @@ use futures::FutureExt; -use pixi_record::PixiRecord; +use pixi_record::PixiPackageRecord; use super::{CommandDispatcherProcessor, PendingSolveCondaEnvironment, TaskResult}; use crate::{ @@ -90,7 +90,7 @@ impl CommandDispatcherProcessor { pub(crate) fn on_solve_conda_environment_result( &mut self, id: SolveCondaEnvironmentId, - result: Result, CommandDispatcherError>, + result: Result, CommandDispatcherError>, ) { self.parent_contexts.remove(&id.into()); let env = self diff --git a/crates/pixi_command_dispatcher/src/command_dispatcher_processor/solve_pixi.rs b/crates/pixi_command_dispatcher/src/command_dispatcher_processor/solve_pixi.rs index fbe1b719f6..26febee8f8 100644 --- a/crates/pixi_command_dispatcher/src/command_dispatcher_processor/solve_pixi.rs +++ b/crates/pixi_command_dispatcher/src/command_dispatcher_processor/solve_pixi.rs @@ -1,5 +1,5 @@ use futures::FutureExt; -use pixi_record::PixiRecord; +use pixi_record::PixiPackageRecord; use super::{CommandDispatcherProcessor, PendingPixiEnvironment, TaskResult}; use crate::{ @@ -74,7 +74,7 @@ impl CommandDispatcherProcessor { pub(crate) fn on_solve_pixi_environment_result( &mut self, id: SolvePixiEnvironmentId, - result: Result, CommandDispatcherError>, + result: Result, CommandDispatcherError>, ) { self.parent_contexts.remove(&id.into()); let env = self diff --git a/crates/pixi_command_dispatcher/src/install_pixi/mod.rs b/crates/pixi_command_dispatcher/src/install_pixi/mod.rs index 98b6b1de63..c784d1f09d 100644 --- a/crates/pixi_command_dispatcher/src/install_pixi/mod.rs +++ b/crates/pixi_command_dispatcher/src/install_pixi/mod.rs @@ -95,14 +95,14 @@ pub struct InstallPixiEnvironmentResult { } impl InstallPixiEnvironmentSpec { - pub fn new(records: Vec, prefix: Prefix) -> Self { + pub fn new>(records: Vec, prefix: Prefix) -> Self { InstallPixiEnvironmentSpec { name: prefix .file_name() .map(OsStr::to_string_lossy) .map(Cow::into_owned) .unwrap_or_default(), - records, + records: records.into_iter().map(Into::into).collect(), prefix, installed: None, ignore_packages: None, @@ -139,7 +139,7 @@ impl InstallPixiEnvironmentSpec { if self .ignore_packages .as_ref() - .is_some_and(|ignore| ignore.contains(&source_record.package_record.name)) + .is_some_and(|ignore| ignore.contains(&source_record.name)) { continue; } @@ -210,17 +210,16 @@ impl InstallPixiEnvironmentSpec { ) -> Result> { // Build the source package. // Verify if we need to force the build even if the cache is up to date. - let force = self - .force_reinstall - .contains(&source_record.package_record.name); + let force = self.force_reinstall.contains(&source_record.name); let built_source = command_dispatcher .source_build(SourceBuildSpec { manifest_source: source_record.manifest_source.clone(), - package: source_record.into(), + package_name: source_record.name.clone(), + package_variant: source_record.variants.clone().into(), channel_config: self.channel_config.clone(), channels: self.channels.clone(), build_environment: self.build_environment.clone(), - variants: self.variants.clone(), + variant_config: self.variants.clone(), variant_files: self.variant_files.clone(), enabled_protocols: self.enabled_protocols.clone(), output_directory: None, @@ -248,7 +247,7 @@ pub enum InstallPixiEnvironmentError { Installer(InstallerError), #[error("failed to build '{}' from '{}'", - .0.package_record.name.as_source(), + .0.name.as_source(), .0.manifest_source)] BuildSourceError( Box, diff --git a/crates/pixi_command_dispatcher/src/instantiate_tool_env/mod.rs b/crates/pixi_command_dispatcher/src/instantiate_tool_env/mod.rs index 3e83bd31e8..67cd5dc9fb 100644 --- a/crates/pixi_command_dispatcher/src/instantiate_tool_env/mod.rs +++ b/crates/pixi_command_dispatcher/src/instantiate_tool_env/mod.rs @@ -13,6 +13,7 @@ use pixi_build_discovery::EnabledProtocols; use pixi_build_types::{ PIXI_BUILD_API_VERSION_NAME, PIXI_BUILD_API_VERSION_SPEC, PixiBuildApiVersion, }; +use pixi_record::PixiRecord; use pixi_spec::{BinarySpec, PixiSpec}; use pixi_spec_containers::DependencyMap; use pixi_utils::AsyncPrefixGuard; @@ -225,8 +226,8 @@ impl InstantiateToolEnvironmentSpec { // Ensure that the solution contains matching api version package let Some(api_version) = solved_environment .iter() - .find(|r| r.package_record().name == *PIXI_BUILD_API_VERSION_NAME) - .map(|r| r.package_record().version.as_ref()) + .find(|r| r.name() == &*PIXI_BUILD_API_VERSION_NAME) + .map(|r| r.version().as_ref()) .and_then(PixiBuildApiVersion::from_version) else { return Err(CommandDispatcherError::Failed( @@ -239,10 +240,9 @@ impl InstantiateToolEnvironmentSpec { // Extract the version of the main requirement package. let version = solved_environment .iter() - .find(|r| r.package_record().name == self.requirement.0) + .find(|r| r.name() == &self.requirement.0) .expect("The solved environment should always contain the main requirement package") - .package_record() - .version + .version() .clone(); // Construct the prefix for the tool environment. @@ -268,7 +268,10 @@ impl InstantiateToolEnvironmentSpec { command_queue .install_pixi_environment(InstallPixiEnvironmentSpec { name, - records: solved_environment, + records: solved_environment + .into_iter() + .map(PixiRecord::from) + .collect(), prefix: prefix.clone(), installed: None, build_environment: self.build_environment, diff --git a/crates/pixi_command_dispatcher/src/lib.rs b/crates/pixi_command_dispatcher/src/lib.rs index 24f3e8ecad..36066b727a 100644 --- a/crates/pixi_command_dispatcher/src/lib.rs +++ b/crates/pixi_command_dispatcher/src/lib.rs @@ -51,6 +51,7 @@ mod source_build; mod source_build_cache_status; mod source_checkout; mod source_metadata; +mod variant; pub use backend_source_build::{ BackendBuiltSource, BackendSourceBuildError, BackendSourceBuildMethod, @@ -87,6 +88,7 @@ pub use source_build_cache_status::{ }; pub use source_checkout::{InvalidPathError, SourceCheckout, SourceCheckoutError}; pub use source_metadata::{Cycle, SourceMetadata, SourceMetadataError, SourceMetadataSpec}; +pub use variant::{SelectedVariant, VariantValue}; /// A helper function to check if a value is the default value for its type. fn is_default(value: &T) -> bool { diff --git a/crates/pixi_command_dispatcher/src/package_identifier.rs b/crates/pixi_command_dispatcher/src/package_identifier.rs index cd2104ca98..0495f56a87 100644 --- a/crates/pixi_command_dispatcher/src/package_identifier.rs +++ b/crates/pixi_command_dispatcher/src/package_identifier.rs @@ -1,6 +1,6 @@ use std::{fmt::Display, hash::Hash}; -use pixi_record::SourceRecord; +use pixi_record::SourcePackageRecord; use rattler_conda_types::{PackageName, PackageRecord, VersionWithSource}; use serde::{Deserialize, Serialize}; @@ -57,14 +57,24 @@ impl<'a> From<&'a PackageRecord> for PackageIdentifier { } } -impl From for PackageIdentifier { - fn from(record: SourceRecord) -> Self { - record.package_record.into() +impl From for PackageIdentifier { + fn from(record: SourcePackageRecord) -> Self { + Self { + name: record.source_record.name, + version: record.version, + build: record.build, + subdir: record.subdir, + } } } -impl<'a> From<&'a SourceRecord> for PackageIdentifier { - fn from(record: &'a SourceRecord) -> Self { - (&record.package_record).into() +impl<'a> From<&'a SourcePackageRecord> for PackageIdentifier { + fn from(record: &'a SourcePackageRecord) -> Self { + Self { + name: record.source_record.name.clone(), + version: record.version.clone(), + build: record.build.clone(), + subdir: record.subdir.clone(), + } } } diff --git a/crates/pixi_command_dispatcher/src/solve_conda/mod.rs b/crates/pixi_command_dispatcher/src/solve_conda/mod.rs index 3617937f42..ff5fa59523 100644 --- a/crates/pixi_command_dispatcher/src/solve_conda/mod.rs +++ b/crates/pixi_command_dispatcher/src/solve_conda/mod.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, path::PathBuf, sync::Arc}; use chrono::{DateTime, Utc}; use itertools::Itertools; -use pixi_record::{PixiRecord, SourceRecord}; +use pixi_record::{PixiPackageRecord, PixiRecord, SourcePackageRecord}; use pixi_spec::{BinarySpec, SourceSpec}; use pixi_spec_containers::DependencyMap; use rattler_conda_types::{ @@ -105,7 +105,7 @@ impl SolveCondaEnvironmentSpec { /// Solves this environment pub async fn solve( self, - ) -> Result, CommandDispatcherError> { + ) -> Result, CommandDispatcherError> { // Solving is a CPU-intensive task, we spawn this on a background task to allow // for more concurrency. let solve_result = tokio::task::spawn_blocking(move || { @@ -143,20 +143,21 @@ impl SolveCondaEnvironmentSpec { let mut url_to_source_package = HashMap::new(); for source_metadata in &self.source_repodata { for record in &source_metadata.records { - let url = unique_url(record); + let url = unique_url(&record); + let package_record = record.package_record(); let repodata_record = RepoDataRecord { - package_record: record.package_record.clone(), + package_record: package_record.clone(), url: url.clone(), file_name: format!( "{}-{}-{}.source", - record.package_record.name.as_normalized(), - &record.package_record.version, - &record.package_record.build + package_record.name.as_normalized(), + &package_record.version, + &package_record.build ), channel: None, }; let mut record = record.clone(); - record.build_source = source_metadata.build_source.clone(); + record.source_record.build_source = source_metadata.build_source.clone(); url_to_source_package.insert(url, (record, repodata_record)); } } @@ -195,16 +196,16 @@ impl SolveCondaEnvironmentSpec { let solver_result = rattler_solve::resolvo::Solver.solve(task)?; - // Convert the results back into pixi records. + // Convert the results back into pixi records with metadata. Ok::<_, SolveCondaEnvironmentError>( solver_result .records .into_iter() .map(|record| { url_to_source_package.remove(&record.url).map_or_else( - || PixiRecord::Binary(record), - |(source_record, _repodata_record)| { - PixiRecord::Source(source_record.clone()) + || PixiPackageRecord::Binary(record), + |(resolved_source_record, _repodata_record)| { + PixiPackageRecord::Source(resolved_source_record.clone()) }, ) }) @@ -224,16 +225,21 @@ impl SolveCondaEnvironmentSpec { } /// Generates a unique URL for a source record. -fn unique_url(source: &SourceRecord) -> Url { - let mut url = source.manifest_source.identifiable_url(); +fn unique_url(source: &SourcePackageRecord) -> Url { + let mut url = source.source_record.manifest_source.identifiable_url(); // Add unique identifiers to the URL. - url.query_pairs_mut() - .append_pair("name", source.package_record.name.as_source()) - .append_pair("version", &source.package_record.version.as_str()) - .append_pair("build", &source.package_record.build) - .append_pair("subdir", &source.package_record.subdir); + let mut query = url.query_pairs_mut(); + query.append_pair("name", source.source_record.name.as_source()); + if let Some(version) = &source.source_record.version { + query.append_pair("version", &version.as_str()); + } + query + .append_pair("build", &source.build) + .append_pair("subdir", &source.subdir); + + drop(query); url } diff --git a/crates/pixi_command_dispatcher/src/solve_pixi/mod.rs b/crates/pixi_command_dispatcher/src/solve_pixi/mod.rs index af8f645bd5..d92c3408d5 100644 --- a/crates/pixi_command_dispatcher/src/solve_pixi/mod.rs +++ b/crates/pixi_command_dispatcher/src/solve_pixi/mod.rs @@ -7,7 +7,7 @@ use chrono::{DateTime, Utc}; use itertools::{Either, Itertools}; use miette::Diagnostic; use pixi_build_discovery::EnabledProtocols; -use pixi_record::PixiRecord; +use pixi_record::{PixiPackageRecord, PixiRecord}; use pixi_spec::{BinarySpec, PixiSpec, SourceSpec, SpecConversionError}; use pixi_spec_containers::DependencyMap; use rattler_conda_types::{Channel, ChannelConfig, ChannelUrl, ParseChannelError, Platform}; @@ -128,7 +128,7 @@ impl PixiEnvironmentSpec { self, command_queue: CommandDispatcher, gateway_reporter: Option>, - ) -> Result, CommandDispatcherError> { + ) -> Result, CommandDispatcherError> { // Split the requirements into source and binary requirements. let (source_specs, binary_specs) = Self::split_into_source_and_binary_requirements(self.dependencies); diff --git a/crates/pixi_command_dispatcher/src/solve_pixi/source_metadata_collector.rs b/crates/pixi_command_dispatcher/src/solve_pixi/source_metadata_collector.rs index d4d4faf33d..729ae32c5e 100644 --- a/crates/pixi_command_dispatcher/src/solve_pixi/source_metadata_collector.rs +++ b/crates/pixi_command_dispatcher/src/solve_pixi/source_metadata_collector.rs @@ -126,12 +126,16 @@ impl SourceMetadataCollector { // Process transitive dependencies for record in &source_metadata.records { - chain.push(record.package_record.name.clone()); - let anchor = SourceAnchor::from(SourceSpec::from(record.manifest_source.clone())); - for depend in &record.package_record.depends { + chain.push(record.source_record.name.clone()); + let anchor = SourceAnchor::from(SourceSpec::from( + record.source_record.manifest_source.clone(), + )); + + for depend in &record.source_record.depends { if let Ok(spec) = MatchSpec::from_str(depend, ParseStrictness::Lenient) { if let Some((name, source_spec)) = spec.name.as_ref().and_then(|name| { record + .source_record .sources .get(name.as_normalized()) .map(|source_spec| (name.clone(), source_spec.clone())) diff --git a/crates/pixi_command_dispatcher/src/source_build/mod.rs b/crates/pixi_command_dispatcher/src/source_build/mod.rs index 7914bf8f3f..0f37994615 100644 --- a/crates/pixi_command_dispatcher/src/source_build/mod.rs +++ b/crates/pixi_command_dispatcher/src/source_build/mod.rs @@ -1,5 +1,6 @@ use std::{ collections::BTreeMap, + fmt::Display, path::{Path, PathBuf}, sync::Arc, }; @@ -9,11 +10,12 @@ use miette::Diagnostic; use pixi_build_discovery::EnabledProtocols; use pixi_build_frontend::Backend; use pixi_build_types::procedures::conda_outputs::CondaOutputsParams; -use pixi_record::{PinnedSourceSpec, PixiRecord}; -use pixi_spec::{SourceAnchor, SourceLocationSpec, SourceSpec}; +use pixi_record::{PinnedSourceSpec, PixiPackageRecord, PixiRecord}; +use pixi_spec::SourceLocationSpec; +use pixi_spec::{SourceAnchor, SourceSpec}; use rattler_conda_types::{ - ChannelConfig, ChannelUrl, ConvertSubdirError, InvalidPackageNameError, PackageRecord, - Platform, RepoDataRecord, prefix::Prefix, + ChannelConfig, ChannelUrl, ConvertSubdirError, InvalidPackageNameError, PackageName, + PackageRecord, Platform, RepoDataRecord, prefix::Prefix, }; use rattler_digest::Sha256Hash; use rattler_repodata_gateway::{RunExportExtractorError, RunExportsReporter}; @@ -31,11 +33,10 @@ use crate::{ SolvePixiEnvironmentError, SourceBuildCacheStatusError, SourceBuildCacheStatusSpec, SourceCheckoutError, build::{ - BuildCacheError, BuildHostEnvironment, BuildHostPackage, CachedBuild, - CachedBuildSourceInfo, Dependencies, DependenciesError, MoveError, PackageBuildInputHash, - PixiRunExports, SourceRecordOrCheckout, WorkDirKey, move_file, + BuildCacheError, BuildHostEnvironment, BuildHostPackage, BuildHostSourcePackage, + CachedBuild, CachedBuildSourceInfo, Dependencies, DependenciesError, MoveError, + PackageBuildInputHash, PixiRunExports, SourceRecordOrCheckout, WorkDirKey, move_file, }, - package_identifier::PackageIdentifier, }; /// Describes all parameters required to build a conda package from a pixi @@ -48,8 +49,11 @@ use crate::{ /// be done serially. #[derive(Debug, Clone, Serialize, Eq, PartialEq, Hash)] pub struct SourceBuildSpec { - /// The source to build - pub package: PackageIdentifier, + /// The name of the package to build + pub package_name: PackageName, + + /// The specific variant of the package to build (from the lock file) + pub package_variant: crate::SelectedVariant, /// The location of the source code to build. pub manifest_source: PinnedSourceSpec, @@ -76,8 +80,8 @@ pub struct SourceBuildSpec { /// The build profile to use for the build. pub build_profile: BuildProfile, - /// Build variants to use during the build - pub variants: Option>>, + /// Build variant configuration to use during the build + pub variant_config: Option>>, /// Build variant file contents to use during the build pub variant_files: Option>, @@ -125,7 +129,7 @@ impl SourceBuildSpec { name = "source-build", fields( source= %self.manifest_source, - package = %self.package, + package = %self.package_name.as_normalized(), ) )] pub(crate) async fn build( @@ -145,7 +149,8 @@ impl SourceBuildSpec { let build_cache = command_dispatcher .clone() .source_build_cache_status(SourceBuildCacheStatusSpec { - package: self.package.clone(), + package_name: self.package_name.clone(), + package_variant: self.package_variant.clone(), build_environment: self.build_environment.clone(), source: self.manifest_source.clone(), channels: self.channels.clone(), @@ -176,13 +181,13 @@ impl SourceBuildSpec { } tracing::debug!( "source build for {} is up to date, but force rebuild is set, rebuilding anyway", - self.package.name.as_normalized() + self.package_name.as_normalized() ); } if let CachedBuildStatus::New(cached_build) = &*build_cache.cached_build.lock().await { tracing::debug!( "source build for {} is already built and marked as new, reusing the cache entry", - self.package.name.as_normalized() + self.package_name.as_normalized() ); tracing::debug!( source = %self.manifest_source, @@ -297,7 +302,7 @@ impl SourceBuildSpec { WorkDirKey { source: SourceRecordOrCheckout::Record { pinned: self.manifest_source.clone(), - package_name: self.package.name.clone(), + package_name: self.package_name.clone(), }, host_platform: self.build_environment.host_platform, build_backend: backend.identifier().to_string(), @@ -438,38 +443,6 @@ impl SourceBuildSpec { }) } - /// Little helper function the build a `BuildHostPackage` from expected and - /// installed records. - fn extract_prefix_repodata( - records: Vec, - prefix: Option, - ) -> Vec { - let Some(prefix) = prefix else { - return vec![]; - }; - - records - .into_iter() - .map(|record| match record { - PixiRecord::Binary(repodata_record) => BuildHostPackage { - repodata_record, - source: None, - }, - PixiRecord::Source(source) => { - let repodata_record = prefix - .resolved_source_records - .get(&source.package_record.name) - .cloned() - .expect("the source record should be present in the result sources"); - BuildHostPackage { - repodata_record, - source: Some(source.manifest_source), - } - } - }) - .collect() - } - /// Returns whether the package should be built in an editable mode. fn editable(&self) -> bool { self.build_profile == BuildProfile::Development && self.manifest_source.is_mutable() @@ -490,12 +463,12 @@ impl SourceBuildSpec { // Request the metadata from the backend. // TODO: Can we somehow cache this metadata? - let outputs = backend + let mut outputs = backend .conda_outputs( CondaOutputsParams { host_platform, build_platform, - variant_configuration: self.variants.clone(), + variant_configuration: self.variant_config.clone(), variant_files: self.variant_files.clone(), work_directory: work_directory.clone(), channels: self.channels.clone(), @@ -509,24 +482,24 @@ impl SourceBuildSpec { .map_err(SourceBuildError::from) .map_err(CommandDispatcherError::Failed)?; - // Find the output that we want to build. - let output = outputs - .outputs - .into_iter() - .find(|output| { - output.metadata.name == self.package.name - && output.metadata.version == self.package.version - && output.metadata.build == self.package.build - && output.metadata.subdir.as_str() == self.package.subdir - }) - .ok_or_else(|| { - CommandDispatcherError::Failed(SourceBuildError::MissingOutput { - subdir: self.package.subdir.clone(), - name: self.package.name.as_normalized().to_string(), - version: self.package.version.to_string(), - build: self.package.build.clone(), - }) - })?; + // Find the output that we want to build by matching name and variants. + let Some(output) = outputs.outputs.iter().position(|output| { + output.metadata.name == self.package_name + && self.package_variant == output.metadata.variant + }) else { + return Err(CommandDispatcherError::Failed( + SourceBuildError::MissingOutput(MissingOutput { + name: self.package_name, + variant: self.package_variant.clone(), + outputs: outputs + .outputs + .into_iter() + .map(|output| (output.metadata.name, output.metadata.variant.into())) + .collect(), + }), + )); + }; + let output = outputs.outputs.swap_remove(output); // Determine final directories for everything. let directories = Directories::new(&work_directory, host_platform); @@ -542,7 +515,7 @@ impl SourceBuildSpec { .unwrap_or_default(); let mut build_records = self .solve_dependencies( - format!("{} (build)", self.package.name.as_source()), + format!("{} (build)", self.package_name.as_source()), &command_dispatcher, build_dependencies.clone(), self.build_environment.to_build_from_build(), @@ -576,7 +549,7 @@ impl SourceBuildSpec { .extend_with_run_exports_from_build(&build_run_exports); let mut host_records = self .solve_dependencies( - format!("{} (host)", self.package.name.as_source()), + format!("{} (host)", self.package_name.as_source()), &command_dispatcher, host_dependencies.clone(), self.build_environment.clone(), @@ -602,8 +575,12 @@ impl SourceBuildSpec { Some( command_dispatcher .install_pixi_environment(InstallPixiEnvironmentSpec { - name: format!("{} (build)", self.package.name.as_source()), - records: build_records.clone(), + name: format!("{} (build)", self.package_name.as_source()), + records: build_records + .iter() + .cloned() + .map(PixiRecord::from) + .collect(), prefix: Prefix::create(&directories.build_prefix) .map_err(SourceBuildError::CreateBuildEnvironmentDirectory) .map_err(CommandDispatcherError::Failed)?, @@ -613,7 +590,7 @@ impl SourceBuildSpec { force_reinstall: Default::default(), channels: self.channels.clone(), channel_config: self.channel_config.clone(), - variants: self.variants.clone(), + variants: self.variant_config.clone(), variant_files: self.variant_files.clone(), enabled_protocols: self.enabled_protocols.clone(), }) @@ -635,8 +612,8 @@ impl SourceBuildSpec { Some( command_dispatcher .install_pixi_environment(InstallPixiEnvironmentSpec { - name: format!("{} (host)", self.package.name.as_source()), - records: host_records.clone(), + name: format!("{} (host)", self.package_name.as_source()), + records: host_records.iter().cloned().map(PixiRecord::from).collect(), prefix: host_prefix_directory, installed: None, ignore_packages: None, @@ -644,7 +621,7 @@ impl SourceBuildSpec { force_reinstall: Default::default(), channels: self.channels.clone(), channel_config: self.channel_config.clone(), - variants: self.variants.clone(), + variants: self.variant_config.clone(), variant_files: self.variant_files.clone(), enabled_protocols: self.enabled_protocols.clone(), }) @@ -702,11 +679,12 @@ impl SourceBuildSpec { .map(|p| p.repodata_record.clone()) .collect(), }, - variant: output.metadata.variant, + variant: output.metadata.variant.into(), output_directory: self.output_directory, }), backend, - package: self.package, + package_name: self.package_name, + platform: output.metadata.subdir, source: self.manifest_source, work_directory, channels: self.channels, @@ -730,13 +708,48 @@ impl SourceBuildSpec { }) } + /// Little helper function the build a `BuildHostPackage` from expected and + /// installed records. + fn extract_prefix_repodata( + records: Vec, + prefix: Option, + ) -> Vec { + let Some(prefix) = prefix else { + return vec![]; + }; + + records + .into_iter() + .map(|record| match record { + PixiPackageRecord::Binary(repodata_record) => BuildHostPackage { + repodata_record, + source: None, + }, + PixiPackageRecord::Source(source) => { + let repodata_record = prefix + .resolved_source_records + .get(&source.source_record.name) + .cloned() + .expect("the source record should be present in the result sources"); + BuildHostPackage { + repodata_record, + source: Some(BuildHostSourcePackage { + source: source.source_record.manifest_source, + package_variant: source.source_record.variants.into(), + }), + } + } + }) + .collect() + } + async fn solve_dependencies( &self, name: String, command_dispatcher: &CommandDispatcher, dependencies: Dependencies, build_environment: BuildEnvironment, - ) -> Result, CommandDispatcherError> { + ) -> Result, CommandDispatcherError> { if dependencies.dependencies.is_empty() { return Ok(vec![]); } @@ -760,7 +773,7 @@ impl SourceBuildSpec { channel_priority: Default::default(), exclude_newer: None, channel_config: self.channel_config.clone(), - variants: self.variants.clone(), + variants: self.variant_config.clone(), variant_files: self.variant_files.clone(), enabled_protocols: self.enabled_protocols.clone(), pin_overrides: BTreeMap::new(), @@ -871,15 +884,8 @@ pub enum SourceBuildError { #[error("failed to install the host environment")] InstallHostEnvironment(#[source] Box), - #[error( - "The build backend does not provide the requested output: {subdir}/{name}={version}={build}." - )] - MissingOutput { - subdir: String, - name: String, - version: String, - build: String, - }, + #[error(transparent)] + MissingOutput(#[from] MissingOutput), #[error( "The build backend returned a path for the build package ({0}), but the path does not exist." @@ -936,3 +942,212 @@ impl From for SourceBuildError { } } } + +#[derive(Debug, thiserror::Error)] +pub struct MissingOutput { + pub name: PackageName, + pub variant: crate::SelectedVariant, + + pub outputs: Vec<(PackageName, crate::SelectedVariant)>, +} + +impl Display for MissingOutput { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "The build backend did not provide the requested output for package '{}' with variant {}\n\n", + self.name.as_normalized(), + self.variant, + )?; + + // Separate outputs into matching name and other packages + let matching_outputs: Vec<_> = self + .outputs + .iter() + .filter(|(name, _)| name == &self.name) + .collect(); + + let other_packages: std::collections::BTreeSet<_> = self + .outputs + .iter() + .filter(|(name, _)| name != &self.name) + .map(|(name, _)| name.as_normalized().to_string()) + .collect(); + + // Show available variants for the matching package name + if !matching_outputs.is_empty() { + writeln!(f, "Available variants for {}:", self.name.as_normalized())?; + for (_, variant) in &matching_outputs { + // Calculate how many variant keys match + let matching_keys = variant + .iter() + .filter(|(key, val)| self.variant.get(key).map(|v| v == *val).unwrap_or(false)) + .count(); + let total_keys = variant.iter().count(); + + write!(f, " - {variant}")?; + if matching_keys > 0 && matching_keys < total_keys { + write!(f, " ← {matching_keys}/{total_keys} keys match")?; + } + writeln!(f)?; + } + } + + // Show other available packages if any + if !other_packages.is_empty() { + if !matching_outputs.is_empty() { + writeln!(f)?; + } + writeln!(f, "Other available packages:")?; + for pkg in &other_packages { + writeln!(f, " - {pkg}")?; + } + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::SelectedVariant; + use rattler_conda_types::PackageName; + + #[test] + fn test_missing_output_with_matching_package_name() { + let requested_name = PackageName::new_unchecked("scipy"); + let requested_variant = SelectedVariant::from([("python", "3.11"), ("blas", "mkl")]); + + let outputs = vec![ + ( + PackageName::new_unchecked("scipy"), + SelectedVariant::from([("python", "3.10"), ("blas", "mkl")]), + ), + ( + PackageName::new_unchecked("scipy"), + SelectedVariant::from([("python", "3.11"), ("blas", "openblas")]), + ), + ( + PackageName::new_unchecked("scipy"), + SelectedVariant::from([("python", "3.12"), ("blas", "mkl")]), + ), + ]; + + let error = MissingOutput { + name: requested_name, + variant: requested_variant, + outputs, + }; + + insta::assert_snapshot!(error.to_string()); + } + + #[test] + fn test_missing_output_with_matching_and_other_packages() { + let requested_name = PackageName::new_unchecked("scipy"); + let requested_variant = SelectedVariant::from([("python", "3.11"), ("blas", "mkl")]); + + let outputs = vec![ + ( + PackageName::new_unchecked("numpy"), + SelectedVariant::from([("python", "3.10")]), + ), + ( + PackageName::new_unchecked("scipy"), + SelectedVariant::from([("python", "3.10"), ("blas", "mkl")]), + ), + ( + PackageName::new_unchecked("scipy"), + SelectedVariant::from([("python", "3.11"), ("blas", "openblas")]), + ), + ( + PackageName::new_unchecked("tensorflow"), + SelectedVariant::from([("cuda", "12.0")]), + ), + ]; + + let error = MissingOutput { + name: requested_name, + variant: requested_variant, + outputs, + }; + + insta::assert_snapshot!(error.to_string()); + } + + #[test] + fn test_missing_output_no_matching_package() { + let requested_name = PackageName::new_unchecked("scipy"); + let requested_variant = SelectedVariant::from([("python", "3.11")]); + + let outputs = vec![ + ( + PackageName::new_unchecked("numpy"), + SelectedVariant::from([("python", "3.11")]), + ), + ( + PackageName::new_unchecked("tensorflow"), + SelectedVariant::from([("cuda", "12.0")]), + ), + ]; + + let error = MissingOutput { + name: requested_name, + variant: requested_variant, + outputs, + }; + + insta::assert_snapshot!(error.to_string()); + } + + #[test] + fn test_missing_output_empty_variant() { + let requested_name = PackageName::new_unchecked("scipy"); + let requested_variant = SelectedVariant::default(); + + let outputs = vec![ + ( + PackageName::new_unchecked("scipy"), + SelectedVariant::from([("python", "3.10")]), + ), + ( + PackageName::new_unchecked("scipy"), + SelectedVariant::from([("python", "3.11")]), + ), + ]; + + let error = MissingOutput { + name: requested_name, + variant: requested_variant, + outputs, + }; + + insta::assert_snapshot!(error.to_string()); + } + + #[test] + fn test_missing_output_single_variant_key() { + let requested_name = PackageName::new_unchecked("numpy"); + let requested_variant = SelectedVariant::from([("python", "3.12")]); + + let outputs = vec![ + ( + PackageName::new_unchecked("numpy"), + SelectedVariant::from([("python", "3.10")]), + ), + ( + PackageName::new_unchecked("numpy"), + SelectedVariant::from([("python", "3.11")]), + ), + ]; + + let error = MissingOutput { + name: requested_name, + variant: requested_variant, + outputs, + }; + + insta::assert_snapshot!(error.to_string()); + } +} diff --git a/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_empty_variant.snap b/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_empty_variant.snap new file mode 100644 index 0000000000..b9fc44d9f7 --- /dev/null +++ b/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_empty_variant.snap @@ -0,0 +1,9 @@ +--- +source: crates/pixi_command_dispatcher/src/source_build/mod.rs +expression: error.to_string() +--- +The build backend did not provide the requested output for package 'scipy' with variant { } + +Available variants for scipy: + - {"python":"3.10"} + - {"python":"3.11"} diff --git a/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_no_matching_package.snap b/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_no_matching_package.snap new file mode 100644 index 0000000000..4669f4fcda --- /dev/null +++ b/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_no_matching_package.snap @@ -0,0 +1,9 @@ +--- +source: crates/pixi_command_dispatcher/src/source_build/mod.rs +expression: error.to_string() +--- +The build backend did not provide the requested output for package 'scipy' with variant {"python":"3.11"} + +Other available packages: + - numpy + - tensorflow diff --git a/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_single_variant_key.snap b/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_single_variant_key.snap new file mode 100644 index 0000000000..e1b7d7dc9f --- /dev/null +++ b/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_single_variant_key.snap @@ -0,0 +1,9 @@ +--- +source: crates/pixi_command_dispatcher/src/source_build/mod.rs +expression: error.to_string() +--- +The build backend did not provide the requested output for package 'numpy' with variant {"python":"3.12"} + +Available variants for numpy: + - {"python":"3.10"} + - {"python":"3.11"} diff --git a/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_with_matching_and_other_packages.snap b/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_with_matching_and_other_packages.snap new file mode 100644 index 0000000000..943e70fa72 --- /dev/null +++ b/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_with_matching_and_other_packages.snap @@ -0,0 +1,13 @@ +--- +source: crates/pixi_command_dispatcher/src/source_build/mod.rs +expression: error.to_string() +--- +The build backend did not provide the requested output for package 'scipy' with variant {"blas":"mkl","python":"3.11"} + +Available variants for scipy: + - {"blas":"mkl","python":"3.10"} ← 1/2 keys match + - {"blas":"openblas","python":"3.11"} ← 1/2 keys match + +Other available packages: + - numpy + - tensorflow diff --git a/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_with_matching_package_name.snap b/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_with_matching_package_name.snap new file mode 100644 index 0000000000..7d88a11eeb --- /dev/null +++ b/crates/pixi_command_dispatcher/src/source_build/snapshots/pixi_command_dispatcher__source_build__tests__missing_output_with_matching_package_name.snap @@ -0,0 +1,10 @@ +--- +source: crates/pixi_command_dispatcher/src/source_build/mod.rs +expression: error.to_string() +--- +The build backend did not provide the requested output for package 'scipy' with variant {"blas":"mkl","python":"3.11"} + +Available variants for scipy: + - {"blas":"mkl","python":"3.10"} ← 1/2 keys match + - {"blas":"openblas","python":"3.11"} ← 1/2 keys match + - {"blas":"mkl","python":"3.12"} ← 1/2 keys match diff --git a/crates/pixi_command_dispatcher/src/source_build_cache_status/mod.rs b/crates/pixi_command_dispatcher/src/source_build_cache_status/mod.rs index 544d7f80ff..05ce9a4e43 100644 --- a/crates/pixi_command_dispatcher/src/source_build_cache_status/mod.rs +++ b/crates/pixi_command_dispatcher/src/source_build_cache_status/mod.rs @@ -12,7 +12,7 @@ use tracing::instrument; use crate::{ BuildEnvironment, CommandDispatcher, CommandDispatcherError, CommandDispatcherErrorResultExt, - PackageIdentifier, SourceCheckoutError, + SourceCheckoutError, build::{ BuildCacheEntry, BuildCacheError, BuildInput, CachedBuild, PackageBuildInputHashBuilder, }, @@ -31,8 +31,11 @@ use crate::{ /// 2. A build dependency changed. #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub struct SourceBuildCacheStatusSpec { - /// Describes the package to query in the source build cache. - pub package: PackageIdentifier, + /// The name of the package to query in the source build cache. + pub package_name: rattler_conda_types::PackageName, + + /// The specific variant of the package to query (from the lock file) + pub package_variant: crate::SelectedVariant, /// Describes the source location of the package to query. pub source: PinnedSourceSpec, @@ -117,7 +120,7 @@ pub struct SourceBuildCacheEntry { impl SourceBuildCacheStatusSpec { /// Creates a new query for the source build cache. - #[instrument(skip_all, fields(package = %self.package, source = %self.source))] + #[instrument(skip_all, fields(package = %self.package_name.as_source(), source = %self.source))] pub async fn query( self, command_dispatcher: CommandDispatcher, @@ -125,10 +128,8 @@ impl SourceBuildCacheStatusSpec { // Query the build cache directly. let build_input = BuildInput { channel_urls: self.channels.clone(), - name: self.package.name.as_source().to_string(), - version: self.package.version.to_string(), - build: self.package.build.to_string(), - subdir: self.package.subdir.clone(), + name: self.package_name.as_source().to_string(), + package_variant: self.package_variant.clone(), host_platform: self.build_environment.host_platform, host_virtual_packages: self.build_environment.host_virtual_packages.clone(), build_virtual_packages: self.build_environment.build_virtual_packages.clone(), @@ -143,7 +144,7 @@ impl SourceBuildCacheStatusSpec { // Check the staleness of the cached entry tracing::debug!( "determining cache status for package '{}' from source build cache", - self.package, + self.package_name.as_source(), ); let cached_build = match cached_build { Some(cached_build) => { @@ -155,7 +156,7 @@ impl SourceBuildCacheStatusSpec { tracing::debug!( "status of cached build for package '{}' is '{}'", - self.package, + self.package_name.as_source(), &cached_build ); @@ -235,13 +236,12 @@ impl SourceBuildCacheStatusSpec { continue; }; - let identifier = PackageIdentifier::from(&dep.repodata_record.package_record); - // Check the build cache to see if the source of that package is still fresh. match command_dispatcher .source_build_cache_status(SourceBuildCacheStatusSpec { - package: identifier.clone(), - source: source.clone(), + source: source.source.clone(), + package_name: dep.repodata_record.package_record.name.clone(), + package_variant: source.package_variant.clone(), channels: self.channels.clone(), build_environment: self.build_environment.clone(), channel_config: self.channel_config.clone(), @@ -264,6 +264,7 @@ impl SourceBuildCacheStatusSpec { CachedBuildStatus::Missing | CachedBuildStatus::Stale(_) => { tracing::debug!( "package is stale because its build dependency '{identifier}' is missing or stale", + identifier = &source ); return Ok(CachedBuildStatus::Stale(cached_build)); } @@ -279,6 +280,7 @@ impl SourceBuildCacheStatusSpec { { tracing::debug!( "package is stale because its build dependency '{identifier}' has changed", + identifier = &source ); return Ok(CachedBuildStatus::Stale(cached_build)); } diff --git a/crates/pixi_command_dispatcher/src/source_metadata/mod.rs b/crates/pixi_command_dispatcher/src/source_metadata/mod.rs index cc6d01cfe0..0ca2a14643 100644 --- a/crates/pixi_command_dispatcher/src/source_metadata/mod.rs +++ b/crates/pixi_command_dispatcher/src/source_metadata/mod.rs @@ -10,12 +10,13 @@ use futures::TryStreamExt; use itertools::{Either, Itertools}; use miette::Diagnostic; use pixi_build_types::procedures::conda_outputs::CondaOutput; -use pixi_record::{InputHash, PinnedSourceSpec, PixiRecord, SourceRecord}; +use pixi_record::{ + InputHash, PinnedSourceSpec, PixiPackageRecord, SourcePackageRecord, SourceRecord, +}; use pixi_spec::{BinarySpec, PixiSpec, SourceAnchor, SourceSpec, SpecConversionError}; use pixi_spec_containers::DependencyMap; use rattler_conda_types::{ - ChannelConfig, InvalidPackageNameError, MatchSpec, PackageName, PackageRecord, - package::RunExportsJson, + ChannelConfig, InvalidPackageNameError, MatchSpec, PackageName, package::RunExportsJson, }; use rattler_repodata_gateway::{RunExportExtractorError, RunExportsReporter}; use thiserror::Error; @@ -25,10 +26,7 @@ use crate::{ BuildBackendMetadataError, BuildBackendMetadataSpec, BuildEnvironment, CommandDispatcher, CommandDispatcherError, CommandDispatcherErrorResultExt, PixiEnvironmentSpec, SolvePixiEnvironmentError, - build::{ - Dependencies, DependenciesError, PixiRunExports, conversion, - source_metadata_cache::MetadataKind, - }, + build::{Dependencies, DependenciesError, PixiRunExports}, executor::ExecutorFutures, }; @@ -52,8 +50,8 @@ pub struct SourceMetadata { /// this is used mainly for out-of-tree builds pub build_source: Option, - /// All the source records for this particular package. - pub records: Vec, + /// All the source records with metadata for this particular package. + pub records: Vec, /// All package names that where skipped but the backend could provide. pub skipped_packages: Vec, @@ -82,51 +80,30 @@ impl SourceMetadataSpec { let build_backend_metadata = build_backend_metadata?; - match &build_backend_metadata.metadata.metadata { - MetadataKind::GetMetadata { packages } => { - // Convert the metadata to source records. - let records = conversion::package_metadata_to_source_records( - &build_backend_metadata.manifest_source, - build_backend_metadata.build_source.as_ref(), - packages, - &self.package, - &build_backend_metadata.metadata.input_hash, - ); - - Ok(SourceMetadata { - manifest_source: build_backend_metadata.manifest_source.clone(), - records, - // As the GetMetadata kind returns all records at once and we don't solve them we can skip this. - skipped_packages: Default::default(), - build_source: build_backend_metadata.build_source.clone(), - }) - } - MetadataKind::Outputs { outputs } => { - let mut skipped_packages = vec![]; - let mut futures = ExecutorFutures::new(command_dispatcher.executor()); - for output in outputs { - if output.metadata.name != self.package { - skipped_packages.push(output.metadata.name.clone()); - continue; - } - futures.push(self.resolve_output( - &command_dispatcher, - output, - build_backend_metadata.metadata.input_hash.clone(), - build_backend_metadata.manifest_source.clone(), - build_backend_metadata.build_source.clone(), - reporter.clone(), - )); - } - - Ok(SourceMetadata { - manifest_source: build_backend_metadata.manifest_source.clone(), - records: futures.try_collect().await?, - skipped_packages, - build_source: build_backend_metadata.build_source.clone(), - }) + let outputs = &build_backend_metadata.metadata.outputs; + let mut skipped_packages = vec![]; + let mut futures = ExecutorFutures::new(command_dispatcher.executor()); + for output in outputs { + if output.metadata.name != self.package { + skipped_packages.push(output.metadata.name.clone()); + continue; } + futures.push(self.resolve_output( + &command_dispatcher, + output, + build_backend_metadata.metadata.input_hash.clone(), + build_backend_metadata.manifest_source.clone(), + build_backend_metadata.build_source.clone(), + reporter.clone(), + )); } + + Ok(SourceMetadata { + manifest_source: build_backend_metadata.manifest_source.clone(), + build_source: build_backend_metadata.build_source.clone(), + records: futures.try_collect().await?, + skipped_packages, + }) } async fn resolve_output( @@ -137,7 +114,7 @@ impl SourceMetadataSpec { manifest_source: PinnedSourceSpec, build_source: Option, reporter: Option>, - ) -> Result> { + ) -> Result> { let source_anchor = SourceAnchor::from(SourceSpec::from(manifest_source.clone())); // Solve the build environment for the output. @@ -300,66 +277,65 @@ impl SourceMetadataSpec { strong_constrains: binary_specs_to_match_spec(run_exports.strong_constrains)?, }; - Ok(SourceRecord { - package_record: PackageRecord { - // We cannot now these values from the metadata because no actual package - // was built yet. - size: None, - sha256: None, - md5: None, - - // TODO(baszalmstra): Decide if it makes sense to include the current - // timestamp here. - timestamp: None, - - // These values are derived from the build backend values. - platform: output - .metadata - .subdir - .only_platform() - .map(ToString::to_string), - arch: output - .metadata - .subdir - .arch() - .as_ref() - .map(ToString::to_string), - - // These values are passed by the build backend + Ok(SourcePackageRecord { + source_record: SourceRecord { name: output.metadata.name.clone(), - build: output.metadata.build.clone(), - version: output.metadata.version.clone(), - build_number: output.metadata.build_number, - license: output.metadata.license.clone(), - subdir: output.metadata.subdir.to_string(), - license_family: output.metadata.license_family.clone(), - noarch: output.metadata.noarch, - constrains, + version: if manifest_source.is_immutable() { + // Only record the version if the source code is immutable. + Some(output.metadata.version.clone()) + } else { + None + }, + build_source, + manifest_source, + variants: output + .metadata + .variant + .iter() + .map(|(k, v)| (k.clone(), crate::VariantValue::from(v.clone()).into())) + .collect(), depends, - run_exports: Some(run_exports), + constrains, + experimental_extra_depends: Default::default(), + license: output.metadata.license.clone(), purls: output .metadata .purls .as_ref() .map(|purls| purls.iter().cloned().collect()), + input_hash, + sources: sources + .into_iter() + .map(|(name, source)| (name.as_source().to_string(), source)) + .collect(), python_site_packages_path: output.metadata.python_site_packages_path.clone(), - - // These are deprecated and no longer used. - features: None, - track_features: vec![], - legacy_bz2_md5: None, - legacy_bz2_size: None, - - // These are not important at this point. - experimental_extra_depends: Default::default(), }, - manifest_source, - input_hash, - build_source, - sources: sources - .into_iter() - .map(|(name, source)| (name.as_source().to_string(), source)) - .collect(), + version: output.metadata.version.clone(), + build: output.metadata.build.clone(), + build_number: output.metadata.build_number, + subdir: output.metadata.subdir.to_string(), + arch: output + .metadata + .subdir + .arch() + .as_ref() + .map(ToString::to_string), + platform: output + .metadata + .subdir + .only_platform() + .map(ToString::to_string), + md5: None, + sha256: None, + size: None, + track_features: vec![], + features: None, + license_family: output.metadata.license_family.clone(), + timestamp: None, + run_exports: Some(run_exports), + noarch: output.metadata.noarch, + legacy_bz2_md5: None, + legacy_bz2_size: None, }) } @@ -370,7 +346,7 @@ impl SourceMetadataSpec { command_dispatcher: &CommandDispatcher, dependencies: Dependencies, build_environment: BuildEnvironment, - ) -> Result, CommandDispatcherError> { + ) -> Result, CommandDispatcherError> { if dependencies.dependencies.is_empty() { return Ok(vec![]); } diff --git a/crates/pixi_command_dispatcher/src/variant.rs b/crates/pixi_command_dispatcher/src/variant.rs new file mode 100644 index 0000000000..f7b1c3165a --- /dev/null +++ b/crates/pixi_command_dispatcher/src/variant.rs @@ -0,0 +1,206 @@ +use std::fmt::Display; +use std::{cmp::Ordering, collections::BTreeMap}; + +use serde::{Deserialize, Serialize}; + +/// A collection of key-value pairs representing selected conda-build variants for a package. +#[derive(Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(transparent)] +pub struct SelectedVariant(pub BTreeMap); + +impl, V: Into, I: IntoIterator> From + for SelectedVariant +{ + fn from(iter: I) -> Self { + Self( + iter.into_iter() + .map(|(k, v)| (k.into(), v.into())) + .collect(), + ) + } +} + +impl> From for BTreeMap { + fn from(selected: SelectedVariant) -> Self { + selected + .0 + .into_iter() + .map(|(k, v)| (k, V::from(v))) + .collect() + } +} + +impl SelectedVariant { + pub fn iter(&self) -> impl Iterator { + self.0.iter() + } + + pub fn get(&self, key: &str) -> Option<&VariantValue> { + self.0.get(key) + } +} + +impl PartialEq> for SelectedVariant { + fn eq(&self, other: &BTreeMap) -> bool { + if self.0.len() != other.len() { + return false; + } + for (key, value) in &self.0 { + match other.get(key) { + Some(other_value) if value == other_value => continue, + _ => return false, + } + } + true + } +} + +impl std::fmt::Debug for SelectedVariant { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_map().entries(self.0.iter()).finish() + } +} + +impl std::fmt::Display for SelectedVariant { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.0.is_empty() { + write!(f, "{{ }}") + } else { + let str = serde_json::to_string(&self.0).unwrap_or_default(); + write!(f, "{str}") + } + } +} + +/// +/// Variants are used in conda-build to specify different build configurations. +/// They can be strings (e.g., "3.11" for python version), integers (e.g., 1 for feature flags), +/// or booleans (e.g., true/false for optional features). +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[serde(untagged)] +pub enum VariantValue { + /// String variant value (most common, e.g., python version "3.11") + String(String), + /// Integer variant value (e.g., for numeric feature flags) + Int(i64), + /// Boolean variant value (e.g., for on/off features) + Bool(bool), +} + +impl PartialOrd for VariantValue { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for VariantValue { + fn cmp(&self, other: &Self) -> Ordering { + #[allow(clippy::match_same_arms)] + match (self, other) { + (VariantValue::String(a), VariantValue::String(b)) => a.cmp(b), + (VariantValue::Int(a), VariantValue::Int(b)) => a.cmp(b), + (VariantValue::Bool(a), VariantValue::Bool(b)) => a.cmp(b), + // Define ordering between different types for deterministic sorting + (VariantValue::String(_), _) => Ordering::Less, + (_, VariantValue::String(_)) => Ordering::Greater, + (VariantValue::Int(_), VariantValue::Bool(_)) => Ordering::Less, + (VariantValue::Bool(_), VariantValue::Int(_)) => Ordering::Greater, + } + } +} + +impl Display for VariantValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + VariantValue::String(s) => write!(f, "{s}"), + VariantValue::Int(i) => write!(f, "{i}"), + VariantValue::Bool(b) => write!(f, "{b}"), + } + } +} + +impl From for VariantValue { + fn from(value: bool) -> Self { + VariantValue::Bool(value) + } +} + +impl From for VariantValue { + fn from(value: i64) -> Self { + VariantValue::Int(value) + } +} + +impl From for VariantValue { + fn from(value: String) -> Self { + VariantValue::String(value) + } +} + +impl From<&str> for VariantValue { + fn from(value: &str) -> Self { + VariantValue::String(value.to_string()) + } +} + +impl From for VariantValue { + fn from(value: pixi_build_types::VariantValue) -> Self { + match value { + pixi_build_types::VariantValue::String(s) => VariantValue::String(s), + pixi_build_types::VariantValue::Int(i) => VariantValue::Int(i), + pixi_build_types::VariantValue::Bool(b) => VariantValue::Bool(b), + } + } +} + +impl From for pixi_build_types::VariantValue { + fn from(value: VariantValue) -> Self { + match value { + VariantValue::String(s) => Self::String(s), + VariantValue::Int(i) => Self::Int(i), + VariantValue::Bool(b) => Self::Bool(b), + } + } +} + +impl From for pixi_record::VariantValue { + fn from(value: VariantValue) -> Self { + match value { + VariantValue::String(s) => pixi_record::VariantValue::String(s), + VariantValue::Int(i) => pixi_record::VariantValue::Int(i), + VariantValue::Bool(b) => pixi_record::VariantValue::Bool(b), + } + } +} + +impl From for VariantValue { + fn from(value: pixi_record::VariantValue) -> Self { + match value { + pixi_record::VariantValue::String(s) => Self::String(s), + pixi_record::VariantValue::Int(i) => Self::Int(i), + pixi_record::VariantValue::Bool(b) => Self::Bool(b), + } + } +} + +impl PartialEq for VariantValue { + fn eq(&self, other: &pixi_build_types::VariantValue) -> bool { + match (self, other) { + (VariantValue::String(a), pixi_build_types::VariantValue::String(b)) => a == b, + (VariantValue::Int(a), pixi_build_types::VariantValue::Int(b)) => a == b, + (VariantValue::Bool(a), pixi_build_types::VariantValue::Bool(b)) => a == b, + _ => false, + } + } +} + +impl PartialEq for VariantValue { + fn eq(&self, other: &pixi_record::VariantValue) -> bool { + match (self, other) { + (VariantValue::String(a), pixi_record::VariantValue::String(b)) => a == b, + (VariantValue::Int(a), pixi_record::VariantValue::Int(b)) => a == b, + (VariantValue::Bool(a), pixi_record::VariantValue::Bool(b)) => a == b, + _ => false, + } + } +} diff --git a/crates/pixi_command_dispatcher/tests/integration/event_reporter.rs b/crates/pixi_command_dispatcher/tests/integration/event_reporter.rs index dd79ad6fdd..12efb75a3a 100644 --- a/crates/pixi_command_dispatcher/tests/integration/event_reporter.rs +++ b/crates/pixi_command_dispatcher/tests/integration/event_reporter.rs @@ -6,9 +6,9 @@ use std::{ use futures::{Stream, StreamExt}; use pixi_command_dispatcher::{ BackendSourceBuildSpec, BuildBackendMetadataSpec, CondaSolveReporter, GitCheckoutReporter, - InstallPixiEnvironmentSpec, InstantiateToolEnvironmentSpec, PackageIdentifier, - PixiEnvironmentSpec, PixiInstallReporter, PixiSolveReporter, Reporter, ReporterContext, - SolveCondaEnvironmentSpec, SourceBuildSpec, SourceMetadataSpec, + InstallPixiEnvironmentSpec, InstantiateToolEnvironmentSpec, PixiEnvironmentSpec, + PixiInstallReporter, PixiSolveReporter, Reporter, ReporterContext, SolveCondaEnvironmentSpec, + SourceBuildSpec, SourceMetadataSpec, reporter::{ BackendSourceBuildId, BackendSourceBuildReporter, BuildBackendMetadataId, BuildBackendMetadataReporter, CondaSolveId, GitCheckoutId, InstantiateToolEnvId, @@ -125,7 +125,7 @@ pub enum Event { id: BackendSourceBuildId, #[serde(skip_serializing_if = "Option::is_none")] context: Option, - package: PackageIdentifier, + package_name: rattler_conda_types::PackageName, }, BackendSourceBuildStarted { id: BackendSourceBuildId, @@ -524,7 +524,7 @@ impl BackendSourceBuildReporter for EventReporter { let event = Event::BackendSourceBuildQueued { id: next_id, context, - package: spec.package.clone(), + package_name: spec.package_name.clone(), }; eprintln!("{}", serde_json::to_string_pretty(&event).unwrap()); self.events.push(event); diff --git a/crates/pixi_command_dispatcher/tests/integration/event_tree.rs b/crates/pixi_command_dispatcher/tests/integration/event_tree.rs index 234df1521a..43e2f9454a 100644 --- a/crates/pixi_command_dispatcher/tests/integration/event_tree.rs +++ b/crates/pixi_command_dispatcher/tests/integration/event_tree.rs @@ -164,7 +164,7 @@ impl EventTree { *id, format!( "{} @ {}", - spec.package.name.as_source(), + spec.package_name.as_source(), spec.manifest_source ), ); @@ -179,10 +179,10 @@ impl EventTree { Event::SourceBuildFinished { .. } => {} Event::BackendSourceBuildQueued { id, - package, + package_name, context, } => { - backend_source_build_labels.insert(*id, package.name.as_source().to_owned()); + backend_source_build_labels.insert(*id, package_name.as_source().to_owned()); builder.set_event_parent((*id).into(), *context); } Event::BackendSourceBuildStarted { id } => { diff --git a/crates/pixi_command_dispatcher/tests/integration/main.rs b/crates/pixi_command_dispatcher/tests/integration/main.rs index 6d016344ad..0ddbcc8419 100644 --- a/crates/pixi_command_dispatcher/tests/integration/main.rs +++ b/crates/pixi_command_dispatcher/tests/integration/main.rs @@ -14,11 +14,11 @@ use pixi_build_backend_passthrough::PassthroughBackend; use pixi_build_frontend::{BackendOverride, InMemoryOverriddenBackends}; use pixi_command_dispatcher::{ BuildEnvironment, CacheDirs, CommandDispatcher, Executor, InstallPixiEnvironmentSpec, - InstantiateToolEnvironmentSpec, PackageIdentifier, PixiEnvironmentSpec, + InstantiateToolEnvironmentSpec, PackageIdentifier, PixiEnvironmentSpec, SelectedVariant, SourceBuildCacheStatusSpec, }; use pixi_config::default_channel_config; -use pixi_record::PinnedPathSpec; +use pixi_record::{PinnedPathSpec, PixiRecord}; use pixi_spec::{GitReference, GitSpec, PathSpec, PixiSpec}; use pixi_spec_containers::DependencyMap; use pixi_test_utils::format_diagnostic; @@ -112,10 +112,10 @@ pub async fn simple_test() { .await .unwrap(); - dispatcher + if let Err(err) = dispatcher .install_pixi_environment(InstallPixiEnvironmentSpec { name: "test-env".to_owned(), - records: records.clone(), + records: records.iter().cloned().map(PixiRecord::from).collect(), prefix: Prefix::create(&prefix_dir).unwrap(), installed: None, build_environment: build_env, @@ -132,7 +132,9 @@ pub async fn simple_test() { enabled_protocols: Default::default(), }) .await - .unwrap(); + { + panic!("{}", format_diagnostic(&err)) + } println!( "Built the environment successfully: {}", @@ -492,8 +494,8 @@ pub async fn test_stale_host_dependency_triggers_rebuild() { let rebuild_packages = second_events .iter() .filter_map(|event| match event { - event_reporter::Event::BackendSourceBuildQueued { package, .. } => { - Some(package.name.as_normalized()) + event_reporter::Event::BackendSourceBuildQueued { package_name, .. } => { + Some(package_name.as_normalized()) } _ => None, }) @@ -562,7 +564,8 @@ async fn source_build_cache_status_clear_works() { }; let spec = SourceBuildCacheStatusSpec { - package: pkg, + package_name: pkg.name, + package_variant: SelectedVariant::default(), source: PinnedPathSpec { path: tmp_dir.path().to_string_lossy().into_owned().into(), } @@ -690,8 +693,8 @@ pub async fn test_force_rebuild() { let rebuild_packages = second_events .iter() .filter_map(|event| match event { - event_reporter::Event::BackendSourceBuildQueued { package, .. } => { - Some(package.name.as_normalized()) + event_reporter::Event::BackendSourceBuildQueued { package_name, .. } => { + Some(package_name.as_normalized()) } _ => None, }) @@ -722,8 +725,8 @@ pub async fn test_force_rebuild() { let rebuild_packages = second_events .iter() .filter_map(|event| match event { - event_reporter::Event::BackendSourceBuildQueued { package, .. } => { - Some(package.name.as_normalized()) + event_reporter::Event::BackendSourceBuildQueued { package_name, .. } => { + Some(package_name.as_normalized()) } _ => None, }) @@ -750,8 +753,8 @@ pub async fn test_force_rebuild() { let rebuild_packages = last_events .iter() .filter_map(|event| match event { - event_reporter::Event::BackendSourceBuildQueued { package, .. } => { - Some(package.name.as_normalized()) + event_reporter::Event::BackendSourceBuildQueued { package_name, .. } => { + Some(package_name.as_normalized()) } _ => None, }) diff --git a/crates/pixi_core/src/environment/mod.rs b/crates/pixi_core/src/environment/mod.rs index 97ca8ee247..a751b3c10d 100644 --- a/crates/pixi_core/src/environment/mod.rs +++ b/crates/pixi_core/src/environment/mod.rs @@ -15,7 +15,7 @@ pub use pixi_python_status::PythonStatus; use pixi_spec::{GitSpec, PixiSpec}; use pixi_utils::{prefix::Prefix, rlimit::try_increase_rlimit_to_sensible}; use rattler_conda_types::Platform; -use rattler_lock::{LockFile, LockedPackageRef}; +use rattler_lock::{CondaPackageData, LockFile, LockedPackageRef}; use serde::{Deserialize, Serialize}; use std::collections::HashSet; use std::fmt::{Display, Formatter}; @@ -183,13 +183,18 @@ impl LockedEnvironmentHash { match package { // A select set of fields are used to hash the package - LockedPackageRef::Conda(pack) => { - if let Some(sha) = pack.record().sha256 { + LockedPackageRef::Conda(CondaPackageData::Binary(data)) => { + if let Some(sha) = data.package_record.sha256 { sha.hash(&mut hasher); - } else if let Some(md5) = pack.record().md5 { + } else if let Some(md5) = data.package_record.md5 { md5.hash(&mut hasher); } } + LockedPackageRef::Conda(CondaPackageData::Source(data)) => { + data.location.hash(&mut hasher); + data.variants.hash(&mut hasher); + data.name.hash(&mut hasher); + } LockedPackageRef::Pypi(pack, env) => { pack.editable.hash(&mut hasher); env.extras.hash(&mut hasher); diff --git a/crates/pixi_core/src/lock_file/install_subset.rs b/crates/pixi_core/src/lock_file/install_subset.rs index 03cee92865..e5870a57ec 100644 --- a/crates/pixi_core/src/lock_file/install_subset.rs +++ b/crates/pixi_core/src/lock_file/install_subset.rs @@ -1,5 +1,6 @@ use itertools::Itertools; use miette::Diagnostic; +use pixi_record::{ParseLockFileError, PixiRecord}; use rattler_lock::LockedPackageRef; use std::collections::{HashMap, HashSet, VecDeque}; @@ -29,24 +30,18 @@ struct PackageNode { pub source: PackageSource, } -impl<'a> From> for PackageNode { +impl<'a> TryFrom> for PackageNode { + type Error = ParseLockFileError; /// Convert a LockedPackageRef to a PackageNode for efficient processing. - fn from(package_ref: LockedPackageRef<'a>) -> Self { + fn try_from(package_ref: LockedPackageRef<'a>) -> Result { let name = package_ref.name().to_string(); let dependency_names: Vec = match package_ref { LockedPackageRef::Conda(conda_data) => { + let pixi_record = PixiRecord::try_from(conda_data.clone())?; // Extract dependencies from conda data and parse as MatchSpec - let depends = match conda_data { - rattler_lock::CondaPackageData::Binary(binary_data) => { - &binary_data.package_record.depends - } - rattler_lock::CondaPackageData::Source(source_data) => { - &source_data.package_record.depends - } - }; - - depends + pixi_record + .depends() .iter() .filter_map(|dep_spec| { // Parse as MatchSpec to get the package name @@ -67,14 +62,14 @@ impl<'a> From> for PackageNode { } }; - PackageNode { + Ok(PackageNode { name, dependencies: dependency_names, source: match package_ref { LockedPackageRef::Conda(_) => PackageSource::Conda, LockedPackageRef::Pypi(_, _) => PackageSource::Pypi, }, - } + }) } } @@ -112,6 +107,9 @@ pub enum InstallSubsetError { #[error("the following `--only` packages do not exist: {}", .0.iter().map(|s| format!("'{s}'")).join(", "))] #[diagnostic(help("try finding the correct package with `pixi list`"))] TargetPackagesDoNotExist(Vec), + + #[error(transparent)] + ParseLockFile(#[from] ParseLockFileError), } impl<'a> InstallSubset<'a> { @@ -168,7 +166,7 @@ impl<'a> InstallSubset<'a> { let filtered_packages = if !self.target_packages.is_empty() { // Target mode: Collect targets + dependencies with skip short-circuiting - let reach = Self::build_reachability(&all_packages); + let reach = Self::build_reachability(&all_packages)?; let required = reach.collect_targets_dependencies( self.target_packages, // This is the stop set, because we just short-circuit getting dependencies @@ -191,7 +189,7 @@ impl<'a> InstallSubset<'a> { FilteredPackages::new(to_process, to_ignore) } else { // Skip mode: Apply stop/passthrough rules from original roots - self.filter_with_skips(&all_packages) + self.filter_with_skips(&all_packages)? }; Ok(filtered_packages) @@ -202,16 +200,16 @@ impl<'a> InstallSubset<'a> { fn filter_with_skips<'lock>( &self, all_packages: &[LockedPackageRef<'lock>], - ) -> FilteredPackages<'lock> { + ) -> Result, InstallSubsetError> { if self.skip_with_deps.is_empty() && self.skip_direct.is_empty() { - return FilteredPackages::new(all_packages.to_vec(), Vec::new()); + return Ok(FilteredPackages::new(all_packages.to_vec(), Vec::new())); } // Compute the set of package names that remain required when the skip // packages are removed. We do this by walking the dependency graph // starting from every non-skipped package and never traversing through // skipped packages. - let reach = Self::build_reachability(all_packages); + let reach = Self::build_reachability(all_packages)?; let kept = reach.collect_reachable_from_non_skipped(self.skip_with_deps, self.skip_direct); let to_process: Vec<_> = all_packages .iter() @@ -223,13 +221,19 @@ impl<'a> InstallSubset<'a> { .filter(|pkg| !kept.contains(pkg.name())) .copied() .collect(); - FilteredPackages::new(to_process, to_ignore) + Ok(FilteredPackages::new(to_process, to_ignore)) } /// Build a reachability analyzer for a set of packages. - fn build_reachability(all_packages: &[LockedPackageRef<'_>]) -> PackageReachability { - let nodes: Vec = all_packages.iter().copied().map(Into::into).collect(); - PackageReachability::new(nodes) + fn build_reachability( + all_packages: &[LockedPackageRef<'_>], + ) -> Result { + let nodes: Vec = all_packages + .iter() + .copied() + .map(PackageNode::try_from) + .collect::, _>>()?; + Ok(PackageReachability::new(nodes)) } } diff --git a/crates/pixi_core/src/lock_file/outdated.rs b/crates/pixi_core/src/lock_file/outdated.rs index fd2de51405..560665d565 100644 --- a/crates/pixi_core/src/lock_file/outdated.rs +++ b/crates/pixi_core/src/lock_file/outdated.rs @@ -263,6 +263,26 @@ async fn find_unsatisfiable_targets<'p>( .insert(platform); } } + + if lock_file.version() < rattler_lock::FileFormatVersion::V7 + && locked_environment + .packages(platform) + .into_iter() + .flatten() + .any(|p| p.as_source_conda().is_some()) + { + tracing::info!( + "environment '{0}' for platform {platform} is out of date because the lock-file contains source packages in an old specification (v{1}) which is not longer supported", + environment.name().fancy_display(), + lock_file.version() + ); + + unsatisfiable_targets + .outdated_conda + .entry(environment.clone()) + .or_default() + .insert(platform); + } } } @@ -415,18 +435,16 @@ fn find_inconsistent_solve_groups<'p>( for package in locked_env.packages(platform).into_iter().flatten() { match package { - LockedPackageRef::Conda(pkg) => { - match conda_packages_by_name.get(&pkg.record().name) { - None => { - conda_packages_by_name - .insert(pkg.record().name.clone(), pkg.location().clone()); - } - Some(url) if pkg.location() != url => { - conda_package_mismatch = true; - } - _ => {} + LockedPackageRef::Conda(pkg) => match conda_packages_by_name.get(pkg.name()) { + None => { + conda_packages_by_name + .insert(pkg.name().clone(), pkg.location().clone()); } - } + Some(url) if pkg.location() != url => { + conda_package_mismatch = true; + } + _ => {} + }, LockedPackageRef::Pypi(pkg, _) => match pypi_packages_by_name.get(&pkg.name) { None => { pypi_packages_by_name.insert(pkg.name.clone(), pkg.location.clone()); diff --git a/crates/pixi_core/src/lock_file/records_by_name.rs b/crates/pixi_core/src/lock_file/records_by_name.rs index cbd0c0cd41..f9dd7b1a1d 100644 --- a/crates/pixi_core/src/lock_file/records_by_name.rs +++ b/crates/pixi_core/src/lock_file/records_by_name.rs @@ -1,9 +1,9 @@ use super::package_identifier::ConversionError; use crate::lock_file::{PypiPackageIdentifier, PypiRecord}; -use pixi_record::PixiRecord; +use pixi_record::{PixiPackageRecord, PixiRecord}; use pixi_uv_conversions::to_uv_normalize; use pypi_modifiers::pypi_tags::is_python_record; -use rattler_conda_types::{PackageName, RepoDataRecord, VersionWithSource}; +use rattler_conda_types::RepoDataRecord; use std::collections::HashMap; use std::collections::hash_map::Entry; use std::hash::Hash; @@ -12,64 +12,88 @@ pub type PypiRecordsByName = DependencyRecordsByName; pub type PixiRecordsByName = DependencyRecordsByName; /// A trait required from the dependencies stored in DependencyRecordsByName -pub trait HasNameVersion { +pub trait HasName { // Name type of the dependency type N: Hash + Eq + Clone; - // Version type of the dependency - type V: PartialOrd + ToString; /// Returns the name of the dependency fn name(&self) -> &Self::N; +} + +/// A trait required from the dependencies stored in DependencyRecordsByName +pub trait HasVersion { + // Version type of the dependency + type V: PartialOrd + ToString; + /// Returns the version of the dependency fn version(&self) -> &Self::V; } -impl HasNameVersion for PypiRecord { +impl HasName for PypiRecord { type N = pep508_rs::PackageName; - type V = pep440_rs::Version; fn name(&self) -> &pep508_rs::PackageName { &self.0.name } +} + +impl HasVersion for PypiRecord { + type V = pep440_rs::Version; + fn version(&self) -> &Self::V { &self.0.version } } -impl HasNameVersion for RepoDataRecord { +impl HasName for RepoDataRecord { type N = rattler_conda_types::PackageName; - type V = VersionWithSource; fn name(&self) -> &rattler_conda_types::PackageName { &self.package_record.name } +} + +impl HasVersion for RepoDataRecord { + type V = rattler_conda_types::Version; + fn version(&self) -> &Self::V { &self.package_record.version } } -impl HasNameVersion for PixiRecord { - type N = PackageName; - type V = VersionWithSource; +impl HasName for PixiRecord { + type N = rattler_conda_types::PackageName; - fn name(&self) -> &Self::N { - &self.package_record().name + fn name(&self) -> &rattler_conda_types::PackageName { + self.name() } +} + +impl HasName for PixiPackageRecord { + type N = rattler_conda_types::PackageName; + + fn name(&self) -> &rattler_conda_types::PackageName { + self.name() + } +} + +impl HasVersion for PixiPackageRecord { + type V = rattler_conda_types::Version; fn version(&self) -> &Self::V { - &self.package_record().version + self.version().as_ref() } } /// A struct that holds both a ``Vec` of `DependencyRecord` and a mapping from /// name to index. #[derive(Clone, Debug)] -pub struct DependencyRecordsByName { +pub struct DependencyRecordsByName { pub records: Vec, by_name: HashMap, } -impl Default for DependencyRecordsByName { +impl Default for DependencyRecordsByName { fn default() -> Self { Self { records: Vec::new(), @@ -78,7 +102,7 @@ impl Default for DependencyRecordsByName { } } -impl From> for DependencyRecordsByName { +impl From> for DependencyRecordsByName { fn from(records: Vec) -> Self { let by_name = records .iter() @@ -89,7 +113,20 @@ impl From> for DependencyRecordsByName { } } -impl DependencyRecordsByName { +impl From> for DependencyRecordsByName { + fn from(iter: HashMap) -> Self { + let mut records = Vec::new(); + let mut by_name = HashMap::new(); + for (name, record) in iter { + let idx = records.len(); + records.push(record); + by_name.insert(name, idx); + } + Self { records, by_name } + } +} + +impl DependencyRecordsByName { /// Returns the record with the given name or `None` if no such record /// exists. pub(crate) fn by_name(&self, key: &D::N) -> Option<&D> { @@ -145,10 +182,10 @@ impl DependencyRecordsByName { Ok(Self { records, by_name }) } - /// Constructs a new instance from an iterator of repodata records. The - /// records are deduplicated where the record with the highest version - /// wins. - pub(crate) fn from_iter>(iter: I) -> Self { + pub(crate) fn from_iter_cmp, F: Fn(&D, &D) -> std::cmp::Ordering>( + iter: I, + cmp: F, + ) -> Self { let iter = iter.into_iter(); let min_size = iter.size_hint().0; let mut by_name = HashMap::with_capacity(min_size); @@ -161,9 +198,8 @@ impl DependencyRecordsByName { entry.insert(idx); } Entry::Occupied(entry) => { - // Use the entry with the highest version or otherwise the first we encounter. let idx = *entry.get(); - if records[idx].version() < record.version() { + if cmp(&records[idx], &record) == std::cmp::Ordering::Less { records[idx] = record; } } @@ -201,10 +237,12 @@ impl PixiRecordsByName { .ok() .map(move |identifiers| (idx, record, identifiers)) } - PixiRecord::Source(source_record) => { - PypiPackageIdentifier::from_package_record(&source_record.package_record) - .ok() - .map(move |identifiers| (idx, record, identifiers)) + PixiRecord::Source(_source_record) => { + // TODO: We dont have a source record so we cannot extract pypi identifiers for source records. + // PypiPackageIdentifier::from_package_record(&source_record.package_record) + // .ok() + // .map(move |identifiers| (idx, record, identifiers)) + None } }) .flat_map(|(idx, record, identifiers)| { @@ -215,4 +253,25 @@ impl PixiRecordsByName { }) .collect::, ConversionError>>() } + + pub fn from_iter>(iter: I) -> Self { + Self::from_iter_cmp(iter, |a, b| { + match (a, b) { + (PixiRecord::Binary(a_record), PixiRecord::Binary(b_record)) => { + a_record.version().cmp(b_record.version()) + } + // Prefer source packages over binary packages + (PixiRecord::Binary(_), PixiRecord::Source(_)) => std::cmp::Ordering::Less, + (PixiRecord::Source(_), PixiRecord::Binary(_)) => std::cmp::Ordering::Greater, + // Both are source records, consider them equal + (PixiRecord::Source(_), PixiRecord::Source(_)) => std::cmp::Ordering::Equal, + } + }) + } +} + +impl PypiRecordsByName { + pub fn from_iter>(iter: I) -> Self { + Self::from_iter_cmp(iter, |a, b| a.version().cmp(b.version())) + } } diff --git a/crates/pixi_core/src/lock_file/resolve/pypi.rs b/crates/pixi_core/src/lock_file/resolve/pypi.rs index 857d69f8d8..667d26e4d2 100644 --- a/crates/pixi_core/src/lock_file/resolve/pypi.rs +++ b/crates/pixi_core/src/lock_file/resolve/pypi.rs @@ -64,7 +64,6 @@ use crate::{ lock_file::{ CondaPrefixUpdater, LockedPypiPackages, PixiRecordsByName, PypiPackageIdentifier, PypiRecord, - records_by_name::HasNameVersion, resolve::{ build_dispatch::{ LazyBuildDispatch, LazyBuildDispatchDependencies, UvBuildDispatchParams, @@ -299,8 +298,13 @@ pub async fn resolve_pypi( PixiRecord::Binary(repodata_record) => { PypiPackageIdentifier::from_repodata_record(repodata_record) } - PixiRecord::Source(source_record) => { - PypiPackageIdentifier::from_package_record(&source_record.package_record) + PixiRecord::Source(_source_record) => { + // TODO(baszalmstra): We dont have access to the version here yet because we + // only have access to `PixiRecord`. We have to figure out how to get the + // version here or create the identifier purely based on the purl. This should + // be possible if the purl also contains a version. + Ok(Vec::new()) + // PypiPackageIdentifier::from_package_record(&source_record.package_record) } }; @@ -349,11 +353,14 @@ pub async fn resolve_pypi( // Determine the python interpreter that is installed as part of the conda // packages. + // + // TODO(baszalmstra): Currently this only supports binary records. In the future it would be + // great to also support source records to allow building and using python from source. let python_record = locked_pixi_records .iter() - .find(|r| match r { - PixiRecord::Binary(r) => is_python_record(r), - _ => false, + .find_map(|r| match r { + PixiRecord::Binary(r) if is_python_record(r) => Some(r), + _ => None, }) .ok_or_else(|| { miette::miette!( @@ -374,7 +381,8 @@ pub async fn resolve_pypi( // wheel. So make sure the interpreter does not touch the solve parts of // this function let interpreter_version = python_record - .version() + .package_record + .version .as_major_minor() .ok_or_else(|| miette::miette!("conda python record missing major.minor version"))?; let pep_version = uv_pep440::Version::from_str(&format!( diff --git a/crates/pixi_core/src/lock_file/resolve/resolver_provider.rs b/crates/pixi_core/src/lock_file/resolve/resolver_provider.rs index d267d1bc1a..b294bd832f 100644 --- a/crates/pixi_core/src/lock_file/resolve/resolver_provider.rs +++ b/crates/pixi_core/src/lock_file/resolve/resolver_provider.rs @@ -42,7 +42,7 @@ impl ResolverProvider for CondaResolverProvider<'_, Conte ) -> impl Future + 'io { if let Some((repodata_record, identifier)) = self.conda_python_identifiers.get(package_name) { - let version = repodata_record.package_record().version.to_string(); + let version = &identifier.version.to_string(); tracing::debug!( "overriding PyPI package version request {}=={}", diff --git a/crates/pixi_core/src/lock_file/satisfiability/mod.rs b/crates/pixi_core/src/lock_file/satisfiability/mod.rs index 29d7898f00..20d68d3853 100644 --- a/crates/pixi_core/src/lock_file/satisfiability/mod.rs +++ b/crates/pixi_core/src/lock_file/satisfiability/mod.rs @@ -716,7 +716,7 @@ pub async fn verify_platform_satisfiability( Ok(pixi_records) => pixi_records, Err(duplicate) => { return Err(Box::new(PlatformUnsat::DuplicateEntry( - duplicate.package_record().name.as_source().to_string(), + duplicate.name().as_source().to_string(), ))); } }; @@ -1312,7 +1312,7 @@ pub(crate) async fn verify_package_platform_satisfiability( } let record = &locked_pixi_records.records[idx.0]; - for depends in &record.package_record().depends { + for depends in record.depends() { let spec = MatchSpec::from_str(depends.as_str(), Lenient) .map_err(|e| PlatformUnsat::FailedToParseMatchSpec(depends.clone(), e))?; @@ -1324,7 +1324,7 @@ pub(crate) async fn verify_package_platform_satisfiability( PixiRecord::Source(record) => ( Cow::Owned(format!( "{} @ {}", - record.package_record.name.as_source(), + record.name.as_source(), &record.manifest_source )), SourceSpec::from(record.manifest_source.clone()).into(), @@ -1484,9 +1484,9 @@ pub(crate) async fn verify_package_platform_satisfiability( .iter() .filter_map(PixiRecord::as_source) { - if !expected_conda_source_dependencies.contains(&record.package_record.name) { + if !expected_conda_source_dependencies.contains(&record.name) { return Err(Box::new(PlatformUnsat::RequiredBinaryIsSource( - record.package_record.name.as_source().to_string(), + record.name.as_source().to_string(), ))); } } @@ -1871,7 +1871,7 @@ fn verify_build_source_matches_manifest( let Some(record) = locked_pixi_records .records .iter() - .find(|r| r.package_record().name.as_source() == pkg_name) + .find(|r| r.name().as_source() == pkg_name) else { return Ok(()); }; @@ -1884,13 +1884,13 @@ fn verify_build_source_matches_manifest( pixi_spec::SourceLocationSpec::Url(url_spec) => { let Some(locked_url) = src_record.build_source.as_ref().and_then(|p| p.as_url()) else { return Err(Box::new(PlatformUnsat::PackageBuildSourceMismatch( - src_record.package_record.name.as_source().to_string(), + src_record.name.as_source().to_string(), SourceMismatchError::SourceTypeMismatch, ))); }; locked_url.satisfies(&url_spec).map_err(|e| { Box::new(PlatformUnsat::PackageBuildSourceMismatch( - src_record.package_record.name.as_source().to_string(), + src_record.name.as_source().to_string(), e, )) }) @@ -1898,7 +1898,7 @@ fn verify_build_source_matches_manifest( pixi_spec::SourceLocationSpec::Git(mut git_spec) => { let Some(locked_git) = src_record.build_source.as_ref().and_then(|p| p.as_git()) else { return Err(Box::new(PlatformUnsat::PackageBuildSourceMismatch( - src_record.package_record.name.as_source().to_string(), + src_record.name.as_source().to_string(), SourceMismatchError::SourceTypeMismatch, ))); }; @@ -1914,7 +1914,7 @@ fn verify_build_source_matches_manifest( } locked_git.satisfies(&git_spec).map_err(|e| { Box::new(PlatformUnsat::PackageBuildSourceMismatch( - src_record.package_record.name.as_source().to_string(), + src_record.name.as_source().to_string(), e, )) }) @@ -1923,14 +1923,14 @@ fn verify_build_source_matches_manifest( let Some(locked_path) = src_record.build_source.as_ref().and_then(|p| p.as_path()) else { return Err(Box::new(PlatformUnsat::PackageBuildSourceMismatch( - src_record.package_record.name.as_source().to_string(), + src_record.name.as_source().to_string(), SourceMismatchError::SourceTypeMismatch, ))); }; locked_path.satisfies(&path_spec).map_err(|e| { Box::new(PlatformUnsat::PackageBuildSourceMismatch( - src_record.package_record.name.as_source().to_string(), + src_record.name.as_source().to_string(), e, )) }) @@ -1949,7 +1949,7 @@ mod tests { use insta::Settings; use miette::{IntoDiagnostic, NarratableReportHandler}; use pep440_rs::{Operator, Version}; - use rattler_lock::LockFile; + use rattler_lock::{FileFormatVersion, LockFile}; use rstest::rstest; use super::*; @@ -1972,6 +1972,11 @@ mod tests { "solve group '{0}' does not satisfy the requirements of the project for platform '{1}'" )] SolveGroupUnsat(String, Platform, #[source] SolveGroupUnsat), + + #[error( + "source packages for lockfile version {0} do not contain variants which makes the lockfile unusable" + )] + PreV7SourceDependencies(FileFormatVersion), } async fn verify_lockfile_satisfiability( @@ -1980,6 +1985,20 @@ mod tests { ) -> Result<(), LockfileUnsat> { let mut individual_verified_envs = HashMap::new(); + // If there are pre-v7 source dependencies present, the lock-file must be invalidated. + if lock_file.version() < FileFormatVersion::V7 { + for (_, env) in lock_file.environments() { + for package in env + .conda_packages_by_platform() + .flat_map(|(_, packages)| packages) + { + if let rattler_lock::CondaPackageData::Source(_) = package { + return Err(LockfileUnsat::PreV7SourceDependencies(lock_file.version())); + } + } + } + } + // Verify individual environment satisfiability for env in project.environments() { let locked_env = lock_file @@ -2036,6 +2055,8 @@ mod tests { async fn test_good_satisfiability( #[files("../../tests/data/satisfiability/*/pixi.toml")] manifest_path: PathBuf, ) { + eprintln!("Path to pixi.toml: {}", manifest_path.display()); + // TODO: skip this test on windows // Until we can figure out how to handle unix file paths with pep508_rs url // parsing correctly @@ -2048,6 +2069,7 @@ mod tests { } let project = Workspace::from_path(&manifest_path).unwrap(); + eprintln!("Path to pixi.lock: {}", project.lock_file_path().display()); let lock_file = LockFile::from_path(&project.lock_file_path()).unwrap(); match verify_lockfile_satisfiability(&project, &lock_file) .await @@ -2097,6 +2119,8 @@ mod tests { async fn test_failing_satisiability( #[files("../../tests/data/non-satisfiability/*/pixi.toml")] manifest_path: PathBuf, ) { + eprintln!("Path to pixi.toml: {}", manifest_path.display()); + let report_handler = NarratableReportHandler::new().with_cause_chain(); let project = Workspace::from_path(&manifest_path).unwrap(); diff --git a/crates/pixi_core/src/lock_file/update.rs b/crates/pixi_core/src/lock_file/update.rs index 27796fc072..9b38797ea9 100644 --- a/crates/pixi_core/src/lock_file/update.rs +++ b/crates/pixi_core/src/lock_file/update.rs @@ -30,7 +30,7 @@ use pixi_install_pypi::{ }; use pixi_manifest::{ChannelPriority, EnvironmentName, FeaturesExt}; use pixi_progress::global_multi_progress; -use pixi_record::{ParseLockFileError, PixiRecord}; +use pixi_record::{ParseLockFileError, PixiPackageRecord, PixiRecord}; use pixi_utils::{prefix::Prefix, variants::VariantConfig}; use pixi_uv_context::UvResolutionContext; use pixi_uv_conversions::{ @@ -498,7 +498,7 @@ impl<'p> LockFileDerivedData<'p> { let (ignored_conda, ignored_pypi): (HashSet<_>, HashSet<_>) = ignored.into_iter().partition_map(|p| match p { - LockedPackageRef::Conda(data) => Either::Left(data.record().name.clone()), + LockedPackageRef::Conda(data) => Either::Left(data.name().clone()), LockedPackageRef::Pypi(data, _) => Either::Right(data.name.clone()), }); @@ -1428,7 +1428,7 @@ impl<'p> UpdateContext<'p> { .iter() .filter_map(|r| match r { PixiRecord::Source(src) => { - let name = src.package_record.name.clone(); + let name = src.name.clone(); if targets.contains(name.as_source()) { src.build_source.clone().map(|spec| (name, spec)) } else { @@ -2044,7 +2044,9 @@ async fn spawn_solve_conda_environment_task( mapping_client .amend_purls( &pypi_name_mapping_location, - records.iter_mut().filter_map(PixiRecord::as_binary_mut), + records + .iter_mut() + .filter_map(PixiPackageRecord::as_binary_mut), None, ) .await @@ -2052,7 +2054,9 @@ async fn spawn_solve_conda_environment_task( } // Turn the records into a map by name - let records_by_name = PixiRecordsByName::from(records); + let records_by_name = + PixiRecordsByName::from_unique_iter(records.into_iter().map(PixiRecord::from)) + .expect("records returned by solve must have unique names"); let end = Instant::now(); @@ -2171,7 +2175,7 @@ async fn spawn_extract_environment_task( match record { PackageRecord::Conda(record) => { // Find all dependencies in the record and add them to the queue. - for dependency in record.package_record().depends.iter() { + for dependency in record.depends().iter() { let dependency_name = PackageName::Conda(rattler_conda_types::PackageName::new_unchecked( dependency.split_once(' ').unwrap_or((dependency, "")).0, @@ -2231,9 +2235,10 @@ async fn spawn_extract_environment_task( Ok(TaskResult::ExtractedRecordsSubset( environment.name().clone(), platform, - Arc::new(PixiRecordsByName::from_iter( - pixi_records.into_iter().cloned(), - )), + Arc::new( + PixiRecordsByName::from_unique_iter(pixi_records.into_iter().cloned()) + .expect("solver should never return multiple entries for a single package name"), + ), Arc::new(PypiRecordsByName::from_iter( pypi_records.into_values().cloned(), )), diff --git a/crates/pixi_core/src/workspace/mod.rs b/crates/pixi_core/src/workspace/mod.rs index 9e5d7dac0b..9753dc34d3 100644 --- a/crates/pixi_core/src/workspace/mod.rs +++ b/crates/pixi_core/src/workspace/mod.rs @@ -734,9 +734,7 @@ impl Workspace { filter_lock_file(self, lock_file, |env, platform, package| { if affected_environments.contains(&(env.name().as_str(), platform)) { match package { - LockedPackageRef::Conda(package) => { - !conda_packages.contains(&package.record().name) - } + LockedPackageRef::Conda(package) => !conda_packages.contains(package.name()), LockedPackageRef::Pypi(package, _env) => !pypi_packages.contains(&package.name), } } else { diff --git a/crates/pixi_diff/src/lib.rs b/crates/pixi_diff/src/lib.rs index 5bbed7820b..f6416562e5 100644 --- a/crates/pixi_diff/src/lib.rs +++ b/crates/pixi_diff/src/lib.rs @@ -9,7 +9,7 @@ use itertools::{Either, Itertools}; use pixi_consts::consts; use pixi_manifest::{EnvironmentName, FeaturesExt}; use rattler_conda_types::Platform; -use rattler_lock::{LockFile, LockedPackage, LockedPackageRef}; +use rattler_lock::{CondaPackageData, LockFile, LockedPackage, LockedPackageRef}; use serde::Serialize; use serde_json::Value; use tabwriter::TabWriter; @@ -57,10 +57,9 @@ impl LockFileDiff { .into_iter() .flatten() .partition_map(|p| match p { - LockedPackageRef::Conda(conda_package_data) => Either::Left(( - conda_package_data.record().name.clone(), - conda_package_data, - )), + LockedPackageRef::Conda(conda_package_data) => { + Either::Left((conda_package_data.name(), conda_package_data)) + } LockedPackageRef::Pypi(pypi_package_data, pypi_env_data) => { Either::Right(( pypi_package_data.name.clone(), @@ -75,7 +74,7 @@ impl LockFileDiff { for package in packages { match package { LockedPackageRef::Conda(data) => { - let name = &data.record().name; + let name = &data.name(); match previous_conda_packages.remove(name) { Some(previous) if previous.location() != data.location() => { diff.changed @@ -254,9 +253,22 @@ impl LockFileDiff { fn format_package_identifier(package: &LockedPackage) -> String { match package { - LockedPackage::Conda(p) => { - format!("{} {}", &p.record().version.as_str(), &p.record().build) - } + LockedPackage::Conda(p) => match p { + CondaPackageData::Binary(binary) => { + format!( + "{} {}", + &binary.package_record.version.as_str(), + &binary.package_record.build + ) + } + CondaPackageData::Source(conda_source_data) => { + format!( + "{} @ {}", + conda_source_data.name.as_source(), + conda_source_data.location + ) + } + }, LockedPackage::Pypi(p, _) => p.version.to_string(), } } @@ -310,19 +322,54 @@ impl LockFileDiff { let name = previous.name(); let line = match (previous, current) { (LockedPackage::Conda(previous), LockedPackage::Conda(current)) => { - let previous = previous.record(); - let current = current.record(); - - format!( - "{} {} {}\t{} {}\t->\t{} {}", - console::style("~").yellow(), - consts::CondaEmoji, - name, - choose_style(&previous.version.as_str(), ¤t.version.as_str()), - choose_style(previous.build.as_str(), current.build.as_str()), - choose_style(¤t.version.as_str(), &previous.version.as_str()), - choose_style(current.build.as_str(), previous.build.as_str()), - ) + // Handle both Binary and Source variants + match (previous.as_binary(), current.as_binary()) { + (Some(prev_binary), Some(curr_binary)) => { + let previous = &prev_binary.package_record; + let current = &curr_binary.package_record; + + format!( + "{} {} {}\t{} {}\t->\t{} {}", + console::style("~").yellow(), + consts::CondaEmoji, + name, + choose_style( + &previous.version.as_str(), + ¤t.version.as_str() + ), + choose_style(previous.build.as_str(), current.build.as_str()), + choose_style( + ¤t.version.as_str(), + &previous.version.as_str() + ), + choose_style(current.build.as_str(), previous.build.as_str()), + ) + } + // For source packages, show location instead of version/build + (Some(_), None) | (None, Some(_)) => { + // Transition between binary and source + format!( + "{} {} {} (binary <-> source)", + console::style("~").yellow(), + consts::CondaEmoji, + name, + ) + } + (None, None) => { + // Both are source packages, show location + let prev_location = previous.location().to_string(); + let curr_location = current.location().to_string(); + + format!( + "{} {} {}\t{}\t->\t{}", + console::style("~").yellow(), + consts::CondaEmoji, + name, + choose_style(&prev_location, &curr_location), + choose_style(&curr_location, &prev_location), + ) + } + } } (LockedPackage::Pypi(previous, _), LockedPackage::Pypi(current, _)) => { format!( @@ -404,13 +451,13 @@ impl LockFileJsonDiff { let add_diffs = packages_diff.added.into_iter().map(|new| match new { LockedPackage::Conda(pkg) => JsonPackageDiff { - name: pkg.record().name.as_normalized().to_string(), + name: pkg.name().as_normalized().to_string(), before: None, after: Some( serde_json::to_value(&pkg).expect("should be able to serialize"), ), ty: JsonPackageType::Conda, - explicit: conda_dependencies.contains_key(&pkg.record().name), + explicit: conda_dependencies.contains_key(pkg.name()), }, LockedPackage::Pypi(pkg, _) => JsonPackageDiff { name: pkg.name.as_dist_info_name().into_owned(), @@ -425,13 +472,13 @@ impl LockFileJsonDiff { let removed_diffs = packages_diff.removed.into_iter().map(|old| match old { LockedPackage::Conda(pkg) => JsonPackageDiff { - name: pkg.record().name.as_normalized().to_string(), + name: pkg.name().as_normalized().to_string(), before: Some( serde_json::to_value(&pkg).expect("should be able to serialize"), ), after: None, ty: JsonPackageType::Conda, - explicit: conda_dependencies.contains_key(&pkg.record().name), + explicit: conda_dependencies.contains_key(pkg.name()), }, LockedPackage::Pypi(pkg, _) => JsonPackageDiff { @@ -452,11 +499,11 @@ impl LockFileJsonDiff { let after = serde_json::to_value(&new).expect("should be able to serialize"); let (before, after) = compute_json_diff(before, after); JsonPackageDiff { - name: old.record().name.as_normalized().to_string(), + name: old.name().as_normalized().to_string(), before: Some(before), after: Some(after), ty: JsonPackageType::Conda, - explicit: conda_dependencies.contains_key(&old.record().name), + explicit: conda_dependencies.contains_key(old.name()), } } (LockedPackage::Pypi(old, _), LockedPackage::Pypi(new, _)) => { diff --git a/crates/pixi_glob/src/snapshots/pixi_glob__glob_hash__test__glob_hash_case_1_satisfiability.snap b/crates/pixi_glob/src/snapshots/pixi_glob__glob_hash__test__glob_hash_case_1_satisfiability.snap index 68160edea1..4566586cd1 100644 --- a/crates/pixi_glob/src/snapshots/pixi_glob__glob_hash__test__glob_hash_case_1_satisfiability.snap +++ b/crates/pixi_glob/src/snapshots/pixi_glob__glob_hash__test__glob_hash_case_1_satisfiability.snap @@ -4,7 +4,7 @@ expression: snapshot --- Globs: - tests/data/satisfiability/source-dependency/**/* -Hash: 3ed91dc28b0561c516e9e9eccd7f977f3ec45fe8b36883f5201389fced4a7aaa +Hash: e9b1ff09360893cd09292a2fce60f80174b76716c7c125735527263d4f5db23f Matched files: - tests/data/satisfiability/source-dependency/child-package/pixi.toml - tests/data/satisfiability/source-dependency/pixi.lock diff --git a/crates/pixi_global/src/common.rs b/crates/pixi_global/src/common.rs index 73e437af1b..6bbae157bc 100644 --- a/crates/pixi_global/src/common.rs +++ b/crates/pixi_global/src/common.rs @@ -1259,7 +1259,7 @@ mod tests { #[cfg(windows)] { for script_name in script_names { - let script_path = bin_dir.path().join(format!("{}.bat", script_name)); + let script_path = bin_dir.path().join(format!("{script_name}.bat")); let script = format!( r#" @"{}" %* @@ -1267,7 +1267,7 @@ mod tests { env_dir .path() .join("bin") - .join(format!("{}.exe", script_name)) + .join(format!("{script_name}.exe")) .to_string_lossy() ); tokio_fs::write(&script_path, script).await.unwrap(); diff --git a/crates/pixi_global/src/project/mod.rs b/crates/pixi_global/src/project/mod.rs index a39953ff6b..bdf6e0751a 100644 --- a/crates/pixi_global/src/project/mod.rs +++ b/crates/pixi_global/src/project/mod.rs @@ -612,7 +612,7 @@ impl Project { let result = command_dispatcher .install_pixi_environment(InstallPixiEnvironmentSpec { name: env_name.to_string(), - records: pixi_records, + records: pixi_records.into_iter().map(From::from).collect(), prefix: rattler_conda_types::prefix::Prefix::create(prefix.root()) .into_diagnostic()?, build_environment, @@ -1409,11 +1409,14 @@ impl Project { match packages.len() { 0 => Err(InferPackageNameError::NoPackageOutputs), 1 => { - let package = &packages[0]; - Ok(package.name.clone()) + let (package_name, _) = &packages[0]; + Ok(package_name.clone()) } _ => { - let package_names: Vec<_> = packages.iter().map(|p| p.name.as_source()).collect(); + let package_names: Vec<_> = packages + .iter() + .map(|(package_name, _)| package_name.as_source()) + .collect(); Err(InferPackageNameError::MultiplePackageOutputs { package_names: package_names.join(", "), }) diff --git a/crates/pixi_install_pypi/src/lib.rs b/crates/pixi_install_pypi/src/lib.rs index 59c5659703..a511853bc6 100644 --- a/crates/pixi_install_pypi/src/lib.rs +++ b/crates/pixi_install_pypi/src/lib.rs @@ -9,7 +9,7 @@ use chrono::{DateTime, Utc}; use conda_pypi_clobber::PypiCondaClobberRegistry; use fancy_display::FancyDisplay; use itertools::Itertools; -use miette::{IntoDiagnostic, WrapErr}; +use miette::{IntoDiagnostic, WrapErr, miette}; use pixi_consts::consts; use pixi_manifest::{ EnvironmentName, SystemRequirements, @@ -26,10 +26,7 @@ use pixi_uv_conversions::{ to_exclude_newer, to_index_strategy, }; use plan::{InstallPlanner, InstallReason, NeedReinstall, PyPIInstallationPlan}; -use pypi_modifiers::{ - Tags, - pypi_tags::{get_pypi_tags, is_python_record}, -}; +use pypi_modifiers::{Tags, pypi_tags::get_pypi_tags}; use rattler_conda_types::Platform; use rattler_lock::{PypiIndexes, PypiPackageData, PypiPackageEnvironmentData}; use rayon::prelude::*; @@ -318,14 +315,17 @@ impl<'a> PyPIEnvironmentUpdater<'a> { // Determine the current environment markers. let python_record = pixi_records .iter() - .find(|r| is_python_record(r)) + .find(|r| r.name() == &rattler_conda_types::PackageName::new_unchecked("python")) .cloned() .ok_or_else(|| miette::miette!("could not resolve pypi dependencies because no python interpreter is added to the dependencies of the project.\nMake sure to add a python interpreter to the [dependencies] section of the {manifest}, or run:\n\n\tpixi add python", manifest=consts::WORKSPACE_MANIFEST))?; + // TODO: resolve python record if its a source record let tags = get_pypi_tags( self.config.platform, self.config.system_requirements, - python_record.package_record(), + python_record + .package_record() + .ok_or_else(|| miette!("python from source is not yet supported"))?, )?; let index_locations = self diff --git a/crates/pixi_record/Cargo.toml b/crates/pixi_record/Cargo.toml index 31a4990a4a..5d87d1bf26 100644 --- a/crates/pixi_record/Cargo.toml +++ b/crates/pixi_record/Cargo.toml @@ -10,6 +10,7 @@ repository.workspace = true version = "0.1.0" [dependencies] +chrono = { workspace = true } file_url = { workspace = true } miette = { workspace = true } pixi_git = { workspace = true } diff --git a/crates/pixi_record/src/lib.rs b/crates/pixi_record/src/lib.rs index 7992cc29ea..af7325406c 100644 --- a/crates/pixi_record/src/lib.rs +++ b/crates/pixi_record/src/lib.rs @@ -6,11 +6,18 @@ pub use pinned_source::{ PinnedPathSpec, PinnedSourceSpec, PinnedUrlSpec, SourceMismatchError, }; use rattler_conda_types::{ - MatchSpec, Matches, NamelessMatchSpec, PackageName, PackageRecord, RepoDataRecord, + MatchSpec, Matches, PackageName, PackageRecord, RepoDataRecord, VersionWithSource, + package::RunExportsJson, }; use rattler_lock::{CondaPackageData, ConversionError, UrlOrPath}; use serde::Serialize; -pub use source_record::{InputHash, SourceRecord}; +pub use source_record::{InputHash, SourcePackageRecord, SourceRecord}; +// Re-export VariantValue for convenience +pub use rattler_lock::VariantValue; + +/// A map of variant keys to their selected values. +/// Used to uniquely identify which output variant of a source package to build. +pub type SelectedVariant = std::collections::BTreeMap; use thiserror::Error; /// A record of a conda package that is either something installable from a @@ -20,6 +27,7 @@ use thiserror::Error; #[allow(clippy::large_enum_variant)] #[derive(Debug, Clone, Serialize)] #[serde(untagged)] +#[allow(clippy::large_enum_variant)] pub enum PixiRecord { Binary(RepoDataRecord), Source(SourceRecord), @@ -27,14 +35,44 @@ pub enum PixiRecord { impl PixiRecord { /// The name of the package pub fn name(&self) -> &PackageName { - &self.package_record().name + match self { + PixiRecord::Binary(record) => &record.package_record.name, + PixiRecord::Source(record) => &record.name, + } + } + + /// Returns the version of the package if it is known. + pub fn version(&self) -> Option<&VersionWithSource> { + match self { + PixiRecord::Binary(record) => Some(&record.package_record.version), + PixiRecord::Source(record) => record.version.as_ref(), + } + } + + /// The dependencies of the package + pub fn depends(&self) -> &[String] { + match self { + PixiRecord::Binary(record) => &record.package_record.depends, + PixiRecord::Source(record) => &record.depends, + } + } + + /// The constraints of the package + pub fn constrains(&self) -> &[String] { + match self { + PixiRecord::Binary(record) => &record.package_record.constrains, + PixiRecord::Source(record) => &record.constrains, + } } /// Metadata information of the package. - pub fn package_record(&self) -> &PackageRecord { + /// + /// Returns `Some` for binary packages, `None` for source packages. + /// Source packages don't have version/build information in the new lock format. + pub fn package_record(&self) -> Option<&PackageRecord> { match self { - PixiRecord::Binary(record) => &record.package_record, - PixiRecord::Source(record) => &record.package_record, + PixiRecord::Binary(record) => Some(&record.package_record), + PixiRecord::Source(_) => None, } } @@ -133,7 +171,7 @@ impl From for CondaPackageData { } } -impl Matches for NamelessMatchSpec { +impl Matches for MatchSpec { fn matches(&self, record: &PixiRecord) -> bool { match record { PixiRecord::Binary(record) => self.matches(record), @@ -142,20 +180,112 @@ impl Matches for NamelessMatchSpec { } } -impl Matches for MatchSpec { - fn matches(&self, record: &PixiRecord) -> bool { - match record { - PixiRecord::Binary(record) => self.matches(record), - PixiRecord::Source(record) => self.matches(record), +/// A conda package record with complete metadata for both binary and source packages. +/// +/// This is the fully-resolved version of [`PixiRecord`], where source packages include +/// complete package metadata (version, build, timestamp, etc.) via [`SourcePackageRecord`]. +/// +/// Unlike [`PixiRecord`], this type contains all information needed for dependency solving. +/// It is used during solve operations but **not** stored in lock files (only [`PixiRecord`] +/// is persisted). +#[derive(Debug, Clone, Serialize)] +#[serde(untagged)] +#[allow(clippy::large_enum_variant)] +pub enum PixiPackageRecord { + Binary(RepoDataRecord), + Source(SourcePackageRecord), +} + +impl PixiPackageRecord { + /// The name of the package + pub fn name(&self) -> &PackageName { + match self { + PixiPackageRecord::Binary(record) => &record.package_record.name, + PixiPackageRecord::Source(record) => &record.source_record.name, + } + } + + /// The version of the package + pub fn version(&self) -> &VersionWithSource { + match self { + PixiPackageRecord::Binary(record) => &record.package_record.version, + PixiPackageRecord::Source(record) => &record.version, } } -} -impl AsRef for PixiRecord { - fn as_ref(&self) -> &PackageRecord { + pub fn run_exports(&self) -> Option<&RunExportsJson> { match self { - PixiRecord::Binary(record) => record.as_ref(), - PixiRecord::Source(record) => record.as_ref(), + PixiPackageRecord::Binary(record) => record.package_record.run_exports.as_ref(), + PixiPackageRecord::Source(record) => record.run_exports.as_ref(), + } + } + + /// Returns a reference to the binary record if it is a binary record. + pub fn as_binary(&self) -> Option<&RepoDataRecord> { + match self { + PixiPackageRecord::Binary(record) => Some(record), + PixiPackageRecord::Source(_) => None, + } + } + + /// Returns a reference to the binary record if it is a binary record. + pub fn as_binary_mut(&mut self) -> Option<&mut RepoDataRecord> { + match self { + PixiPackageRecord::Binary(record) => Some(record), + PixiPackageRecord::Source(_) => None, + } + } + + /// Converts this instance into a binary record if it is a binary record. + pub fn into_binary(self) -> Option { + match self { + PixiPackageRecord::Binary(record) => Some(record), + PixiPackageRecord::Source(_) => None, + } + } + + /// Returns a reference to the source record if it is a source record. + pub fn as_source(&self) -> Option<&SourcePackageRecord> { + match self { + PixiPackageRecord::Binary(_) => None, + PixiPackageRecord::Source(record) => Some(record), + } + } + + /// Converts this instance into a source record if it is a source record. + pub fn into_source(self) -> Option { + match self { + PixiPackageRecord::Binary(_) => None, + PixiPackageRecord::Source(record) => Some(record), + } + } + + /// Returns the package record. + pub fn package_record(&self) -> PackageRecord { + match self { + PixiPackageRecord::Binary(record) => record.package_record.clone(), + PixiPackageRecord::Source(record) => record.package_record(), + } + } +} + +impl From for PixiPackageRecord { + fn from(value: SourcePackageRecord) -> Self { + PixiPackageRecord::Source(value) + } +} + +impl From for PixiPackageRecord { + fn from(value: RepoDataRecord) -> Self { + PixiPackageRecord::Binary(value) + } +} + +impl From for PixiRecord { + fn from(value: PixiPackageRecord) -> Self { + match value { + PixiPackageRecord::Binary(record) => PixiRecord::Binary(record), + PixiPackageRecord::Source(record) => PixiRecord::Source(record.into()), } } } diff --git a/crates/pixi_record/src/source_record.rs b/crates/pixi_record/src/source_record.rs index 68bf60c0b5..2ff4bb894c 100644 --- a/crates/pixi_record/src/source_record.rs +++ b/crates/pixi_record/src/source_record.rs @@ -1,24 +1,39 @@ -use std::{ - collections::{BTreeSet, HashMap}, - str::FromStr, +use std::collections::{BTreeMap, BTreeSet, HashMap}; + +use pixi_spec::SourceSpec; +use rattler_conda_types::{ + MatchSpec, Matches, NoArchType, PackageName, PackageRecord, PackageUrl, VersionWithSource, + package::RunExportsJson, }; +use rattler_digest::{Md5Hash, Sha256, Sha256Hash}; +use rattler_lock::{CondaPackageData, CondaSourceData}; +use std::str::FromStr; use pixi_git::sha::GitSha; -use pixi_spec::{GitReference, SourceSpec}; -use rattler_conda_types::{MatchSpec, Matches, NamelessMatchSpec, PackageRecord}; -use rattler_digest::{Sha256, Sha256Hash}; -use rattler_lock::{CondaPackageData, CondaSourceData, GitShallowSpec, PackageBuildSource}; +use pixi_spec::GitReference; +use rattler_lock::{GitShallowSpec, PackageBuildSource}; use serde::{Deserialize, Serialize}; -use typed_path::Utf8TypedPathBuf; +use crate::SelectedVariant; use crate::{ParseLockFileError, PinnedGitCheckout, PinnedSourceSpec}; -/// A record of a conda package that still requires building. +/// A minimal record of a source package stored in the lock file. +/// +/// This contains only the essential information needed to identify and locate +/// a source package (name, source location, variants, dependencies). Notably, +/// it does **not** include version or build information, which is only known +/// after the package has been built or its metadata has been resolved. +/// +/// This minimal representation is sufficient to perform an install (build the +/// package from source), but not to perform a solve (which requires version +/// and build information). +/// +/// For the complete package information with version/build details, see +/// [`SourcePackageRecord`]. #[derive(Debug, Clone, serde::Serialize)] pub struct SourceRecord { - /// Information about the conda package. This is metadata of the package - /// after it has been build. - pub package_record: PackageRecord, + /// The name of the package + pub name: PackageName, /// Exact definition of the source of the package. pub manifest_source: PinnedSourceSpec, @@ -27,6 +42,29 @@ pub struct SourceRecord { /// This is used when the manifest is not in the same location ad pub build_source: Option, + /// Conda-build variants used to disambiguate between multiple source packages + /// at the same location. + pub variants: SelectedVariant, + + /// Optionally the version of the package + pub version: Option, + + /// Specification of packages this package depends on + pub depends: Vec, + + /// Additional constraints on packages + pub constrains: Vec, + + /// Experimental: additional dependencies grouped by feature name + pub experimental_extra_depends: BTreeMap>, + + /// The specific license of the package + pub license: Option, + + /// Package identifiers of packages that are equivalent to this package but + /// from other ecosystems (e.g., PyPI) + pub purls: Option>, + /// The hash of the input that was used to build the metadata of the /// package. This can be used to verify that the metadata is still valid. /// @@ -37,6 +75,121 @@ pub struct SourceRecord { /// Specifies which packages are expected to be installed as source packages /// and from which location. pub sources: HashMap, + + /// Python site-packages path if this is a Python package + pub python_site_packages_path: Option, +} + +/// A complete source package record with full metadata after resolution or building. +/// +/// This extends [`SourceRecord`] with complete package metadata including version, +/// build string, build number, timestamp, and hashes. This information is obtained +/// after building the package or resolving its metadata from the recipe. +/// +/// Unlike [`SourceRecord`], this contains all the information needed to perform +/// dependency solving. It is **only** used during solve operations; for install +/// operations, [`SourceRecord`] contains sufficient information. +/// +/// This is **not** stored in the lock file (only the minimal [`SourceRecord`] is persisted). +#[derive(Debug, Clone, serde::Serialize)] +pub struct SourcePackageRecord { + /// The base source record + pub source_record: SourceRecord, + + /// The version of the package + pub version: VersionWithSource, + + /// The build string of the package + pub build: String, + + /// The build number of the package + pub build_number: rattler_conda_types::BuildNumber, + + /// The subdir of the package + pub subdir: String, + + /// Optionally the architecture the package supports + pub arch: Option, + + /// Optionally the platform the package supports + pub platform: Option, + + /// MD5 hash of the package archive + pub md5: Option, + + /// SHA256 hash of the package archive + pub sha256: Option, + + /// Size of the package archive in bytes + pub size: Option, + + /// Track features + pub track_features: Vec, + + /// Features (deprecated) + pub features: Option, + + /// License family + pub license_family: Option, + + /// Timestamp of when the package was built + pub timestamp: Option>, + + /// Run exports information + pub run_exports: Option, + + /// NoArch type + pub noarch: NoArchType, + + /// Legacy bz2 MD5 hash + pub legacy_bz2_md5: Option, + + /// Legacy bz2 size + pub legacy_bz2_size: Option, +} + +impl From for SourceRecord { + fn from(value: SourcePackageRecord) -> Self { + value.source_record + } +} + +impl From for PackageRecord { + fn from(value: SourcePackageRecord) -> Self { + PackageRecord { + name: value.source_record.name, + version: value.version, + build: value.build, + build_number: value.build_number, + subdir: value.subdir, + depends: value.source_record.depends, + constrains: value.source_record.constrains, + arch: value.arch, + platform: value.platform, + md5: value.md5, + sha256: value.sha256, + size: value.size, + license: value.source_record.license, + license_family: value.license_family, + purls: value.source_record.purls, + track_features: value.track_features, + features: value.features, + timestamp: value.timestamp.map(From::from), + run_exports: value.run_exports, + experimental_extra_depends: value.source_record.experimental_extra_depends, + noarch: value.noarch, + legacy_bz2_md5: value.legacy_bz2_md5, + legacy_bz2_size: value.legacy_bz2_size, + python_site_packages_path: value.source_record.python_site_packages_path, + } + } +} + +impl SourcePackageRecord { + /// Convert to a PackageRecord + pub fn package_record(&self) -> PackageRecord { + self.clone().into() + } } /// Defines the hash of the input files that were used to build the metadata of @@ -57,51 +210,28 @@ pub struct InputHash { impl From for CondaPackageData { fn from(value: SourceRecord) -> Self { - let package_build_source = value.build_source.map(|s| match s { - PinnedSourceSpec::Url(pinned_url_spec) => PackageBuildSource::Url { - url: pinned_url_spec.url, - sha256: pinned_url_spec.sha256, - subdir: None, - }, - PinnedSourceSpec::Git(pinned_git_spec) => { - let subdirectory = pinned_git_spec - .source - .subdirectory - .as_deref() - .map(Utf8TypedPathBuf::from); - - let spec = match &pinned_git_spec.source.reference { - GitReference::Branch(branch) => Some(GitShallowSpec::Branch(branch.clone())), - GitReference::Tag(tag) => Some(GitShallowSpec::Tag(tag.clone())), - GitReference::Rev(_) => Some(GitShallowSpec::Rev), - GitReference::DefaultBranch => None, - }; - - PackageBuildSource::Git { - url: pinned_git_spec.git, - spec, - rev: pinned_git_spec.source.commit.to_string(), - subdir: subdirectory, - } - } - PinnedSourceSpec::Path(pinned_path) => PackageBuildSource::Path { - path: pinned_path.path, - }, - }); CondaPackageData::Source(CondaSourceData { - package_record: value.package_record, - location: value.manifest_source.clone().into(), - package_build_source, - input: value.input_hash.map(|i| rattler_lock::InputHash { - hash: i.hash, - // TODO: fix this in rattler - globs: Vec::from_iter(i.globs), - }), + name: value.name, + location: value.manifest_source.into(), + variants: value.variants, + version: value.version, + depends: value.depends, + constrains: value.constrains, + experimental_extra_depends: value.experimental_extra_depends, + license: value.license, + purls: value.purls, sources: value .sources .into_iter() .map(|(k, v)| (k, v.into())) .collect(), + input: value.input_hash.map(|i| rattler_lock::InputHash { + hash: i.hash, + globs: Vec::from_iter(i.globs), + }), + package_build_source: None, + python_site_packages_path: value.python_site_packages_path, + dev: false, // TODO: adapt this when we implement the dev feature }) } } @@ -147,8 +277,15 @@ impl TryFrom for SourceRecord { } }); Ok(Self { - package_record: value.package_record, + name: value.name, manifest_source: value.location.try_into()?, + version: value.version, + variants: value.variants, + depends: value.depends, + constrains: value.constrains, + experimental_extra_depends: value.experimental_extra_depends, + license: value.license, + purls: value.purls, input_hash: value.input.map(|hash| InputHash { hash: hash.hash, globs: BTreeSet::from_iter(hash.globs), @@ -159,30 +296,24 @@ impl TryFrom for SourceRecord { .into_iter() .map(|(k, v)| (k, SourceSpec::from(v))) .collect(), + python_site_packages_path: value.python_site_packages_path, }) } } -impl Matches for NamelessMatchSpec { +impl Matches for MatchSpec { fn matches(&self, pkg: &SourceRecord) -> bool { - if !self.matches(&pkg.package_record) { - return false; - } - - if self.channel.is_some() { - // We don't have a channel in a source record. So if a matchspec requires that - // information it can't match. - return false; + // Check if the name matches + if let Some(ref name) = self.name { + if name != &pkg.name { + return false; + } } - true - } -} - -impl Matches for MatchSpec { - fn matches(&self, pkg: &SourceRecord) -> bool { - if !self.matches(&pkg.package_record) { - return false; + if let (Some(version_spec), Some(version)) = (&self.version, &pkg.version) { + if !version_spec.matches(version) { + return false; + } } if self.channel.is_some() { @@ -191,35 +322,21 @@ impl Matches for MatchSpec { return false; } + // For source packages, version, build, and build_number are not stored + // in the lock file, so we only match by name true } } -impl AsRef for SourceRecord { - fn as_ref(&self) -> &PackageRecord { - &self.package_record - } -} - #[cfg(test)] mod tests { use super::*; use pixi_git::sha::GitSha; - use serde_json::json; use std::str::FromStr; use url::Url; #[test] fn package_build_source_roundtrip_preserves_git_subdirectory() { - let package_record: PackageRecord = serde_json::from_value(json!({ - "name": "example", - "version": "1.0.0", - "build": "0", - "build_number": 0, - "subdir": "noarch", - })) - .expect("valid package record"); - let git_url = Url::parse("https://example.com/repo.git").unwrap(); let pinned_source = PinnedSourceSpec::Git(crate::PinnedGitSpec { git: git_url.clone(), @@ -231,11 +348,19 @@ mod tests { }); let record = SourceRecord { - package_record, + name: PackageName::from_str("example").unwrap(), + version: Some(VersionWithSource::from_str("1.0.0").unwrap()), manifest_source: pinned_source.clone(), build_source: Some(pinned_source.clone()), input_hash: None, sources: Default::default(), + variants: Default::default(), + constrains: Default::default(), + depends: Default::default(), + experimental_extra_depends: Default::default(), + license: None, + purls: None, + python_site_packages_path: None, }; let CondaPackageData::Source(conda_source) = record.clone().into() else { diff --git a/crates/pixi_reporters/src/download_verify_reporter.rs b/crates/pixi_reporters/src/download_verify_reporter.rs index 0d44293cb7..5515a2b877 100644 --- a/crates/pixi_reporters/src/download_verify_reporter.rs +++ b/crates/pixi_reporters/src/download_verify_reporter.rs @@ -146,7 +146,7 @@ impl BuildDownloadVerifyReporter { entries.insert( id, Entry { - name: format!("building {}", spec.package.name.as_source()), + name: format!("building {}", spec.package_name.as_source()), size: None, state: EntryState::Pending, }, diff --git a/examples/pixi-build/array-api-extra/pixi.lock b/examples/pixi-build/array-api-extra/pixi.lock index 88c97d8d85..95e28146e1 100644 --- a/examples/pixi-build/array-api-extra/pixi.lock +++ b/examples/pixi-build/array-api-extra/pixi.lock @@ -1,4 +1,4 @@ -version: 6 +version: 7 environments: default: channels: @@ -10,9 +10,9 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/array-api-compat-1.12.0-pyhe01879c_0.conda - conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.44-ha97dd6f_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.44-h1aa0949_3.conda - conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda + - conda: https://prefix.dev/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda - conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda @@ -23,7 +23,7 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.4-h26f9b46_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/python-3.14.0-h5989046_101_cp314.conda + - conda: https://prefix.dev/conda-forge/linux-64/python-3.14.0-h32b2ec7_102_cp314.conda - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda @@ -35,14 +35,14 @@ environments: - conda: https://prefix.dev/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda - conda: https://prefix.dev/conda-forge/osx-64/libexpat-2.7.1-h21dd04a_0.conda - - conda: https://prefix.dev/conda-forge/osx-64/libffi-3.4.6-h281671d_1.conda + - conda: https://prefix.dev/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda - conda: https://prefix.dev/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda - conda: https://prefix.dev/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda - conda: https://prefix.dev/conda-forge/osx-64/libsqlite-3.50.4-h39a8b3b_0.conda - conda: https://prefix.dev/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - conda: https://prefix.dev/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda - conda: https://prefix.dev/conda-forge/osx-64/openssl-3.5.4-h230baf5_0.conda - - conda: https://prefix.dev/conda-forge/osx-64/python-3.14.0-h759804c_101_cp314.conda + - conda: https://prefix.dev/conda-forge/osx-64/python-3.14.0-hf88997e_102_cp314.conda - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://prefix.dev/conda-forge/osx-64/readline-8.2-h7cca4af_2.conda - conda: https://prefix.dev/conda-forge/osx-64/tk-8.6.13-hf689a15_2.conda @@ -55,14 +55,14 @@ environments: - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.7.1-hec049ff_0.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.6-h1da3d7d_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.50.4-h4237e3c_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.4-h5503f6c_0.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.14.0-h8929636_101_cp314.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.14.0-h40d2674_102_cp314.conda - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda @@ -74,13 +74,13 @@ environments: - conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.10.5-h4c7d964_0.conda - conda: https://prefix.dev/conda-forge/win-64/libexpat-2.7.1-hac47afa_0.conda - - conda: https://prefix.dev/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda + - conda: https://prefix.dev/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda - conda: https://prefix.dev/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.50.4-hf5d6505_0.conda - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.4-h725018a_0.conda - - conda: https://prefix.dev/conda-forge/win-64/python-3.14.0-h6fd79ff_101_cp314.conda + - conda: https://prefix.dev/conda-forge/win-64/python-3.14.0-h4b44e0e_102_cp314.conda - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda @@ -122,19 +122,17 @@ packages: timestamp: 1747403732947 - conda: . name: array-api-extra - version: 0.8.0 - build: pyh4616a5c_0 - subdir: noarch depends: - python >=3.10 - python * - array-api-compat license: MIT input: - hash: 1101422a995a18b9c73ca5617a726f185782e5329c2739d754b921baaf16b7ca + hash: fe9f9c29f1f198e2c28d9586f19a7ae6762b0f867789c6a91ed9948620b0f2c3 globs: - - recipe.yaml - variants.yaml + variants: + target_platform: noarch - conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 md5: 51a19bba1b8ebfb60df25cde030b7ebc @@ -199,17 +197,17 @@ packages: license_family: MIT size: 11857802 timestamp: 1720853997952 -- conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.44-ha97dd6f_2.conda - sha256: 707dfb8d55d7a5c6f95c772d778ef07a7ca85417d9971796f7d3daad0b615de8 - md5: 14bae321b8127b63cba276bd53fac237 +- conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.44-h1aa0949_3.conda + sha256: e26f4435c372264136a9c71e19f7620ec7f107abe73134ff305d26bfaeabb0b3 + md5: 72cc69c30de0b6d39c7f97f501fdbb1c depends: - __glibc >=2.17,<3.0.a0 + - zstd >=1.5.7,<1.6.0a0 constrains: - binutils_impl_linux-64 2.44 license: GPL-3.0-only - license_family: GPL - size: 747158 - timestamp: 1758810907507 + size: 741904 + timestamp: 1761248509961 - conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda sha256: da2080da8f0288b95dd86765c801c6e166c4619b910b11f9a8446fb852438dc2 md5: 4211416ecba1866fab0c6470986c22d6 @@ -257,45 +255,45 @@ packages: license_family: MIT size: 141322 timestamp: 1752719767870 -- conda: https://prefix.dev/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - sha256: 764432d32db45466e87f10621db5b74363a9f847d2b8b1f9743746cd160f06ab - md5: ede4673863426c0883c0063d853bbd85 +- conda: https://prefix.dev/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda + sha256: 25cbdfa65580cfab1b8d15ee90b4c9f1e0d72128f1661449c9a999d341377d54 + md5: 35f29eec58405aaf55e01cb470d8c26a depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT - size: 57433 - timestamp: 1743434498161 -- conda: https://prefix.dev/conda-forge/osx-64/libffi-3.4.6-h281671d_1.conda - sha256: 6394b1bc67c64a21a5cc73d1736d1d4193a64515152e861785c44d2cfc49edf3 - md5: 4ca9ea59839a9ca8df84170fab4ceb41 + size: 57821 + timestamp: 1760295480630 +- conda: https://prefix.dev/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda + sha256: 277dc89950f5d97f1683f26e362d6dca3c2efa16cb2f6fdb73d109effa1cd3d0 + md5: d214916b24c625bcc459b245d509f22e depends: - __osx >=10.13 license: MIT license_family: MIT - size: 51216 - timestamp: 1743434595269 -- conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.6-h1da3d7d_1.conda - sha256: c6a530924a9b14e193ea9adfe92843de2a806d1b7dbfd341546ece9653129e60 - md5: c215a60c2935b517dcda8cad4705734d + size: 52573 + timestamp: 1760295626449 +- conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda + sha256: 9b8acdf42df61b7bfe8bdc545c016c29e61985e79748c64ad66df47dbc2e295f + md5: 411ff7cd5d1472bba0f55c0faf04453b depends: - __osx >=11.0 license: MIT license_family: MIT - size: 39839 - timestamp: 1743434670405 -- conda: https://prefix.dev/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda - sha256: d3b0b8812eab553d3464bbd68204f007f1ebadf96ce30eb0cbc5159f72e353f5 - md5: 85d8fa5e55ed8f93f874b3b23ed54ec6 + size: 40251 + timestamp: 1760295839166 +- conda: https://prefix.dev/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda + sha256: ddff25aaa4f0aa535413f5d831b04073789522890a4d8626366e43ecde1534a3 + md5: ba4ad812d2afc22b9a34ce8327a0930f depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT - size: 44978 - timestamp: 1743435053850 + size: 44866 + timestamp: 1760295760649 - conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda sha256: 08f9b87578ab981c7713e4e6a7d935e40766e10691732bba376d4964562bcb45 md5: c0374badb3a5d4b1372db28d19462c53 @@ -576,16 +574,16 @@ packages: license_family: Apache size: 9218823 timestamp: 1759326176247 -- conda: https://prefix.dev/conda-forge/linux-64/python-3.14.0-h5989046_101_cp314.conda - build_number: 101 - sha256: 61ae2c29b1097c12161a09a4061be8f909bc1387d8388e875d8ed5e357ef0824 - md5: b2ad21488149ec2c4d83640619de2430 +- conda: https://prefix.dev/conda-forge/linux-64/python-3.14.0-h32b2ec7_102_cp314.conda + build_number: 102 + sha256: 76d750045b94fded676323bfd01975a26a474023635735773d0e4d80aaa72518 + md5: 0a19d2cc6eb15881889b0c6fa7d6a78d depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 - ld_impl_linux-64 >=2.36.1 - libexpat >=2.7.1,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 + - libffi >=3.5.2,<3.6.0a0 - libgcc >=14 - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 @@ -600,18 +598,18 @@ packages: - tzdata - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 - size: 36692257 - timestamp: 1760299587505 + size: 36681389 + timestamp: 1761176838143 python_site_packages_path: lib/python3.14/site-packages -- conda: https://prefix.dev/conda-forge/osx-64/python-3.14.0-h759804c_101_cp314.conda - build_number: 101 - sha256: a93cf6bbd5bf2fe0ddab09f5dadad49b41bc13eb85c35d8ae84d3989624fca2f - md5: 9eca06d9b62b949495b072df4ac1d2a2 +- conda: https://prefix.dev/conda-forge/osx-64/python-3.14.0-hf88997e_102_cp314.conda + build_number: 102 + sha256: 2470866eee70e75d6be667aa537424b63f97c397a0a90f05f2bab347b9ed5a51 + md5: 7917d1205eed3e72366a3397dca8a2af depends: - __osx >=10.13 - bzip2 >=1.0.8,<2.0a0 - libexpat >=2.7.1,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 + - libffi >=3.5.2,<3.6.0a0 - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - libsqlite >=3.50.4,<4.0a0 @@ -624,18 +622,18 @@ packages: - tzdata - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 - size: 14431661 - timestamp: 1760300228434 + size: 14427639 + timestamp: 1761177864469 python_site_packages_path: lib/python3.14/site-packages -- conda: https://prefix.dev/conda-forge/osx-arm64/python-3.14.0-h8929636_101_cp314.conda - build_number: 101 - sha256: 0b821bbff81b0735d94aca62958b152ad9565773f99760fe0dd59db8e7154245 - md5: 01a476ede0de7e71c2e9b178315cc7f1 +- conda: https://prefix.dev/conda-forge/osx-arm64/python-3.14.0-h40d2674_102_cp314.conda + build_number: 102 + sha256: 3ca1da026fe5df8a479d60e1d3ed02d9bc50fcbafd5f125d86abe70d21a34cc7 + md5: a9ff09231c555da7e30777747318321b depends: - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - libexpat >=2.7.1,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 + - libffi >=3.5.2,<3.6.0a0 - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - libsqlite >=3.50.4,<4.0a0 @@ -648,17 +646,17 @@ packages: - tzdata - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 - size: 13530883 - timestamp: 1760298885457 + size: 13590581 + timestamp: 1761177195716 python_site_packages_path: lib/python3.14/site-packages -- conda: https://prefix.dev/conda-forge/win-64/python-3.14.0-h6fd79ff_101_cp314.conda - build_number: 101 - sha256: 469a62c550143b30f26bdbb445d2596c7299ad8e278763388793ed106773a1ee - md5: 834cb790da2cbee272bf888e4558c92a +- conda: https://prefix.dev/conda-forge/win-64/python-3.14.0-h4b44e0e_102_cp314.conda + build_number: 102 + sha256: 2b8c8fcafcc30690b4c5991ee28eb80c962e50e06ce7da03b2b302e2d39d6a81 + md5: 3e1ce2fb0f277cebcae01a3c418eb5e2 depends: - bzip2 >=1.0.8,<2.0a0 - libexpat >=2.7.1,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 + - libffi >=3.5.2,<3.6.0a0 - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - libsqlite >=3.50.4,<4.0a0 @@ -672,8 +670,8 @@ packages: - vc14_runtime >=14.44.35208 - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 - size: 16903251 - timestamp: 1760298231628 + size: 16706286 + timestamp: 1761175439068 python_site_packages_path: Lib/site-packages - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda build_number: 8 diff --git a/examples/pixi-build/cpp-sdl/pixi.lock b/examples/pixi-build/cpp-sdl/pixi.lock index 6557ba8bb0..bd4cf8828d 100644 --- a/examples/pixi-build/cpp-sdl/pixi.lock +++ b/examples/pixi-build/cpp-sdl/pixi.lock @@ -1,4 +1,4 @@ -version: 6 +version: 7 environments: default: channels: @@ -7,8 +7,8 @@ environments: linux-64: - conda: https://prefix.dev/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://prefix.dev/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://prefix.dev/conda-forge/linux-64/attr-2.5.1-h166bdaf_1.tar.bz2 - - conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda + - conda: https://prefix.dev/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda - conda: https://prefix.dev/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda - conda: https://prefix.dev/conda-forge/linux-64/gettext-0.25.1-h3f43e3d_1.conda - conda: https://prefix.dev/conda-forge/linux-64/gettext-tools-0.25.1-h3f43e3d_1.conda @@ -16,21 +16,21 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/libasprintf-0.25.1-h3f43e3d_1.conda - conda: https://prefix.dev/conda-forge/linux-64/libasprintf-devel-0.25.1-h3f43e3d_1.conda - conda: https://prefix.dev/conda-forge/linux-64/libcap-2.76-h0b2e76d_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/libdrm-2.4.125-hb9d3cd8_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda - conda: https://prefix.dev/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda - conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda + - conda: https://prefix.dev/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.1.0-h767d61c_4.conda - - conda: https://prefix.dev/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_4.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda - conda: https://prefix.dev/conda-forge/linux-64/libgcrypt-lib-1.11.1-hb9d3cd8_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libgettextpo-0.25.1-h3f43e3d_1.conda - conda: https://prefix.dev/conda-forge/linux-64/libgettextpo-devel-0.25.1-h3f43e3d_1.conda - conda: https://prefix.dev/conda-forge/linux-64/libgl-1.7.0-ha4b6fd6_2.conda - - conda: https://prefix.dev/conda-forge/linux-64/libglib-2.84.3-hf39c6af_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libglib-2.86.0-h32235b2_1.conda - conda: https://prefix.dev/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda - conda: https://prefix.dev/conda-forge/linux-64/libglx-1.7.0-ha4b6fd6_2.conda - - conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.1.0-h767d61c_4.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda - conda: https://prefix.dev/conda-forge/linux-64/libgpg-error-1.55-h3f2d84a_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libiconv-1.18-h3b78370_2.conda - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda @@ -38,8 +38,8 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/libopus-1.5.2-hd0c01bc_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libpciaccess-0.18-hb9d3cd8_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda - - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_4.conda - - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_4.conda + - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda + - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda - conda: https://prefix.dev/conda-forge/linux-64/libsystemd0-257.9-h996ca69_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libudev1-257.9-h085a93f_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libunwind-1.8.3-h65a8314_0.conda @@ -48,18 +48,19 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/libvorbis-1.3.7-h54a6638_2.conda - conda: https://prefix.dev/conda-forge/linux-64/libvulkan-loader-1.4.328.1-h5279c79_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libxcb-1.17.0-h8a09558_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/libxml2-2.13.8-h2cb61b6_1.conda + - conda: https://prefix.dev/conda-forge/linux-64/libxkbcommon-1.12.2-hca5e8e5_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libxml2-16-2.15.1-hf2a90c1_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libxml2-2.15.1-h031cc0b_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://prefix.dev/conda-forge/linux-64/lz4-c-1.10.0-h5888daf_1.conda - conda: https://prefix.dev/conda-forge/linux-64/mpg123-1.32.9-hc50e24c_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/pcre2-10.45-hc749103_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda - conda: https://prefix.dev/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda - - conda: https://prefix.dev/conda-forge/linux-64/pulseaudio-client-17.0-hac146a9_1.conda + - conda: https://prefix.dev/conda-forge/linux-64/pulseaudio-client-17.0-h9a8bead_2.conda - conda: https://prefix.dev/conda-forge/linux-64/sdl2-2.32.56-h54a6638_0.conda - conda: https://prefix.dev/conda-forge/linux-64/sdl3-3.2.24-h68140b3_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/wayland-1.24.0-h3e06ad9_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/xkeyboard-config-2.45-hb9d3cd8_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda + - conda: https://prefix.dev/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda - conda: https://prefix.dev/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda - conda: https://prefix.dev/conda-forge/linux-64/xorg-libxau-1.0.12-hb9d3cd8_0.conda - conda: https://prefix.dev/conda-forge/linux-64/xorg-libxcursor-1.2.3-hb9d3cd8_0.conda @@ -71,52 +72,56 @@ environments: - conda: https://prefix.dev/conda-forge/linux-64/xorg-libxscrnsaver-1.2.4-hb9d3cd8_0.conda - conda: https://prefix.dev/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda - conda: . - subdir: linux-64 + variants: + target_platform: linux-64 osx-64: - - conda: https://prefix.dev/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda + - conda: https://prefix.dev/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda - conda: https://prefix.dev/conda-forge/osx-64/dbus-1.16.2-h27bd348_0.conda - - conda: https://prefix.dev/conda-forge/osx-64/libcxx-21.1.3-h3d58e20_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libcxx-21.1.4-h3d58e20_0.conda - conda: https://prefix.dev/conda-forge/osx-64/libexpat-2.7.1-h21dd04a_0.conda - - conda: https://prefix.dev/conda-forge/osx-64/libffi-3.4.6-h281671d_1.conda - - conda: https://prefix.dev/conda-forge/osx-64/libglib-2.84.3-h5fed8df_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/libglib-2.86.0-h6ca3a76_1.conda - conda: https://prefix.dev/conda-forge/osx-64/libiconv-1.18-h57a12c2_2.conda - conda: https://prefix.dev/conda-forge/osx-64/libintl-0.25.1-h3184127_1.conda - conda: https://prefix.dev/conda-forge/osx-64/libusb-1.0.29-h2287256_0.conda - conda: https://prefix.dev/conda-forge/osx-64/libvulkan-loader-1.4.328.1-hfc0b2d5_0.conda - conda: https://prefix.dev/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://prefix.dev/conda-forge/osx-64/pcre2-10.45-hf733adb_0.conda + - conda: https://prefix.dev/conda-forge/osx-64/pcre2-10.46-ha3e7e28_0.conda - conda: https://prefix.dev/conda-forge/osx-64/sdl2-2.32.56-h53ec75d_0.conda - conda: https://prefix.dev/conda-forge/osx-64/sdl3-3.2.24-h53c92ef_0.conda - conda: . - subdir: osx-64 + variants: + target_platform: osx-64 osx-arm64: - - conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda - conda: https://prefix.dev/conda-forge/osx-arm64/dbus-1.16.2-hda038a8_0.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-21.1.3-hf598326_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-21.1.4-hf598326_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.7.1-hec049ff_0.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.6-h1da3d7d_1.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/libglib-2.84.3-h587fa63_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libglib-2.86.0-he69a767_1.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libintl-0.25.1-h493aca8_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libusb-1.0.29-hbc156a2_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libvulkan-loader-1.4.328.1-h49c215f_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/pcre2-10.45-ha881caa_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/pcre2-10.46-h7125dd6_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/sdl2-2.32.56-h248ca61_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/sdl3-3.2.24-h919df07_0.conda - conda: . - subdir: osx-arm64 + variants: + target_platform: osx-arm64 win-64: - conda: https://prefix.dev/conda-forge/win-64/libusb-1.0.29-h1839187_0.conda - conda: https://prefix.dev/conda-forge/win-64/libvulkan-loader-1.4.328.1-h477610d_0.conda - conda: https://prefix.dev/conda-forge/win-64/sdl2-2.32.56-h5112557_0.conda - conda: https://prefix.dev/conda-forge/win-64/sdl3-3.2.24-h5112557_0.conda - - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-h41ae7f8_31.conda - - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_31.conda - - conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.44.35208-h818238b_31.conda + - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-h2b53caa_32.conda + - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda + - conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda - conda: . - build: h9352c13_0 + variants: + cxx_compiler: vs2019 packages: - conda: https://prefix.dev/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 sha256: fe51de6107f9edc7aa4f786a70f4a883943bc9d39b3bb7307c04c41410990726 @@ -137,43 +142,44 @@ packages: license_family: BSD size: 23621 timestamp: 1650670423406 -- conda: https://prefix.dev/conda-forge/linux-64/attr-2.5.1-h166bdaf_1.tar.bz2 - sha256: 82c13b1772c21fc4a17441734de471d3aabf82b61db9b11f4a1bd04a9c4ac324 - md5: d9c69a24ad678ffce24c6543a0176b00 +- conda: https://prefix.dev/conda-forge/linux-64/attr-2.5.2-h39aace5_0.conda + sha256: a9c114cbfeda42a226e2db1809a538929d2f118ef855372293bd188f71711c48 + md5: 791365c5f65975051e4e017b5da3abf5 depends: - - libgcc-ng >=12 + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 license: GPL-2.0-or-later license_family: GPL - size: 71042 - timestamp: 1660065501192 -- conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d - md5: 62ee74e96c5ebb0af99386de58cf9553 + size: 68072 + timestamp: 1756738968573 +- conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 + md5: 51a19bba1b8ebfb60df25cde030b7ebc depends: - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 + - libgcc >=14 license: bzip2-1.0.6 license_family: BSD - size: 252783 - timestamp: 1720974456583 -- conda: https://prefix.dev/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda - sha256: cad153608b81fb24fc8c509357daa9ae4e49dfc535b2cb49b91e23dbd68fc3c5 - md5: 7ed4301d437b59045be7e051a0308211 + size: 260341 + timestamp: 1757437258798 +- conda: https://prefix.dev/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda + sha256: 8f50b58efb29c710f3cecf2027a8d7325ba769ab10c746eff75cea3ac050b10c + md5: 97c4b3bd8a90722104798175a1bdddbf depends: - __osx >=10.13 license: bzip2-1.0.6 license_family: BSD - size: 134188 - timestamp: 1720974491916 -- conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda - sha256: adfa71f158cbd872a36394c56c3568e6034aa55c623634b37a4836bd036e6b91 - md5: fc6948412dbbbe9a4c9ddbbcfe0a79ab + size: 132607 + timestamp: 1757437730085 +- conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + sha256: b456200636bd5fecb2bec63f7e0985ad2097cf1b83d60ce0b6968dffa6d02aa1 + md5: 58fd217444c2a5701a44244faf518206 depends: - __osx >=11.0 license: bzip2-1.0.6 license_family: BSD - size: 122909 - timestamp: 1720974522888 + size: 125061 + timestamp: 1757437486465 - conda: https://prefix.dev/conda-forge/linux-64/dbus-1.16.2-h3c4dab8_0.conda sha256: 3b988146a50e165f0fa4e839545c679af88e4782ec284cc7b6d07dd226d6a068 md5: 679616eb5ad4e521c83da4650860aba7 @@ -282,35 +288,35 @@ packages: license_family: BSD size: 121852 timestamp: 1744577167992 -- conda: https://prefix.dev/conda-forge/osx-64/libcxx-21.1.3-h3d58e20_0.conda - sha256: 9bba2ce10e1c390a4091ca48fab0c71c010f6526c27ac2da53399940ad4c113f - md5: 432d125a340932454d777b66b09c32a1 +- conda: https://prefix.dev/conda-forge/osx-64/libcxx-21.1.4-h3d58e20_0.conda + sha256: 64f58f7ad9076598ae4a19f383f6734116d96897032c77de599660233f2924f9 + md5: 17c4292004054f6783b16b55b499f086 depends: - __osx >=10.13 license: Apache-2.0 WITH LLVM-exception license_family: Apache - size: 571632 - timestamp: 1760166417842 -- conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-21.1.3-hf598326_0.conda - sha256: b9bad452e3e1d0cc597d907681461341209cb7576178d5c1933026a650b381d1 - md5: e976227574dfcd0048324576adf8d60d + size: 571252 + timestamp: 1761043932993 +- conda: https://prefix.dev/conda-forge/osx-arm64/libcxx-21.1.4-hf598326_0.conda + sha256: df55e80dda21f2581366f66cf18a6c11315d611f6fb01e56011c5199f983c0d9 + md5: 6002a2ba796f1387b6a5c6d77051d1db depends: - __osx >=11.0 license: Apache-2.0 WITH LLVM-exception license_family: Apache - size: 568715 - timestamp: 1760166479630 -- conda: https://prefix.dev/conda-forge/linux-64/libdrm-2.4.125-hb9d3cd8_0.conda - sha256: f53458db897b93b4a81a6dbfd7915ed8fa4a54951f97c698dde6faa028aadfd2 - md5: 4c0ab57463117fbb8df85268415082f5 + size: 567892 + timestamp: 1761043967532 +- conda: https://prefix.dev/conda-forge/linux-64/libdrm-2.4.125-hb03c661_1.conda + sha256: c076a213bd3676cc1ef22eeff91588826273513ccc6040d9bea68bccdc849501 + md5: 9314bc5a1fe7d1044dc9dfd3ef400535 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - libpciaccess >=0.18,<0.19.0a0 license: MIT license_family: MIT - size: 246161 - timestamp: 1749904704373 + size: 310785 + timestamp: 1757212153962 - conda: https://prefix.dev/conda-forge/linux-64/libegl-1.7.0-ha4b6fd6_2.conda sha256: 7fd5408d359d05a969133e47af580183fbf38e2235b562193d427bb9dad79723 md5: c151d5eb730e9b7480e6d48c0fc44048 @@ -354,34 +360,34 @@ packages: license_family: MIT size: 65971 timestamp: 1752719657566 -- conda: https://prefix.dev/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - sha256: 764432d32db45466e87f10621db5b74363a9f847d2b8b1f9743746cd160f06ab - md5: ede4673863426c0883c0063d853bbd85 +- conda: https://prefix.dev/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda + sha256: 25cbdfa65580cfab1b8d15ee90b4c9f1e0d72128f1661449c9a999d341377d54 + md5: 35f29eec58405aaf55e01cb470d8c26a depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT - size: 57433 - timestamp: 1743434498161 -- conda: https://prefix.dev/conda-forge/osx-64/libffi-3.4.6-h281671d_1.conda - sha256: 6394b1bc67c64a21a5cc73d1736d1d4193a64515152e861785c44d2cfc49edf3 - md5: 4ca9ea59839a9ca8df84170fab4ceb41 + size: 57821 + timestamp: 1760295480630 +- conda: https://prefix.dev/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda + sha256: 277dc89950f5d97f1683f26e362d6dca3c2efa16cb2f6fdb73d109effa1cd3d0 + md5: d214916b24c625bcc459b245d509f22e depends: - __osx >=10.13 license: MIT license_family: MIT - size: 51216 - timestamp: 1743434595269 -- conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.6-h1da3d7d_1.conda - sha256: c6a530924a9b14e193ea9adfe92843de2a806d1b7dbfd341546ece9653129e60 - md5: c215a60c2935b517dcda8cad4705734d + size: 52573 + timestamp: 1760295626449 +- conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda + sha256: 9b8acdf42df61b7bfe8bdc545c016c29e61985e79748c64ad66df47dbc2e295f + md5: 411ff7cd5d1472bba0f55c0faf04453b depends: - __osx >=11.0 license: MIT license_family: MIT - size: 39839 - timestamp: 1743434670405 + size: 40251 + timestamp: 1760295839166 - conda: https://prefix.dev/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda sha256: 65908b75fa7003167b8a8f0001e11e58ed5b1ef5e98b96ab2ba66d7c1b822c7d md5: ee48bf17cc83a00f59ca1494d5646869 @@ -395,28 +401,28 @@ packages: license_family: BSD size: 394383 timestamp: 1687765514062 -- conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.1.0-h767d61c_4.conda - sha256: 144e35c1c2840f2dc202f6915fc41879c19eddbb8fa524e3ca4aa0d14018b26f - md5: f406dcbb2e7bef90d793e50e79a2882b +- conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda + sha256: 08f9b87578ab981c7713e4e6a7d935e40766e10691732bba376d4964562bcb45 + md5: c0374badb3a5d4b1372db28d19462c53 depends: - __glibc >=2.17,<3.0.a0 - _openmp_mutex >=4.5 constrains: - - libgcc-ng ==15.1.0=*_4 - - libgomp 15.1.0 h767d61c_4 + - libgomp 15.2.0 h767d61c_7 + - libgcc-ng ==15.2.0=*_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL - size: 824153 - timestamp: 1753903866511 -- conda: https://prefix.dev/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_4.conda - sha256: 76ceac93ed98f208363d6e9c75011b0ff7b97b20f003f06461a619557e726637 - md5: 28771437ffcd9f3417c66012dc49a3be + size: 822552 + timestamp: 1759968052178 +- conda: https://prefix.dev/conda-forge/linux-64/libgcc-ng-15.2.0-h69a702a_7.conda + sha256: 2045066dd8e6e58aaf5ae2b722fb6dfdbb57c862b5f34ac7bfb58c40ef39b6ad + md5: 280ea6eee9e2ddefde25ff799c4f0363 depends: - - libgcc 15.1.0 h767d61c_4 + - libgcc 15.2.0 h767d61c_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL - size: 29249 - timestamp: 1753903872571 + size: 29313 + timestamp: 1759968065504 - conda: https://prefix.dev/conda-forge/linux-64/libgcrypt-lib-1.11.1-hb9d3cd8_0.conda sha256: dc9c7d7a6c0e6639deee6fde2efdc7e119e7739a6b229fa5f9049a449bae6109 md5: 8504a291085c9fb809b66cabd5834307 @@ -460,51 +466,51 @@ packages: license: LicenseRef-libglvnd size: 134712 timestamp: 1731330998354 -- conda: https://prefix.dev/conda-forge/linux-64/libglib-2.84.3-hf39c6af_0.conda - sha256: e1ad3d9ddaa18f95ff5d244587fd1a37aca6401707f85a37f7d9b5002fcf16d0 - md5: 467f23819b1ea2b89c3fc94d65082301 +- conda: https://prefix.dev/conda-forge/linux-64/libglib-2.86.0-h32235b2_1.conda + sha256: 8f4ccf81ebde248f8a8070a987e2dc7caa02471ae3506667da8e02176a8e0060 + md5: a400fd9bad095c7cdf74661552ef802f depends: - __glibc >=2.17,<3.0.a0 - - libffi >=3.4.6,<3.5.0a0 + - libffi >=3.5.2,<3.6.0a0 - libgcc >=14 - libiconv >=1.18,<2.0a0 - libzlib >=1.3.1,<2.0a0 - - pcre2 >=10.45,<10.46.0a0 + - pcre2 >=10.46,<10.47.0a0 constrains: - - glib 2.84.3 *_0 + - glib 2.86.0 *_1 license: LGPL-2.1-or-later - size: 3961899 - timestamp: 1754315006443 -- conda: https://prefix.dev/conda-forge/osx-64/libglib-2.84.3-h5fed8df_0.conda - sha256: 28d60cfaa74dd5427b35941ea28069bfd87d4dfdaaae79b13e569b4b4c21098d - md5: 2bb92de7159f9c47a4455eb3c08484d8 + size: 3963505 + timestamp: 1761244787601 +- conda: https://prefix.dev/conda-forge/osx-64/libglib-2.86.0-h6ca3a76_1.conda + sha256: 1203396d3e367efcb38ae1500ff26d48459ebdbbec57ab811ad1406078e35bd0 + md5: 030b0493f4bcabc77e5a56d03169a0bc depends: - __osx >=10.13 - - libffi >=3.4.6,<3.5.0a0 + - libffi >=3.5.2,<3.6.0a0 - libiconv >=1.18,<2.0a0 - libintl >=0.25.1,<1.0a0 - libzlib >=1.3.1,<2.0a0 - - pcre2 >=10.45,<10.46.0a0 + - pcre2 >=10.46,<10.47.0a0 constrains: - - glib 2.84.3 *_0 + - glib 2.86.0 *_1 license: LGPL-2.1-or-later - size: 3735183 - timestamp: 1754315274931 -- conda: https://prefix.dev/conda-forge/osx-arm64/libglib-2.84.3-h587fa63_0.conda - sha256: a30510a18f0b85a036f99c744750611b5f26b972cfa70cc9f130b9f42e5bbc18 - md5: bb98995c244b6038892fd59a694a93ed + size: 3685678 + timestamp: 1761246545220 +- conda: https://prefix.dev/conda-forge/osx-arm64/libglib-2.86.0-he69a767_1.conda + sha256: 58b0ccce58b6503cd9448d332c46de9b0757bee6251eb14ac5dd95f7ad3e83fe + md5: 16edb7fa702df38c414e1638de3596de depends: - __osx >=11.0 - - libffi >=3.4.6,<3.5.0a0 + - libffi >=3.5.2,<3.6.0a0 - libiconv >=1.18,<2.0a0 - libintl >=0.25.1,<1.0a0 - libzlib >=1.3.1,<2.0a0 - - pcre2 >=10.45,<10.46.0a0 + - pcre2 >=10.46,<10.47.0a0 constrains: - - glib 2.84.3 *_0 + - glib 2.86.0 *_1 license: LGPL-2.1-or-later - size: 3661135 - timestamp: 1754315631978 + size: 3656888 + timestamp: 1761246684692 - conda: https://prefix.dev/conda-forge/linux-64/libglvnd-1.7.0-ha4b6fd6_2.conda sha256: 1175f8a7a0c68b7f81962699751bb6574e6f07db4c9f72825f978e3016f46850 md5: 434ca7e50e40f4918ab701e3facd59a0 @@ -523,15 +529,15 @@ packages: license: LicenseRef-libglvnd size: 75504 timestamp: 1731330988898 -- conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.1.0-h767d61c_4.conda - sha256: e0487a8fec78802ac04da0ac1139c3510992bc58a58cde66619dde3b363c2933 - md5: 3baf8976c96134738bba224e9ef6b1e5 +- conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda + sha256: e9fb1c258c8e66ee278397b5822692527c5f5786d372fe7a869b900853f3f5ca + md5: f7b4d76975aac7e5d9e6ad13845f92fe depends: - __glibc >=2.17,<3.0.a0 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL - size: 447289 - timestamp: 1753903801049 + size: 447919 + timestamp: 1759967942498 - conda: https://prefix.dev/conda-forge/linux-64/libgpg-error-1.55-h3f2d84a_0.conda sha256: 697334de4786a1067ea86853e520c64dd72b11a05137f5b318d8a444007b5e60 md5: 2bd47db5807daade8500ed7ca4c512a4 @@ -643,25 +649,27 @@ packages: license_family: LGPL size: 354372 timestamp: 1695747735668 -- conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.1.0-h8f9b012_4.conda - sha256: b5b239e5fca53ff90669af1686c86282c970dd8204ebf477cf679872eb6d48ac - md5: 3c376af8888c386b9d3d1c2701e2f3ab +- conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda + sha256: 1b981647d9775e1cdeb2fab0a4dd9cd75a6b0de2963f6c3953dbd712f78334b3 + md5: 5b767048b1b3ee9a954b06f4084f93dc depends: - __glibc >=2.17,<3.0.a0 - - libgcc 15.1.0 h767d61c_4 + - libgcc 15.2.0 h767d61c_7 + constrains: + - libstdcxx-ng ==15.2.0=*_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL - size: 3903453 - timestamp: 1753903894186 -- conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-ng-15.1.0-h4852527_4.conda - sha256: 81c841c1cf4c0d06414aaa38a249f9fdd390554943065c3a0b18a9fb7e8cc495 - md5: 2d34729cbc1da0ec988e57b13b712067 + size: 3898269 + timestamp: 1759968103436 +- conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-ng-15.2.0-h4852527_7.conda + sha256: 024fd46ac3ea8032a5ec3ea7b91c4c235701a8bf0e6520fe5e6539992a6bd05f + md5: f627678cf829bd70bccf141a19c3ad3e depends: - - libstdcxx 15.1.0 h8f9b012_4 + - libstdcxx 15.2.0 h8f9b012_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL - size: 29317 - timestamp: 1753903924491 + size: 29343 + timestamp: 1759968157195 - conda: https://prefix.dev/conda-forge/linux-64/libsystemd0-257.9-h996ca69_0.conda sha256: 6b063df2d13dc9cedeae7b1591b1917ced7f4e1b04f7246e66cc7fb0088dea07 md5: b6d222422c17dc11123e63fae4ad4178 @@ -829,36 +837,54 @@ packages: license_family: MIT size: 395888 timestamp: 1727278577118 -- conda: https://prefix.dev/conda-forge/linux-64/libxkbcommon-1.11.0-he8b52b9_0.conda - sha256: 23f47e86cc1386e7f815fa9662ccedae151471862e971ea511c5c886aa723a54 - md5: 74e91c36d0eef3557915c68b6c2bef96 +- conda: https://prefix.dev/conda-forge/linux-64/libxkbcommon-1.12.2-hca5e8e5_0.conda + sha256: e11e8890a097c9e16a3fc40f2540d887ef2497e7f31f6e5a744aa951f82dbeea + md5: 3c3e5ccbb2d96ac75e1b8b028586db5c depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 - libstdcxx >=14 - libxcb >=1.17.0,<2.0a0 - - libxml2 >=2.13.8,<2.14.0a0 + - libxml2 + - libxml2-16 >=2.14.6 - xkeyboard-config - xorg-libxau >=1.0.12,<2.0a0 license: MIT/X11 Derivative license_family: MIT - size: 791328 - timestamp: 1754703902365 -- conda: https://prefix.dev/conda-forge/linux-64/libxml2-2.13.8-h2cb61b6_1.conda - sha256: 2c80ef042b47dfddb1f425d57d367e0657f8477d80111644c88b172ff2f99151 - md5: 42a8e4b54e322b4cd1dbfb30a8a7ce9e + size: 830418 + timestamp: 1760990182307 +- conda: https://prefix.dev/conda-forge/linux-64/libxml2-2.15.1-h031cc0b_0.conda + sha256: ee64e507b37b073e0bdad739e35330933dd5be7c639600a096551a6968f1035d + md5: a67cd8f7b0369bbf2c40411f05a62f3b depends: - __glibc >=2.17,<3.0.a0 - libgcc >=14 - libiconv >=1.18,<2.0a0 - liblzma >=5.8.1,<6.0a0 + - libxml2-16 2.15.1 hf2a90c1_0 - libzlib >=1.3.1,<2.0a0 constrains: - icu <0.0a0 license: MIT license_family: MIT - size: 697020 - timestamp: 1754315347913 + size: 45292 + timestamp: 1761015784683 +- conda: https://prefix.dev/conda-forge/linux-64/libxml2-16-2.15.1-hf2a90c1_0.conda + sha256: f5220ff49efc31431279859049199b9250e79f98c1dee1da12feb74bda2d9cf1 + md5: 23720d17346b21efb08d68c2255c8431 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libiconv >=1.18,<2.0a0 + - liblzma >=5.8.1,<6.0a0 + - libzlib >=1.3.1,<2.0a0 + constrains: + - libxml2 2.15.1 + - icu <0.0a0 + license: MIT + license_family: MIT + size: 554734 + timestamp: 1761015772672 - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 md5: edb0dca6bc32e4f4789199455a1dbeb8 @@ -915,40 +941,40 @@ packages: license_family: LGPL size: 491140 timestamp: 1730581373280 -- conda: https://prefix.dev/conda-forge/linux-64/pcre2-10.45-hc749103_0.conda - sha256: 27c4014f616326240dcce17b5f3baca3953b6bc5f245ceb49c3fa1e6320571eb - md5: b90bece58b4c2bf25969b70f3be42d25 +- conda: https://prefix.dev/conda-forge/linux-64/pcre2-10.46-h1321c63_0.conda + sha256: 5c7380c8fd3ad5fc0f8039069a45586aa452cf165264bc5a437ad80397b32934 + md5: 7fa07cb0fb1b625a089ccc01218ee5b1 depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 - - libgcc >=13 + - libgcc >=14 - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD - size: 1197308 - timestamp: 1745955064657 -- conda: https://prefix.dev/conda-forge/osx-64/pcre2-10.45-hf733adb_0.conda - sha256: 5b2c93ee8714c17682cd926127f1e712efef00441a79732635a80b24f5adc212 - md5: d9f1976154f2f45588251dcfc48bcdda + size: 1209177 + timestamp: 1756742976157 +- conda: https://prefix.dev/conda-forge/osx-64/pcre2-10.46-ha3e7e28_0.conda + sha256: cb262b7f369431d1086445ddd1f21d40003bb03229dfc1d687e3a808de2663a6 + md5: 3b504da3a4f6d8b2b1f969686a0bf0c0 depends: - __osx >=10.13 - bzip2 >=1.0.8,<2.0a0 - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD - size: 1086588 - timestamp: 1745955211398 -- conda: https://prefix.dev/conda-forge/osx-arm64/pcre2-10.45-ha881caa_0.conda - sha256: e9ecb706b58b5a2047c077b3a1470e8554f3aad02e9c3c00cfa35d537420fea3 - md5: a52385b93558d8e6bbaeec5d61a21cd7 + size: 1097626 + timestamp: 1756743061564 +- conda: https://prefix.dev/conda-forge/osx-arm64/pcre2-10.46-h7125dd6_0.conda + sha256: 5bf2eeaa57aab6e8e95bea6bd6bb2a739f52eb10572d8ed259d25864d3528240 + md5: 0e6e82c3cc3835f4692022e9b9cd5df8 depends: - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - libzlib >=1.3.1,<2.0a0 license: BSD-3-Clause license_family: BSD - size: 837826 - timestamp: 1745955207242 + size: 835080 + timestamp: 1756743041908 - conda: https://prefix.dev/conda-forge/linux-64/pthread-stubs-0.4-hb9d3cd8_1002.conda sha256: 9c88f8c64590e9567c6c80823f0328e58d3b1efb0e1c539c0315ceca764e0973 md5: b3c17d95b5a10c6e64a21fa17573e70e @@ -959,24 +985,24 @@ packages: license_family: MIT size: 8252 timestamp: 1726802366959 -- conda: https://prefix.dev/conda-forge/linux-64/pulseaudio-client-17.0-hac146a9_1.conda - sha256: d2377bb571932f2373f593b7b2fc3b9728dc6ae5b993b1b65d7f2c8bb39a0b49 - md5: 66b1fa9608d8836e25f9919159adc9c6 +- conda: https://prefix.dev/conda-forge/linux-64/pulseaudio-client-17.0-h9a8bead_2.conda + sha256: 8a6729861c9813a756b0438c30bd271722fb3f239ded3afc3bf1cb03327a640e + md5: b6f21b1c925ee2f3f7fc37798c5988db depends: - __glibc >=2.17,<3.0.a0 - - dbus >=1.13.6,<2.0a0 - - libgcc >=13 - - libglib >=2.82.2,<3.0a0 + - dbus >=1.16.2,<2.0a0 + - libgcc >=14 + - libglib >=2.86.0,<3.0a0 - libiconv >=1.18,<2.0a0 - libsndfile >=1.2.2,<1.3.0a0 - - libsystemd0 >=257.4 + - libsystemd0 >=257.7 - libxcb >=1.17.0,<2.0a0 constrains: - - pulseaudio 17.0 *_1 + - pulseaudio 17.0 *_2 license: LGPL-2.1-or-later license_family: LGPL - size: 764231 - timestamp: 1742507189208 + size: 761857 + timestamp: 1757472971364 - conda: https://prefix.dev/conda-forge/linux-64/sdl2-2.32.56-h54a6638_0.conda sha256: 987ad072939fdd51c92ea8d3544b286bb240aefda329f9b03a51d9b7e777f9de md5: cdd138897d94dc07d99afe7113a07bec @@ -1093,9 +1119,6 @@ packages: timestamp: 1759445836649 - conda: . name: sdl_example - version: 0.1.0 - build: h9352c13_0 - subdir: win-64 depends: - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -1104,11 +1127,11 @@ packages: input: hash: edfac7bd3233d95d1173e54bb2b8900757a662b8a553d89225c1a81ea98796af globs: [] + variants: + cxx_compiler: vs2019 + target_platform: win-64 - conda: . name: sdl_example - version: 0.1.0 - build: hbf21a9e_0 - subdir: linux-64 depends: - libstdcxx >=15 - libgcc >=15 @@ -1116,94 +1139,95 @@ packages: input: hash: edfac7bd3233d95d1173e54bb2b8900757a662b8a553d89225c1a81ea98796af globs: [] + variants: + target_platform: linux-64 - conda: . name: sdl_example - version: 0.1.0 - build: hbf21a9e_0 - subdir: osx-64 depends: - libcxx >=21 - sdl2 >=2.32.56,<3.0a0 input: hash: edfac7bd3233d95d1173e54bb2b8900757a662b8a553d89225c1a81ea98796af globs: [] + variants: + target_platform: osx-64 - conda: . name: sdl_example - version: 0.1.0 - build: hbf21a9e_0 - subdir: osx-arm64 depends: - libcxx >=21 - sdl2 >=2.32.56,<3.0a0 input: hash: edfac7bd3233d95d1173e54bb2b8900757a662b8a553d89225c1a81ea98796af globs: [] -- conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - sha256: db8dead3dd30fb1a032737554ce91e2819b43496a0db09927edf01c32b577450 - md5: 6797b005cd0f439c4c5c9ac565783700 + variants: + target_platform: osx-arm64 +- conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 constrains: + - vc14_runtime >=14.29.30037 - vs2015_runtime >=14.29.30037 license: LicenseRef-MicrosoftWindowsSDK10 - size: 559710 - timestamp: 1728377334097 -- conda: https://prefix.dev/conda-forge/win-64/vc-14.3-h41ae7f8_31.conda - sha256: cb357591d069a1e6cb74199a8a43a7e3611f72a6caed9faa49dbb3d7a0a98e0b - md5: 28f4ca1e0337d0f27afb8602663c5723 + size: 694692 + timestamp: 1756385147981 +- conda: https://prefix.dev/conda-forge/win-64/vc-14.3-h2b53caa_32.conda + sha256: 82250af59af9ff3c6a635dd4c4764c631d854feb334d6747d356d949af44d7cf + md5: ef02bbe151253a72b8eda264a935db66 depends: - - vc14_runtime >=14.44.35208 + - vc14_runtime >=14.42.34433 track_features: - vc14 license: BSD-3-Clause license_family: BSD - size: 18249 - timestamp: 1753739241465 -- conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_31.conda - sha256: af4b4b354b87a9a8d05b8064ff1ea0b47083274f7c30b4eb96bc2312c9b5f08f - md5: 603e41da40a765fd47995faa021da946 + size: 18861 + timestamp: 1760418772353 +- conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda + sha256: e3a3656b70d1202e0d042811ceb743bd0d9f7e00e2acdf824d231b044ef6c0fd + md5: 378d5dcec45eaea8d303da6f00447ac0 depends: - ucrt >=10.0.20348.0 - - vcomp14 14.44.35208 h818238b_31 + - vcomp14 14.44.35208 h818238b_32 constrains: - - vs2015_runtime 14.44.35208.* *_31 + - vs2015_runtime 14.44.35208.* *_32 license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary - size: 682424 - timestamp: 1753739239305 -- conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.44.35208-h818238b_31.conda - sha256: 67b317b64f47635415776718d25170a9a6f9a1218c0f5a6202bfd687e07b6ea4 - md5: a6b1d5c1fc3cb89f88f7179ee6a9afe3 + size: 682706 + timestamp: 1760418629729 +- conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda + sha256: f3790c88fbbdc55874f41de81a4237b1b91eab75e05d0e58661518ff04d2a8a1 + md5: 58f67b437acbf2764317ba273d731f1d depends: - ucrt >=10.0.20348.0 constrains: - - vs2015_runtime 14.44.35208.* *_31 + - vs2015_runtime 14.44.35208.* *_32 license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary - size: 113963 - timestamp: 1753739198723 -- conda: https://prefix.dev/conda-forge/linux-64/wayland-1.24.0-h3e06ad9_0.conda - sha256: ba673427dcd480cfa9bbc262fd04a9b1ad2ed59a159bd8f7e750d4c52282f34c - md5: 0f2ca7906bf166247d1d760c3422cb8a + size: 114846 + timestamp: 1760418593847 +- conda: https://prefix.dev/conda-forge/linux-64/wayland-1.24.0-hd6090a7_1.conda + sha256: 3aa04ae8e9521d9b56b562376d944c3e52b69f9d2a0667f77b8953464822e125 + md5: 035da2e4f5770f036ff704fa17aace24 depends: - __glibc >=2.17,<3.0.a0 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 - - libgcc >=13 - - libstdcxx >=13 + - libexpat >=2.7.1,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - libstdcxx >=14 license: MIT license_family: MIT - size: 330474 - timestamp: 1751817998141 -- conda: https://prefix.dev/conda-forge/linux-64/xkeyboard-config-2.45-hb9d3cd8_0.conda - sha256: a5d4af601f71805ec67403406e147c48d6bad7aaeae92b0622b7e2396842d3fe - md5: 397a013c2dc5145a70737871aaa87e98 + size: 329779 + timestamp: 1761174273487 +- conda: https://prefix.dev/conda-forge/linux-64/xkeyboard-config-2.46-hb03c661_0.conda + sha256: aa03b49f402959751ccc6e21932d69db96a65a67343765672f7862332aa32834 + md5: 71ae752a748962161b4740eaff510258 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - xorg-libx11 >=1.8.12,<2.0a0 license: MIT license_family: MIT - size: 392406 - timestamp: 1749375847832 + size: 396975 + timestamp: 1759543819846 - conda: https://prefix.dev/conda-forge/linux-64/xorg-libx11-1.8.12-h4f16b4b_0.conda sha256: 51909270b1a6c5474ed3978628b341b4d4472cd22610e5f22b506855a5e20f67 md5: db038ce880f100acc74dba10302b5630 diff --git a/examples/pixi-build/recursive-run-dependencies/pixi.lock b/examples/pixi-build/recursive-run-dependencies/pixi.lock index 5119b69886..a7b4311cf5 100644 --- a/examples/pixi-build/recursive-run-dependencies/pixi.lock +++ b/examples/pixi-build/recursive-run-dependencies/pixi.lock @@ -1,4 +1,4 @@ -version: 6 +version: 7 environments: default: channels: @@ -8,66 +8,71 @@ environments: linux-64: - conda: https://prefix.dev/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://prefix.dev/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://prefix.dev/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda - - conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - - conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda - - conda: https://prefix.dev/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda - - conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.1.0-h767d61c_2.conda - - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_1.conda - - conda: https://prefix.dev/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.49.2-hee588c1_0.conda - - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda + - conda: https://prefix.dev/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.44-h1aa0949_3.conda + - conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda + - conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda + - conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + - conda: https://prefix.dev/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.50.4-h0c1763c_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda + - conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - conda: https://prefix.dev/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda - - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda - - conda: https://prefix.dev/conda-forge/linux-64/python-3.13.3-hf636f53_101_cp313.conda - - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.13-7_cp313.conda + - conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.4-h26f9b46_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/python-3.14.0-h32b2ec7_102_cp314.conda + - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda - - conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda + - conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://prefix.dev/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda - conda: src/depend - conda: src/root osx-arm64: - - conda: https://prefix.dev/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda - - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.7.0-h286801f_0.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.6-h1da3d7d_1.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_1.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h99b78c6_0.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.49.2-h3f77e49_0.conda + - conda: https://prefix.dev/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.7.1-hec049ff_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.50.4-h4237e3c_0.conda - conda: https://prefix.dev/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - conda: https://prefix.dev/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.0-h81ee809_1.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.3-h81fe080_101_cp313.conda - - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.13-7_cp313.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.4-h5503f6c_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/python-3.14.0-h40d2674_102_cp314.conda + - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda - conda: https://prefix.dev/conda-forge/osx-arm64/readline-8.2-h1d1bf99_2.conda - - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda + - conda: https://prefix.dev/conda-forge/osx-arm64/zstd-1.5.7-h6491c7d_2.conda - conda: src/depend - conda: src/root win-64: - - conda: https://prefix.dev/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_1.conda - - conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.4.26-h4c7d964_0.conda - - conda: https://prefix.dev/conda-forge/win-64/libexpat-2.7.0-he0c23c2_0.conda - - conda: https://prefix.dev/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda - - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.1-h2466b09_1.conda + - conda: https://prefix.dev/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda + - conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + - conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.10.5-h4c7d964_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libexpat-2.7.1-hac47afa_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda + - conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda - conda: https://prefix.dev/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda - - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.49.2-h67fdade_0.conda + - conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.50.4-hf5d6505_0.conda - conda: https://prefix.dev/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - - conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.0-ha4e3fda_1.conda - - conda: https://prefix.dev/conda-forge/win-64/python-3.13.3-h261c0b1_101_cp313.conda - - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.13-7_cp313.conda - - conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h5226925_1.conda + - conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.4-h725018a_0.conda + - conda: https://prefix.dev/conda-forge/win-64/python-3.14.0-h4b44e0e_102_cp314.conda + - conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda - - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-h2b53caa_26.conda - - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.42.34438-hfd919c2_26.conda + - conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://prefix.dev/conda-forge/win-64/vc-14.3-h2b53caa_32.conda + - conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda + - conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda + - conda: https://prefix.dev/conda-forge/win-64/zstd-1.5.7-hbeecb71_2.conda - conda: src/depend - conda: src/root packages: @@ -90,237 +95,232 @@ packages: license_family: BSD size: 23621 timestamp: 1650670423406 -- conda: https://prefix.dev/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_1.conda - sha256: 4d6101f6a900c22495fbaa3c0ca713f1876d11f14aba3f7832bf6e6986ee5e64 - md5: d88c38e66d85ecc9c7e2c4110676bbf4 +- conda: https://prefix.dev/conda-forge/noarch/boltons-25.0.0-pyhd8ed1ab_0.conda + sha256: ea5f4c876eff2ed469551b57f1cc889a3c01128bf3e2e10b1fea11c3ef39eac2 + md5: c7eb87af73750d6fd97eff8bbee8cb9c depends: - python >=3.9 license: BSD-3-Clause license_family: BSD - size: 297459 - timestamp: 1733827374270 -- conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d - md5: 62ee74e96c5ebb0af99386de58cf9553 + size: 302296 + timestamp: 1749686302834 +- conda: https://prefix.dev/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 + md5: 51a19bba1b8ebfb60df25cde030b7ebc depends: - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 + - libgcc >=14 license: bzip2-1.0.6 license_family: BSD - size: 252783 - timestamp: 1720974456583 -- conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda - sha256: adfa71f158cbd872a36394c56c3568e6034aa55c623634b37a4836bd036e6b91 - md5: fc6948412dbbbe9a4c9ddbbcfe0a79ab + size: 260341 + timestamp: 1757437258798 +- conda: https://prefix.dev/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + sha256: b456200636bd5fecb2bec63f7e0985ad2097cf1b83d60ce0b6968dffa6d02aa1 + md5: 58fd217444c2a5701a44244faf518206 depends: - __osx >=11.0 license: bzip2-1.0.6 license_family: BSD - size: 122909 - timestamp: 1720974522888 -- conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - sha256: 35a5dad92e88fdd7fc405e864ec239486f4f31eec229e31686e61a140a8e573b - md5: 276e7ffe9ffe39688abc665ef0f45596 + size: 125061 + timestamp: 1757437486465 +- conda: https://prefix.dev/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + sha256: d882712855624641f48aa9dc3f5feea2ed6b4e6004585d3616386a18186fe692 + md5: 1077e9333c41ff0be8edd1a5ec0ddace depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: bzip2-1.0.6 license_family: BSD - size: 54927 - timestamp: 1720974860185 -- conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.4.26-h4c7d964_0.conda - sha256: 1454f3f53a3b828d3cb68a3440cb0fa9f1cc0e3c8c26e9e023773dc19d88cc06 - md5: 23c7fd5062b48d8294fc7f61bf157fba + size: 55977 + timestamp: 1757437738856 +- conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.10.5-h4c7d964_0.conda + sha256: bfb7f9f242f441fdcd80f1199edd2ecf09acea0f2bcef6f07d7cbb1a8131a345 + md5: e54200a1cd1fe33d61c9df8d3b00b743 depends: - __win license: ISC - size: 152945 - timestamp: 1745653639656 -- conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.4.26-hbd8a1cb_0.conda - sha256: 2a70ed95ace8a3f8a29e6cd1476a943df294a7111dfb3e152e3478c4c889b7ac - md5: 95db94f75ba080a22eb623590993167b + size: 156354 + timestamp: 1759649104842 +- conda: https://prefix.dev/conda-forge/noarch/ca-certificates-2025.10.5-hbd8a1cb_0.conda + sha256: 3b5ad78b8bb61b6cdc0978a6a99f8dfb2cc789a451378d054698441005ecbdb6 + md5: f9e5fbc24009179e8b0409624691758a depends: - __unix license: ISC - size: 152283 - timestamp: 1745653616541 + size: 155907 + timestamp: 1759649036195 - conda: src/depend name: depend - version: 0.1.0 - build: pyh4616a5c_0 - subdir: noarch depends: - boltons - - python >=3.11 + - python - python * input: - hash: d3f1cccaf86d7fdee5dd02d003d58293d9ba97e005544c9936160c26f5131ec0 - globs: - - pyproject.toml -- conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_4.conda - sha256: db73f38155d901a610b2320525b9dd3b31e4949215c870685fd92ea61b5ce472 - md5: 01f8d123c96816249efd255a31ad7712 + hash: c33f206dfc06551f0242c7037fe4d8f019bf8fbb3473b626f808d8947b8671f7 + globs: [] + variants: + target_platform: noarch +- conda: https://prefix.dev/conda-forge/osx-arm64/icu-75.1-hfee45f7_0.conda + sha256: 9ba12c93406f3df5ab0a43db8a4b4ef67a5871dfd401010fbe29b218b2cbe620 + md5: 5eb22c1d7b3fc4abb50d92d621583137 + depends: + - __osx >=11.0 + license: MIT + license_family: MIT + size: 11857802 + timestamp: 1720853997952 +- conda: https://prefix.dev/conda-forge/linux-64/ld_impl_linux-64-2.44-h1aa0949_3.conda + sha256: e26f4435c372264136a9c71e19f7620ec7f107abe73134ff305d26bfaeabb0b3 + md5: 72cc69c30de0b6d39c7f97f501fdbb1c depends: - __glibc >=2.17,<3.0.a0 + - zstd >=1.5.7,<1.6.0a0 constrains: - - binutils_impl_linux-64 2.43 + - binutils_impl_linux-64 2.44 license: GPL-3.0-only - license_family: GPL - size: 671240 - timestamp: 1740155456116 -- conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.7.0-h5888daf_0.conda - sha256: 33ab03438aee65d6aa667cf7d90c91e5e7d734c19a67aa4c7040742c0a13d505 - md5: db0bfbe7dd197b68ad5f30333bae6ce0 + size: 741904 + timestamp: 1761248509961 +- conda: https://prefix.dev/conda-forge/linux-64/libexpat-2.7.1-hecca717_0.conda + sha256: da2080da8f0288b95dd86765c801c6e166c4619b910b11f9a8446fb852438dc2 + md5: 4211416ecba1866fab0c6470986c22d6 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 constrains: - - expat 2.7.0.* + - expat 2.7.1.* license: MIT license_family: MIT - size: 74427 - timestamp: 1743431794976 -- conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.7.0-h286801f_0.conda - sha256: ee550e44765a7bbcb2a0216c063dcd53ac914a7be5386dd0554bd06e6be61840 - md5: 6934bbb74380e045741eb8637641a65b + size: 74811 + timestamp: 1752719572741 +- conda: https://prefix.dev/conda-forge/osx-arm64/libexpat-2.7.1-hec049ff_0.conda + sha256: 8fbb17a56f51e7113ed511c5787e0dec0d4b10ef9df921c4fd1cccca0458f648 + md5: b1ca5f21335782f71a8bd69bdc093f67 depends: - __osx >=11.0 constrains: - - expat 2.7.0.* + - expat 2.7.1.* license: MIT license_family: MIT - size: 65714 - timestamp: 1743431789879 -- conda: https://prefix.dev/conda-forge/win-64/libexpat-2.7.0-he0c23c2_0.conda - sha256: 1a227c094a4e06bd54e8c2f3ec40c17ff99dcf3037d812294f842210aa66dbeb - md5: b6f5352fdb525662f4169a0431d2dd7a + size: 65971 + timestamp: 1752719657566 +- conda: https://prefix.dev/conda-forge/win-64/libexpat-2.7.1-hac47afa_0.conda + sha256: 8432ca842bdf8073ccecf016ccc9140c41c7114dc4ec77ca754551c01f780845 + md5: 3608ffde260281fa641e70d6e34b1b96 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - - expat 2.7.0.* + - expat 2.7.1.* license: MIT license_family: MIT - size: 140896 - timestamp: 1743432122520 -- conda: https://prefix.dev/conda-forge/linux-64/libffi-3.4.6-h2dba641_1.conda - sha256: 764432d32db45466e87f10621db5b74363a9f847d2b8b1f9743746cd160f06ab - md5: ede4673863426c0883c0063d853bbd85 + size: 141322 + timestamp: 1752719767870 +- conda: https://prefix.dev/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda + sha256: 25cbdfa65580cfab1b8d15ee90b4c9f1e0d72128f1661449c9a999d341377d54 + md5: 35f29eec58405aaf55e01cb470d8c26a depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 license: MIT license_family: MIT - size: 57433 - timestamp: 1743434498161 -- conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.4.6-h1da3d7d_1.conda - sha256: c6a530924a9b14e193ea9adfe92843de2a806d1b7dbfd341546ece9653129e60 - md5: c215a60c2935b517dcda8cad4705734d + size: 57821 + timestamp: 1760295480630 +- conda: https://prefix.dev/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda + sha256: 9b8acdf42df61b7bfe8bdc545c016c29e61985e79748c64ad66df47dbc2e295f + md5: 411ff7cd5d1472bba0f55c0faf04453b depends: - __osx >=11.0 license: MIT license_family: MIT - size: 39839 - timestamp: 1743434670405 -- conda: https://prefix.dev/conda-forge/win-64/libffi-3.4.6-h537db12_1.conda - sha256: d3b0b8812eab553d3464bbd68204f007f1ebadf96ce30eb0cbc5159f72e353f5 - md5: 85d8fa5e55ed8f93f874b3b23ed54ec6 + size: 40251 + timestamp: 1760295839166 +- conda: https://prefix.dev/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda + sha256: ddff25aaa4f0aa535413f5d831b04073789522890a4d8626366e43ecde1534a3 + md5: ba4ad812d2afc22b9a34ce8327a0930f depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT - size: 44978 - timestamp: 1743435053850 -- conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.1.0-h767d61c_2.conda - sha256: 0024f9ab34c09629621aefd8603ef77bf9d708129b0dd79029e502c39ffc2195 - md5: ea8ac52380885ed41c1baa8f1d6d2b93 + size: 44866 + timestamp: 1760295760649 +- conda: https://prefix.dev/conda-forge/linux-64/libgcc-15.2.0-h767d61c_7.conda + sha256: 08f9b87578ab981c7713e4e6a7d935e40766e10691732bba376d4964562bcb45 + md5: c0374badb3a5d4b1372db28d19462c53 depends: - __glibc >=2.17,<3.0.a0 - _openmp_mutex >=4.5 constrains: - - libgcc-ng ==15.1.0=*_2 - - libgomp 15.1.0 h767d61c_2 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 829108 - timestamp: 1746642191935 -- conda: https://prefix.dev/conda-forge/linux-64/libgcc-ng-15.1.0-h69a702a_2.conda - sha256: 0ab5421a89f090f3aa33841036bb3af4ed85e1f91315b528a9d75fab9aad51ae - md5: ddca86c7040dd0e73b2b69bd7833d225 - depends: - - libgcc 15.1.0 h767d61c_2 + - libgomp 15.2.0 h767d61c_7 + - libgcc-ng ==15.2.0=*_7 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL - size: 34586 - timestamp: 1746642200749 -- conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.1.0-h767d61c_2.conda - sha256: 05fff3dc7e80579bc28de13b511baec281c4343d703c406aefd54389959154fb - md5: fbe7d535ff9d3a168c148e07358cd5b1 + size: 822552 + timestamp: 1759968052178 +- conda: https://prefix.dev/conda-forge/linux-64/libgomp-15.2.0-h767d61c_7.conda + sha256: e9fb1c258c8e66ee278397b5822692527c5f5786d372fe7a869b900853f3f5ca + md5: f7b4d76975aac7e5d9e6ad13845f92fe depends: - __glibc >=2.17,<3.0.a0 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL - size: 452635 - timestamp: 1746642113092 -- conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_1.conda - sha256: eeff241bddc8f1b87567dd6507c9f441f7f472c27f0860a07628260c000ef27c - md5: a76fd702c93cd2dfd89eff30a5fd45a8 + size: 447919 + timestamp: 1759967942498 +- conda: https://prefix.dev/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 + md5: 1a580f7796c7bf6393fddb8bbbde58dc depends: - __glibc >=2.17,<3.0.a0 - libgcc >=13 constrains: - xz 5.8.1.* - - xz ==5.8.1=*_1 license: 0BSD - size: 112845 - timestamp: 1746531470399 -- conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_1.conda - sha256: 5ab62c179229640c34491a7de806ad4ab7bec47ea2b5fc2136e3b8cf5ef26a57 - md5: 4e8ef3d79c97c9021b34d682c24c2044 + size: 112894 + timestamp: 1749230047870 +- conda: https://prefix.dev/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + sha256: 0cb92a9e026e7bd4842f410a5c5c665c89b2eb97794ffddba519a626b8ce7285 + md5: d6df911d4564d77c4374b02552cb17d1 depends: - __osx >=11.0 constrains: - xz 5.8.1.* - - xz ==5.8.1=*_1 license: 0BSD - size: 92218 - timestamp: 1746531818330 -- conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.1-h2466b09_1.conda - sha256: adbf6c7bde70536ada734a81b8b5aa23654f2b95445204404622e0cc40e921a0 - md5: 14a1042c163181e143a7522dfb8ad6ab + size: 92286 + timestamp: 1749230283517 +- conda: https://prefix.dev/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda + sha256: 55764956eb9179b98de7cc0e55696f2eff8f7b83fc3ebff5e696ca358bca28cc + md5: c15148b2e18da456f5108ccb5e411446 depends: - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 constrains: - xz 5.8.1.* - - xz ==5.8.1=*_1 license: 0BSD - size: 104699 - timestamp: 1746531718026 -- conda: https://prefix.dev/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda - sha256: d02d1d3304ecaf5c728e515eb7416517a0b118200cd5eacbe829c432d1664070 - md5: aeb98fdeb2e8f25d43ef71fbacbeec80 + size: 104935 + timestamp: 1749230611612 +- conda: https://prefix.dev/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda + sha256: 3aa92d4074d4063f2a162cd8ecb45dccac93e543e565c01a787e16a43501f7ee + md5: c7e925f37e3b40d893459e625f6a53f1 depends: - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 + - libgcc >=13 license: BSD-2-Clause license_family: BSD - size: 89991 - timestamp: 1723817448345 -- conda: https://prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h99b78c6_0.conda - sha256: f7917de9117d3a5fe12a39e185c7ce424f8d5010a6f97b4333e8a1dcb2889d16 - md5: 7476305c35dd9acef48da8f754eedb40 + size: 91183 + timestamp: 1748393666725 +- conda: https://prefix.dev/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda + sha256: 0a1875fc1642324ebd6c4ac864604f3f18f57fbcf558a8264f6ced028a3c75b2 + md5: 85ccccb47823dd9f7a99d2c7f530342f depends: - __osx >=11.0 license: BSD-2-Clause license_family: BSD - size: 69263 - timestamp: 1723817629767 + size: 71829 + timestamp: 1748393749336 - conda: https://prefix.dev/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda sha256: fc529fc82c7caf51202cc5cec5bb1c2e8d90edbac6d0a4602c966366efe3c7bf md5: 74860100b2029e2523cf480804c76b9b @@ -332,44 +332,58 @@ packages: license_family: BSD size: 88657 timestamp: 1723861474602 -- conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.49.2-hee588c1_0.conda - sha256: 525d4a0e24843f90b3ff1ed733f0a2e408aa6dd18b9d4f15465595e078e104a2 - md5: 93048463501053a00739215ea3f36324 +- conda: https://prefix.dev/conda-forge/linux-64/libsqlite-3.50.4-h0c1763c_0.conda + sha256: 6d9c32fc369af5a84875725f7ddfbfc2ace795c28f246dc70055a79f9b2003da + md5: 0b367fad34931cb79e0d6b7e5c06bb1c depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 - libzlib >=1.3.1,<2.0a0 - license: Unlicense - size: 916313 - timestamp: 1746637007836 -- conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.49.2-h3f77e49_0.conda - sha256: d89f979497cf56eccb099b6ab9558da7bba1f1ba264f50af554e0ea293d9dcf9 - md5: 85f443033cd5b3df82b5cabf79bddb09 + license: blessing + size: 932581 + timestamp: 1753948484112 +- conda: https://prefix.dev/conda-forge/osx-arm64/libsqlite-3.50.4-h4237e3c_0.conda + sha256: 802ebe62e6bc59fc26b26276b793e0542cfff2d03c086440aeaf72fb8bbcec44 + md5: 1dcb0468f5146e38fae99aef9656034b depends: - __osx >=11.0 + - icu >=75.1,<76.0a0 - libzlib >=1.3.1,<2.0a0 - license: Unlicense - size: 899462 - timestamp: 1746637228408 -- conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.49.2-h67fdade_0.conda - sha256: 1612baa49124ec1972b085ab9d6bf1855c5f38e8f16e8d8f96c193d6e11688b2 - md5: a3900c97ba9e03332e9a911fe63f7d64 + license: blessing + size: 902645 + timestamp: 1753948599139 +- conda: https://prefix.dev/conda-forge/win-64/libsqlite-3.50.4-hf5d6505_0.conda + sha256: 5dc4f07b2d6270ac0c874caec53c6984caaaa84bc0d3eb593b0edf3dc8492efa + md5: ccb20d946040f86f0c05b644d5eadeca depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: Unlicense - size: 1081123 - timestamp: 1746637406471 -- conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18 - md5: 40b61aab5c7ba9ff276c41cfffe6b80b - depends: - - libgcc-ng >=12 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: blessing + size: 1288499 + timestamp: 1753948889360 +- conda: https://prefix.dev/conda-forge/linux-64/libstdcxx-15.2.0-h8f9b012_7.conda + sha256: 1b981647d9775e1cdeb2fab0a4dd9cd75a6b0de2963f6c3953dbd712f78334b3 + md5: 5b767048b1b3ee9a954b06f4084f93dc + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 h767d61c_7 + constrains: + - libstdcxx-ng ==15.2.0=*_7 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL + size: 3898269 + timestamp: 1759968103436 +- conda: https://prefix.dev/conda-forge/linux-64/libuuid-2.41.2-he9a06e4_0.conda + sha256: e5ec6d2ad7eef538ddcb9ea62ad4346fde70a4736342c4ad87bd713641eb9808 + md5: 80c07c68d2f6870250959dcc95b209d1 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 license: BSD-3-Clause license_family: BSD - size: 33601 - timestamp: 1680112270483 + size: 37135 + timestamp: 1758626800002 - conda: https://prefix.dev/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 md5: edb0dca6bc32e4f4789199455a1dbeb8 @@ -423,121 +437,124 @@ packages: license: X11 AND BSD-3-Clause size: 797030 timestamp: 1738196177597 -- conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.0-h7b32b05_1.conda - sha256: b4491077c494dbf0b5eaa6d87738c22f2154e9277e5293175ec187634bd808a0 - md5: de356753cfdbffcde5bb1e86e3aa6cd0 +- conda: https://prefix.dev/conda-forge/linux-64/openssl-3.5.4-h26f9b46_0.conda + sha256: e807f3bad09bdf4075dbb4168619e14b0c0360bacb2e12ef18641a834c8c5549 + md5: 14edad12b59ccbfa3910d42c72adc2a0 depends: - __glibc >=2.17,<3.0.a0 - ca-certificates - - libgcc >=13 + - libgcc >=14 license: Apache-2.0 license_family: Apache - size: 3117410 - timestamp: 1746223723843 -- conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.0-h81ee809_1.conda - sha256: 73d366c1597a10bcd5f3604b5f0734b31c23225536e03782c6a13f9be9d01bff - md5: 5c7aef00ef60738a14e0e612cfc5bcde + size: 3119624 + timestamp: 1759324353651 +- conda: https://prefix.dev/conda-forge/osx-arm64/openssl-3.5.4-h5503f6c_0.conda + sha256: f0512629f9589392c2fb9733d11e753d0eab8fc7602f96e4d7f3bd95c783eb07 + md5: 71118318f37f717eefe55841adb172fd depends: - __osx >=11.0 - ca-certificates license: Apache-2.0 license_family: Apache - size: 3064197 - timestamp: 1746223530698 -- conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.0-ha4e3fda_1.conda - sha256: 02846553d2a4c9bde850c60824d0f02803eb9c9b674d5c1a8cce25bc387e748f - md5: 72c07e46b6766bb057018a9a74861b89 + size: 3067808 + timestamp: 1759324763146 +- conda: https://prefix.dev/conda-forge/win-64/openssl-3.5.4-h725018a_0.conda + sha256: 5ddc1e39e2a8b72db2431620ad1124016f3df135f87ebde450d235c212a61994 + md5: f28ffa510fe055ab518cbd9d6ddfea23 depends: - ca-certificates - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: Apache - size: 9025176 - timestamp: 1746227349882 -- conda: https://prefix.dev/conda-forge/linux-64/python-3.13.3-hf636f53_101_cp313.conda - build_number: 101 - sha256: eecb11ea60f8143deeb301eab2e04d04f7acb83659bb20fdfeacd431a5f31168 - md5: 10622e12d649154af0bd76bcf33a7c5c + size: 9218823 + timestamp: 1759326176247 +- conda: https://prefix.dev/conda-forge/linux-64/python-3.14.0-h32b2ec7_102_cp314.conda + build_number: 102 + sha256: 76d750045b94fded676323bfd01975a26a474023635735773d0e4d80aaa72518 + md5: 0a19d2cc6eb15881889b0c6fa7d6a78d depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 - - libgcc >=13 + - libexpat >=2.7.1,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.49.1,<4.0a0 - - libuuid >=2.38.1,<3.0a0 + - libsqlite >=3.50.4,<4.0a0 + - libuuid >=2.41.2,<3.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.5.0,<4.0a0 - - python_abi 3.13.* *_cp313 + - openssl >=3.5.4,<4.0a0 + - python_abi 3.14.* *_cp314 - readline >=8.2,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata + - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 - size: 33268245 - timestamp: 1744665022734 - python_site_packages_path: lib/python3.13/site-packages -- conda: https://prefix.dev/conda-forge/osx-arm64/python-3.13.3-h81fe080_101_cp313.conda - build_number: 101 - sha256: f96468ab1e6f27bda92157bfc7f272d1fbf2ba2f85697bdc5bb106bccba1befb - md5: b3240ae8c42a3230e0b7f831e1c72e9f + size: 36681389 + timestamp: 1761176838143 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://prefix.dev/conda-forge/osx-arm64/python-3.14.0-h40d2674_102_cp314.conda + build_number: 102 + sha256: 3ca1da026fe5df8a479d60e1d3ed02d9bc50fcbafd5f125d86abe70d21a34cc7 + md5: a9ff09231c555da7e30777747318321b depends: - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 + - libexpat >=2.7.1,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.49.1,<4.0a0 + - libsqlite >=3.50.4,<4.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.5.0,<4.0a0 - - python_abi 3.13.* *_cp313 + - openssl >=3.5.4,<4.0a0 + - python_abi 3.14.* *_cp314 - readline >=8.2,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata + - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 - size: 12136505 - timestamp: 1744663807953 - python_site_packages_path: lib/python3.13/site-packages -- conda: https://prefix.dev/conda-forge/win-64/python-3.13.3-h261c0b1_101_cp313.conda - build_number: 101 - sha256: 25cf0113c0e4fa42d31b0ff85349990dc454f1237638ba4642b009b451352cdf - md5: 4784d7aecc8996babe9681d017c81b8a + size: 13590581 + timestamp: 1761177195716 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://prefix.dev/conda-forge/win-64/python-3.14.0-h4b44e0e_102_cp314.conda + build_number: 102 + sha256: 2b8c8fcafcc30690b4c5991ee28eb80c962e50e06ce7da03b2b302e2d39d6a81 + md5: 3e1ce2fb0f277cebcae01a3c418eb5e2 depends: - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.7.0,<3.0a0 - - libffi >=3.4.6,<3.5.0a0 + - libexpat >=2.7.1,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.49.1,<4.0a0 + - libsqlite >=3.50.4,<4.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.5.0,<4.0a0 - - python_abi 3.13.* *_cp313 + - openssl >=3.5.4,<4.0a0 + - python_abi 3.14.* *_cp314 - tk >=8.6.13,<8.7.0a0 - tzdata - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 - size: 16614435 - timestamp: 1744663103022 + size: 16706286 + timestamp: 1761175439068 python_site_packages_path: Lib/site-packages -- conda: https://prefix.dev/conda-forge/noarch/python_abi-3.13-7_cp313.conda - build_number: 7 - sha256: 0595134584589064f56e67d3de1d8fcbb673a972946bce25fb593fb092fdcd97 - md5: e84b44e6300f1703cb25d29120c5b1d8 +- conda: https://prefix.dev/conda-forge/noarch/python_abi-3.14-8_cp314.conda + build_number: 8 + sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 + md5: 0539938c55b6b1a59b560e843ad864a4 constrains: - - python 3.13.* *_cp313 + - python 3.14.* *_cp314 license: BSD-3-Clause license_family: BSD - size: 6988 - timestamp: 1745258852285 + size: 6989 + timestamp: 1752805904792 - conda: https://prefix.dev/conda-forge/linux-64/readline-8.2-h8c095d6_2.conda sha256: 2d6d0c026902561ed77cd646b5021aef2d4db22e57a5b0178dfc669231e06d2c md5: 283b96675859b20a825f8fa30f311446 @@ -559,83 +576,130 @@ packages: timestamp: 1740379663071 - conda: src/root name: root - version: 0.1.0 - build: pyh4616a5c_0 - subdir: noarch depends: - depend - - python >=3.11 + - python - python * input: - hash: 960c4783940e6a7bd4f5f557ea68b61d70319c2e9a46947564e9a8e87d64cd81 - globs: - - pyproject.toml + hash: d74786cfcf078d97d1c9d5e38440e52418fc4650ee65f4adc27d02afcf50c8d0 + globs: [] sources: depend: path: ../depend -- conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - sha256: e0569c9caa68bf476bead1bed3d79650bb080b532c64a4af7d8ca286c08dea4e - md5: d453b98d9c83e71da0741bb0ff4d76bc + variants: + target_platform: noarch +- conda: https://prefix.dev/conda-forge/linux-64/tk-8.6.13-noxft_hd72426e_102.conda + sha256: a84ff687119e6d8752346d1d408d5cf360dee0badd487a472aa8ddedfdc219e1 + md5: a0116df4f4ed05c303811a837d5b39d8 depends: - - libgcc-ng >=12 - - libzlib >=1.2.13,<2.0.0a0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libzlib >=1.3.1,<2.0a0 license: TCL license_family: BSD - size: 3318875 - timestamp: 1699202167581 -- conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - sha256: 72457ad031b4c048e5891f3f6cb27a53cb479db68a52d965f796910e71a403a8 - md5: b50a57ba89c32b62428b71a875291c9b + size: 3285204 + timestamp: 1748387766691 +- conda: https://prefix.dev/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_2.conda + sha256: cb86c522576fa95c6db4c878849af0bccfd3264daf0cc40dd18e7f4a7bfced0e + md5: 7362396c170252e7b7b0c8fb37fe9c78 depends: - - libzlib >=1.2.13,<2.0.0a0 + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 license: TCL license_family: BSD - size: 3145523 - timestamp: 1699202432999 -- conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - sha256: 2c4e914f521ccb2718946645108c9bd3fc3216ba69aea20c2c3cedbd8db32bb1 - md5: fc048363eb8f03cd1737600a5d08aafe + size: 3125538 + timestamp: 1748388189063 +- conda: https://prefix.dev/conda-forge/win-64/tk-8.6.13-h2c6b04d_2.conda + sha256: e3614b0eb4abcc70d98eae159db59d9b4059ed743ef402081151a948dce95896 + md5: ebd0e761de9aa879a51d22cc721bd095 depends: - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: TCL license_family: BSD - size: 3503410 - timestamp: 1699202577803 + size: 3466348 + timestamp: 1748388121356 - conda: https://prefix.dev/conda-forge/noarch/tzdata-2025b-h78e105d_0.conda sha256: 5aaa366385d716557e365f0a4e9c3fca43ba196872abbbe3d56bb610d131e192 md5: 4222072737ccff51314b5ece9c7d6f5a license: LicenseRef-Public-Domain size: 122968 timestamp: 1742727099393 -- conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - sha256: db8dead3dd30fb1a032737554ce91e2819b43496a0db09927edf01c32b577450 - md5: 6797b005cd0f439c4c5c9ac565783700 +- conda: https://prefix.dev/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 constrains: + - vc14_runtime >=14.29.30037 - vs2015_runtime >=14.29.30037 license: LicenseRef-MicrosoftWindowsSDK10 - size: 559710 - timestamp: 1728377334097 -- conda: https://prefix.dev/conda-forge/win-64/vc-14.3-h2b53caa_26.conda - sha256: 7a685b5c37e9713fa314a0d26b8b1d7a2e6de5ab758698199b5d5b6dba2e3ce1 - md5: d3f0381e38093bde620a8d85f266ae55 + size: 694692 + timestamp: 1756385147981 +- conda: https://prefix.dev/conda-forge/win-64/vc-14.3-h2b53caa_32.conda + sha256: 82250af59af9ff3c6a635dd4c4764c631d854feb334d6747d356d949af44d7cf + md5: ef02bbe151253a72b8eda264a935db66 depends: - vc14_runtime >=14.42.34433 track_features: - vc14 license: BSD-3-Clause license_family: BSD - size: 17893 - timestamp: 1743195261486 -- conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.42.34438-hfd919c2_26.conda - sha256: 30dcb71bb166e351aadbdc18f1718757c32cdaa0e1e5d9368469ee44f6bf4709 - md5: 91651a36d31aa20c7ba36299fb7068f4 + size: 18861 + timestamp: 1760418772353 +- conda: https://prefix.dev/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_32.conda + sha256: e3a3656b70d1202e0d042811ceb743bd0d9f7e00e2acdf824d231b044ef6c0fd + md5: 378d5dcec45eaea8d303da6f00447ac0 depends: - ucrt >=10.0.20348.0 + - vcomp14 14.44.35208 h818238b_32 constrains: - - vs2015_runtime 14.42.34438.* *_26 + - vs2015_runtime 14.44.35208.* *_32 license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary - size: 750733 - timestamp: 1743195092905 + size: 682706 + timestamp: 1760418629729 +- conda: https://prefix.dev/conda-forge/win-64/vcomp14-14.44.35208-h818238b_32.conda + sha256: f3790c88fbbdc55874f41de81a4237b1b91eab75e05d0e58661518ff04d2a8a1 + md5: 58f67b437acbf2764317ba273d731f1d + depends: + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.44.35208.* *_32 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary + size: 114846 + timestamp: 1760418593847 +- conda: https://prefix.dev/conda-forge/linux-64/zstd-1.5.7-hb8e6e7a_2.conda + sha256: a4166e3d8ff4e35932510aaff7aa90772f84b4d07e9f6f83c614cba7ceefe0eb + md5: 6432cb5d4ac0046c3ac0a8a0f95842f9 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libstdcxx >=13 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 567578 + timestamp: 1742433379869 +- conda: https://prefix.dev/conda-forge/osx-arm64/zstd-1.5.7-h6491c7d_2.conda + sha256: 0d02046f57f7a1a3feae3e9d1aa2113788311f3cf37a3244c71e61a93177ba67 + md5: e6f69c7bcccdefa417f056fa593b40f0 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + size: 399979 + timestamp: 1742433432699 +- conda: https://prefix.dev/conda-forge/win-64/zstd-1.5.7-hbeecb71_2.conda + sha256: bc64864377d809b904e877a98d0584f43836c9f2ef27d3d2a1421fa6eae7ca04 + md5: 21f56217d6125fb30c3c3f10c786d751 + depends: + - libzlib >=1.3.1,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: BSD-3-Clause + license_family: BSD + size: 354697 + timestamp: 1742433568506 diff --git a/tests/data/non-satisfiability/binary-spec-source-record/pixi.lock b/tests/data/non-satisfiability/binary-spec-source-record/pixi.lock index 1bb64999a1..1c0ce328b7 100644 --- a/tests/data/non-satisfiability/binary-spec-source-record/pixi.lock +++ b/tests/data/non-satisfiability/binary-spec-source-record/pixi.lock @@ -1,4 +1,4 @@ -version: 6 +version: 7 environments: default: channels: @@ -13,8 +13,6 @@ packages: - conda: source name: source version: 0.1.0 - build: hbf21a9e_0 - subdir: win-64 depends: - vc >=14.1,<15 - vc14_runtime >=14.16.27033 @@ -27,8 +25,6 @@ packages: md5: 6797b005cd0f439c4c5c9ac565783700 constrains: - vs2015_runtime >=14.29.30037 - arch: x86_64 - platform: win license: LicenseRef-MicrosoftWindowsSDK10 size: 559710 timestamp: 1728377334097 @@ -37,8 +33,6 @@ packages: md5: 311c9ba1dfdd2895a8cb08346ff26259 depends: - vc14_runtime >=14.38.33135 - arch: x86_64 - platform: win track_features: - vc14 license: BSD-3-Clause @@ -52,8 +46,6 @@ packages: - ucrt >=10.0.20348.0 constrains: - vs2015_runtime 14.40.33810.* *_22 - arch: x86_64 - platform: win license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary size: 750719 diff --git a/tests/data/non-satisfiability/explicit-pypi-dependency/pixi.lock b/tests/data/non-satisfiability/explicit-pypi-dependency/pixi.lock index da1fe60936..645d7cb891 100644 --- a/tests/data/non-satisfiability/explicit-pypi-dependency/pixi.lock +++ b/tests/data/non-satisfiability/explicit-pypi-dependency/pixi.lock @@ -6,26 +6,24 @@ # conda packages reference the boltons conda package, it should be dropped in # favor of the pypi package. -version: 6 +version: 7 environments: default: channels: - - url: https://conda.anaconda.org/conda-forge/ + - url: https://conda.anaconda.org/conda-forge/ packages: win-64: - - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.2-h261c0b1_101_cp313.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.2-h261c0b1_101_cp313.conda packages: -- conda: https://conda.anaconda.org/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_1.conda - sha256: 4d6101f6a900c22495fbaa3c0ca713f1876d11f14aba3f7832bf6e6986ee5e64 - md5: d88c38e66d85ecc9c7e2c4110676bbf4 - depends: - - python >=3.9 - purls: - - pkg:pypi/boltons?source=hash-mapping -- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.2-h261c0b1_101_cp313.conda - build_number: 101 - sha256: b6e7a6f314343926b5a236592272e5014edcda150e14d18d0fb9440d8a185c3f - md5: 5116c74f5e3e77b915b7b72eea0ec946 - # Faked to be empty to reduce the size of the example - depends: [] + - conda: https://conda.anaconda.org/conda-forge/noarch/boltons-24.0.0-pyhd8ed1ab_1.conda + sha256: 4d6101f6a900c22495fbaa3c0ca713f1876d11f14aba3f7832bf6e6986ee5e64 + md5: d88c38e66d85ecc9c7e2c4110676bbf4 + depends: + - python >=3.9 + purls: + - pkg:pypi/boltons?source=hash-mapping + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.2-h261c0b1_101_cp313.conda + build_number: 101 + sha256: b6e7a6f314343926b5a236592272e5014edcda150e14d18d0fb9440d8a185c3f + md5: 5116c74f5e3e77b915b7b72eea0ec946 diff --git a/tests/data/non-satisfiability/mismatch-exclude-newer2/pixi.lock b/tests/data/non-satisfiability/mismatch-exclude-newer2/pixi.lock index 161b2c54e8..52b4301add 100644 --- a/tests/data/non-satisfiability/mismatch-exclude-newer2/pixi.lock +++ b/tests/data/non-satisfiability/mismatch-exclude-newer2/pixi.lock @@ -1,10 +1,10 @@ -version: 6 +version: 7 environments: default: channels: - url: https://conda.anaconda.org/conda-forge/ options: - exclude-newer: "2023-10-01T00:00:00Z" + exclude-newer: 2023-10-01T00:00:00Z packages: win-64: - conda: https://conda.anaconda.org/conda-forge/win-64/foobar-0.1.0-h2628c8c_0.conda diff --git a/tests/data/non-satisfiability/mismatched-source-spec/pixi.lock b/tests/data/non-satisfiability/mismatched-source-spec/pixi.lock index b3e659526f..32cb30c97f 100644 --- a/tests/data/non-satisfiability/mismatched-source-spec/pixi.lock +++ b/tests/data/non-satisfiability/mismatched-source-spec/pixi.lock @@ -1,4 +1,4 @@ -version: 6 +version: 7 environments: default: channels: @@ -7,10 +7,6 @@ environments: win-64: - conda: child-package packages: -# This should invalidate the lock-file because the package `child-package` is -# requested as a git package in the pixi.toml. - conda: child-package name: child-package version: 0.1.0 - build: pyhbf21a9e_0 - subdir: noarch diff --git a/tests/data/non-satisfiability/non-binary-no-build/pixi.lock b/tests/data/non-satisfiability/non-binary-no-build/pixi.lock index 05160af0b8..7b18e45a05 100644 --- a/tests/data/non-satisfiability/non-binary-no-build/pixi.lock +++ b/tests/data/non-satisfiability/non-binary-no-build/pixi.lock @@ -1,4 +1,4 @@ -version: 6 +version: 7 environments: default: channels: diff --git a/tests/data/non-satisfiability/source-dependency-changed-project-model/pixi.lock b/tests/data/non-satisfiability/source-dependency-changed-project-model/pixi.lock index 5450d956b2..eceb65cc16 100644 --- a/tests/data/non-satisfiability/source-dependency-changed-project-model/pixi.lock +++ b/tests/data/non-satisfiability/source-dependency-changed-project-model/pixi.lock @@ -1,4 +1,4 @@ -version: 6 +version: 7 environments: default: channels: @@ -35,8 +35,6 @@ packages: - conda: child-package name: child-package version: 0.1.0 - build: hbf21a9e_0 - subdir: linux-64 depends: - libstdcxx >=15 - libgcc >=15 diff --git a/tests/data/non-satisfiability/source-dependency/pixi.lock b/tests/data/non-satisfiability/source-dependency/pixi.lock index 2b1624d1b0..691e14b35d 100644 --- a/tests/data/non-satisfiability/source-dependency/pixi.lock +++ b/tests/data/non-satisfiability/source-dependency/pixi.lock @@ -1,4 +1,4 @@ -version: 6 +version: 7 environments: default: channels: @@ -11,22 +11,15 @@ packages: - conda: child-package name: child-package version: 0.1.0 - build: pyhbf21a9e_0 - subdir: noarch depends: - python input: - # This should cause the lock-file to be invalid because the hash is - # not the same as the expected one. hash: b67010bf5bc5608db89c0399e726852b07a7ef4fb26b3aa18171f1d0f6a19c89 globs: - pixi.toml - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.0-h2628c8c_0_cpython.conda sha256: 90553586879bf328f2f9efb8d8faa958ecba822faf379f0a20c3461467b9b955 md5: defd5d375853a2caff36a19d2d81a28e - arch: x86_64 - platform: win - channel: https://conda.anaconda.org/conda-forge/ license: Python-2.0 size: 16140836 timestamp: 1696321871976 diff --git a/tests/data/non-satisfiability/source-recursive-dependency-changed-dir/pixi.lock b/tests/data/non-satisfiability/source-recursive-dependency-changed-dir/pixi.lock index aa79d3266f..7aef3e77df 100644 --- a/tests/data/non-satisfiability/source-recursive-dependency-changed-dir/pixi.lock +++ b/tests/data/non-satisfiability/source-recursive-dependency-changed-dir/pixi.lock @@ -1,27 +1,21 @@ -version: 6 +version: 7 environments: default: channels: - url: https://conda.anaconda.org/conda-forge/ packages: win-64: - - conda: foobar - conda: child-package + - conda: foobar packages: - conda: child-package name: child-package version: 0.1.0 - build: pyhbf21a9e_0 - subdir: noarch depends: - foobar 0.1.0 baz - # This should cause the lock-file to be invalid because the package `foobar` - # does not come from the directory `not-foobar`. sources: foobar: - path: "../not-foobar" + path: ../not-foobar - conda: foobar name: foobar version: 0.1.0 - build: baz - subdir: noarch diff --git a/tests/data/non-satisfiability/source-recursive-dependency-mismatch/pixi.lock b/tests/data/non-satisfiability/source-recursive-dependency-mismatch/pixi.lock index 774e3106b1..87c0b56fa6 100644 --- a/tests/data/non-satisfiability/source-recursive-dependency-mismatch/pixi.lock +++ b/tests/data/non-satisfiability/source-recursive-dependency-mismatch/pixi.lock @@ -1,27 +1,21 @@ -version: 6 +version: 7 environments: default: channels: - url: https://conda.anaconda.org/conda-forge/ packages: win-64: - - conda: foobar - conda: child-package + - conda: foobar packages: - conda: child-package name: child-package version: 0.1.0 - build: pyhbf21a9e_0 - subdir: noarch depends: - foobar 0.2.0 baz - # This should cause the lock-file to be invalid because the package `foobar` - # has a different version. sources: foobar: - path: "../foobar" + path: ../foobar - conda: foobar name: foobar version: 0.1.0 - build: baz - subdir: noarch diff --git a/tests/data/non-satisfiability/source-recursive-dependency/pixi.lock b/tests/data/non-satisfiability/source-recursive-dependency/pixi.lock index 29e020a9ea..85b548ac4b 100644 --- a/tests/data/non-satisfiability/source-recursive-dependency/pixi.lock +++ b/tests/data/non-satisfiability/source-recursive-dependency/pixi.lock @@ -1,4 +1,4 @@ -version: 6 +version: 7 environments: default: channels: @@ -11,15 +11,11 @@ packages: - conda: child-package name: child-package version: 0.1.0 - build: pyhbf21a9e_0 - subdir: noarch depends: - foobar 0.1.0 baz - # This should cause the lock-file to be invalid because `foobar` should be a source package, - # but it is installed in the environment as a binary package. sources: foobar: - path: "foobar" + path: foobar - conda: https://conda.anaconda.org/conda-forge/win-64/foobar-0.1.0-baz.conda sha256: 90553586879bf328f2f9efb8d8faa958ecba822faf379f0a20c3461467b9b955 md5: defd5d375853a2caff36a19d2d81a28e diff --git a/tests/data/satisfiability/source-dependency/pixi.lock b/tests/data/satisfiability/source-dependency/pixi.lock index 1d6a13065a..29a9cfcd40 100644 --- a/tests/data/satisfiability/source-dependency/pixi.lock +++ b/tests/data/satisfiability/source-dependency/pixi.lock @@ -1,4 +1,4 @@ -version: 6 +version: 7 environments: default: channels: @@ -35,8 +35,6 @@ packages: - conda: child-package name: child-package version: 0.1.0 - build: hbf21a9e_0 - subdir: linux-64 depends: - libstdcxx >=15 - libgcc >=15