diff --git a/Cargo.lock b/Cargo.lock index 6bc06f900..3a0f34ae0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -349,9 +349,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" @@ -529,7 +529,7 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" dependencies = [ - "getrandom", + "getrandom 0.2.15", "once_cell", "tiny-keccak", ] @@ -1037,8 +1037,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] @@ -1164,9 +1180,9 @@ checksum = "d0e7a4dd27b9476dc40cb050d3632d3bba3a70ddbff012285f7f8559a1e7e545" [[package]] name = "hyper" -version = "1.3.1" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ "bytes", "futures-channel", @@ -1183,9 +1199,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.26.0" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", "http", @@ -1196,13 +1212,14 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", + "webpki-roots", ] [[package]] name = "hyper-util" -version = "0.1.5" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" +checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2" dependencies = [ "bytes", "futures-channel", @@ -1210,10 +1227,10 @@ dependencies = [ "http", "http-body", "hyper", + "libc", "pin-project-lite", "socket2", "tokio", - "tower", "tower-service", "tracing", ] @@ -1467,10 +1484,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.69" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -1616,7 +1634,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -1833,26 +1851,6 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.99", -] - [[package]] name = "pin-project-lite" version = "0.2.14" @@ -1979,6 +1977,60 @@ dependencies = [ "memchr", ] +[[package]] +name = "quinn" +version = "0.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012" +dependencies = [ + "bytes", + "cfg_aliases 0.2.1", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.12", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" +dependencies = [ + "bytes", + "getrandom 0.3.2", + "rand 0.9.0", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.12", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5" +dependencies = [ + "cfg_aliases 0.2.1", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "quote" version = "1.0.36" @@ -1988,6 +2040,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -1995,8 +2053,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "zerocopy", ] [[package]] @@ -2006,7 +2075,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -2015,7 +2094,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", ] [[package]] @@ -2033,7 +2121,7 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox", "thiserror 1.0.61", ] @@ -2044,7 +2132,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ - "getrandom", + "getrandom 0.2.15", "libredox", "thiserror 2.0.12", ] @@ -2104,9 +2192,9 @@ checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" -version = "0.12.4" +version = "0.12.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" dependencies = [ "base64 0.22.1", "bytes", @@ -2126,6 +2214,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "quinn", "rustls", "rustls-pemfile", "rustls-pki-types", @@ -2135,13 +2224,14 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-rustls", + "tower", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", "webpki-roots", - "winreg", + "windows-registry", ] [[package]] @@ -2152,7 +2242,7 @@ checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", "untrusted", "windows-sys 0.52.0", @@ -2232,6 +2322,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "rustc_version" version = "0.4.0" @@ -2256,11 +2352,11 @@ dependencies = [ [[package]] name = "rustls" -version = "0.22.4" +version = "0.23.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +checksum = "df51b5869f3a441595eac5e8ff14d486ff285f7b8c0df8770e49c3b56351f0f0" dependencies = [ - "log", + "once_cell", "ring", "rustls-pki-types", "rustls-webpki", @@ -2280,15 +2376,18 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +dependencies = [ + "web-time", +] [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.103.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03" dependencies = [ "ring", "rustls-pki-types", @@ -2500,7 +2599,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -2520,9 +2619,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" dependencies = [ "libc", "windows-sys 0.52.0", @@ -2608,9 +2707,12 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "0.1.2" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] [[package]] name = "synstructure" @@ -2779,6 +2881,21 @@ dependencies = [ "zerovec", ] +[[package]] +name = "tinyvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.38.2" @@ -2798,12 +2915,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.25.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ "rustls", - "rustls-pki-types", "tokio", ] @@ -2906,6 +3022,7 @@ dependencies = [ "self_update", "semver", "serde", + "serde_json", "shell-words", "shellexpand", "strum", @@ -2924,14 +3041,14 @@ dependencies = [ [[package]] name = "tower" -version = "0.4.13" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "pin-project", "pin-project-lite", + "sync_wrapper", "tokio", "tower-layer", "tower-service", @@ -2939,15 +3056,15 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -3152,25 +3269,35 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn 2.0.99", @@ -3191,9 +3318,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3201,9 +3328,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -3214,9 +3341,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" @@ -3228,6 +3358,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webpki-roots" version = "0.26.2" @@ -3319,7 +3459,7 @@ checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" dependencies = [ "windows-implement", "windows-interface", - "windows-result", + "windows-result 0.1.2", "windows-targets 0.52.6", ] @@ -3345,6 +3485,23 @@ dependencies = [ "syn 2.0.99", ] +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + +[[package]] +name = "windows-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +dependencies = [ + "windows-result 0.3.2", + "windows-strings", + "windows-targets 0.53.0", +] + [[package]] name = "windows-result" version = "0.1.2" @@ -3354,6 +3511,24 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -3405,13 +3580,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows-version" version = "0.1.1" @@ -3433,6 +3624,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -3445,6 +3642,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -3457,12 +3660,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -3475,6 +3690,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -3487,6 +3708,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3499,6 +3726,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3511,6 +3744,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" version = "0.5.40" @@ -3529,22 +3768,21 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "winsafe" version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.5.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -3635,7 +3873,7 @@ dependencies = [ "hex", "nix 0.28.0", "ordered-stream", - "rand", + "rand 0.8.5", "serde", "serde_repr", "sha1", @@ -3673,6 +3911,26 @@ dependencies = [ "zvariant", ] +[[package]] +name = "zerocopy" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", +] + [[package]] name = "zerofrom" version = "0.1.4" diff --git a/Cargo.toml b/Cargo.toml index 1baacc39c..deb708d2a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -53,6 +53,7 @@ notify-rust = "~4.11" wildmatch = "2.3.0" rust-i18n = "3.0.1" sys-locale = "0.3.1" +serde_json = "1.0.117" jetbrains-toolbox-updater = "5.0.0" indexmap = { version = "2.9.0", features = ["serde"] } diff --git a/config.example.toml b/config.example.toml index bca777fcb..f2b297df7 100644 --- a/config.example.toml +++ b/config.example.toml @@ -358,3 +358,25 @@ # during the pixi step # (default: false) # include_release_notes = false + +[uv_python] +# If this is true, Topgrade will compare the latest python version +# with the current uv-managed (installed with `uv python`) version. It requires that only a single version be present, not more, not less. +# When a new version is available, Topgrade will: +# - Uninstall that version of python with `uv python uninstall` +# - Install the latest version of python with `uv python install` +# - (If "reinstall_tools" is not disabled) reinstall all tools with `uv tool install --reinstall ` +# WARNING: Enabling this may break virtual environments created with earlier Python versions. +# It may also break other things. Use at your own risk. +# (default: false) +# enable_uv_python_update = true + +# All the below are only applicable if "enable_uv_python_update = true". + +# If disabled, Topgrade will not reinstall tools +# (default: true) +# reinstall_tools = true + +# Topgrade will run these commands after a successful update. +# (default: not defined) +# post_commands = [ "for project in ~/projects/*; do cd $project || exit; if [[ -e '.venv' ]]; then rm -rf .venv; uv venv; uv pip install -r requirements.txt; fi; done;" ] diff --git a/src/config.rs b/src/config.rs index d46c904b8..25e922777 100644 --- a/src/config.rs +++ b/src/config.rs @@ -378,6 +378,14 @@ pub struct VscodeConfig { profile: Option, } +#[derive(Deserialize, Default, Debug, Merge)] +#[serde(deny_unknown_fields)] +pub struct UvPythonConfig { + enable_uv_python_update: Option, + reinstall_tools: Option, + post_commands: Option>, +} + #[derive(Deserialize, Default, Debug, Merge)] #[serde(deny_unknown_fields)] /// Configuration file @@ -459,6 +467,9 @@ pub struct ConfigFile { #[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)] vscode: Option, + + #[merge(strategy = crate::utils::merge_strategies::inner_merge_opt)] + uv_python: Option, } fn config_directory() -> PathBuf { @@ -1688,6 +1699,29 @@ impl Config { Some(profile.as_str()) } } + + pub fn enable_uv_python(&self) -> bool { + self.config_file + .uv_python + .as_ref() + .and_then(|uv_python| uv_python.enable_uv_python_update) + .unwrap_or(false) + } + + pub fn uv_python_reinstall_tools(&self) -> bool { + self.config_file + .uv_python + .as_ref() + .and_then(|uv_python| uv_python.reinstall_tools) + .unwrap_or(true) + } + + pub fn uv_python_post_commands(&self) -> Option<&[String]> { + self.config_file + .uv_python + .as_ref() + .and_then(|uv_python| uv_python.post_commands.as_deref()) + } } #[cfg(test)] diff --git a/src/step.rs b/src/step.rs index 866b80eff..3cb6b7ca9 100644 --- a/src/step.rs +++ b/src/step.rs @@ -147,6 +147,7 @@ pub enum Step { Tmux, Toolbx, Uv, + UvPython, Vagrant, Vcpkg, Vim, @@ -604,6 +605,7 @@ impl Step { runner.execute(*self, "toolbx", || toolbx::run_toolbx(ctx))? } Uv => runner.execute(*self, "uv", || generic::run_uv(ctx))?, + UvPython => runner.execute(*self, "uv python", || generic::run_uv_python(ctx))?, Vagrant => { if ctx.config().should_run(Vagrant) { if let Ok(boxes) = vagrant::collect_boxes(ctx) { @@ -819,6 +821,7 @@ pub(crate) fn default_steps() -> Vec { Lensfun, Poetry, Uv, + UvPython, Zvm, Aqua, Bun, diff --git a/src/steps/generic.rs b/src/steps/generic.rs index a4fe91407..18135ddac 100644 --- a/src/steps/generic.rs +++ b/src/steps/generic.rs @@ -5,6 +5,8 @@ use jetbrains_toolbox_updater::{find_jetbrains_toolbox, update_jetbrains_toolbox use regex::bytes::Regex; use rust_i18n::t; use semver::Version; +use serde::Deserialize; +use std::cmp::Ordering; use std::ffi::OsString; use std::iter::once; use std::path::PathBuf; @@ -20,9 +22,10 @@ use crate::execution_context::ExecutionContext; use crate::executor::ExecutorOutput; use crate::output_changed_message; use crate::step::Step; -use crate::terminal::{print_separator, shell}; +use crate::terminal::print_separator; use crate::utils::{ - check_is_python_2_or_shim, get_require_sudo_string, require, require_one, require_option, which, PathExt, + check_is_python_2_or_shim, get_require_sudo_string, require, require_one, require_option, run_with_shell, which, + PathExt, }; use crate::HOME_DIR; use crate::{ @@ -901,15 +904,7 @@ pub fn run_myrepos_update(ctx: &ExecutionContext) -> Result<()> { pub fn run_custom_command(name: &str, command: &str, ctx: &ExecutionContext) -> Result<()> { print_separator(name); - let mut exec = ctx.run_type().execute(shell()); - #[cfg(unix)] - let command = if let Some(command) = command.strip_prefix("-i ") { - exec.arg("-i"); - command - } else { - command - }; - exec.arg("-c").arg(command).status_checked() + run_with_shell(command, ctx) } pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> { @@ -1492,6 +1487,187 @@ pub fn run_uv(ctx: &ExecutionContext) -> Result<()> { Ok(()) } +#[derive(Deserialize, Debug)] +struct UvPythonVersionData { + version: String, + // version_parts: ..., + path: Option, // Not a PathBuf because we don't need it + // symlink: Option, + url: Option, + // os: String, + variant: String, + // implementation: String, + // arch: String, + // libc: String, +} + +#[derive(Debug)] +struct UvPythonVersion { + version: Version, + installed: bool, +} + +impl UvPythonVersionData { + /// Returns `None` when the version is undesirable, that is when any of the following conditions is met: + /// - It's a pre-release (we don't care about pre-releases) (TODO: add an option to care about pre-releases) + /// - The variant is not default (we don't care about free-threaded python versions) + fn normalize(self) -> Result> { + if self.variant != "default" { + return Ok(None); + } + Ok(Some(UvPythonVersion { + version: { + // If it contains anything but digits and dots, it's a pre-release. + // (e.g. "3.14.0a6") + if !self.version.chars().all(|c| c.is_ascii_digit() || c == '.') { + return Ok(None); + } + // If there is still an error with parsing the version, it's just an invalid version + self.version.parse()? + }, + installed: match (self.path, self.url) { + (Some(_), None) => true, // It has `path`, so it's installed + (None, Some(_)) => false, // It has `url`, so it's not installed and downloadable + (None, None) => return Err(eyre!("Version has neither of `path` and `url`")), + (Some(_), Some(_)) => return Err(eyre!("Version has both of `path` and `url`")), + }, + })) + } +} + +pub fn run_uv_python(ctx: &ExecutionContext) -> Result<()> { + let uv = require("uv")?; + + if !ctx.config().enable_uv_python() { + // We do not print a warning nor print the separator, because: + // - The uv_python step is not dependent on a single utility like pip_review is, + // if you have uv installed chances are you don't even use `uv python` + // - The uv_python step for now only works with a single uv-managed python installation + // - The uv_python step can be dangerous to run, most people might not want to run it + return Err(SkipStep(String::from("uv_python is disabled by default")).into()); + } + + print_separator("uv python"); + + let versions: Vec = serde_json::from_str(&String::from_utf8( + ctx.run_type() + .execute(&uv) + .args(["python", "list"]) + .arg("--managed-python") // Exclude non-managed pythons + .args(["--output-format", "json"]) + .output_checked()? + .stdout, + )?)?; + let versions: Vec = versions + .into_iter() + .filter_map(|version_data| version_data.normalize().transpose()) + .collect::>>()?; + + let latest = versions + .iter() + .map(|version| &version.version) + .max() + .ok_or_else(|| eyre!("No versions found"))?; + + debug!("Found latest version: {latest:?}"); + + // TODO: support multiple versions. Install new patch releases for each? Optionally install new minor release? + let mut it = versions.iter().filter(|version| version.installed); + let installed = &it + .next() + .ok_or_else(|| eyre!("Expected there to be exactly one uv-managed python version installed. (Found 0)"))? + .version; + if it.next().is_some() { + return Err(eyre!( + "Expected there to be exactly one uv-managed python version installed. (Found more than 1)" + )); + } + + debug!("Found installed version: {installed:?}"); + + match latest.cmp(installed) { + Ordering::Equal => { + debug!("Latest version already installed."); + return Ok(()); + } + Ordering::Less => unreachable!(), // Literally unreachable; we grabbed `latest` from the same pool as `installed`. + Ordering::Greater => (), // Continue updating + } + debug!("Found new version: {latest}; currently installed: {installed}"); + + // Store which tools are installed before they're broken + let tools = if ctx.config().uv_python_reinstall_tools() { + // Example: + // black v25.1.0 + // - black + // - blackd + // get-pypi-latest-version v0.1.0 + // - get_pypi_latest_version + // termdown v1.18.0 + // - termdown + // when v3.3 + // - when + let stdout = ctx + .run_type() + .execute(&uv) + .args(["tool", "list"]) + .output_checked()? + .stdout; + Some( + String::from_utf8(stdout) + .wrap_err("Expected valid utf8")? + .lines() + .filter(|l| !l.starts_with('-')) // Ignore lines starting with "-" + // Strip the version + .map(|line| { + line.split_once(' ') + .ok_or_else(|| eyre!(output_changed_message!("uv tool list", "Expected a space in that line"))) + .map(|parts| parts.0.to_string()) + }) + .collect::>>()?, + ) + } else { + None + }; + if let Some(tools) = &tools { + debug!("Found tools: {tools:?}"); + } + + // Uninstall previous python version + ctx.run_type() + .execute(&uv) + .args(["python", "uninstall"]) + .arg(installed.to_string()) + .status_checked()?; + + // Install the new version + ctx.run_type() + .execute(&uv) + .args(["python", "install"]) + .arg(latest.to_string()) + .status_checked()?; + + // Reinstall tools + if let Some(tools) = tools { + for tool in tools { + ctx.run_type() + .execute(&uv) + .args(["tool", "install", "--reinstall"]) + .arg(tool) + .status_checked()?; + } + } + + // Run post commands + if let Some(commands) = ctx.config().uv_python_post_commands() { + for command in commands { + run_with_shell(command, ctx)?; + } + } + + Ok(()) +} + /// Involve `zvm upgrade` to update ZVM pub fn run_zvm(ctx: &ExecutionContext) -> Result<()> { let zvm = require("zvm")?; diff --git a/src/utils.rs b/src/utils.rs index 6f3afac00..ca35de872 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -17,6 +17,8 @@ use tracing_subscriber::{registry, EnvFilter}; use crate::command::CommandExt; use crate::config::DEFAULT_LOG_LEVEL; use crate::error::SkipStep; +use crate::execution_context::ExecutionContext; +use crate::terminal::shell; pub trait PathExt where @@ -306,6 +308,19 @@ pub fn install_color_eyre() -> Result<()> { .install() } +/// Run a string as shell command +pub fn run_with_shell(command: &str, ctx: &ExecutionContext) -> Result<()> { + let mut exec = ctx.run_type().execute(shell()); + #[cfg(unix)] + let command = if let Some(command) = command.strip_prefix("-i ") { + exec.arg("-i"); + command + } else { + command + }; + exec.arg("-c").arg(command).status_checked() +} + /// Macro to construct an error message for when the output of a command is unexpected. #[macro_export] macro_rules! output_changed_message {