diff --git a/Cargo.lock b/Cargo.lock index 8cae870bba..7c1a6adf51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -150,9 +150,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.16.3" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" dependencies = [ "aws-lc-sys", "zeroize", @@ -160,9 +160,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.40.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" dependencies = [ "cc", "cmake", @@ -237,9 +237,9 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.61" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "jobserver", @@ -247,12 +247,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - [[package]] name = "cfg-if" version = "0.1.10" @@ -326,9 +320,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.6.2" +version = "4.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff7a1dccbdd8b078c2bdebff47e404615151534d5043da397ec50286816f9cb" +checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772" dependencies = [ "clap", ] @@ -529,9 +523,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer", "const-oid", @@ -644,13 +638,12 @@ checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "filetime" -version = "0.2.27" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if 1.0.4", "libc", - "libredox", ] [[package]] @@ -859,9 +852,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", @@ -896,9 +889,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heapless" @@ -987,9 +980,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hybrid-array" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" dependencies = [ "typenum", ] @@ -1184,9 +1177,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1199,7 +1192,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -1223,16 +1216,6 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1254,22 +1237,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" -[[package]] -name = "jni" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" -dependencies = [ - "cesu8", - "cfg-if 1.0.4", - "combine", - "jni-sys 0.3.1", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", -] - [[package]] name = "jni" version = "0.22.4" @@ -1279,7 +1246,7 @@ dependencies = [ "cfg-if 1.0.4", "combine", "jni-macros", - "jni-sys 0.4.1", + "jni-sys", "log", "simd_cesu8", "thiserror 2.0.18", @@ -1300,15 +1267,6 @@ dependencies = [ "syn", ] -[[package]] -name = "jni-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" -dependencies = [ - "jni-sys 0.4.1", -] - [[package]] name = "jni-sys" version = "0.4.1" @@ -1340,9 +1298,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ "cfg-if 1.0.4", "futures-util", @@ -1368,18 +1326,6 @@ version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" -[[package]] -name = "libredox" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" -dependencies = [ - "bitflags", - "libc", - "plain", - "redox_syscall", -] - [[package]] name = "libz-sys" version = "1.1.24" @@ -1494,9 +1440,9 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "normpath" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" +checksum = "b9985ef7269fa99f3b12437bb698381da2428743ab90f20393f399fa14cab21a" dependencies = [ "windows-sys 0.61.2", ] @@ -1560,15 +1506,14 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.78" +version = "0.10.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38c4372413cdaaf3cc79dd92d29d7d9f5ab09b51b10dded508fb90bb70b9222" +checksum = "a45fa2aa886c42762255da344f0a0d313e254066c46aad76f300c3d3da62d967" dependencies = [ "bitflags", "cfg-if 1.0.4", "foreign-types", "libc", - "once_cell", "openssl-macros", "openssl-sys", ] @@ -1607,9 +1552,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.114" +version = "0.9.116" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13ce1245cd07fcc4cfdb438f7507b0c7e4f3849a69fd84d52374c66d83741bb6" +checksum = "f28a22dc7140cda5f096e5e7724a6962ca81a7f8bfd2979f9b18c11af56318c4" dependencies = [ "cc", "libc", @@ -1620,9 +1565,9 @@ dependencies = [ [[package]] name = "opentelemetry" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84bcd6ae87133e903af7ef497404dda70c60d0ea14895fc8a5e6722754fc2a0" +checksum = "b0142c63252a9e054e68a4c61a5778f7b14f576274d593f8ce883d191a099682" dependencies = [ "futures-core", "futures-sink", @@ -1634,22 +1579,22 @@ dependencies = [ [[package]] name = "opentelemetry-http" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" +checksum = "5683015d09e2df236ef005b17f6f196f0d5f6313c4fa43a7b6a53b52776e4331" dependencies = [ "async-trait", "bytes", "http", "opentelemetry", - "reqwest 0.12.28", + "reqwest", ] [[package]] name = "opentelemetry-otlp" -version = "0.31.1" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f69cd6acbb9af919df949cd1ec9e5e7fdc2ef15d234b6b795aaa525cc02f71f" +checksum = "9966929966d17620d7c316c643ba62631826e10021409357772d5eea84f62c35" dependencies = [ "http", "opentelemetry", @@ -1657,18 +1602,18 @@ dependencies = [ "opentelemetry-proto", "opentelemetry_sdk", "prost", - "reqwest 0.12.28", + "reqwest", "thiserror 2.0.18", "tokio", "tonic", - "tracing", + "tonic-types", ] [[package]] name = "opentelemetry-proto" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7175df06de5eaee9909d4805a3d07e28bb752c34cab57fa9cff549da596b30f" +checksum = "56d658ba1faf63f7b9c492cfbe6e0ec365440a16132d3270c1065f7b33f1b638" dependencies = [ "opentelemetry", "opentelemetry_sdk", @@ -1679,15 +1624,16 @@ dependencies = [ [[package]] name = "opentelemetry_sdk" -version = "0.31.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14ae4f5991976fd48df6d843de219ca6d31b01daaab2dad5af2badeded372bd" +checksum = "368afaed344110f40b179bb8fbe54bc52d98f9bd2b281799ef32487c2650c956" dependencies = [ "futures-channel", "futures-executor", "futures-util", "opentelemetry", "percent-encoding", + "portable-atomic", "rand 0.9.4", "thiserror 2.0.18", "tokio", @@ -1702,18 +1648,18 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -1732,12 +1678,6 @@ version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" -[[package]] -name = "plain" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" - [[package]] name = "platforms" version = "3.10.0" @@ -1835,6 +1775,15 @@ dependencies = [ "syn", ] +[[package]] +name = "prost-types" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +dependencies = [ + "prost", +] + [[package]] name = "pulldown-cmark" version = "0.13.3" @@ -1948,15 +1897,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" -dependencies = [ - "bitflags", -] - [[package]] name = "regex" version = "1.12.3" @@ -2003,43 +1943,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" -dependencies = [ - "base64", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "reqwest" -version = "0.13.2" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +checksum = "62e0021ea2c22aed41653bc7e1419abb2c97e038ff2c33d0e1309e49a97deec0" dependencies = [ "base64", "bytes", @@ -2061,7 +1967,7 @@ dependencies = [ "pin-project-lite", "rustls", "rustls-pki-types", - "rustls-platform-verifier 0.6.2", + "rustls-platform-verifier", "sync_wrapper", "tokio", "tokio-native-tls", @@ -2134,9 +2040,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.39" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "aws-lc-rs", "log", @@ -2168,27 +2074,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "rustls-platform-verifier" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" -dependencies = [ - "core-foundation", - "core-foundation-sys", - "jni 0.21.1", - "log", - "once_cell", - "rustls", - "rustls-native-certs", - "rustls-platform-verifier-android", - "rustls-webpki", - "security-framework", - "security-framework-sys", - "webpki-root-certs", - "windows-sys 0.61.2", -] - [[package]] name = "rustls-platform-verifier" version = "0.7.0" @@ -2197,7 +2082,7 @@ checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" dependencies = [ "core-foundation", "core-foundation-sys", - "jni 0.22.4", + "jni", "log", "once_cell", "rustls", @@ -2272,11 +2157,11 @@ dependencies = [ "rayon", "regex", "remove_dir_all", - "reqwest 0.13.2", + "reqwest", "retry", "rs_tracing", "rustls", - "rustls-platform-verifier 0.7.0", + "rustls-platform-verifier", "rustls-webpki", "same-file", "scopeguard", @@ -2328,12 +2213,6 @@ dependencies = [ "wait-timeout", ] -[[package]] -name = "ryu" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" - [[package]] name = "same-file" version = "1.0.6" @@ -2439,18 +2318,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - [[package]] name = "sha2" version = "0.11.0" @@ -2745,9 +2612,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -2865,9 +2732,9 @@ checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" [[package]] name = "tonic" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", "base64", @@ -2891,15 +2758,26 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" dependencies = [ "bytes", "prost", "tonic", ] +[[package]] +name = "tonic-types" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab1b02061f83d519bba3caa167f88f261ef05720ab8ebc954ade70de3348e8" +dependencies = [ + "prost", + "prost-types", + "tonic", +] + [[package]] name = "tower" version = "0.5.3" @@ -2921,9 +2799,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51" dependencies = [ "async-compression", "bitflags", @@ -2933,13 +2811,13 @@ dependencies = [ "http", "http-body", "http-body-util", - "iri-string", "pin-project-lite", "tokio", "tokio-util", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -2999,9 +2877,9 @@ dependencies = [ [[package]] name = "tracing-opentelemetry" -version = "0.32.1" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ac28f2d093c6c477eaa76b23525478f38de514fa9aeb1285738d4b97a9552fc" +checksum = "adbc64cba7137545b8044cb1fe9814f7aacf3c6b5f9b45be8bb5db538befdb26" dependencies = [ "js-sys", "opentelemetry", @@ -3181,9 +3059,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if 1.0.4", "once_cell", @@ -3194,9 +3072,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.68" +version = "0.4.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" dependencies = [ "js-sys", "wasm-bindgen", @@ -3204,9 +3082,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3214,9 +3092,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", @@ -3227,9 +3105,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] @@ -3283,9 +3161,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.95" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" dependencies = [ "js-sys", "wasm-bindgen", @@ -3376,22 +3254,13 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -3400,7 +3269,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -3412,67 +3281,34 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "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", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -3485,48 +3321,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -3535,9 +3347,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" [[package]] name = "wit-bindgen" @@ -3703,9 +3515,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] diff --git a/Cargo.toml b/Cargo.toml index fdb16a08da..2d8d9bdbd0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -71,9 +71,9 @@ openssl = { version = "0.10", optional = true } # HACK: Temporarily pinned due to ppc64 ELFv1/v2 ABI issue in 300.5.5, to be # removed when lands. openssl-src = { version = "=300.5.4", optional = true } -opentelemetry = { version = "0.31", optional = true } -opentelemetry-otlp = { version = "0.31", features = ["grpc-tonic"], optional = true } -opentelemetry_sdk = { version = "0.31", features = ["rt-tokio"], optional = true } +opentelemetry = { version = "0.32", optional = true } +opentelemetry-otlp = { version = "0.32", features = ["grpc-tonic"], optional = true } +opentelemetry_sdk = { version = "0.32", features = ["rt-tokio"], optional = true } platforms = "3.4" pulldown-cmark = { version = "0.13", default-features = false } rand = "0.10" @@ -101,7 +101,7 @@ tokio-stream = "0.1.14" toml = "1.0" tracing = "0.1" tracing-log = "0.2" -tracing-opentelemetry = { version = "0.32", optional = true } +tracing-opentelemetry = { version = "0.33", optional = true } tracing-subscriber = { version = "0.3.23", features = ["env-filter"] } url = "2.4" wait-timeout = "0.2" diff --git a/doc/dev-guide/src/coding-standards.md b/doc/dev-guide/src/coding-standards.md index 077b635d8c..cf2d4aafb5 100644 --- a/doc/dev-guide/src/coding-standards.md +++ b/doc/dev-guide/src/coding-standards.md @@ -58,7 +58,7 @@ which can build up over time. ## Writing platform-specific code -For developers using BSD/Linux/Mac OS, there are Windows VM's suitable for such +For developers using BSD/Linux/Mac OS, there are Windows VMs suitable for such development tasks for use with virtualbox and other hypervisors are downloadable from [Microsoft](https://developer.microsoft.com/en-us/windows/downloads/virtual-machines/). diff --git a/doc/user-guide/src/installation/other.md b/doc/user-guide/src/installation/other.md index 73fac6e6d4..811d63c05c 100644 --- a/doc/user-guide/src/installation/other.md +++ b/doc/user-guide/src/installation/other.md @@ -102,7 +102,7 @@ which is a `brew`-managed `rust` toolchain installation. ## Manual installation You can manually download `rustup-init` for a given target from -`https://static.rust-lang.org/rustup/dist/{target-triple}/rustup-init[.exe]`[^msys2] [^msvc]. +`https://static.rust-lang.org/rustup/dist/{target-tuple}/rustup-init[.exe]`[^msys2] [^msvc].
Direct links @@ -187,7 +187,7 @@ You can manually download `rustup-init` for a given target from
To get a previous version, use -`https://static.rust-lang.org/rustup/archive/{rustup-version}/{target-triple}/rustup-init[.exe]`. +`https://static.rust-lang.org/rustup/archive/{rustup-version}/{target-tuple}/rustup-init[.exe]`. SHA-256 checksums are also available by appending `.sha256` to the link. diff --git a/doc/user-guide/src/installation/windows.md b/doc/user-guide/src/installation/windows.md index 97499c049d..59ac3bde82 100644 --- a/doc/user-guide/src/installation/windows.md +++ b/doc/user-guide/src/installation/windows.md @@ -20,7 +20,7 @@ a target tuple of either `i686-pc-windows-msvc`, `x86_64-pc-windows-msvc`, or `a depending on the CPU architecture of the host Windows OS. The toolchains that `rustup` chooses to install, unless told otherwise through the [toolchain specification], will be compiled to run on that target tuple host and will -target that triple by default. +target that tuple by default. You can change this behavior with `rustup set default-host` or during installation. diff --git a/rustup-init.sh b/rustup-init.sh index 46717ce205..cff65bf345 100755 --- a/rustup-init.sh +++ b/rustup-init.sh @@ -44,7 +44,7 @@ Options: Set log level to 'DEBUG' if 'RUSTUP_LOG' is unset -q, --quiet Disable progress output, set log level to 'WARN' if 'RUSTUP_LOG' is unset - -y + -y, --yes Disable confirmation prompt --default-host Choose a default host tuple @@ -134,6 +134,11 @@ main() { --quiet) RUSTUP_QUIET=yes ;; + --yes) + # user wants to skip the prompt -- + # we don't need /dev/tty + need_tty=no + ;; *) OPTIND=1 if [ "${arg%%--*}" = "" ]; then diff --git a/src/cli/common.rs b/src/cli/common.rs index 11f8f698e5..cf0257c958 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -17,7 +17,7 @@ use tracing_subscriber::{EnvFilter, Registry, reload::Handle}; use crate::{ config::Cfg, - dist::{DistOptions, TargetTriple, ToolchainDesc}, + dist::{DistOptions, TargetTuple, ToolchainDesc}, errors::RustupError, install::{InstallMethod, UpdateStatus}, process::Process, @@ -510,16 +510,16 @@ pub(crate) fn ignorable_error( /// - The `force_non_host` flag is set to `false`. pub(crate) fn check_non_host_toolchain( toolchain: String, - host_arch: &TargetTriple, - target_triple: &TargetTriple, + host_arch: &TargetTuple, + target_tuple: &TargetTuple, force_non_host: bool, ) -> Result<()> { - if force_non_host || host_arch.can_run(target_triple)? { + if force_non_host || host_arch.can_run(target_tuple)? { return Ok(()); } Err(RustupError::ToolchainIncompatible { toolchain, - target_triple: target_triple.clone(), + target_tuple: target_tuple.clone(), } .into()) } @@ -531,10 +531,10 @@ pub(crate) fn warn_if_host_is_emulated(process: &Process) { if process.var("RUSTUP_CI").is_ok() { return; } - if TargetTriple::is_host_emulated() { + if TargetTuple::is_host_emulated() { warn!( "Rustup is not running natively. It's running under emulation of {}.", - TargetTriple::from_host_or_build(process) + TargetTuple::from_host_or_build(process) ); warn!( "For best compatibility and performance you should reinstall rustup for your native CPU." diff --git a/src/cli/help.rs b/src/cli/help.rs index 75bb8e3ca8..015e847077 100644 --- a/src/cli/help.rs +++ b/src/cli/help.rs @@ -99,7 +99,7 @@ pub(crate) fn toolchain_help() -> String { {PLACEHOLDER} = |{PLACEHOLDER:#} {PLACEHOLDER} = beta[.]{PLACEHOLDER:#} {PLACEHOLDER} = YYYY-MM-DD{PLACEHOLDER:#} - {PLACEHOLDER} = {PLACEHOLDER:#} + {PLACEHOLDER} = {PLACEHOLDER:#} 'channel' is a named release channel, a major and minor version number such as `1.42`, or a fully specified version number, such diff --git a/src/cli/proxy_mode.rs b/src/cli/proxy_mode.rs index e387cd7ed7..0e480e920f 100644 --- a/src/cli/proxy_mode.rs +++ b/src/cli/proxy_mode.rs @@ -32,11 +32,11 @@ pub async fn main(arg0: &str, current_dir: PathBuf, process: &Process) -> Result .skip(1 + toolchain.is_some() as usize) .collect(); - let cfg = Cfg::from_env(current_dir, false, process)?; + let cfg = Cfg::from_env(current_dir, false, true, process)?; let (toolchain, source) = cfg .local_toolchain(match toolchain { Some(name) => Some(( - name.resolve(&cfg.get_default_host_triple()?)?, + name.resolve(&cfg.default_host_tuple()?)?, ActiveSource::CommandLine, )), None => None, diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index 50d4da2c68..8ce4a292ca 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -44,7 +44,7 @@ use crate::{ command, component_for_bin, config::{ActiveSource, Cfg}, dist::{ - AutoInstallMode, DistOptions, PartialToolchainDesc, Profile, TargetTriple, + AutoInstallMode, DistOptions, PartialToolchainDesc, Profile, TargetTuple, download::DownloadCfg, manifest::{Component, ComponentStatus, ManifestWithHash}, }, @@ -556,7 +556,7 @@ enum SelfSubcmd { /// Uninstall rustup Uninstall { /// Disable confirmation prompt - #[arg(short = 'y')] + #[arg(short = 'y', long = "yes")] no_prompt: bool, /// Do not clean up the `PATH` environment variable @@ -571,8 +571,8 @@ enum SelfSubcmd { #[derive(Debug, Subcommand)] #[command(arg_required_else_help = true, subcommand_required = true)] enum SetSubcmd { - /// The triple used to identify toolchains when not specified - DefaultHost { host_triple: String }, + /// The tuple used to identify toolchains when not specified + DefaultHost { host_tuple: String }, /// The default components installed with a toolchain Profile { @@ -631,7 +631,7 @@ pub async fn main( update_console_filter(process, &console_filter, matches.quiet, matches.verbose); - let cfg = &mut Cfg::from_env(current_dir, matches.quiet, process)?; + let cfg = &mut Cfg::from_env(current_dir, matches.quiet, true, process)?; cfg.toolchain_override = matches.plus_toolchain; let Some(subcmd) = matches.subcmd else { @@ -751,8 +751,8 @@ pub async fn main( SelfSubcmd::UpgradeData => cfg.upgrade_data().map(|_| ExitCode::SUCCESS), }, RustupSubcmd::Set { subcmd } => match subcmd { - SetSubcmd::DefaultHost { host_triple } => cfg - .set_default_host_triple(host_triple) + SetSubcmd::DefaultHost { host_tuple } => cfg + .set_default_host_tuple(host_tuple) .map(|_| ExitCode::SUCCESS), SetSubcmd::Profile { profile_name } => { cfg.set_profile(profile_name).map(|_| ExitCode::SUCCESS) @@ -787,11 +787,11 @@ async fn default_( cfg.set_default(Some(&toolchain_name.into()))?; } MaybeResolvableToolchainName::Some(ResolvableToolchainName::Official(toolchain)) => { - let desc = toolchain.resolve(&cfg.get_default_host_triple()?)?; + let desc = toolchain.resolve(&cfg.default_host_tuple()?)?; let status = cfg .ensure_installed(&desc, vec![], vec![], None, force_non_host, true) .await? - .0; + .status; cfg.set_default(Some(&(&desc).into()))?; @@ -982,17 +982,17 @@ async fn update( if !names.is_empty() { for name in names { // This needs another pass to fix it all up - if name.has_triple() { - let host_arch = TargetTriple::from_host_or_build(cfg.process); - let target_triple = name.clone().resolve(&host_arch)?.target; + if !name.target.is_empty() { + let host_arch = TargetTuple::from_host_or_build(cfg.process); + let target_tuple = name.clone().resolve(&host_arch)?.target; common::check_non_host_toolchain( name.to_string(), &host_arch, - &target_triple, + &target_tuple, force_non_host, )?; } - let desc = name.resolve(&cfg.get_default_host_triple()?)?; + let desc = name.resolve(&cfg.default_host_tuple()?)?; let components = opts.component.iter().map(|s| &**s).collect::>(); let targets = opts.target.iter().map(|s| &**s).collect::>(); @@ -1039,7 +1039,7 @@ async fn update( exit_code &= self_update_mode.update(should_self_update, &dl_cfg).await?; } else if ensure_active_toolchain { let (toolchain, source) = cfg.ensure_active_toolchain(force_non_host, true).await?; - info!("the active toolchain `{toolchain}` has been installed"); + info!("the active toolchain `{}` has been installed", *toolchain); info!("it's active because: {}", source.to_reason()); exit_code &= self_update_mode.update(should_self_update, &dl_cfg).await?; } else { @@ -1060,7 +1060,7 @@ async fn run( command: Vec, install: bool, ) -> Result { - let toolchain = toolchain.resolve(&cfg.get_default_host_triple()?)?; + let toolchain = toolchain.resolve(&cfg.default_host_tuple()?)?; let toolchain = Toolchain::from_local(toolchain, install, cfg).await?; let cmd = toolchain.command(&command[0])?; command::run_command_for_dir(cmd, &command[0], &command[1..]) @@ -1074,7 +1074,7 @@ async fn which( let (toolchain, _) = cfg .local_toolchain(match toolchain { Some(name) => Some(( - name.resolve(&cfg.get_default_host_triple()?)?.into(), + name.resolve(&cfg.default_host_tuple()?)?.into(), ActiveSource::CommandLine, // From --toolchain option )), None => None, @@ -1108,20 +1108,17 @@ async fn which( async fn show(cfg: &Cfg<'_>, verbose: bool) -> Result { common::warn_if_host_is_emulated(cfg.process); - // Print host triple - { - let t = cfg.process.stdout(); - let mut t = t.lock(); - writeln!( - t, - "{HEADER}Default host: {HEADER:#}{}", - cfg.get_default_host_triple()? - )?; - } + let mut t = cfg.process.stdout(); + + // Print host tuple + writeln!( + t.lock(), + "{HEADER}Default host: {HEADER:#}{}", + cfg.default_host_tuple()? + )?; // Print rustup home directory { - let t = cfg.process.stdout(); let mut t = t.lock(); writeln!( t, @@ -1146,90 +1143,88 @@ async fn show(cfg: &Cfg<'_>, verbose: bool) -> Result { .map(|atar| (&atar.0, &atar.1)) .unzip(); - let active_toolchain_targets = match active_toolchain_name { - Some(ToolchainName::Official(desc)) => DistributableToolchain::new(cfg, desc.clone())? - .components()? - .into_iter() - .filter_map(|c| { - (c.installed && c.component.short_name() == "rust-std") - .then(|| c.component.target.expect("rust-std should have a target")) - }) - .collect(), - Some(ToolchainName::Custom(name)) => { - Toolchain::new(cfg, LocalToolchainName::Named(name.into()))?.installed_targets()? - } - None => Vec::new(), - }; - // show installed toolchains - { - let mut t = cfg.process.stdout(); - - print_header(&mut t, "installed toolchains")?; - - let default_toolchain_name = cfg.get_default()?; - let last_index = installed_toolchains.len().wrapping_sub(1); - for (n, toolchain_name) in installed_toolchains.into_iter().enumerate() { - let is_default_toolchain = default_toolchain_name.as_ref() == Some(&toolchain_name); - let is_active_toolchain = active_toolchain_name == Some(&toolchain_name); + print_header(&mut t, "installed toolchains")?; + + let default_toolchain_name = cfg.get_default()?; + let last_index = installed_toolchains.len().wrapping_sub(1); + for (n, toolchain_name) in installed_toolchains.into_iter().enumerate() { + let is_default_toolchain = default_toolchain_name.as_ref() == Some(&toolchain_name); + let is_active_toolchain = active_toolchain_name == Some(&toolchain_name); + + let status_str = match (is_active_toolchain, is_default_toolchain) { + (true, true) => " (active, default)", + (true, false) => " (active)", + (false, true) => " (default)", + (false, false) => "", + }; - let status_str = match (is_active_toolchain, is_default_toolchain) { - (true, true) => " (active, default)", - (true, false) => " (active)", - (false, true) => " (default)", - (false, false) => "", - }; + let mut t = t.lock(); - writeln!(t.lock(), "{toolchain_name}{CONTEXT}{status_str}{CONTEXT:#}")?; + writeln!(t, "{toolchain_name}{CONTEXT}{status_str}{CONTEXT:#}")?; - if verbose { - let toolchain = Toolchain::new(cfg, toolchain_name.into())?; - writeln!( - cfg.process.stdout().lock(), - " {}\n path: {}", - toolchain.rustc_version(), - toolchain.path().display() - )?; - if n != last_index { - writeln!(cfg.process.stdout().lock())?; - } + if verbose { + let toolchain = Toolchain::new(cfg, toolchain_name.into())?; + writeln!( + t, + " {}\n path: {}", + toolchain.rustc_version(), + toolchain.path().display() + )?; + if n != last_index { + writeln!(t)?; } } } // show active toolchain - { - let mut t = cfg.process.stdout(); + writeln!(t.lock())?; - writeln!(t.lock())?; + print_header(&mut t, "active toolchain")?; - print_header(&mut t, "active toolchain")?; + let Some((active_toolchain_name, active_source)) = active_toolchain_and_source else { + writeln!(t.lock(), "no active toolchain")?; + return Ok(ExitCode::SUCCESS); + }; - match active_toolchain_and_source { - Some((active_toolchain_name, active_source)) => { - let active_toolchain = Toolchain::with_source( - cfg, - active_toolchain_name.clone().into(), - &active_source, - )?; - writeln!(t.lock(), "name: {}", active_toolchain.name())?; - writeln!(t.lock(), "active because: {}", active_source.to_reason())?; - if verbose { - writeln!(t.lock(), "compiler: {}", active_toolchain.rustc_version())?; - writeln!(t.lock(), "path: {}", active_toolchain.path().display())?; - } + writeln!(t.lock(), "name: {active_toolchain_name}")?; + writeln!(t.lock(), "active because: {}", active_source.to_reason())?; - // show installed targets for the active toolchain - writeln!(t.lock(), "installed targets:")?; + let active_toolchain = match Toolchain::new(cfg, active_toolchain_name.clone().into()) { + Ok(active_toolchain) => active_toolchain, + Err( + RustupError::ToolchainNotInstalled { .. } | RustupError::PathToolchainNotInstalled(..), + ) => { + info!("the active toolchain `{active_toolchain_name}` is not installed"); + return Ok(ExitCode::SUCCESS); + } + Err(e) => return Err(e.into()), + }; - for target in active_toolchain_targets { - writeln!(t.lock(), " {target}")?; - } - } - None => { - writeln!(t.lock(), "no active toolchain")?; - } + if verbose { + writeln!(t.lock(), "compiler: {}", active_toolchain.rustc_version())?; + writeln!(t.lock(), "path: {}", active_toolchain.path().display())?; + } + + // show installed targets for the active toolchain + writeln!(t.lock(), "installed targets:")?; + + let active_toolchain_targets = match active_toolchain_name { + ToolchainName::Official(desc) => DistributableToolchain::new(cfg, desc.clone())? + .components()? + .into_iter() + .filter_map(|c| { + (c.installed && c.component.short_name() == "rust-std") + .then(|| c.component.target.expect("rust-std should have a target")) + }) + .collect(), + ToolchainName::Custom(name) => { + Toolchain::new(cfg, LocalToolchainName::Named(name.into()))?.installed_targets()? } + }; + + for target in active_toolchain_targets { + writeln!(t.lock(), " {target}")?; } fn print_header(t: &mut ColorableTerminal, text: &str) -> Result<(), Error> { @@ -1363,7 +1358,7 @@ async fn target_add( .map(|target| { Component::new( "rust-std".to_string(), - Some(TargetTriple::new(target)), + Some(TargetTuple::new(target)), false, ) }) @@ -1386,8 +1381,8 @@ async fn target_remove( .await?; for target in targets { - let target = TargetTriple::new(target); - let default_target = cfg.get_default_host_triple()?; + let target = TargetTuple::new(target); + let default_target = cfg.default_host_tuple()?; if target == default_target { warn!( "removing the default host target; proc-macros and build scripts might no longer build" @@ -1476,9 +1471,9 @@ async fn component_add( fn get_target( target: Option, distributable: &DistributableToolchain<'_>, -) -> Option { +) -> Option { target - .map(TargetTriple::new) + .map(TargetTuple::new) .or_else(|| Some(distributable.desc().target.clone())) } @@ -1562,7 +1557,7 @@ async fn toolchain_remove(cfg: &mut Cfg<'_>, opts: UninstallOpts) -> Result, ) -> Result { - let toolchain_name = toolchain.resolve(&cfg.get_default_host_triple()?)?; + let toolchain_name = toolchain.resolve(&cfg.default_host_tuple()?)?; match Toolchain::new(cfg, (&toolchain_name).into()) { Ok(_) => {} Err(e @ RustupError::ToolchainNotInstalled { .. }) => match &toolchain_name { @@ -1974,7 +1969,7 @@ fn output_completion_script( async fn display_version(current_dir: PathBuf, process: &Process) -> Result<()> { info!("This is the version for the rustup toolchain manager, not the rustc compiler."); - let mut cfg = Cfg::from_env(current_dir, true, process)?; + let mut cfg = Cfg::from_env(current_dir, true, true, process)?; cfg.toolchain_override = cfg .process .args() diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index 2ef4726955..7edd7322cb 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -60,7 +60,7 @@ use crate::{ }, config::Cfg, dist::{ - DistOptions, PartialToolchainDesc, Profile, TargetTriple, ToolchainDesc, + DistOptions, PartialToolchainDesc, Profile, TargetTuple, ToolchainDesc, download::DownloadCfg, }, download::download_file, @@ -96,7 +96,7 @@ use windows::{delete_rustup_and_cargo_home, do_add_to_path, do_remove_from_path} pub(crate) use windows::{run_update, self_replace}; pub(crate) struct InstallOpts<'a> { - pub default_host_triple: Option, + pub default_host_tuple: Option, pub default_toolchain: Option, pub profile: Profile, pub no_modify_path: bool, @@ -108,7 +108,7 @@ pub(crate) struct InstallOpts<'a> { impl InstallOpts<'_> { fn install(self, cfg: &mut Cfg<'_>) -> Result> { let Self { - default_host_triple, + default_host_tuple, default_toolchain, profile, no_modify_path: _no_modify_path, @@ -119,12 +119,12 @@ impl InstallOpts<'_> { cfg.set_profile(profile)?; - if let Some(default_host_triple) = &default_host_triple { - // Set host triple now as it will affect resolution of toolchain_str - info!("setting default host triple to {}", default_host_triple); - cfg.set_default_host_triple(default_host_triple.to_owned())?; + if let Some(default_host_tuple) = &default_host_tuple { + // Set host tuple now as it will affect resolution of toolchain_str + info!("setting default host tuple to {}", default_host_tuple); + cfg.set_default_host_tuple(default_host_tuple.to_owned())?; } else { - info!("default host triple is {}", cfg.get_default_host_triple()?); + info!("default host tuple is {}", cfg.default_host_tuple()?); } let user_specified_something = default_toolchain.is_some() @@ -164,7 +164,7 @@ impl InstallOpts<'_> { MaybeOfficialToolchainName::None => unreachable!(), MaybeOfficialToolchainName::Some(n) => n, }; - Some(toolchain_name.resolve(&cfg.get_default_host_triple()?)?) + Some(toolchain_name.resolve(&cfg.default_host_tuple()?)?) } None => match cfg.get_default()? { // Default is installable @@ -174,7 +174,7 @@ impl InstallOpts<'_> { None => Some( "stable" .parse::()? - .resolve(&cfg.get_default_host_triple()?)?, + .resolve(&cfg.default_host_tuple()?)?, ), }, }) @@ -195,12 +195,12 @@ impl InstallOpts<'_> { writeln!(process.stdout().lock())?; - self.default_host_triple = Some(common::question_str( - "Default host triple?", + self.default_host_tuple = Some(common::question_str( + "Default host tuple?", &self - .default_host_triple + .default_host_tuple .take() - .unwrap_or_else(|| TargetTriple::from_host_or_build(process).to_string()), + .unwrap_or_else(|| TargetTuple::from_host_or_build(process).to_string()), process, )?); @@ -232,18 +232,18 @@ impl InstallOpts<'_> { fn validate(&self, process: &Process) -> Result<()> { common::warn_if_host_is_emulated(process); - let host_triple = self - .default_host_triple + let host_tuple = self + .default_host_tuple .as_ref() - .map(TargetTriple::new) - .unwrap_or_else(|| TargetTriple::from_host_or_build(process)); + .map(TargetTuple::new) + .unwrap_or_else(|| TargetTuple::from_host_or_build(process)); let partial_channel = match &self.default_toolchain { None | Some(MaybeOfficialToolchainName::None) => { ResolvableToolchainName::try_from("stable")? } Some(MaybeOfficialToolchainName::Some(s)) => s.into(), }; - let resolved = partial_channel.resolve(&host_triple)?; + let resolved = partial_channel.resolve(&host_tuple)?; trace!("Successfully resolved installation toolchain as: {resolved}"); Ok(()) } @@ -567,8 +567,8 @@ pub(crate) async fn install( anyhow!( "Pre-checks for host and toolchain failed: {e}\n\ If you are unsure of suitable values, the 'stable' toolchain is the default.\n\ - Valid host triples look something like: {}", - TargetTriple::from_host_or_build(cfg.process) + Valid host tuples look something like: {}", + TargetTuple::from_host_or_build(cfg.process) ) })?; @@ -710,11 +710,13 @@ fn check_existence_of_rustc_or_cargo_in_path(no_prompt: bool, process: &Process) if let Err(path) = rustc_or_cargo_exists_in_path(process) { warn!("It looks like you have an existing installation of Rust at:"); warn!("{}", path); - warn!("It is recommended that rustup be the primary Rust installation."); - warn!("Otherwise you may have confusion unless you are careful with your PATH."); - warn!("If you are sure that you want both rustup and your already installed Rust"); - warn!("then please reply `y' or `yes' or set RUSTUP_INIT_SKIP_PATH_CHECK to yes"); - warn!("or pass `-y' to ignore all ignorable checks."); + warn!("This could mean one of the following:"); + warn!("- You have already installed rustup: you can quit the installer right now."); + warn!("- You haven't installed rustup yet, but have Rust installed from elsewhere."); + warn!("In the latter case, rustup can coexist with and adopt your existing Rust."); + warn!("To adopt, please reply `yes`, or set RUSTUP_INIT_SKIP_PATH_CHECK to yes,"); + warn!("or pass `-y` to ignore all ignorable checks, then follow the instructions at:"); + warn!(""); ignorable_error("cannot install while Rust is installed", no_prompt, process)?; } Ok(()) @@ -736,11 +738,10 @@ fn check_existence_of_settings_file(cfg: &Cfg<'_>) -> Result<()> { }; warn!("it looks like you have an existing rustup settings file at:"); warn!("{}", settings_file_path.display()); - let inferred = - PartialToolchainDesc::from_str("stable")?.resolve(&cfg.get_default_host_triple()?)?; + let inferred = PartialToolchainDesc::from_str("stable")?.resolve(&cfg.default_host_tuple()?)?; if default_toolchain != inferred.to_string() { warn!("rustup will install the default toolchain as specified in the settings file,"); - warn!("instead of the one inferred from the default host triple."); + warn!("instead of the one inferred from the default host tuple."); } Ok(()) } @@ -790,15 +791,15 @@ fn current_install_opts(opts: &InstallOpts<'_>, process: &Process) -> String { format!( r"Current installation options: -- ` `default host triple: `{}` +- ` `default host tuple: `{}` - ` `default toolchain: `{}` - ` `profile: `{}` - modify PATH variable: `{}` ", - opts.default_host_triple + opts.default_host_tuple .as_ref() - .map(TargetTriple::new) - .unwrap_or_else(|| TargetTriple::from_host_or_build(process)), + .map(TargetTuple::new) + .unwrap_or_else(|| TargetTuple::from_host_or_build(process)), opts.default_toolchain .as_ref() .map(ToString::to_string) @@ -817,18 +818,18 @@ fn warn_if_default_linker_missing(process: &Process) { return; }; - // If we have the host triple, attempt to determine the CC/linker path that + // If we have the host tuple, attempt to determine the CC/linker path that // `cc-rs` would use, as this is *usually* why we need a linker to invoke. // // Doing it this way allows us to correctly diagnose quirky systems like // solaris and illumos that use `gcc` rather than `cc` for historical reasons. - let cc_tool = TargetTriple::from_host(process).and_then(|triple| { + let cc_tool = TargetTuple::from_host(process).and_then(|tuple| { // Fill in some dummy settings for `Build`/`Tool` to be able to properly // give us the metadata we want cc::Build::new() .opt_level(0) - .target(&triple) - .host(&triple) + .target(&tuple) + .host(&tuple) .try_get_compiler() .ok() }); @@ -1299,8 +1300,8 @@ pub(crate) async fn prepare_update(dl_cfg: &DownloadCfg<'_>) -> Result) -> Result) -> Result() .unwrap() - .resolve(&cfg.get_default_host_triple().unwrap()) + .resolve(&cfg.default_host_tuple().unwrap()) .unwrap(), opts.install(&mut cfg) .unwrap() // result @@ -1488,7 +1489,7 @@ mod tests { assert_eq!( for_host!( r"info: profile set to default -info: default host triple is {0} +info: default host tuple is {0} " ), &String::from_utf8(tp.stderr()).unwrap() diff --git a/src/cli/self_update/shell.rs b/src/cli/self_update/shell.rs index f4caa12a7a..abf1f9a67a 100644 --- a/src/cli/self_update/shell.rs +++ b/src/cli/self_update/shell.rs @@ -91,9 +91,10 @@ pub(crate) fn build_source_env_lines(process: &Process) -> String { groups.push((src, vec![shell.name()])); } } + let src_width = groups.iter().map(|(src, _)| src.len()).max().unwrap_or(0); groups .into_iter() - .map(|(src, names)| format!(" {} # For {}\n", src, names.join("/"))) + .map(|(src, names)| format!(" {:, process: &Process) -> Option } use cc::windows_registry; - let host_triple = if let Some(trip) = opts.default_host_triple.as_ref() { - trip.to_owned() + let host_tuple = if let Some(tuple) = opts.default_host_tuple.as_ref() { + tuple.to_owned() } else { - TargetTriple::from_host_or_build(process).to_string() + TargetTuple::from_host_or_build(process).to_string() }; - let installing_msvc = host_triple.contains("msvc"); - let have_msvc = windows_registry::find_tool(&host_triple, "cl.exe").is_some(); + let installing_msvc = host_tuple.contains("msvc"); + let have_msvc = windows_registry::find_tool(&host_tuple, "cl.exe").is_some(); if installing_msvc && !have_msvc { // Visual Studio build tools are required. // If the user does not have Visual Studio installed and their host // machine is i686 or x86_64 then it's OK to try an auto install. // Otherwise a manual install will be required. let has_any_vs = windows_registry::find_vs_version().is_ok(); - let is_x86 = host_triple.contains("i686") || host_triple.contains("x86_64"); + let is_x86 = host_tuple.contains("i686") || host_tuple.contains("x86_64"); if is_x86 && !has_any_vs { Some(VsInstallPlan::Automatic) } else { diff --git a/src/cli/setup_mode.rs b/src/cli/setup_mode.rs index e3a64e06a0..e0bc08df60 100644 --- a/src/cli/setup_mode.rs +++ b/src/cli/setup_mode.rs @@ -36,7 +36,7 @@ struct RustupInit { quiet: bool, /// Disable confirmation prompt - #[arg(short = 'y')] + #[arg(short = 'y', long = "yes")] no_prompt: bool, /// Choose a default host tuple @@ -121,7 +121,7 @@ pub async fn main( update_console_filter(process, &console_filter, quiet, verbose); let opts = InstallOpts { - default_host_triple: default_host, + default_host_tuple: default_host, default_toolchain, profile, no_modify_path, @@ -130,6 +130,6 @@ pub async fn main( targets: &target.iter().map(|s| &**s).collect::>(), }; - let mut cfg = Cfg::from_env(current_dir, quiet, process)?; + let mut cfg = Cfg::from_env(current_dir, quiet, true, process)?; self_update::install(no_prompt, opts, &mut cfg).await } diff --git a/src/config.rs b/src/config.rs index fdb45a0d9c..5b2181b861 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,6 @@ use std::fmt::{self, Debug, Display}; use std::io; +use std::ops::Deref; use std::path::{Path, PathBuf}; use std::str::FromStr; @@ -11,7 +12,7 @@ use tracing::{debug, info, trace, warn}; use crate::{ cli::{common, self_update::SelfUpdateMode}, dist::{ - self, AutoInstallMode, DistOptions, PartialToolchainDesc, Profile, TargetTriple, + self, AutoInstallMode, DistOptions, PartialToolchainDesc, Profile, TargetTuple, ToolchainDesc, }, errors::RustupError, @@ -124,6 +125,48 @@ impl Display for ActiveSource { } } +/// Represents the result of an operation that may ensure the installation of a certain toolchain. +#[derive(Clone, Debug)] +pub(crate) struct EnsureInstalled { + pub inner: T, + pub status: UpdateStatus, +} + +impl EnsureInstalled { + pub fn new(toolchain: T, status: UpdateStatus) -> Self { + Self { + inner: toolchain, + status, + } + } +} + +impl EnsureInstalled { + fn warn_auto_install(&self, process: &Process) { + // If we're already in a recursion, or we haven't just installed the active toolchain, then + // don't print the warning. + let recursions = process.var("RUST_RECURSION_COUNT"); + if recursions.is_ok_and(|it| it != "0") || !matches!(self.status, UpdateStatus::Installed) { + return; + } + + warn!( + "the missing active toolchain `{}` has been auto-installed", + self.inner, + ); + warn!("this might cause rustup commands to take longer time to finish than expected"); + info!("you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable`"); + } +} + +impl Deref for EnsureInstalled { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + // Represents a toolchain override from a +toolchain command line option, // RUSTUP_TOOLCHAIN environment variable, or rust-toolchain.toml file etc. Can // include components and targets from a rust-toolchain.toml that should be @@ -144,7 +187,7 @@ impl OverrideCfg { fn from_file(cfg: &Cfg<'_>, file: OverrideFile) -> Result { let toolchain_name = match (file.toolchain.channel, file.toolchain.path) { (Some(name), None) => { - ResolvableToolchainName::try_from(name)?.resolve(&cfg.get_default_host_triple()?)? + ResolvableToolchainName::try_from(name)?.resolve(&cfg.default_host_tuple()?)? } (None, Some(path)) => { if file.toolchain.targets.is_some() @@ -246,12 +289,21 @@ pub(crate) struct Cfg<'a> { pub quiet: bool, pub current_dir: PathBuf, pub process: &'a Process, + + /// Allows the auto-installation of the active toolchain when it is missing. + /// + /// This flag should be set to `false` when auto-installation behavior is undesired, such as + /// when running `rustup component` and `rustup target` subcommands. In these cases, it has a + /// higher precedence than the `RUSTUP_AUTO_INSTALL` environment variable and the `rustup set + /// auto-install` setting. + pub allow_auto_install: bool, } impl<'a> Cfg<'a> { pub(crate) fn from_env( current_dir: PathBuf, quiet: bool, + allow_auto_install: bool, process: &'a Process, ) -> Result { // Set up the rustup home directory @@ -288,14 +340,11 @@ impl<'a> Cfg<'a> { let update_hash_dir = rustup_dir.join("update-hashes"); let download_dir = rustup_dir.join("downloads"); - // Figure out get_default_host_triple before Config is populated - let default_host_triple = - settings_file.with(|s| Ok(get_default_host_triple(s, process)))?; + // Figure out default_host_tuple before Config is populated + let default_host = settings_file.with(|s| Ok(default_host_tuple(s, process)))?; // Environment override let env_override = match process.var_opt("RUSTUP_TOOLCHAIN")? { - Some(tc) => { - Some(ResolvableLocalToolchainName::try_from(&tc)?.resolve(&default_host_triple)?) - } + Some(tc) => Some(ResolvableLocalToolchainName::try_from(&tc)?.resolve(&default_host)?), None => None, }; @@ -317,13 +366,14 @@ impl<'a> Cfg<'a> { quiet, current_dir, process, + allow_auto_install, }; // Run some basic checks against the constructed configuration // For now, that means simply checking that 'stable' can resolve // for the current configuration. ResolvableToolchainName::try_from("stable")?.resolve( - &cfg.get_default_host_triple() + &cfg.default_host_tuple() .context("Unable parse configuration")?, )?; @@ -373,6 +423,10 @@ impl<'a> Cfg<'a> { } pub(crate) fn should_auto_install(&self) -> Result { + if !self.allow_auto_install { + return Ok(false); + } + if let Ok(mode) = self.process.var("RUSTUP_AUTO_INSTALL") { Ok(mode != "0") } else { @@ -483,7 +537,7 @@ impl<'a> Cfg<'a> { .map(|(desc, source)| { anyhow::Ok(( LocalToolchainName::Named(ToolchainName::Official( - desc.resolve(&self.get_default_host_triple()?)?, + desc.resolve(&self.default_host_tuple()?)?, )), source, )) @@ -506,7 +560,11 @@ impl<'a> Cfg<'a> { } match self.ensure_active_toolchain(true, false).await { - Ok(r) => Ok(Some(r)), + Ok(r) => { + let (tc, source) = r; + tc.warn_auto_install(self.process); + Ok(Some((tc.inner, source))) + } Err(e) => match e.downcast_ref::() { Some(RustupError::ToolchainNotSelected(_)) => Ok(None), _ => Err(e), @@ -529,7 +587,7 @@ impl<'a> Cfg<'a> { let override_config: Option<(OverrideCfg, ActiveSource)> = // First check +toolchain override from the command line if let Some(name) = &self.toolchain_override { - let override_config = name.resolve(&self.get_default_host_triple()?)?.into(); + let override_config = name.resolve(&self.default_host_tuple()?)?.into(); Some((override_config, ActiveSource::CommandLine)) } // Then check the RUSTUP_TOOLCHAIN environment variable @@ -574,7 +632,7 @@ impl<'a> Cfg<'a> { // have an unresolved name. I'm just preserving pre-existing // behaviour by choosing ResolvableToolchainName here. let toolchain_name = ResolvableToolchainName::try_from(name)? - .resolve(&get_default_host_triple(settings, self.process))?; + .resolve(&default_host_tuple(settings, self.process))?; let override_cfg = toolchain_name.into(); return Ok(Some((override_cfg, source))); } @@ -632,11 +690,11 @@ impl<'a> Cfg<'a> { toolchain_file.display() ) })?; - let default_host_triple = get_default_host_triple(settings, self.process); + let default_host = default_host_tuple(settings, self.process); // Do not permit architecture/os selection in channels as // these are host specific and toolchain files are portable. if let ResolvableToolchainName::Official(name) = &toolchain_name - && name.has_triple() + && !name.target.is_empty() { // Permit fully qualified names IFF the toolchain is installed. TODO(robertc): consider // disabling this and backing out https://github.com/rust-lang/rustup/pull/2141 (but provide @@ -648,7 +706,7 @@ impl<'a> Cfg<'a> { } // XXX: this awkwardness deals with settings file being locked already - let toolchain_name = toolchain_name.resolve(&default_host_triple)?; + let toolchain_name = toolchain_name.resolve(&default_host)?; if !Toolchain::exists(self, &(&toolchain_name).into())? && matches!(toolchain_name, ToolchainName::Custom(_)) { @@ -708,10 +766,10 @@ impl<'a> Cfg<'a> { match name { Some((tc, source)) => { let install_if_missing = self.should_auto_install()?; - Ok(( - Toolchain::from_local(tc, install_if_missing, self).await?, - source, - )) + let EnsureInstalled { inner: tc, status } = + Toolchain::from_local(tc, install_if_missing, self).await?; + EnsureInstalled::new(tc.name(), status).warn_auto_install(self.process); + Ok((tc, source)) } None => { let (tc, source) = self @@ -728,10 +786,10 @@ impl<'a> Cfg<'a> { &self, force_non_host: bool, verbose: bool, - ) -> Result<(LocalToolchainName, ActiveSource)> { + ) -> Result<(EnsureInstalled, ActiveSource)> { if let Some((override_config, source)) = self.find_override_config()? { let toolchain = override_config.clone().into_local_toolchain_name(); - if let OverrideCfg::Official { + let status = if let OverrideCfg::Official { toolchain, components, targets, @@ -746,20 +804,24 @@ impl<'a> Cfg<'a> { force_non_host, verbose, ) - .await?; + .await? + .status } else { Toolchain::with_source(self, toolchain.clone(), &source)?; - } - Ok((toolchain, source)) + UpdateStatus::Unchanged + }; + Ok((EnsureInstalled::new(toolchain, status), source)) } else if let Some(toolchain) = self.get_default()? { let source = ActiveSource::Default; - if let ToolchainName::Official(desc) = &toolchain { + let status = if let ToolchainName::Official(desc) = &toolchain { self.ensure_installed(desc, vec![], vec![], None, force_non_host, verbose) - .await?; + .await? + .status } else { Toolchain::with_source(self, toolchain.clone().into(), &source)?; - } - Ok((toolchain.into(), source)) + UpdateStatus::Unchanged + }; + Ok((EnsureInstalled::new(toolchain.into(), status), source)) } else { Err(no_toolchain_error(self.process)) } @@ -776,10 +838,10 @@ impl<'a> Cfg<'a> { profile: Option, force_non_host: bool, verbose: bool, - ) -> Result<(UpdateStatus, Toolchain<'_>)> { + ) -> Result>> { common::check_non_host_toolchain( toolchain.to_string(), - &TargetTriple::from_host_or_build(self.process), + &TargetTuple::from_host_or_build(self.process), &toolchain.target, force_non_host, )?; @@ -820,7 +882,7 @@ impl<'a> Cfg<'a> { } Err(e) => return Err(e.into()), }; - Ok((status, toolchain.into())) + Ok(EnsureInstalled::new(toolchain.into(), status)) } /// Get the configured default toolchain. @@ -839,7 +901,7 @@ impl<'a> Cfg<'a> { toolchain_maybe_str .map(ResolvableToolchainName::try_from) .transpose()? - .map(|t| t.resolve(&self.get_default_host_triple()?)) + .map(|t| t.resolve(&self.default_host_tuple()?)) .transpose() } @@ -896,22 +958,21 @@ impl<'a> Cfg<'a> { }) } - pub(crate) fn set_default_host_triple(&self, host_triple: String) -> Result<()> { - // Ensure that the provided host_triple is capable of resolving + pub(crate) fn set_default_host_tuple(&self, host_tuple: String) -> Result<()> { + // Ensure that the provided host tuple is capable of resolving // against the 'stable' toolchain. This provides early errors - // if the supplied triple is insufficient / bad. - PartialToolchainDesc::from_str("stable")? - .resolve(&TargetTriple::new(host_triple.clone()))?; + // if the supplied tuple is insufficient / bad. + PartialToolchainDesc::from_str("stable")?.resolve(&TargetTuple::new(host_tuple.clone()))?; self.settings_file.with_mut(|s| { - s.default_host_triple = Some(host_triple); + s.default_host_tuple = Some(host_tuple); Ok(()) }) } #[tracing::instrument(level = "trace", skip_all)] - pub(crate) fn get_default_host_triple(&self) -> Result { + pub(crate) fn default_host_tuple(&self) -> Result { self.settings_file - .with(|s| Ok(get_default_host_triple(s, self.process))) + .with(|s| Ok(default_host_tuple(s, self.process))) } /// The path on disk of any concrete toolchain @@ -959,6 +1020,7 @@ impl Debug for Cfg<'_> { dist_root_url, quiet, current_dir, + allow_auto_install, process: _, } = self; @@ -976,15 +1038,16 @@ impl Debug for Cfg<'_> { .field("dist_root_url", dist_root_url) .field("quiet", quiet) .field("current_dir", current_dir) + .field("allow_auto_install", allow_auto_install) .finish() } } -fn get_default_host_triple(s: &Settings, process: &Process) -> TargetTriple { - s.default_host_triple +fn default_host_tuple(s: &Settings, process: &Process) -> TargetTuple { + s.default_host_tuple .as_ref() - .map(TargetTriple::new) - .unwrap_or_else(|| TargetTriple::from_host_or_build(process)) + .map(TargetTuple::new) + .unwrap_or_else(|| TargetTuple::from_host_or_build(process)) } fn no_toolchain_error(process: &Process) -> anyhow::Error { diff --git a/src/diskio/mod.rs b/src/diskio/mod.rs index f2400ed118..0d6dc93a20 100644 --- a/src/diskio/mod.rs +++ b/src/diskio/mod.rs @@ -80,7 +80,7 @@ pub(crate) enum FileBuffer { } impl FileBuffer { - /// All the buffers space to be re-used when the last reference to it is dropped. + /// Allows the buffer's space to be reused when the last reference to it is dropped. pub(crate) fn clear(&mut self) { if let FileBuffer::Threaded(contents) = self { contents.clear() diff --git a/src/dist/manifest.rs b/src/dist/manifest.rs index 545d0b68b9..b3c2933d9a 100644 --- a/src/dist/manifest.rs +++ b/src/dist/manifest.rs @@ -23,7 +23,7 @@ use anyhow::{Context, Result, anyhow, bail}; use serde::{Deserialize, Serialize}; use crate::{ - dist::{Profile, TargetTriple, ToolchainDesc, config::Config}, + dist::{Profile, TargetTuple, ToolchainDesc, config::Config}, errors::RustupError, toolchain::DistributableToolchain, }; @@ -105,16 +105,16 @@ pub struct Package { #[serde(from = "TargetsMap", into = "TargetsMap")] pub enum PackageTargets { Wildcard(TargetedPackage), - Targeted(BTreeMap), + Targeted(BTreeMap), } #[derive(Deserialize, Serialize)] #[serde(transparent)] -struct TargetsMap(BTreeMap); +struct TargetsMap(BTreeMap); impl From for PackageTargets { fn from(mut map: TargetsMap) -> Self { - let wildcard = TargetTriple::new("*"); + let wildcard = TargetTuple::new("*"); match (map.0.len(), map.0.entry(wildcard)) { (1, Entry::Occupied(entry)) => Self::Wildcard(entry.remove()), (_, _) => Self::Targeted(map.0), @@ -127,7 +127,7 @@ impl From for TargetsMap { match targets { PackageTargets::Wildcard(tpkg) => { let mut map = BTreeMap::new(); - map.insert(TargetTriple::new("*"), tpkg); + map.insert(TargetTuple::new("*"), tpkg); Self(map) } PackageTargets::Targeted(tpkgs) => Self(tpkgs), @@ -264,7 +264,7 @@ pub struct HashedBinary { pub struct Component { pub pkg: String, #[serde(with = "component_target")] - pub target: Option, + pub target: Option, // Older Rustup distinguished between components (which are essential) and // extensions (which are not). #[serde(default)] @@ -288,11 +288,11 @@ impl Hash for Component { } mod component_target { - use super::{Result, TargetTriple}; + use super::{Result, TargetTuple}; use serde::{Deserialize, Deserializer, Serializer}; pub fn serialize( - target: &Option, + target: &Option, serializer: S, ) -> Result { serializer.serialize_str(match target { @@ -303,9 +303,9 @@ mod component_target { pub fn deserialize<'de, D: Deserializer<'de>>( deserializer: D, - ) -> Result, D::Error> { + ) -> Result, D::Error> { Ok(match Option::::deserialize(deserializer)? { - Some(s) if s != "*" => Some(TargetTriple::new(s)), + Some(s) if s != "*" => Some(TargetTuple::new(s)), _ => None, }) } @@ -344,7 +344,7 @@ impl Manifest { self.get_package("rust").map(|p| &*p.version) } - pub(crate) fn get_legacy_components(&self, target: &TargetTriple) -> Result> { + pub(crate) fn get_legacy_components(&self, target: &TargetTuple) -> Result> { // Build a profile from the components/extensions. let result = self .get_package("rust")? @@ -360,7 +360,7 @@ impl Manifest { pub fn get_profile_components( &self, profile: Profile, - target: &TargetTriple, + target: &TargetTuple, ) -> Result> { // An older manifest with no profiles section. if self.profiles.is_empty() { @@ -462,7 +462,7 @@ impl Manifest { for component in &targ_pkg.components { let installed = component.contained_within(&config.components); - let component_target = TargetTriple::new(component.target()); + let component_target = TargetTuple::new(component.target()); // Get the component so we can check if it is available let component_pkg = self @@ -493,7 +493,7 @@ impl Manifest { } impl Package { - pub fn get_target(&self, target: Option<&TargetTriple>) -> Result<&TargetedPackage> { + pub fn get_target(&self, target: Option<&TargetTuple>) -> Result<&TargetedPackage> { match &self.targets { PackageTargets::Wildcard(tpkg) => Ok(tpkg), PackageTargets::Targeted(tpkgs) => { @@ -511,13 +511,13 @@ impl Package { } impl PackageTargets { - pub(crate) fn get<'a>(&'a self, target: &TargetTriple) -> Option<&'a TargetedPackage> { + pub(crate) fn get<'a>(&'a self, target: &TargetTuple) -> Option<&'a TargetedPackage> { match self { Self::Wildcard(tpkg) => Some(tpkg), Self::Targeted(tpkgs) => tpkgs.get(target), } } - pub fn get_mut<'a>(&'a mut self, target: &TargetTriple) -> Option<&'a mut TargetedPackage> { + pub fn get_mut<'a>(&'a mut self, target: &TargetTuple) -> Option<&'a mut TargetedPackage> { match self { Self::Wildcard(tpkg) => Some(tpkg), Self::Targeted(tpkgs) => tpkgs.get_mut(target), @@ -532,7 +532,7 @@ impl TargetedPackage { } impl Component { - pub fn new(pkg: String, target: Option, is_extension: bool) -> Self { + pub fn new(pkg: String, target: Option, is_extension: bool) -> Self { Self { pkg, target, @@ -543,7 +543,7 @@ impl Component { pub(crate) fn try_new( name: &str, distributable: &DistributableToolchain<'_>, - fallback_target: Option<&TargetTriple>, + fallback_target: Option<&TargetTuple>, ) -> Result { let manifest = distributable.get_manifest()?; for component_status in distributable.components()? { @@ -649,7 +649,7 @@ impl fmt::Display for ManifestVersion { #[cfg(test)] mod tests { use crate::RustupError; - use crate::dist::TargetTriple; + use crate::dist::TargetTuple; use crate::dist::manifest::Manifest; // Example manifest from https://public.etherpad-mozilla.org/p/Rust-infra-work-week @@ -662,8 +662,8 @@ mod tests { #[test] fn parse_smoke_test() { - let x86_64_unknown_linux_gnu = TargetTriple::new("x86_64-unknown-linux-gnu"); - let x86_64_unknown_linux_musl = TargetTriple::new("x86_64-unknown-linux-musl"); + let x86_64_unknown_linux_gnu = TargetTuple::new("x86_64-unknown-linux-gnu"); + let x86_64_unknown_linux_musl = TargetTuple::new("x86_64-unknown-linux-musl"); let pkg = Manifest::parse(EXAMPLE).unwrap(); diff --git a/src/dist/manifestation.rs b/src/dist/manifestation.rs index 174307d5fd..50c5d821d7 100644 --- a/src/dist/manifestation.rs +++ b/src/dist/manifestation.rs @@ -24,7 +24,7 @@ use tracing::{debug, info, warn}; use crate::{ diskio::{Executor, IO_CHUNK_SIZE, get_executor, unpack_ram}, dist::{ - DEFAULT_DIST_SERVER, Profile, TargetTriple, ToolchainDesc, + DEFAULT_DIST_SERVER, Profile, TargetTuple, ToolchainDesc, component::{Components, DirectoryPackage, Transaction}, config::Config, download::{DownloadCfg, DownloadStatus, File}, @@ -42,7 +42,7 @@ pub(crate) const CONFIG_FILE: &str = "multirust-config.toml"; #[derive(Debug)] pub struct Manifestation { installation: Components, - target_triple: TargetTriple, + target_tuple: TargetTuple, } #[derive(Debug)] @@ -87,12 +87,12 @@ impl Manifestation { /// it will be created as needed. If there's an existing install /// then the rust-install installation format will be verified. A /// bad installer version is the only reason this will fail. - pub fn open(prefix: InstallPrefix, triple: TargetTriple) -> Result { - // TODO: validate the triple with the existing install as well + pub fn open(prefix: InstallPrefix, target_tuple: TargetTuple) -> Result { + // TODO: validate the tuple with the existing install as well // as the metadata format of the existing install Ok(Self { installation: Components::open(prefix)?, - target_triple: triple, + target_tuple, }) } @@ -146,7 +146,7 @@ impl Manifestation { { for component in &components { match &component.target { - Some(t) if t != &self.target_triple => warn!( + Some(t) if t != &self.target_tuple => warn!( "skipping unavailable component {} for target {}", new_manifest.short_name(component), t @@ -215,14 +215,14 @@ impl Manifestation { // Uninstall components for component in update.components_to_uninstall { match (implicit_modify, &component.target) { - (true, Some(t)) if t != &self.target_triple => { + (true, Some(t)) if t != &self.target_tuple => { info!( "removing previous version of component {} for target {}", new_manifest.short_name(&component), t ); } - (false, Some(t)) if t != &self.target_triple => { + (false, Some(t)) if t != &self.target_tuple => { info!( "removing component {} for target {}", new_manifest.short_name(&component), @@ -416,11 +416,11 @@ impl Manifestation { let url = new_manifest .iter() - .find(|u| u.contains(&format!("{}{}", self.target_triple, ".tar.gz"))); + .find(|u| u.contains(&format!("{}{}", self.target_tuple, ".tar.gz"))); if url.is_none() { return Err(anyhow!( "binary package was not provided for '{}'", - self.target_triple, + self.target_tuple, )); } // Only replace once. The cost is inexpensive. @@ -595,7 +595,7 @@ impl Update { ) -> Result { // The package to install. let rust_package = new_manifest.get_package("rust")?; - let rust_target_package = rust_package.get_target(Some(&manifestation.target_triple))?; + let rust_target_package = rust_package.get_target(Some(&manifestation.target_tuple))?; changes.check_invariants(config)?; @@ -609,7 +609,7 @@ impl Update { let looks_like_v1 = config.is_none() && !installed_components.is_empty(); if looks_like_v1 { let mut profile_components = new_manifest - .get_profile_components(Profile::Default, &manifestation.target_triple)?; + .get_profile_components(Profile::Default, &manifestation.target_tuple)?; starting_list.append(&mut profile_components); } @@ -689,7 +689,7 @@ impl Update { result.components_to_install.push(component.clone()); } else if changes.explicit_add_components.contains(component) { match &component.target { - Some(t) if t != &manifestation.target_triple => info!( + Some(t) if t != &manifestation.target_tuple => info!( "component {} for target {} is up to date", new_manifest.short_name(component), t, diff --git a/src/dist/manifestation/tests.rs b/src/dist/manifestation/tests.rs index 29e87b7cbf..748ced26b7 100644 --- a/src/dist/manifestation/tests.rs +++ b/src/dist/manifestation/tests.rs @@ -5,6 +5,7 @@ use std::{ collections::HashMap, env, fs, + io::Write, path::{Path, PathBuf}, str::FromStr, sync::Arc, @@ -14,8 +15,9 @@ use anyhow::{Result, anyhow}; use url::Url; use crate::{ + config::Cfg, dist::{ - DEFAULT_DIST_SERVER, Profile, TargetTriple, ToolchainDesc, + DEFAULT_DIST_SERVER, Profile, TargetTuple, ToolchainDesc, download::{DownloadCfg, DownloadTracker}, manifest::{Component, Manifest}, manifestation::{Changes, Manifestation, UpdateStatus}, @@ -26,8 +28,10 @@ use crate::{ errors::RustupError, process::TestProcess, test::{ + Env, RustupHome, dist::*, mock::{MockComponentBuilder, MockFile, MockInstallerBuilder}, + test_dir, }, utils::{self, raw as utils_raw}, }; @@ -317,7 +321,7 @@ async fn rename_component() { let adds = [Component::new( "bonus".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), + Some(TargetTuple::new("x86_64-apple-darwin")), true, )]; @@ -357,7 +361,7 @@ async fn rename_component_new() { let adds = [Component::new( "bobo".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), + Some(TargetTuple::new("x86_64-apple-darwin")), true, )]; // Install the basics from day 1 @@ -635,7 +639,7 @@ async fn unavailable_component() { let cx = TestContext::new(Some(edit), GZOnly); let adds = [Component::new( "bonus".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), + Some(TargetTuple::new("x86_64-apple-darwin")), true, )]; @@ -734,7 +738,7 @@ async fn removed_component() { let cx = TestContext::new(Some(edit), GZOnly); let adds = [Component::new( "bonus".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), + Some(TargetTuple::new("x86_64-apple-darwin")), true, )]; @@ -785,12 +789,12 @@ async fn unavailable_components_is_target() { let adds = [ Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, ), Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, ), ]; @@ -905,12 +909,12 @@ async fn update_preserves_extensions() { let adds = vec![ Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, ), Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, ), ]; @@ -955,12 +959,12 @@ async fn add_extensions_for_initial_install() { let adds = vec![ Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, ), Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, ), ]; @@ -984,12 +988,12 @@ async fn add_extensions_for_same_manifest() { let adds = vec![ Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, ), Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, ), ]; @@ -1018,12 +1022,12 @@ async fn add_extensions_for_upgrade() { let adds = vec![ Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, ), Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, ), ]; @@ -1046,7 +1050,7 @@ async fn add_extension_not_in_manifest() { let cx = TestContext::new(None, GZOnly); let adds = vec![Component::new( "rust-bogus".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), true, )]; @@ -1059,7 +1063,7 @@ async fn add_extension_that_is_required_component() { let cx = TestContext::new(None, GZOnly); let adds = vec![Component::new( "rustc".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), + Some(TargetTuple::new("x86_64-apple-darwin")), false, )]; @@ -1081,7 +1085,7 @@ async fn add_extensions_does_not_remove_other_components() { let adds = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; @@ -1097,7 +1101,7 @@ async fn remove_extensions_for_initial_install() { let cx = TestContext::new(None, GZOnly); let removes = vec![Component::new( "rustc".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), + Some(TargetTuple::new("x86_64-apple-darwin")), false, )]; @@ -1110,12 +1114,12 @@ async fn remove_extensions_for_same_manifest() { let adds = vec![ Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, ), Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, ), ]; @@ -1124,7 +1128,7 @@ async fn remove_extensions_for_same_manifest() { let removes = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; @@ -1148,12 +1152,12 @@ async fn remove_extensions_for_upgrade() { let adds = vec![ Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, ), Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, ), ]; @@ -1164,7 +1168,7 @@ async fn remove_extensions_for_upgrade() { let removes = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; @@ -1193,7 +1197,7 @@ async fn remove_extension_not_in_manifest() { let removes = vec![Component::new( "rust-bogus".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), true, )]; @@ -1227,7 +1231,7 @@ async fn remove_extension_not_in_manifest_but_is_already_installed() { let adds = [Component::new( "bonus".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), + Some(TargetTuple::new("x86_64-apple-darwin")), true, )]; cx.update_from_dist(&adds, &[], false).await.unwrap(); @@ -1237,7 +1241,7 @@ async fn remove_extension_not_in_manifest_but_is_already_installed() { let removes = vec![Component::new( "bonus".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), + Some(TargetTuple::new("x86_64-apple-darwin")), true, )]; cx.update_from_dist(&[], &removes, false).await.unwrap(); @@ -1251,7 +1255,7 @@ async fn remove_extension_that_is_required_component() { let removes = vec![Component::new( "rustc".to_string(), - Some(TargetTriple::new("x86_64-apple-darwin")), + Some(TargetTuple::new("x86_64-apple-darwin")), false, )]; @@ -1266,7 +1270,7 @@ async fn remove_extension_not_installed() { let removes = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; @@ -1282,7 +1286,7 @@ async fn remove_extensions_does_not_remove_other_components() { let cx = TestContext::new(None, GZOnly); let adds = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; @@ -1290,7 +1294,7 @@ async fn remove_extensions_does_not_remove_other_components() { let removes = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; @@ -1309,7 +1313,7 @@ async fn remove_extensions_does_not_hang_with_concurrent_downloads_override() { let adds = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; @@ -1317,7 +1321,7 @@ async fn remove_extensions_does_not_hang_with_concurrent_downloads_override() { let removes = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; @@ -1333,7 +1337,7 @@ async fn add_and_remove_for_upgrade() { let adds = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, )]; @@ -1343,13 +1347,13 @@ async fn add_and_remove_for_upgrade() { let adds = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; let removes = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, )]; @@ -1371,7 +1375,7 @@ async fn add_and_remove() { let adds = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, )]; @@ -1379,13 +1383,13 @@ async fn add_and_remove() { let adds = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; let removes = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-unknown-linux-gnu")), + Some(TargetTuple::new("i686-unknown-linux-gnu")), false, )]; @@ -1408,13 +1412,13 @@ async fn add_and_remove_same_component() { let adds = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; let removes = vec![Component::new( "rust-std".to_string(), - Some(TargetTriple::new("i686-apple-darwin")), + Some(TargetTuple::new("i686-apple-darwin")), false, )]; @@ -1529,3 +1533,67 @@ async fn handle_corrupt_partial_downloads() { assert!(utils::path_exists(cx.prefix.path().join("bin/rustc"))); assert!(utils::path_exists(cx.prefix.path().join("lib/libstd.rlib"))); } + +/// If the v2 channel manifest bytes do not match the published `.sha256`, the failure must be +/// reported as an error (not treated as "no update" / `Ok(None)`). +#[tokio::test] +async fn v2_manifest_checksum_mismatch_surfaces_error() { + let cx = TestContext::new(None, GZOnly); + let mock_root = cx.url.to_file_path().unwrap(); + let manifest_path = mock_root.join("dist/channel-rust-nightly.toml"); + fs::OpenOptions::new() + .append(true) + .open(&manifest_path) + .unwrap() + .write_all(b"\n# test: corrupt manifest body vs .sha256\n") + .unwrap(); + + let root = test_dir().unwrap(); + let rustup_home = RustupHome::new_in(root.path()).unwrap(); + let cargo_home = tempfile::Builder::new() + .prefix("cargo") + .tempdir_in(root.path()) + .unwrap(); + let home = tempfile::Builder::new() + .prefix("home") + .tempdir_in(root.path()) + .unwrap(); + + let mut vars = HashMap::new(); + rustup_home.apply(&mut vars); + vars.env( + "CARGO_HOME", + cargo_home.path().to_string_lossy().to_string(), + ); + vars.env("HOME", home.path().to_string_lossy().to_string()); + vars.env("RUSTUP_DIST_SERVER", cx.url.as_str()); + + let tp = TestProcess::new(env::current_dir().unwrap(), &["rustup"], vars, ""); + let cfg = Cfg::from_env(tp.process.current_dir().unwrap(), false, true, &tp.process).unwrap(); + let dl_cfg = DownloadCfg::new(&cfg); + let update_hash = cfg.get_hash_file(&cx.toolchain, true).unwrap(); + let mut fetched = String::new(); + + let err = super::super::try_update_from_dist_( + &dl_cfg, + &update_hash, + &cx.toolchain, + Some(Profile::Default), + &cx.prefix, + false, + &[], + &[], + &mut fetched, + &cfg, + None, + ) + .await + .unwrap_err(); + + match err.downcast_ref::() { + Some(RustupError::ChecksumFailed { .. }) => {} + e => { + panic!("expected ChecksumFailed for corrupt v2 manifest, got {e:?} full error: {err:?}") + } + } +} diff --git a/src/dist/mod.rs b/src/dist/mod.rs index 185f903a9b..5782799aab 100644 --- a/src/dist/mod.rs +++ b/src/dist/mod.rs @@ -44,8 +44,8 @@ use prefix::InstallPrefix; pub mod temp; -pub(crate) mod triple; -pub(crate) use triple::*; +pub(crate) mod target_tuple; +pub(crate) use target_tuple::*; pub static DEFAULT_DIST_SERVER: &str = "https://static.rust-lang.org"; @@ -140,17 +140,17 @@ struct ParsedToolchainDesc { /// A toolchain descriptor from rustup's perspective. These contain /// 'partial target tuples', which allow toolchain names like /// 'stable-msvc' to work. Partial target tuples though are parsed -/// from a hardcoded set of known triples, whereas target tuples +/// from a hardcoded set of known tuples, whereas target tuples /// are nearly-arbitrary strings. #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)] pub struct PartialToolchainDesc { pub channel: Channel, pub date: Option, - pub target: PartialTargetTriple, + pub target: PartialTargetTuple, } /// Fully-resolved toolchain descriptors. These always have full target -/// triples attached to them and are used for canonical identification, +/// tuples attached to them and are used for canonical identification, /// such as naming their installation directory. /// /// As strings they look like stable-x86_64-pc-windows-msvc or @@ -159,7 +159,7 @@ pub struct PartialToolchainDesc { pub struct ToolchainDesc { pub channel: Channel, pub date: Option, - pub target: TargetTriple, + pub target: TargetTuple, } #[derive(Debug, Clone, Eq, PartialEq, PartialOrd, Ord)] @@ -247,44 +247,44 @@ impl FromStr for PartialVersion { #[derive(Debug, Clone, Deserialize, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize)] #[serde(transparent)] -pub struct TargetTriple(String); +pub struct TargetTuple(String); // Linux hosts don't indicate clib in uname, however binaries only // run on boxes with the same clib, as expected. #[cfg(all(not(windows), not(target_env = "musl")))] -const TRIPLE_X86_64_UNKNOWN_LINUX: &str = "x86_64-unknown-linux-gnu"; +const TUPLE_X86_64_UNKNOWN_LINUX: &str = "x86_64-unknown-linux-gnu"; #[cfg(all(not(windows), target_env = "musl"))] -const TRIPLE_X86_64_UNKNOWN_LINUX: &str = "x86_64-unknown-linux-musl"; +const TUPLE_X86_64_UNKNOWN_LINUX: &str = "x86_64-unknown-linux-musl"; #[cfg(all(not(windows), not(target_env = "musl")))] -const TRIPLE_AARCH64_UNKNOWN_LINUX: &str = "aarch64-unknown-linux-gnu"; +const TUPLE_AARCH64_UNKNOWN_LINUX: &str = "aarch64-unknown-linux-gnu"; #[cfg(all(not(windows), target_env = "musl"))] -const TRIPLE_AARCH64_UNKNOWN_LINUX: &str = "aarch64-unknown-linux-musl"; +const TUPLE_AARCH64_UNKNOWN_LINUX: &str = "aarch64-unknown-linux-musl"; #[cfg(all(not(windows), not(target_env = "musl")))] -const TRIPLE_LOONGARCH64_UNKNOWN_LINUX: &str = "loongarch64-unknown-linux-gnu"; +const TUPLE_LOONGARCH64_UNKNOWN_LINUX: &str = "loongarch64-unknown-linux-gnu"; #[cfg(all(not(windows), target_env = "musl"))] -const TRIPLE_LOONGARCH64_UNKNOWN_LINUX: &str = "loongarch64-unknown-linux-musl"; +const TUPLE_LOONGARCH64_UNKNOWN_LINUX: &str = "loongarch64-unknown-linux-musl"; #[cfg(all(not(windows), not(target_env = "musl")))] -const TRIPLE_POWERPC64_UNKNOWN_LINUX: &str = "powerpc64-unknown-linux-gnu"; +const TUPLE_POWERPC64_UNKNOWN_LINUX: &str = "powerpc64-unknown-linux-gnu"; #[cfg(all(not(windows), target_env = "musl"))] -const TRIPLE_POWERPC64_UNKNOWN_LINUX: &str = "powerpc64-unknown-linux-musl"; +const TUPLE_POWERPC64_UNKNOWN_LINUX: &str = "powerpc64-unknown-linux-musl"; #[cfg(all(not(windows), not(target_env = "musl")))] -const TRIPLE_POWERPC64LE_UNKNOWN_LINUX: &str = "powerpc64le-unknown-linux-gnu"; +const TUPLE_POWERPC64LE_UNKNOWN_LINUX: &str = "powerpc64le-unknown-linux-gnu"; #[cfg(all(not(windows), target_env = "musl"))] -const TRIPLE_POWERPC64LE_UNKNOWN_LINUX: &str = "powerpc64le-unknown-linux-musl"; +const TUPLE_POWERPC64LE_UNKNOWN_LINUX: &str = "powerpc64le-unknown-linux-musl"; // MIPS platforms don't indicate endianness in uname, however binaries only // run on boxes with the same endianness, as expected. // Hence we could distinguish between the variants with compile-time cfg() // attributes alone. #[cfg(all(not(windows), target_endian = "big"))] -static TRIPLE_MIPS_UNKNOWN_LINUX_GNU: &str = "mips-unknown-linux-gnu"; +static TUPLE_MIPS_UNKNOWN_LINUX_GNU: &str = "mips-unknown-linux-gnu"; #[cfg(all(not(windows), target_endian = "little"))] -static TRIPLE_MIPS_UNKNOWN_LINUX_GNU: &str = "mipsel-unknown-linux-gnu"; +static TUPLE_MIPS_UNKNOWN_LINUX_GNU: &str = "mipsel-unknown-linux-gnu"; #[cfg(all(not(windows), target_endian = "big"))] -static TRIPLE_MIPS64_UNKNOWN_LINUX_GNUABI64: &str = "mips64-unknown-linux-gnuabi64"; +static TUPLE_MIPS64_UNKNOWN_LINUX_GNUABI64: &str = "mips64-unknown-linux-gnuabi64"; #[cfg(all(not(windows), target_endian = "little"))] -static TRIPLE_MIPS64_UNKNOWN_LINUX_GNUABI64: &str = "mips64el-unknown-linux-gnuabi64"; +static TUPLE_MIPS64_UNKNOWN_LINUX_GNUABI64: &str = "mips64el-unknown-linux-gnuabi64"; impl FromStr for ParsedToolchainDesc { type Err = anyhow::Error; @@ -341,7 +341,7 @@ impl FromStr for ParsedToolchainDesc { } } -impl Deref for TargetTriple { +impl Deref for TargetTuple { type Target = str; fn deref(&self) -> &Self::Target { &self.0 @@ -371,7 +371,7 @@ fn is_32bit_userspace() -> bool { inner().unwrap_or(cfg!(target_pointer_width = "32")) } -impl TargetTriple { +impl TargetTuple { pub fn new(name: impl Into) -> Self { Self(name.into()) } @@ -410,7 +410,7 @@ impl TargetTriple { pub(crate) fn from_host(process: &Process) -> Option { #[cfg(windows)] - fn inner() -> Option { + fn inner() -> Option { use std::mem; /// Get the host architecture using `IsWow64Process2`. This function @@ -481,12 +481,12 @@ impl TargetTriple { // Default to msvc let arch = arch_primary().or_else(arch_fallback)?; - let msvc_triple = format!("{arch}-pc-windows-msvc"); - Some(TargetTriple(msvc_triple)) + let msvc_tuple = format!("{arch}-pc-windows-msvc"); + Some(TargetTuple(msvc_tuple)) } #[cfg(not(windows))] - fn inner() -> Option { + fn inner() -> Option { use std::ffi::CStr; use std::mem; @@ -504,22 +504,22 @@ impl TargetTriple { }; #[cfg(not(target_os = "android"))] - let host_triple = match (sysname, machine) { - (b"Linux", b"x86_64") => Some(TRIPLE_X86_64_UNKNOWN_LINUX), + let host_tuple = match (sysname, machine) { + (b"Linux", b"x86_64") => Some(TUPLE_X86_64_UNKNOWN_LINUX), (b"Linux", b"i686") => Some("i686-unknown-linux-gnu"), - (b"Linux", b"mips") => Some(TRIPLE_MIPS_UNKNOWN_LINUX_GNU), - (b"Linux", b"mips64") => Some(TRIPLE_MIPS64_UNKNOWN_LINUX_GNUABI64), + (b"Linux", b"mips") => Some(TUPLE_MIPS_UNKNOWN_LINUX_GNU), + (b"Linux", b"mips64") => Some(TUPLE_MIPS64_UNKNOWN_LINUX_GNUABI64), (b"Linux", b"arm") => Some("arm-unknown-linux-gnueabi"), (b"Linux", b"armv7l") => Some("armv7-unknown-linux-gnueabihf"), (b"Linux", b"armv8l") => Some("armv7-unknown-linux-gnueabihf"), (b"Linux", b"aarch64") => Some(if is_32bit_userspace() { "armv7-unknown-linux-gnueabihf" } else { - TRIPLE_AARCH64_UNKNOWN_LINUX + TUPLE_AARCH64_UNKNOWN_LINUX }), - (b"Linux", b"loongarch64") => Some(TRIPLE_LOONGARCH64_UNKNOWN_LINUX), - (b"Linux", b"ppc64") => Some(TRIPLE_POWERPC64_UNKNOWN_LINUX), - (b"Linux", b"ppc64le") => Some(TRIPLE_POWERPC64LE_UNKNOWN_LINUX), + (b"Linux", b"loongarch64") => Some(TUPLE_LOONGARCH64_UNKNOWN_LINUX), + (b"Linux", b"ppc64") => Some(TUPLE_POWERPC64_UNKNOWN_LINUX), + (b"Linux", b"ppc64le") => Some(TUPLE_POWERPC64LE_UNKNOWN_LINUX), (b"Darwin", b"x86_64") => Some("x86_64-apple-darwin"), (b"Darwin", b"i686") => Some("i686-apple-darwin"), (b"FreeBSD", b"x86_64") => Some("x86_64-unknown-freebsd"), @@ -538,7 +538,7 @@ impl TargetTriple { }; #[cfg(target_os = "android")] - let host_triple = match (sysname, machine) { + let host_tuple = match (sysname, machine) { (_, b"arm") => Some("arm-linux-androideabi"), (_, b"armv7l") => Some("armv7-linux-androideabi"), (_, b"armv8l") => Some("armv7-linux-androideabi"), @@ -548,7 +548,7 @@ impl TargetTriple { _ => None, }; - host_triple.map(TargetTriple::new) + host_tuple.map(TargetTuple::new) } if let Ok(tuple) = process.var("RUSTUP_OVERRIDE_HOST_TUPLE") { @@ -564,15 +564,15 @@ impl TargetTriple { Self::from_host(process).unwrap_or_else(Self::from_build) } - pub(crate) fn can_run(&self, other: &TargetTriple) -> Result { + pub(crate) fn can_run(&self, other: &TargetTuple) -> Result { // Most trivial shortcut of all if self == other { return Ok(true); } // Otherwise we need to parse things - let partial_self = PartialTargetTriple::new(&self.0) + let partial_self = PartialTargetTuple::new(&self.0) .ok_or_else(|| anyhow!(format!("Unable to parse target tuple: {}", self.0)))?; - let partial_other = PartialTargetTriple::new(&other.0) + let partial_other = PartialTargetTuple::new(&other.0) .ok_or_else(|| anyhow!(format!("Unable to parse target tuple: {}", other.0)))?; // First obvious check is OS, if that doesn't match there's no chance let ret = if partial_self.os != partial_other.os { @@ -597,7 +597,7 @@ impl FromStr for PartialToolchainDesc { type Err = anyhow::Error; fn from_str(name: &str) -> Result { let parsed: ParsedToolchainDesc = name.parse()?; - let target = PartialTargetTriple::new(parsed.target.as_deref().unwrap_or("")); + let target = PartialTargetTuple::new(parsed.target.as_deref().unwrap_or("")); target .map(|target| Self { @@ -611,10 +611,10 @@ impl FromStr for PartialToolchainDesc { impl PartialToolchainDesc { /// Create a toolchain desc using input_host to fill in missing fields - pub(crate) fn resolve(self, input_host: &TargetTriple) -> Result { - let host = PartialTargetTriple::new(&input_host.0).ok_or_else(|| { + pub(crate) fn resolve(self, input_host: &TargetTuple) -> Result { + let host = PartialTargetTuple::new(&input_host.0).ok_or_else(|| { anyhow!(format!( - "Provided host '{}' couldn't be converted to partial triple", + "Provided host '{}' couldn't be converted to partial tuple", input_host.0 )) })?; @@ -651,13 +651,9 @@ impl PartialToolchainDesc { Ok(ToolchainDesc { channel: self.channel, date: self.date, - target: TargetTriple(trip), + target: TargetTuple(trip), }) } - - pub(crate) fn has_triple(&self) -> bool { - self.target.arch.is_some() || self.target.os.is_some() || self.target.env.is_some() - } } impl FromStr for ToolchainDesc { @@ -672,7 +668,7 @@ impl FromStr for ToolchainDesc { Ok(Self { channel: parsed.channel, date: parsed.date, - target: TargetTriple(parsed.target.unwrap()), + target: TargetTuple(parsed.target.unwrap()), }) } } @@ -834,7 +830,7 @@ impl fmt::Display for AutoInstallMode { } } -impl fmt::Display for TargetTriple { +impl fmt::Display for TargetTuple { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) } @@ -1195,8 +1191,8 @@ async fn try_update_from_dist_( } for &target in targets { - let triple = TargetTriple::new(target); - all_components.insert(Component::new("rust-std".to_string(), Some(triple), false)); + let tuple = TargetTuple::new(target); + all_components.insert(Component::new("rust-std".to_string(), Some(tuple), false)); } let mut explicit_add_components: Vec<_> = all_components.into_iter().collect(); @@ -1234,11 +1230,15 @@ async fn try_update_from_dist_( Ok(None) => return Ok(None), Err(err) => { match err.downcast_ref::() { - Some(RustupError::ChecksumFailed { .. }) => return Ok(None), Some(RustupError::DownloadNotExists { .. }) => { // Proceed to try v1 as a fallback debug!("manifest not found; trying legacy manifest"); } + // Includes `ChecksumFailed`: if the v2 manifest exists but its + // contents do not match the published `.sha256`, surface the + // integrity failure as an error rather than silently treating + // the toolchain as up to date. The v1 fallback path below + // already does the same. _ => return Err(err), } } @@ -1457,7 +1457,7 @@ mod tests { } #[test] - fn compatible_host_triples() { + fn compatible_host_tuples() { static CASES: &[(&str, &[&str], &[&str])] = &[ ( // 64bit linux @@ -1502,11 +1502,11 @@ mod tests { for &(host, compatible, incompatible) in CASES { println!("host={host}"); - let host = TargetTriple::new(host); + let host = TargetTuple::new(host); assert!(host.can_run(&host).unwrap(), "host wasn't self-compatible"); for &other in compatible.iter() { println!("compatible with {other}"); - let other = TargetTriple::new(other); + let other = TargetTuple::new(other); assert!( host.can_run(&other).unwrap(), "host and other were unexpectedly incompatible" @@ -1514,7 +1514,7 @@ mod tests { } for &other in incompatible.iter() { println!("incompatible with {other}"); - let other = TargetTriple::new(other); + let other = TargetTuple::new(other); assert!( !host.can_run(&other).unwrap(), "host and other were unexpectedly compatible" diff --git a/src/dist/triple.rs b/src/dist/target_tuple.rs similarity index 81% rename from src/dist/triple.rs rename to src/dist/target_tuple.rs index 34aff1475c..3dcc68d12f 100644 --- a/src/dist/triple.rs +++ b/src/dist/target_tuple.rs @@ -5,13 +5,13 @@ use regex::Regex; pub mod known; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] -pub struct PartialTargetTriple { +pub struct PartialTargetTuple { pub arch: Option, pub os: Option, pub env: Option, } -impl PartialTargetTriple { +impl PartialTargetTuple { pub(crate) fn new(name: &str) -> Option { if name.is_empty() { return Some(Self { @@ -22,7 +22,7 @@ impl PartialTargetTriple { } // Prepending `-` makes this next regex easier since - // we can count on all triple components being + // we can count on all tuple components being // delineated by it. let name = format!("-{name}"); static RE: LazyLock = LazyLock::new(|| { @@ -51,6 +51,10 @@ impl PartialTargetTriple { } }) } + + pub(crate) fn is_empty(&self) -> bool { + self.arch.is_none() && self.env.is_none() && self.os.is_none() + } } #[cfg(test)] @@ -58,7 +62,7 @@ mod test { use super::*; #[test] - fn test_partial_target_triple_new() { + fn test_partial_target_tuple_new() { let success_cases = vec![ ("", (None, None, None)), ("i386", (Some("i386"), None, None)), @@ -74,19 +78,19 @@ mod test { ]; for (input, (arch, os, env)) in success_cases { - let partial_target_triple = PartialTargetTriple::new(input); + let partial_target_tuple = PartialTargetTuple::new(input); assert!( - partial_target_triple.is_some(), + partial_target_tuple.is_some(), "expected `{input}` to create some partial target tuple; got None" ); - let expected = PartialTargetTriple { + let expected = PartialTargetTuple { arch: arch.map(String::from), os: os.map(String::from), env: env.map(String::from), }; - assert_eq!(partial_target_triple.unwrap(), expected, "input: `{input}`"); + assert_eq!(partial_target_tuple.unwrap(), expected, "input: `{input}`"); } let failure_cases = vec![ @@ -104,10 +108,10 @@ mod test { ]; for input in failure_cases { - let partial_target_triple = PartialTargetTriple::new(input); + let partial_target_tuple = PartialTargetTuple::new(input); assert!( - partial_target_triple.is_none(), - "expected `{input}` to be `None`, was: `{partial_target_triple:?}`" + partial_target_tuple.is_none(), + "expected `{input}` to be `None`, was: `{partial_target_tuple:?}`" ); } } diff --git a/src/dist/triple/known.rs b/src/dist/target_tuple/known.rs similarity index 100% rename from src/dist/triple/known.rs rename to src/dist/target_tuple/known.rs diff --git a/src/download/tests.rs b/src/download/tests.rs index 36552a5ce2..daa521473b 100644 --- a/src/download/tests.rs +++ b/src/download/tests.rs @@ -120,6 +120,12 @@ mod reqwest { use super::{scrub_env, serve_file, tmp_dir, write_file}; use crate::download::{Backend, Event, TlsBackend}; + #[cfg(feature = "reqwest-rustls-tls")] + const DOWNLOAD_BACKEND: Backend = Backend::Reqwest(TlsBackend::Rustls); + + #[cfg(all(not(feature = "reqwest-rustls-tls"), feature = "reqwest-native-tls"))] + const DOWNLOAD_BACKEND: Backend = Backend::Reqwest(TlsBackend::NativeTls); + // Tests for correctly retrieving the proxy (host, port) tuple from $https_proxy #[tokio::test] async fn read_basic_proxy_params() { @@ -192,7 +198,7 @@ mod reqwest { write_file(&target_path, "123"); let from_url = Url::from_file_path(&from_path).unwrap(); - Backend::Reqwest(TlsBackend::NativeTls) + DOWNLOAD_BACKEND .download_to_path( &from_url, &target_path, @@ -221,7 +227,7 @@ mod reqwest { let callback_len = Mutex::new(None); let received_in_callback = Mutex::new(Vec::new()); - Backend::Reqwest(TlsBackend::NativeTls) + DOWNLOAD_BACKEND .download_to_path( &from_url, &target_path, @@ -268,7 +274,7 @@ mod reqwest { let addr = serve_file(b"xxx45".to_vec(), false); let from_url = format!("http://{addr}").parse().unwrap(); - Backend::Reqwest(TlsBackend::NativeTls) + DOWNLOAD_BACKEND .download_to_path( &from_url, &target_path, @@ -293,7 +299,7 @@ mod reqwest { write_file(&target_path, "123"); let from_url = "http://240.0.0.0:1080".parse().unwrap(); - Backend::Reqwest(TlsBackend::NativeTls) + DOWNLOAD_BACKEND .download_to_path(&from_url, &target_path, true, None, Duration::from_secs(1)) .await .expect_err("download should fail with a connect error"); @@ -430,6 +436,7 @@ async fn scrub_env() -> tokio::sync::MutexGuard<'static, ()> { // mutex guard. unsafe { remove_var("http_proxy"); + remove_var("HTTP_PROXY"); remove_var("https_proxy"); remove_var("HTTPS_PROXY"); remove_var("ftp_proxy"); diff --git a/src/errors.rs b/src/errors.rs index bae5793cff..eac23c2d38 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -12,7 +12,7 @@ use url::Url; use crate::{ dist::{ - Channel, TargetTriple, ToolchainDesc, + Channel, TargetTuple, ToolchainDesc, manifest::{Component, Manifest}, }, toolchain::{PathBasedToolchainName, ToolchainName}, @@ -106,12 +106,12 @@ pub enum RustupError { RunningCommand { name: OsString }, #[error( "toolchain '{toolchain}' may not be able to run on this system\n\ - note: to build software for that platform, try `rustup target add {target_triple}` instead\n\ + note: to build software for that platform, try `rustup target add {target_tuple}` instead\n\ note: add the `--force-non-host` flag to install the toolchain anyway" )] ToolchainIncompatible { toolchain: String, - target_triple: TargetTriple, + target_tuple: TargetTuple, }, #[error("toolchain '{0}' is not installable")] ToolchainNotInstallable(String), @@ -155,14 +155,14 @@ pub enum RustupError { suggest_message(.suggestion))] UnknownTarget { desc: ToolchainDesc, - target: TargetTriple, + target: TargetTuple, suggestion: Option, }, #[error("toolchain '{}' does not have target '{}' installed{}\n", .desc, .target, suggest_message(.suggestion))] TargetNotInstalled { desc: ToolchainDesc, - target: TargetTriple, + target: TargetTuple, suggestion: Option, }, #[error( diff --git a/src/settings.rs b/src/settings.rs index 15d7669fa0..42dc7ceebf 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -82,7 +82,8 @@ impl SettingsFile { pub struct Settings { pub version: MetadataVersion, #[serde(skip_serializing_if = "Option::is_none")] - pub default_host_triple: Option, + #[serde(alias = "default_host_triple")] + pub default_host_tuple: Option, #[serde(skip_serializing_if = "Option::is_none")] pub default_toolchain: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -224,4 +225,28 @@ profile = "default" [overrides] "#; + + #[test] + fn deserialize_default_host_triple() { + let raw = r#"version = "12" +default_host_triple = "stable-aarch64-apple-darwin" +"#; + let settings = Settings::parse(raw).unwrap(); + assert_eq!( + settings.default_host_tuple, + Some("stable-aarch64-apple-darwin".to_owned()) + ); + } + + #[test] + fn deserialize_default_host_tuple() { + let raw = r#"version = "12" +default_host_tuple = "stable-aarch64-apple-darwin" +"#; + let settings = Settings::parse(raw).unwrap(); + assert_eq!( + settings.default_host_tuple, + Some("stable-aarch64-apple-darwin".to_owned()) + ); + } } diff --git a/src/test.rs b/src/test.rs index 97e5460cda..90ae4d12b6 100644 --- a/src/test.rs +++ b/src/test.rs @@ -20,7 +20,7 @@ use std::process::Command; use anyhow::Result; use sha2::{Digest, Sha256}; -use crate::dist::TargetTriple; +use crate::dist::TargetTuple; use crate::process::TestProcess; #[cfg(windows)] @@ -135,14 +135,14 @@ fn tempdir_in_with_prefix>(path: P, prefix: &str) -> io::Result

String { if cfg!(target_os = "windows") { // For windows, this host may be different to the target: we may be // building with i686 toolchain, but on an x86_64 host, so run the // actual detection logic and trust it. let tp = TestProcess::default(); - return TargetTriple::from_host(&tp.process).unwrap().to_string(); + return TargetTuple::from_host(&tp.process).unwrap().to_string(); } let arch = if cfg!(target_arch = "x86") { "i686" diff --git a/src/test/clitools.rs b/src/test/clitools.rs index 0b5032d3cd..1311322696 100644 --- a/src/test/clitools.rs +++ b/src/test/clitools.rs @@ -314,6 +314,12 @@ impl Config { "/bogus-config-file.toml", ); + // Clear current recursion count to avoid messing up related logic + cmd.env("RUST_RECURSION_COUNT", ""); + + // Clear override for auto installation of active toolchain unless explicitly requested + cmd.env("RUSTUP_AUTO_INSTALL", ""); + // Pass `RUSTUP_CI` over to the test process in case it is required downstream if let Some(ci) = env::var_os("RUSTUP_CI") { cmd.env("RUSTUP_CI", ci); @@ -874,7 +880,7 @@ async fn setup_test_state(test_dist_dir: TempDir) -> (TempDir, Config) { hard_link(&rustup_path, rls_path).unwrap(); hard_link(&rustup_path, rust_lldb_path).unwrap(); - // Make sure the host triple matches the build triple. Otherwise testing a 32-bit build of + // Make sure the host tuple matches the build tuple. Otherwise testing a 32-bit build of // rustup on a 64-bit machine will fail, because the tests do not have the host detection // functionality built in. config diff --git a/src/test/dist.rs b/src/test/dist.rs index 48ba91b0d0..abd52f70a7 100644 --- a/src/test/dist.rs +++ b/src/test/dist.rs @@ -13,7 +13,7 @@ use super::clitools::hard_link; use super::mock::MockInstallerBuilder; use super::{CROSS_ARCH1, CROSS_ARCH2, MULTI_ARCH1, create_hash, this_host_tuple}; use crate::dist::{ - DEFAULT_DIST_SERVER, Profile, TargetTriple, + DEFAULT_DIST_SERVER, Profile, TargetTuple, component::{Components, DirectoryPackage, Transaction}, manifest::{ Component, CompressionKind, HashedBinary, Manifest, ManifestVersion, Package, @@ -189,24 +189,24 @@ impl Release { if self.channel == "stable" { // Same for v1 manifests. These are just the installers. - let host_triple = this_host_tuple(); + let host_tuple = this_host_tuple(); hard_link( path.join(format!( "dist/{}/rust-stable-{}.tar.gz", - self.date, host_triple + self.date, host_tuple )), - path.join(format!("dist/rust-{}-{}.tar.gz", self.version, host_triple)), + path.join(format!("dist/rust-{}-{}.tar.gz", self.version, host_tuple)), ) .unwrap(); hard_link( path.join(format!( "dist/{}/rust-stable-{}.tar.gz.sha256", - self.date, host_triple + self.date, host_tuple )), path.join(format!( "dist/rust-{}-{}.tar.gz.sha256", - self.version, host_triple + self.version, host_tuple )), ) .unwrap(); @@ -289,49 +289,49 @@ impl MockChannel { version_hash: &str, rls: RlsStatus, multi_arch: bool, - swap_triples: bool, + swap_tuples: bool, ) -> Self { // Build the mock installers - let host_triple = if swap_triples { + let host_tuple = if swap_tuples { MULTI_ARCH1.to_owned() } else { this_host_tuple() }; - let std = MockInstallerBuilder::std(&host_triple); - let rustc = MockInstallerBuilder::rustc(&host_triple, version, version_hash); + let std = MockInstallerBuilder::std(&host_tuple); + let rustc = MockInstallerBuilder::rustc(&host_tuple, version, version_hash); let cargo = MockInstallerBuilder::cargo(version, version_hash); let rust_docs = MockInstallerBuilder::rust_doc(); let rust = MockInstallerBuilder::combined(&[&std, &rustc, &cargo, &rust_docs]); let cross_std1 = MockInstallerBuilder::cross_std(CROSS_ARCH1, date); let cross_std2 = MockInstallerBuilder::cross_std(CROSS_ARCH2, date); let rust_src = MockInstallerBuilder::rust_src(); - let rust_analysis = MockInstallerBuilder::rust_analysis(&host_triple); + let rust_analysis = MockInstallerBuilder::rust_analysis(&host_tuple); // Convert the mock installers to mock package definitions for the // mock dist server let mut all = MockChannelContent::default(); all.std.extend(vec![ - (std, host_triple.clone()), + (std, host_tuple.clone()), (cross_std1, CROSS_ARCH1.to_string()), (cross_std2, CROSS_ARCH2.to_string()), ]); - all.rustc.push((rustc, host_triple.clone())); - all.cargo.push((cargo, host_triple.clone())); + all.rustc.push((rustc, host_tuple.clone())); + all.cargo.push((cargo, host_tuple.clone())); if rls != RlsStatus::Unavailable { let rls = MockInstallerBuilder::rls(version, version_hash, rls.pkg_name()); - all.rls.push((rls, host_triple.clone())); + all.rls.push((rls, host_tuple.clone())); } else { all.rls.push(( MockInstallerBuilder { components: vec![] }, - host_triple.clone(), + host_tuple.clone(), )); } - all.docs.push((rust_docs, host_triple.clone())); + all.docs.push((rust_docs, host_tuple.clone())); all.src.push((rust_src, "*".to_string())); all.analysis.push((rust_analysis, "*".to_string())); - all.combined.push((rust, host_triple)); + all.combined.push((rust, host_tuple)); if multi_arch { let std = MockInstallerBuilder::std(MULTI_ARCH1); @@ -340,21 +340,23 @@ impl MockChannel { let rust_docs = MockInstallerBuilder::rust_doc(); let rust = MockInstallerBuilder::combined(&[&std, &rustc, &cargo, &rust_docs]); - let triple = MULTI_ARCH1.to_string(); - all.std.push((std, triple.clone())); - all.rustc.push((rustc, triple.clone())); - all.cargo.push((cargo, triple.clone())); + let target_tuple = MULTI_ARCH1.to_string(); + all.std.push((std, target_tuple.clone())); + all.rustc.push((rustc, target_tuple.clone())); + all.cargo.push((cargo, target_tuple.clone())); if rls != RlsStatus::Unavailable { let rls = MockInstallerBuilder::rls(version, version_hash, rls.pkg_name()); - all.rls.push((rls, triple.clone())); + all.rls.push((rls, target_tuple.clone())); } else { - all.rls - .push((MockInstallerBuilder { components: vec![] }, triple.clone())); + all.rls.push(( + MockInstallerBuilder { components: vec![] }, + target_tuple.clone(), + )); } - all.docs.push((rust_docs, triple.to_string())); - all.combined.push((rust, triple)); + all.docs.push((rust_docs, target_tuple.to_string())); + all.combined.push((rust, target_tuple)); } let all_std_archs: Vec = all.std.iter().map(|(_, arch)| arch).cloned().collect(); @@ -365,8 +367,8 @@ impl MockChannel { let target_pkgs = target_pkgs .into_iter() - .map(|(installer, triple)| MockTargetedPackage { - target: triple, + .map(|(installer, target_tuple)| MockTargetedPackage { + target: target_tuple, available: !installer.components.is_empty(), components: vec![], installer, @@ -466,7 +468,7 @@ impl MockChannel { version: &str, version_hash: &str, ) -> Self { - let host_triple = this_host_tuple(); + let host_tuple = this_host_tuple(); let packages = [ "cargo", @@ -483,7 +485,7 @@ impl MockChannel { name, version: format!("{version} ({version_hash})"), targets: vec![MockTargetedPackage { - target: host_triple.clone(), + target: host_tuple.clone(), available: false, components: vec![], installer: MockInstallerBuilder { components: vec![] }, @@ -549,7 +551,7 @@ impl RlsStatus { // A single rust-installer package #[derive(Debug, Hash, Eq, PartialEq)] pub(crate) struct MockPackage { - // rust, rustc, rust-std-$triple, rust-doc, etc. + // rust, rustc, rust-std-$tuple, rust-doc, etc. pub name: &'static str, pub version: String, pub targets: Vec, @@ -836,12 +838,12 @@ impl MockDistServer { for component in &target.components { tpkg.components.push(Component { pkg: component.name.to_owned(), - target: Some(TargetTriple::new(&component.target)), + target: Some(TargetTuple::new(&component.target)), is_extension: component.is_extension, }); } - targets.insert(TargetTriple::new(&target.target), tpkg); + targets.insert(TargetTuple::new(&target.target), tpkg); } manifest.packages.insert( diff --git a/src/toolchain.rs b/src/toolchain.rs index f13ef0aaf3..63f523e2d2 100644 --- a/src/toolchain.rs +++ b/src/toolchain.rs @@ -21,13 +21,14 @@ use wait_timeout::ChildExt; use crate::{ RustupError, - config::{ActiveSource, Cfg, InstalledPath}, + config::{ActiveSource, Cfg, EnsureInstalled, InstalledPath}, dist::{ - DistOptions, PartialToolchainDesc, TargetTriple, + DistOptions, PartialToolchainDesc, TargetTuple, component::{Component, Components}, prefix::InstallPrefix, }, - env_var, install, + env_var, + install::{self, UpdateStatus}, utils::{self, raw::open_dir_following_links}, }; @@ -54,15 +55,16 @@ impl<'a> Toolchain<'a> { name: LocalToolchainName, install_if_missing: bool, cfg: &'a Cfg<'a>, - ) -> anyhow::Result> { + ) -> anyhow::Result>> { match Self::new(cfg, name) { - Ok(tc) => Ok(tc), + Ok(tc) => Ok(EnsureInstalled::new(tc, UpdateStatus::Unchanged)), Err(RustupError::ToolchainNotInstalled { name: ToolchainName::Official(desc), .. }) if install_if_missing => { let options = DistOptions::new(&[], &[], &desc, cfg.get_profile()?, true, cfg)?; - Ok(DistributableToolchain::install(options).await?.1.toolchain) + let tc = DistributableToolchain::install(options).await?.1.toolchain; + Ok(EnsureInstalled::new(tc, UpdateStatus::Installed)) } Err(e) => Err(e.into()), } @@ -371,12 +373,12 @@ impl<'a> Toolchain<'a> { return Ok(None); } - let default_host_triple = self.cfg.get_default_host_triple()?; + let default_host_tuple = self.cfg.default_host_tuple()?; // XXX: This could actually consider all installed distributable // toolchains in principle. for fallback in ["nightly", "beta", "stable"] { let resolved = - PartialToolchainDesc::from_str(fallback)?.resolve(&default_host_triple)?; + PartialToolchainDesc::from_str(fallback)?.resolve(&default_host_tuple)?; if let Ok(fallback) = DistributableToolchain::new(self.cfg, resolved) { let cmd = fallback.create_fallback_command("cargo", self)?; return Ok(Some(cmd)); @@ -588,14 +590,14 @@ impl<'a> Toolchain<'a> { } /// Get the list of installed targets for any toolchain - pub fn installed_targets(&self) -> anyhow::Result> { + pub fn installed_targets(&self) -> anyhow::Result> { Ok(self .installed_components()? .into_iter() .filter_map(|c| { c.name() .strip_prefix("rust-std-") - .map(|triple| TargetTriple::new(triple.to_string())) + .map(|tuple| TargetTuple::new(tuple.to_string())) }) .collect()) } diff --git a/src/toolchain/names.rs b/src/toolchain/names.rs index b9ea7404d4..330ab24fc4 100644 --- a/src/toolchain/names.rs +++ b/src/toolchain/names.rs @@ -6,7 +6,7 @@ //! //! `MaybeOfficialToolchainName` represents a toolchain passed to rustup-init: //! 'none' to select no toolchain to install, and otherwise a partial toolchain -//! description - channel and optional triple and optional date. +//! description - channel and optional target tuple and optional date. //! //! `ResolvableToolchainName` represents a toolchain name from a user. Either a //! partial toolchain description or a single path component that is not 'none'. @@ -15,7 +15,7 @@ //! for both custom and official names. //! //! `ToolchainName` is the result of resolving `ResolvableToolchainName` with a -//! host triple, or parsing an installed toolchain name directly. +//! host tuple, or parsing an installed toolchain name directly. //! //! `ResolvableLocalToolchainName` represents the values permittable in //! `RUSTUP_TOOLCHAIN`: resolved or not resolved official names, custom names, @@ -50,7 +50,7 @@ use std::{ use thiserror::Error; -use crate::dist::{PartialToolchainDesc, TargetTriple, ToolchainDesc}; +use crate::dist::{PartialToolchainDesc, TargetTuple, ToolchainDesc}; /// Errors related to toolchains #[derive(Error, Debug)] @@ -139,7 +139,7 @@ pub(crate) enum ResolvableToolchainName { impl ResolvableToolchainName { /// Resolve to a concrete toolchain name - pub fn resolve(&self, host: &TargetTriple) -> Result { + pub fn resolve(&self, host: &TargetTuple) -> Result { match self.clone() { ResolvableToolchainName::Custom(c) => Ok(ToolchainName::Custom(c)), ResolvableToolchainName::Official(desc) => { @@ -296,7 +296,7 @@ pub(crate) enum ResolvableLocalToolchainName { impl ResolvableLocalToolchainName { /// Resolve to a concrete toolchain name - pub fn resolve(&self, host: &TargetTriple) -> Result { + pub fn resolve(&self, host: &TargetTuple) -> Result { match self.clone() { ResolvableLocalToolchainName::Named(t) => { Ok(LocalToolchainName::Named(t.resolve(host)?)) @@ -482,24 +482,24 @@ mod tests { use crate::{ dist::{ PartialToolchainDesc, - triple::known::{LIST_ARCHS, LIST_ENVS, LIST_OSES}, + target_tuple::known::{LIST_ARCHS, LIST_ENVS, LIST_OSES}, }, toolchain::names::{CustomToolchainName, ResolvableToolchainName, ToolchainName}, }; - fn partial_toolchain_desc_re() -> String { - let triple_re = format!( + fn partial_toolchain_desc_regex() -> String { + let tuple_regex = format!( r"(-({}))?(?:-({}))?(?:-({}))?", LIST_ARCHS.join("|"), LIST_OSES.join("|"), LIST_ENVS.join("|") ); - r"(nightly|beta|stable|[0-9]{1}(\.(0|[1-9][0-9]{0,2}))(\.(0|[1-9][0-9]{0,1}))?(-beta(\.(0|[1-9][1-9]{0,1}))?)?)(-([0-9]{4}-[0-9]{2}-[0-9]{2}))?".to_owned() + &triple_re + r"(nightly|beta|stable|[0-9]{1}(\.(0|[1-9][0-9]{0,2}))(\.(0|[1-9][0-9]{0,1}))?(-beta(\.(0|[1-9][1-9]{0,1}))?)?)(-([0-9]{4}-[0-9]{2}-[0-9]{2}))?".to_owned() + &tuple_regex } prop_compose! { fn arb_partial_toolchain_desc() - (s in string_regex(&partial_toolchain_desc_re()).unwrap()) -> String { + (s in string_regex(&partial_toolchain_desc_regex()).unwrap()) -> String { s } } diff --git a/tests/suite/cli_inst_interactive.rs b/tests/suite/cli_inst_interactive.rs index eb9cb40e60..9b75e951c4 100644 --- a/tests/suite/cli_inst_interactive.rs +++ b/tests/suite/cli_inst_interactive.rs @@ -74,7 +74,7 @@ these changes will be reverted. Current installation options: - default host triple: [HOST_TUPLE] + default host tuple: [HOST_TUPLE] default toolchain: stable (default) profile: default modify PATH variable: no @@ -136,12 +136,12 @@ Rust is installed now. Great! } #[tokio::test] -async fn installer_shows_default_host_triple() { +async fn installer_shows_default_host_tuple() { let cx = CliTestContext::new(Scenario::SimpleV2).await; run_input(&cx.config, &["rustup-init", "--no-modify-path"], "2\n").with_stdout(snapbox::str![ [r#" ... -Default host triple? [[HOST_TUPLE]] +Default host tuple? [[HOST_TUPLE]] ... "#] ]); @@ -545,8 +545,6 @@ async fn install_stops_if_rustc_exists() { ... warn: It looks like you have an existing installation of Rust at: ... -warn: If you are sure that you want both rustup and your already installed Rust -... "#]]); } @@ -576,8 +574,6 @@ async fn install_stops_if_cargo_exists() { ... warn: It looks like you have an existing installation of Rust at: ... -warn: If you are sure that you want both rustup and your already installed Rust -... "#]]); } diff --git a/tests/suite/cli_misc.rs b/tests/suite/cli_misc.rs index 5eb1b11f04..b27a0834d3 100644 --- a/tests/suite/cli_misc.rs +++ b/tests/suite/cli_misc.rs @@ -64,7 +64,7 @@ async fn rustc_with_bad_rustup_toolchain_env_var() { .expect_with_env(["rustc"], [("RUSTUP_TOOLCHAIN", "bogus")]) .await .with_stderr(snapbox::str![[r#" -error: override toolchain 'bogus' is not installed[..] +error:[..] toolchain 'bogus' is not installed[..] "#]]) .is_err(); @@ -226,8 +226,8 @@ async fn subcommand_required_for_self() { #[tokio::test] async fn multi_host_smoke_test() { - // We cannot run this test if the current host triple is equal to the - // multi-arch triple, but this should never be the case. Check that just + // We cannot run this test if the current host tuple is equal to the + // multi-arch tuple, but this should never be the case. Check that just // to be sure. assert_ne!(this_host_tuple(), MULTI_ARCH1); @@ -1381,7 +1381,10 @@ async fn which_asking_uninstalled_toolchain() { "#]]) .is_ok(); cx.config - .expect(["rustup", "which", "--toolchain=nightly", "rustc"]) + .expect_with_env( + ["rustup", "which", "--toolchain=nightly", "rustc"], + [("RUSTUP_AUTO_INSTALL", "1")], + ) .await .with_stdout(snapbox::str![[r#" [..]/toolchains/nightly-[HOST_TUPLE]/bin/rustc[EXE] @@ -1746,3 +1749,49 @@ info: falling back to "[EXTERN_PATH]" "#]]) .is_ok(); } + +#[tokio::test] +async fn warn_auto_install_on_proxy() { + let cx = CliTestContext::new(Scenario::SimpleV2).await; + cx.config + .expect_with_env( + ["rustc", "--version"], + [("RUSTUP_TOOLCHAIN", "stable"), ("RUSTUP_AUTO_INSTALL", "1")], + ) + .await + .with_stdout(snapbox::str![[r#" +1.1.0 (hash-stable-1.1.0) + +"#]]) + .with_stderr(snapbox::str![[r#" +... +warn: the missing active toolchain `stable-[HOST_TUPLE]` has been auto-installed +warn: this might cause rustup commands to take longer time to finish than expected +info: you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable` +... +"#]]) + .is_ok(); +} + +#[tokio::test] +async fn warn_auto_install_on_rustup() { + let cx = CliTestContext::new(Scenario::SimpleV2).await; + cx.config + .expect_with_env( + ["rustup", "doc", "--path"], + [("RUSTUP_TOOLCHAIN", "stable"), ("RUSTUP_AUTO_INSTALL", "1")], + ) + .await + .with_stdout(snapbox::str![[r#" +[..]/toolchains/stable-[HOST_TUPLE]/share/doc/rust/html/index.html + +"#]]) + .with_stderr(snapbox::str![[r#" +... +warn: the missing active toolchain `stable-[HOST_TUPLE]` has been auto-installed +warn: this might cause rustup commands to take longer time to finish than expected +info: you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable` +... +"#]]) + .is_ok(); +} diff --git a/tests/suite/cli_rustup.rs b/tests/suite/cli_rustup.rs index 99f6aa8432..f02390b06c 100644 --- a/tests/suite/cli_rustup.rs +++ b/tests/suite/cli_rustup.rs @@ -1218,14 +1218,21 @@ async fn show_toolchain_toolchain_file_override_not_installed() { Default host: [HOST_TUPLE] rustup home: [RUSTUP_DIR] +installed toolchains +-------------------- +stable-[HOST_TUPLE] (default) + +active toolchain +---------------- +name: nightly-[HOST_TUPLE] +active because: overridden by '[TOOLCHAIN_FILE]' "#]]) .with_stderr(snapbox::str![[r#" -error: toolchain 'nightly-[HOST_TUPLE]' is not installed -help: run `rustup toolchain install` to install it +info: the active toolchain `nightly-[HOST_TUPLE]` is not installed "#]]) - .is_err(); + .is_ok(); } #[tokio::test] @@ -1240,7 +1247,7 @@ async fn show_toolchain_override_not_installed() { .await .is_ok(); cx.config - .expect(["rustup", "show"]) + .expect_with_env(["rustup", "show"], [("RUSTUP_AUTO_INSTALL", "1")]) .await .extend_redactions([("[RUSTUP_DIR]", &cx.config.rustupdir.to_string())]) .with_stdout(snapbox::str![[r#" @@ -1355,7 +1362,13 @@ installed targets: async fn show_toolchain_env_not_installed() { let cx = CliTestContext::new(Scenario::SimpleV2).await; cx.config - .expect_with_env(["rustup", "show"], [("RUSTUP_TOOLCHAIN", "nightly")]) + .expect_with_env( + ["rustup", "show"], + [ + ("RUSTUP_TOOLCHAIN", "nightly"), + ("RUSTUP_AUTO_INSTALL", "1"), + ], + ) .await .extend_redactions([("[RUSTUP_DIR]", &cx.config.rustupdir.to_string())]) .is_ok() @@ -1599,13 +1612,13 @@ Default host: [HOST_TUPLE] // #846 #[tokio::test] -async fn set_default_host_invalid_triple() { +async fn set_default_host_invalid_tuple() { let cx = CliTestContext::new(Scenario::None).await; cx.config .expect(["rustup", "set", "default-host", "foo"]) .await .with_stderr(snapbox::str![[r#" -error: Provided host 'foo' couldn't be converted to partial triple +error: Provided host 'foo' couldn't be converted to partial tuple "#]]) .is_err(); @@ -1613,7 +1626,7 @@ error: Provided host 'foo' couldn't be converted to partial triple // #745 #[tokio::test] -async fn set_default_host_invalid_triple_valid_partial() { +async fn set_default_host_invalid_tuple_valid_partial() { let cx = CliTestContext::new(Scenario::None).await; cx.config .expect(["rustup", "set", "default-host", "x86_64-msvc"]) @@ -1920,7 +1933,7 @@ async fn add_component() { } #[tokio::test] -async fn add_component_by_target_triple() { +async fn add_component_by_target_tuple() { let cx = CliTestContext::new(Scenario::SimpleV2).await; cx.config .expect(["rustup", "default", "stable"]) @@ -1943,7 +1956,7 @@ async fn add_component_by_target_triple() { } #[tokio::test] -async fn add_component_by_target_triple_renamed_from() { +async fn add_component_by_target_tuple_renamed_from() { let cx = CliTestContext::new(Scenario::SimpleV2).await; cx.config .expect(["rustup", "default", "nightly"]) @@ -1970,7 +1983,7 @@ rls-[HOST_TUPLE] } #[tokio::test] -async fn add_component_by_target_triple_renamed_to() { +async fn add_component_by_target_tuple_renamed_to() { let cx = CliTestContext::new(Scenario::SimpleV2).await; cx.config .expect(["rustup", "default", "nightly"]) @@ -2064,15 +2077,15 @@ async fn remove_component() { } #[tokio::test] -async fn remove_component_by_target_triple() { - let component_with_triple = format!("rust-std-{CROSS_ARCH1}"); +async fn remove_component_by_target_tuple() { + let component_with_tuple = format!("rust-std-{CROSS_ARCH1}"); let cx = CliTestContext::new(Scenario::SimpleV2).await; cx.config .expect(&["rustup", "default", "stable"]) .await .is_ok(); cx.config - .expect(&["rustup", "component", "add", &component_with_triple]) + .expect(&["rustup", "component", "add", &component_with_tuple]) .await .is_ok(); let path = PathBuf::from(format!( @@ -2081,7 +2094,7 @@ async fn remove_component_by_target_triple() { )); assert!(cx.config.rustupdir.has(&path)); cx.config - .expect(&["rustup", "component", "remove", &component_with_triple]) + .expect(&["rustup", "component", "remove", &component_with_tuple]) .await .is_ok(); assert!(!cx.config.rustupdir.has(path.parent().unwrap())); @@ -2095,8 +2108,8 @@ async fn add_remove_multiple_components() { format!("lib/rustlib/{CROSS_ARCH1}/lib/libstd.rlib"), format!("lib/rustlib/{CROSS_ARCH2}/lib/libstd.rlib"), ]; - let component_with_triple1 = format!("rust-std-{CROSS_ARCH1}"); - let component_with_triple2 = format!("rust-std-{CROSS_ARCH2}"); + let component_with_tuple1 = format!("rust-std-{CROSS_ARCH1}"); + let component_with_tuple2 = format!("rust-std-{CROSS_ARCH2}"); let cx = CliTestContext::new(Scenario::SimpleV2).await; cx.config @@ -2110,8 +2123,8 @@ async fn add_remove_multiple_components() { "add", "rust-src", "rust-analysis", - &component_with_triple1, - &component_with_triple2, + &component_with_tuple1, + &component_with_tuple2, ]) .await .is_ok(); @@ -2126,8 +2139,8 @@ async fn add_remove_multiple_components() { "remove", "rust-src", "rust-analysis", - &component_with_triple1, - &component_with_triple2, + &component_with_tuple1, + &component_with_tuple2, ]) .await .is_ok(); diff --git a/tests/suite/cli_rustup_init_ui/rustup_init_help_flag.stdout.term.svg b/tests/suite/cli_rustup_init_ui/rustup_init_help_flag.stdout.term.svg index 1758f3b3ee..f4a6ff2f77 100644 --- a/tests/suite/cli_rustup_init_ui/rustup_init_help_flag.stdout.term.svg +++ b/tests/suite/cli_rustup_init_ui/rustup_init_help_flag.stdout.term.svg @@ -42,7 +42,7 @@ Disable progress output, set log level to 'WARN' if 'RUSTUP_LOG' is unset - -y + -y, --yes Disable confirmation prompt diff --git a/tests/suite/cli_rustup_init_ui/rustup_init_sh_help_flag.stdout.term.svg b/tests/suite/cli_rustup_init_ui/rustup_init_sh_help_flag.stdout.term.svg index 31b851c5f4..77a5394210 100644 --- a/tests/suite/cli_rustup_init_ui/rustup_init_sh_help_flag.stdout.term.svg +++ b/tests/suite/cli_rustup_init_ui/rustup_init_sh_help_flag.stdout.term.svg @@ -38,7 +38,7 @@ Disable progress output, set log level to 'WARN' if 'RUSTUP_LOG' is unset - -y + -y, --yes Disable confirmation prompt diff --git a/tests/suite/cli_rustup_ui/rustup_self_cmd_uninstall_cmd_help_flag.stdout.term.svg b/tests/suite/cli_rustup_ui/rustup_self_cmd_uninstall_cmd_help_flag.stdout.term.svg index 5a49ee07d1..4fe5be63ce 100644 --- a/tests/suite/cli_rustup_ui/rustup_self_cmd_uninstall_cmd_help_flag.stdout.term.svg +++ b/tests/suite/cli_rustup_ui/rustup_self_cmd_uninstall_cmd_help_flag.stdout.term.svg @@ -30,7 +30,7 @@ Options: - -y Disable confirmation prompt + -y, --yes Disable confirmation prompt --no-modify-path Do not clean up the `PATH` environment variable diff --git a/tests/suite/cli_rustup_ui/rustup_set_cmd_default_host_cmd_help_flag.stdout.term.svg b/tests/suite/cli_rustup_ui/rustup_set_cmd_default_host_cmd_help_flag.stdout.term.svg index 099258a6e5..a63925ceb9 100644 --- a/tests/suite/cli_rustup_ui/rustup_set_cmd_default_host_cmd_help_flag.stdout.term.svg +++ b/tests/suite/cli_rustup_ui/rustup_set_cmd_default_host_cmd_help_flag.stdout.term.svg @@ -20,17 +20,17 @@ - The triple used to identify toolchains when not specified + The tuple used to identify toolchains when not specified - Usage: rustup[EXE] set default-host <HOST_TRIPLE> + Usage: rustup[EXE] set default-host <HOST_TUPLE> Arguments: - <HOST_TRIPLE> + <HOST_TUPLE> diff --git a/tests/suite/cli_rustup_ui/rustup_set_cmd_help_flag.stdout.term.svg b/tests/suite/cli_rustup_ui/rustup_set_cmd_help_flag.stdout.term.svg index 54cb5a7e5b..dbd73fe467 100644 --- a/tests/suite/cli_rustup_ui/rustup_set_cmd_help_flag.stdout.term.svg +++ b/tests/suite/cli_rustup_ui/rustup_set_cmd_help_flag.stdout.term.svg @@ -30,7 +30,7 @@ Commands: - default-host The triple used to identify toolchains when not specified + default-host The tuple used to identify toolchains when not specified profile The default components installed with a toolchain diff --git a/tests/suite/cli_rustup_ui/rustup_toolchain_cmd_help_flag.stdout.term.svg b/tests/suite/cli_rustup_ui/rustup_toolchain_cmd_help_flag.stdout.term.svg index a3c2b5bc14..7c0d3b87c3 100644 --- a/tests/suite/cli_rustup_ui/rustup_toolchain_cmd_help_flag.stdout.term.svg +++ b/tests/suite/cli_rustup_ui/rustup_toolchain_cmd_help_flag.stdout.term.svg @@ -80,7 +80,7 @@ <date> = YYYY-MM-DD - <host> = <target-triple> + <host> = <target-tuple> diff --git a/tests/suite/cli_v1.rs b/tests/suite/cli_v1.rs index 465b26b59e..2a98f95b65 100644 --- a/tests/suite/cli_v1.rs +++ b/tests/suite/cli_v1.rs @@ -271,7 +271,7 @@ async fn remove_override_toolchain_err_handling() { .await .is_ok(); cx.config - .expect(["rustc", "--version"]) + .expect_with_env(["rustc", "--version"], [("RUSTUP_AUTO_INSTALL", "1")]) .await .with_stdout(snapbox::str![[r#" 1.2.0 (hash-beta-1.2.0) diff --git a/tests/suite/cli_v2.rs b/tests/suite/cli_v2.rs index fdd1d90e29..2b855cbffb 100644 --- a/tests/suite/cli_v2.rs +++ b/tests/suite/cli_v2.rs @@ -5,7 +5,7 @@ use std::fs; use std::io::Write; use std::path::PathBuf; -use rustup::dist::TargetTriple; +use rustup::dist::TargetTuple; use rustup::dist::manifest::Manifest; use rustup::test::{ CROSS_ARCH1, CROSS_ARCH2, CliTestContext, Config, Scenario, create_hash, this_host_tuple, @@ -478,7 +478,7 @@ async fn remove_override_toolchain_err_handling() { .await .is_ok(); cx.config - .expect(["rustc", "--version"]) + .expect_with_env(["rustc", "--version"], [("RUSTUP_AUTO_INSTALL", "1")]) .await .with_stdout(snapbox::str![[r#" 1.2.0 (hash-beta-1.2.0) @@ -488,6 +488,9 @@ async fn remove_override_toolchain_err_handling() { info: syncing channel updates for beta-[HOST_TUPLE] info: latest update on 2015-01-02 for version 1.2.0 (hash-beta-1.2.0) info: downloading 4 components +warn: the missing active toolchain `beta-[HOST_TUPLE]` has been auto-installed +warn: this might cause rustup commands to take longer time to finish than expected +info: you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable` "#]]) .is_ok(); @@ -511,7 +514,7 @@ async fn file_override_toolchain_err_handling() { let toolchain_file = cwd.join("rust-toolchain"); rustup::utils::raw::write_file(&toolchain_file, "beta").unwrap(); cx.config - .expect(["rustc", "--version"]) + .expect_with_env(["rustc", "--version"], [("RUSTUP_AUTO_INSTALL", "1")]) .await .with_stdout(snapbox::str![[r#" 1.2.0 (hash-beta-1.2.0) @@ -521,6 +524,9 @@ async fn file_override_toolchain_err_handling() { info: syncing channel updates for beta-[HOST_TUPLE] info: latest update on 2015-01-02 for version 1.2.0 (hash-beta-1.2.0) info: downloading 4 components +warn: the missing active toolchain `beta-[HOST_TUPLE]` has been auto-installed +warn: this might cause rustup commands to take longer time to finish than expected +info: you may opt out with `RUSTUP_AUTO_INSTALL=0` or `rustup set auto-install disable` "#]]) .is_ok(); @@ -553,7 +559,10 @@ error: toolchain 'beta-[HOST_TUPLE]' is not installed "#]]) .is_err(); cx.config - .expect(["rustc", "+beta", "--version"]) + .expect_with_env( + ["rustc", "+beta", "--version"], + [("RUSTUP_AUTO_INSTALL", "1")], + ) .await .with_stdout(snapbox::str![[r#" 1.2.0 (hash-beta-1.2.0) @@ -1930,7 +1939,7 @@ fn make_component_unavailable(config: &Config, name: &str, target: String) { let mut manifest = Manifest::parse(&manifest_str).unwrap(); { let std_pkg = manifest.packages.get_mut(name).unwrap(); - let target = TargetTriple::new(target); + let target = TargetTuple::new(target); let target_pkg = std_pkg.targets.get_mut(&target).unwrap(); target_pkg.bins = Vec::new(); } diff --git a/tests/suite/known_tuples.rs b/tests/suite/known_target_tuples.rs similarity index 73% rename from tests/suite/known_tuples.rs rename to tests/suite/known_target_tuples.rs index fd0b7385cc..34ea36bd66 100644 --- a/tests/suite/known_tuples.rs +++ b/tests/suite/known_target_tuples.rs @@ -3,12 +3,15 @@ use std::{collections::BTreeSet, io::Write}; use platforms::Platform; #[test] -fn gen_known_tuples() { - let out_path = "src/dist/triple/known.rs"; +fn gen_known_target_tuples() { + let out_path = "src/dist/target_tuple/known.rs"; let existing = std::fs::read_to_string(out_path).unwrap(); let (mut archs, mut oses, mut envs) = (BTreeSet::new(), BTreeSet::new(), BTreeSet::new()); - for (arch, os, env) in Platform::ALL.iter().map(|p| parse_triple(p.target_triple)) { + for (arch, os, env) in Platform::ALL + .iter() + .map(|p| parse_target_tuple(p.target_triple)) + { archs.insert(arch); oses.insert(os); if !env.is_empty() { @@ -50,12 +53,12 @@ fn gen_known_tuples() { } } -/// Parses the given triple into 3 parts (target architecture, OS and environment). +/// Parses the given target tuples into 3 parts (target architecture, OS and environment). /// /// # Discussion /// /// The current model of target tuples in Rustup requires some non-code knowledge to correctly generate the list. -/// For example, the parsing results of two 2-dash triples can be different: +/// For example, the parsing results of two 2-dash target tuples can be different: /// /// ```jsonc /// { arch: aarch64, os: linux, env: android } @@ -79,18 +82,18 @@ fn gen_known_tuples() { /// // for `x-y-z-w` /// { arch: x, os: y-z, env: w } /// ``` -fn parse_triple(triple: &str) -> (&str, &str, &str) { - match triple.split('-').collect::>()[..] { +fn parse_target_tuple(target_tuple: &str) -> (&str, &str, &str) { + match target_tuple.split('-').collect::>()[..] { [arch, os] => (arch, os, ""), [arch, os @ ("none" | "linux"), env] => (arch, os, env), - [arch, _, _] => (arch, &triple[(arch.len() + 1)..], ""), + [arch, _, _] => (arch, &target_tuple[(arch.len() + 1)..], ""), [arch, _, _, env] => ( arch, - &triple[(arch.len() + 1)..(triple.len() - env.len() - 1)], + &target_tuple[(arch.len() + 1)..(target_tuple.len() - env.len() - 1)], env, ), _ => panic!( - "Internal error while parsing target tuple `{triple}`, please file an issue at https://github.com/rust-lang/rustup/issues" + "Internal error while parsing target tuple `{target_tuple}`, please file an issue at https://github.com/rust-lang/rustup/issues" ), } } diff --git a/tests/suite/mod.rs b/tests/suite/mod.rs index 296102d67a..2fa175e633 100644 --- a/tests/suite/mod.rs +++ b/tests/suite/mod.rs @@ -9,5 +9,5 @@ mod cli_self_upd; mod cli_v1; mod cli_v2; mod dist_install; -mod known_tuples; +mod known_target_tuples; mod static_roots;