├── .gitignore ├── .travis.yml ├── Cargo.lock ├── Cargo.toml ├── LICENSE.txt ├── README.md ├── build.rs └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | /target 3 | **/*.rs.bk 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: xenial 2 | language: shell 3 | 4 | git: 5 | depth: 1 6 | quiet: true 7 | 8 | cache: 9 | directories: 10 | - "$HOME/.cargo" 11 | - target 12 | before_cache: 13 | - | 14 | cargo install \ 15 | --debug \ 16 | --force \ 17 | --git https://github.com/matthiaskrgr/cargo-cache \ 18 | --no-default-features \ 19 | --features ci-autoclean \ 20 | --bin cargo-cache \ 21 | -- \ 22 | cargo-cache 23 | - cargo cache 24 | - find ~/.cargo/bin ! -type d -exec strip {} \; 25 | 26 | matrix: 27 | fast_finish: true 28 | include: 29 | - os: linux 30 | - os: osx 31 | - os: windows 32 | - name: rustfmt 33 | install: 34 | - rustup component add rustfmt 35 | script: 36 | - cargo fmt -- --check; 37 | 38 | before_install: 39 | - curl -sSf https://build.travis-ci.com/files/rustup-init.sh | sh -s -- -y --default-toolchain=stable --profile=minimal 40 | - export PATH="$HOME/.cargo/bin:$PATH" 41 | - export CARGO_TARGET_DIR="$TRAVIS_BUILD_DIR/target" 42 | 43 | script: 44 | - cargo build 45 | - if [ -n "$GITHUB_TOKEN" ]; then FEATURES=('--github-token' "$GITHUB_TOKEN"); else FEATURES=(); fi 46 | - RUST_COMMIT=$(git ls-remote https://github.com/rust-lang/rust master | awk '{print $1}') 47 | - cargo run -- "${FEATURES[@]}" 48 | - rustc +"$RUST_COMMIT" -vV 49 | - rustc +"$RUST_COMMIT" -vV | grep "$RUST_COMMIT" 50 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "adler32" 5 | version = "1.1.0" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d" 8 | 9 | [[package]] 10 | name = "ansi_term" 11 | version = "0.11.0" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 14 | dependencies = [ 15 | "winapi 0.3.9", 16 | ] 17 | 18 | [[package]] 19 | name = "ansi_term" 20 | version = "0.12.1" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 23 | dependencies = [ 24 | "winapi 0.3.9", 25 | ] 26 | 27 | [[package]] 28 | name = "anyhow" 29 | version = "1.0.31" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "85bb70cc08ec97ca5450e6eba421deeea5f172c0fc61f78b5357b2a8e8be195f" 32 | 33 | [[package]] 34 | name = "async-compression" 35 | version = "0.3.4" 36 | source = "registry+https://github.com/rust-lang/crates.io-index" 37 | checksum = "ae84766bab9f774e32979583ba56d6af8c701288c6dc99144819d5d2ee0b170f" 38 | dependencies = [ 39 | "bytes", 40 | "flate2", 41 | "futures-core", 42 | "memchr", 43 | "pin-project-lite", 44 | ] 45 | 46 | [[package]] 47 | name = "atty" 48 | version = "0.2.14" 49 | source = "registry+https://github.com/rust-lang/crates.io-index" 50 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 51 | dependencies = [ 52 | "hermit-abi", 53 | "libc", 54 | "winapi 0.3.9", 55 | ] 56 | 57 | [[package]] 58 | name = "autocfg" 59 | version = "1.0.0" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" 62 | 63 | [[package]] 64 | name = "base64" 65 | version = "0.12.3" 66 | source = "registry+https://github.com/rust-lang/crates.io-index" 67 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 68 | 69 | [[package]] 70 | name = "bitflags" 71 | version = "1.2.1" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 74 | 75 | [[package]] 76 | name = "bumpalo" 77 | version = "3.4.0" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820" 80 | 81 | [[package]] 82 | name = "bytes" 83 | version = "0.5.5" 84 | source = "registry+https://github.com/rust-lang/crates.io-index" 85 | checksum = "118cf036fbb97d0816e3c34b2d7a1e8cfc60f68fcf63d550ddbe9bd5f59c213b" 86 | dependencies = [ 87 | "loom", 88 | ] 89 | 90 | [[package]] 91 | name = "cc" 92 | version = "1.0.55" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "b1be3409f94d7bdceeb5f5fac551039d9b3f00e25da7a74fc4d33400a0d96368" 95 | 96 | [[package]] 97 | name = "cfg-if" 98 | version = "0.1.10" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 101 | 102 | [[package]] 103 | name = "clap" 104 | version = "2.33.1" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129" 107 | dependencies = [ 108 | "ansi_term 0.11.0", 109 | "atty", 110 | "bitflags", 111 | "strsim", 112 | "textwrap", 113 | "unicode-width", 114 | "vec_map", 115 | ] 116 | 117 | [[package]] 118 | name = "core-foundation" 119 | version = "0.7.0" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" 122 | dependencies = [ 123 | "core-foundation-sys", 124 | "libc", 125 | ] 126 | 127 | [[package]] 128 | name = "core-foundation-sys" 129 | version = "0.7.0" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" 132 | 133 | [[package]] 134 | name = "crc32fast" 135 | version = "1.2.0" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" 138 | dependencies = [ 139 | "cfg-if", 140 | ] 141 | 142 | [[package]] 143 | name = "crossbeam-channel" 144 | version = "0.4.2" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061" 147 | dependencies = [ 148 | "crossbeam-utils", 149 | "maybe-uninit", 150 | ] 151 | 152 | [[package]] 153 | name = "crossbeam-utils" 154 | version = "0.7.2" 155 | source = "registry+https://github.com/rust-lang/crates.io-index" 156 | checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" 157 | dependencies = [ 158 | "autocfg", 159 | "cfg-if", 160 | "lazy_static", 161 | ] 162 | 163 | [[package]] 164 | name = "dtoa" 165 | version = "0.4.6" 166 | source = "registry+https://github.com/rust-lang/crates.io-index" 167 | checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b" 168 | 169 | [[package]] 170 | name = "encoding_rs" 171 | version = "0.8.23" 172 | source = "registry+https://github.com/rust-lang/crates.io-index" 173 | checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171" 174 | dependencies = [ 175 | "cfg-if", 176 | ] 177 | 178 | [[package]] 179 | name = "filetime" 180 | version = "0.2.10" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "affc17579b132fc2461adf7c575cc6e8b134ebca52c51f5411388965227dc695" 183 | dependencies = [ 184 | "cfg-if", 185 | "libc", 186 | "redox_syscall", 187 | "winapi 0.3.9", 188 | ] 189 | 190 | [[package]] 191 | name = "flate2" 192 | version = "1.0.14" 193 | source = "registry+https://github.com/rust-lang/crates.io-index" 194 | checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" 195 | dependencies = [ 196 | "cfg-if", 197 | "crc32fast", 198 | "libc", 199 | "miniz_oxide", 200 | ] 201 | 202 | [[package]] 203 | name = "fnv" 204 | version = "1.0.7" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 207 | 208 | [[package]] 209 | name = "foreign-types" 210 | version = "0.3.2" 211 | source = "registry+https://github.com/rust-lang/crates.io-index" 212 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 213 | dependencies = [ 214 | "foreign-types-shared", 215 | ] 216 | 217 | [[package]] 218 | name = "foreign-types-shared" 219 | version = "0.1.1" 220 | source = "registry+https://github.com/rust-lang/crates.io-index" 221 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 222 | 223 | [[package]] 224 | name = "fuchsia-zircon" 225 | version = "0.3.3" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 228 | dependencies = [ 229 | "bitflags", 230 | "fuchsia-zircon-sys", 231 | ] 232 | 233 | [[package]] 234 | name = "fuchsia-zircon-sys" 235 | version = "0.3.3" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 238 | 239 | [[package]] 240 | name = "futures-channel" 241 | version = "0.3.5" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5" 244 | dependencies = [ 245 | "futures-core", 246 | ] 247 | 248 | [[package]] 249 | name = "futures-core" 250 | version = "0.3.5" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399" 253 | 254 | [[package]] 255 | name = "futures-io" 256 | version = "0.3.5" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789" 259 | 260 | [[package]] 261 | name = "futures-sink" 262 | version = "0.3.5" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc" 265 | 266 | [[package]] 267 | name = "futures-task" 268 | version = "0.3.5" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626" 271 | dependencies = [ 272 | "once_cell", 273 | ] 274 | 275 | [[package]] 276 | name = "futures-util" 277 | version = "0.3.5" 278 | source = "registry+https://github.com/rust-lang/crates.io-index" 279 | checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6" 280 | dependencies = [ 281 | "futures-core", 282 | "futures-io", 283 | "futures-task", 284 | "memchr", 285 | "pin-project", 286 | "pin-utils", 287 | "slab", 288 | ] 289 | 290 | [[package]] 291 | name = "generator" 292 | version = "0.6.21" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "add72f17bb81521258fcc8a7a3245b1e184e916bfbe34f0ea89558f440df5c68" 295 | dependencies = [ 296 | "cc", 297 | "libc", 298 | "log", 299 | "rustc_version", 300 | "winapi 0.3.9", 301 | ] 302 | 303 | [[package]] 304 | name = "getrandom" 305 | version = "0.1.14" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" 308 | dependencies = [ 309 | "cfg-if", 310 | "libc", 311 | "wasi", 312 | ] 313 | 314 | [[package]] 315 | name = "h2" 316 | version = "0.2.5" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff" 319 | dependencies = [ 320 | "bytes", 321 | "fnv", 322 | "futures-core", 323 | "futures-sink", 324 | "futures-util", 325 | "http", 326 | "indexmap", 327 | "log", 328 | "slab", 329 | "tokio", 330 | "tokio-util", 331 | ] 332 | 333 | [[package]] 334 | name = "heck" 335 | version = "0.3.1" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 338 | dependencies = [ 339 | "unicode-segmentation", 340 | ] 341 | 342 | [[package]] 343 | name = "hermit-abi" 344 | version = "0.1.14" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | checksum = "b9586eedd4ce6b3c498bc3b4dd92fc9f11166aa908a914071953768066c67909" 347 | dependencies = [ 348 | "libc", 349 | ] 350 | 351 | [[package]] 352 | name = "home" 353 | version = "0.5.3" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "2456aef2e6b6a9784192ae780c0f15bc57df0e918585282325e8c8ac27737654" 356 | dependencies = [ 357 | "winapi 0.3.9", 358 | ] 359 | 360 | [[package]] 361 | name = "http" 362 | version = "0.2.1" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "28d569972648b2c512421b5f2a405ad6ac9666547189d0c5477a3f200f3e02f9" 365 | dependencies = [ 366 | "bytes", 367 | "fnv", 368 | "itoa", 369 | ] 370 | 371 | [[package]] 372 | name = "http-body" 373 | version = "0.3.1" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" 376 | dependencies = [ 377 | "bytes", 378 | "http", 379 | ] 380 | 381 | [[package]] 382 | name = "httparse" 383 | version = "1.3.4" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9" 386 | 387 | [[package]] 388 | name = "hyper" 389 | version = "0.13.6" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | checksum = "a6e7655b9594024ad0ee439f3b5a7299369dc2a3f459b47c696f9ff676f9aa1f" 392 | dependencies = [ 393 | "bytes", 394 | "futures-channel", 395 | "futures-core", 396 | "futures-util", 397 | "h2", 398 | "http", 399 | "http-body", 400 | "httparse", 401 | "itoa", 402 | "log", 403 | "pin-project", 404 | "socket2", 405 | "time", 406 | "tokio", 407 | "tower-service", 408 | "want", 409 | ] 410 | 411 | [[package]] 412 | name = "hyper-tls" 413 | version = "0.4.1" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "3adcd308402b9553630734e9c36b77a7e48b3821251ca2493e8cd596763aafaa" 416 | dependencies = [ 417 | "bytes", 418 | "hyper", 419 | "native-tls", 420 | "tokio", 421 | "tokio-tls", 422 | ] 423 | 424 | [[package]] 425 | name = "idna" 426 | version = "0.2.0" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 429 | dependencies = [ 430 | "matches", 431 | "unicode-bidi", 432 | "unicode-normalization", 433 | ] 434 | 435 | [[package]] 436 | name = "indexmap" 437 | version = "1.4.0" 438 | source = "registry+https://github.com/rust-lang/crates.io-index" 439 | checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe" 440 | dependencies = [ 441 | "autocfg", 442 | ] 443 | 444 | [[package]] 445 | name = "iovec" 446 | version = "0.1.4" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 449 | dependencies = [ 450 | "libc", 451 | ] 452 | 453 | [[package]] 454 | name = "itoa" 455 | version = "0.4.6" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" 458 | 459 | [[package]] 460 | name = "js-sys" 461 | version = "0.3.40" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "ce10c23ad2ea25ceca0093bd3192229da4c5b3c0f2de499c1ecac0d98d452177" 464 | dependencies = [ 465 | "wasm-bindgen", 466 | ] 467 | 468 | [[package]] 469 | name = "kernel32-sys" 470 | version = "0.2.2" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" 473 | dependencies = [ 474 | "winapi 0.2.8", 475 | "winapi-build", 476 | ] 477 | 478 | [[package]] 479 | name = "lazy_static" 480 | version = "1.4.0" 481 | source = "registry+https://github.com/rust-lang/crates.io-index" 482 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 483 | 484 | [[package]] 485 | name = "libc" 486 | version = "0.2.71" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "9457b06509d27052635f90d6466700c65095fdf75409b3fbdd903e988b886f49" 489 | 490 | [[package]] 491 | name = "log" 492 | version = "0.4.8" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 495 | dependencies = [ 496 | "cfg-if", 497 | ] 498 | 499 | [[package]] 500 | name = "loom" 501 | version = "0.3.4" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "4ecc775857611e1df29abba5c41355cdf540e7e9d4acfdf0f355eefee82330b7" 504 | dependencies = [ 505 | "cfg-if", 506 | "generator", 507 | "scoped-tls", 508 | ] 509 | 510 | [[package]] 511 | name = "lzma-sys" 512 | version = "0.1.16" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "f24f76ec44a8ac23a31915d6e326bca17ce88da03096f1ff194925dc714dac99" 515 | dependencies = [ 516 | "cc", 517 | "libc", 518 | "pkg-config", 519 | ] 520 | 521 | [[package]] 522 | name = "matches" 523 | version = "0.1.8" 524 | source = "registry+https://github.com/rust-lang/crates.io-index" 525 | checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 526 | 527 | [[package]] 528 | name = "maybe-uninit" 529 | version = "2.0.0" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" 532 | 533 | [[package]] 534 | name = "memchr" 535 | version = "2.3.3" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400" 538 | 539 | [[package]] 540 | name = "mime" 541 | version = "0.3.16" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 544 | 545 | [[package]] 546 | name = "mime_guess" 547 | version = "2.0.3" 548 | source = "registry+https://github.com/rust-lang/crates.io-index" 549 | checksum = "2684d4c2e97d99848d30b324b00c8fcc7e5c897b7cbb5819b09e7c90e8baf212" 550 | dependencies = [ 551 | "mime", 552 | "unicase", 553 | ] 554 | 555 | [[package]] 556 | name = "miniz_oxide" 557 | version = "0.3.7" 558 | source = "registry+https://github.com/rust-lang/crates.io-index" 559 | checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" 560 | dependencies = [ 561 | "adler32", 562 | ] 563 | 564 | [[package]] 565 | name = "mio" 566 | version = "0.6.22" 567 | source = "registry+https://github.com/rust-lang/crates.io-index" 568 | checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430" 569 | dependencies = [ 570 | "cfg-if", 571 | "fuchsia-zircon", 572 | "fuchsia-zircon-sys", 573 | "iovec", 574 | "kernel32-sys", 575 | "libc", 576 | "log", 577 | "miow", 578 | "net2", 579 | "slab", 580 | "winapi 0.2.8", 581 | ] 582 | 583 | [[package]] 584 | name = "miow" 585 | version = "0.2.1" 586 | source = "registry+https://github.com/rust-lang/crates.io-index" 587 | checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 588 | dependencies = [ 589 | "kernel32-sys", 590 | "net2", 591 | "winapi 0.2.8", 592 | "ws2_32-sys", 593 | ] 594 | 595 | [[package]] 596 | name = "native-tls" 597 | version = "0.2.4" 598 | source = "registry+https://github.com/rust-lang/crates.io-index" 599 | checksum = "2b0d88c06fe90d5ee94048ba40409ef1d9315d86f6f38c2efdaad4fb50c58b2d" 600 | dependencies = [ 601 | "lazy_static", 602 | "libc", 603 | "log", 604 | "openssl", 605 | "openssl-probe", 606 | "openssl-sys", 607 | "schannel", 608 | "security-framework", 609 | "security-framework-sys", 610 | "tempfile", 611 | ] 612 | 613 | [[package]] 614 | name = "net2" 615 | version = "0.2.34" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7" 618 | dependencies = [ 619 | "cfg-if", 620 | "libc", 621 | "winapi 0.3.9", 622 | ] 623 | 624 | [[package]] 625 | name = "num_cpus" 626 | version = "1.13.0" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" 629 | dependencies = [ 630 | "hermit-abi", 631 | "libc", 632 | ] 633 | 634 | [[package]] 635 | name = "once_cell" 636 | version = "1.4.0" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" 639 | 640 | [[package]] 641 | name = "openssl" 642 | version = "0.10.30" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "8d575eff3665419f9b83678ff2815858ad9d11567e082f5ac1814baba4e2bcb4" 645 | dependencies = [ 646 | "bitflags", 647 | "cfg-if", 648 | "foreign-types", 649 | "lazy_static", 650 | "libc", 651 | "openssl-sys", 652 | ] 653 | 654 | [[package]] 655 | name = "openssl-probe" 656 | version = "0.1.2" 657 | source = "registry+https://github.com/rust-lang/crates.io-index" 658 | checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" 659 | 660 | [[package]] 661 | name = "openssl-sys" 662 | version = "0.9.58" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "a842db4709b604f0fe5d1170ae3565899be2ad3d9cbc72dedc789ac0511f78de" 665 | dependencies = [ 666 | "autocfg", 667 | "cc", 668 | "libc", 669 | "pkg-config", 670 | "vcpkg", 671 | ] 672 | 673 | [[package]] 674 | name = "pbr" 675 | version = "1.0.3" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "74333e3d1d8bced07fd0b8599304825684bcdb4a1fcc6fa6a470e6e08cefd254" 678 | dependencies = [ 679 | "crossbeam-channel", 680 | "libc", 681 | "time", 682 | "winapi 0.3.9", 683 | ] 684 | 685 | [[package]] 686 | name = "percent-encoding" 687 | version = "2.1.0" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 690 | 691 | [[package]] 692 | name = "pin-project" 693 | version = "0.4.22" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "12e3a6cdbfe94a5e4572812a0201f8c0ed98c1c452c7b8563ce2276988ef9c17" 696 | dependencies = [ 697 | "pin-project-internal", 698 | ] 699 | 700 | [[package]] 701 | name = "pin-project-internal" 702 | version = "0.4.22" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "6a0ffd45cf79d88737d7cc85bfd5d2894bee1139b356e616fe85dc389c61aaf7" 705 | dependencies = [ 706 | "proc-macro2", 707 | "quote", 708 | "syn", 709 | ] 710 | 711 | [[package]] 712 | name = "pin-project-lite" 713 | version = "0.1.7" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "282adbf10f2698a7a77f8e983a74b2d18176c19a7fd32a45446139ae7b02b715" 716 | 717 | [[package]] 718 | name = "pin-utils" 719 | version = "0.1.0" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 722 | 723 | [[package]] 724 | name = "pkg-config" 725 | version = "0.3.17" 726 | source = "registry+https://github.com/rust-lang/crates.io-index" 727 | checksum = "05da548ad6865900e60eaba7f589cc0783590a92e940c26953ff81ddbab2d677" 728 | 729 | [[package]] 730 | name = "ppv-lite86" 731 | version = "0.2.8" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | checksum = "237a5ed80e274dbc66f86bd59c1e25edc039660be53194b5fe0a482e0f2612ea" 734 | 735 | [[package]] 736 | name = "proc-macro-error" 737 | version = "1.0.3" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "fc175e9777c3116627248584e8f8b3e2987405cabe1c0adf7d1dd28f09dc7880" 740 | dependencies = [ 741 | "proc-macro-error-attr", 742 | "proc-macro2", 743 | "quote", 744 | "syn", 745 | "version_check", 746 | ] 747 | 748 | [[package]] 749 | name = "proc-macro-error-attr" 750 | version = "1.0.3" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "3cc9795ca17eb581285ec44936da7fc2335a3f34f2ddd13118b6f4d515435c50" 753 | dependencies = [ 754 | "proc-macro2", 755 | "quote", 756 | "syn", 757 | "syn-mid", 758 | "version_check", 759 | ] 760 | 761 | [[package]] 762 | name = "proc-macro2" 763 | version = "1.0.18" 764 | source = "registry+https://github.com/rust-lang/crates.io-index" 765 | checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa" 766 | dependencies = [ 767 | "unicode-xid", 768 | ] 769 | 770 | [[package]] 771 | name = "quote" 772 | version = "1.0.7" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" 775 | dependencies = [ 776 | "proc-macro2", 777 | ] 778 | 779 | [[package]] 780 | name = "rand" 781 | version = "0.7.3" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 784 | dependencies = [ 785 | "getrandom", 786 | "libc", 787 | "rand_chacha", 788 | "rand_core", 789 | "rand_hc", 790 | ] 791 | 792 | [[package]] 793 | name = "rand_chacha" 794 | version = "0.2.2" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 797 | dependencies = [ 798 | "ppv-lite86", 799 | "rand_core", 800 | ] 801 | 802 | [[package]] 803 | name = "rand_core" 804 | version = "0.5.1" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 807 | dependencies = [ 808 | "getrandom", 809 | ] 810 | 811 | [[package]] 812 | name = "rand_hc" 813 | version = "0.2.0" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 816 | dependencies = [ 817 | "rand_core", 818 | ] 819 | 820 | [[package]] 821 | name = "redox_syscall" 822 | version = "0.1.56" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84" 825 | 826 | [[package]] 827 | name = "remove_dir_all" 828 | version = "0.5.3" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 831 | dependencies = [ 832 | "winapi 0.3.9", 833 | ] 834 | 835 | [[package]] 836 | name = "reqwest" 837 | version = "0.10.6" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | checksum = "3b82c9238b305f26f53443e3a4bc8528d64b8d0bee408ec949eb7bf5635ec680" 840 | dependencies = [ 841 | "async-compression", 842 | "base64", 843 | "bytes", 844 | "encoding_rs", 845 | "futures-core", 846 | "futures-util", 847 | "http", 848 | "http-body", 849 | "hyper", 850 | "hyper-tls", 851 | "js-sys", 852 | "lazy_static", 853 | "log", 854 | "mime", 855 | "mime_guess", 856 | "native-tls", 857 | "percent-encoding", 858 | "pin-project-lite", 859 | "serde", 860 | "serde_urlencoded", 861 | "tokio", 862 | "tokio-tls", 863 | "url", 864 | "wasm-bindgen", 865 | "wasm-bindgen-futures", 866 | "web-sys", 867 | "winreg", 868 | ] 869 | 870 | [[package]] 871 | name = "rustc_version" 872 | version = "0.2.3" 873 | source = "registry+https://github.com/rust-lang/crates.io-index" 874 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 875 | dependencies = [ 876 | "semver", 877 | ] 878 | 879 | [[package]] 880 | name = "rustup-toolchain-install-master" 881 | version = "1.8.0" 882 | dependencies = [ 883 | "ansi_term 0.12.1", 884 | "anyhow", 885 | "home", 886 | "pbr", 887 | "remove_dir_all", 888 | "reqwest", 889 | "structopt", 890 | "tar", 891 | "tee", 892 | "tempfile", 893 | "xz2", 894 | ] 895 | 896 | [[package]] 897 | name = "ryu" 898 | version = "1.0.5" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 901 | 902 | [[package]] 903 | name = "schannel" 904 | version = "0.1.19" 905 | source = "registry+https://github.com/rust-lang/crates.io-index" 906 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" 907 | dependencies = [ 908 | "lazy_static", 909 | "winapi 0.3.9", 910 | ] 911 | 912 | [[package]] 913 | name = "scoped-tls" 914 | version = "0.1.2" 915 | source = "registry+https://github.com/rust-lang/crates.io-index" 916 | checksum = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28" 917 | 918 | [[package]] 919 | name = "security-framework" 920 | version = "0.4.4" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535" 923 | dependencies = [ 924 | "bitflags", 925 | "core-foundation", 926 | "core-foundation-sys", 927 | "libc", 928 | "security-framework-sys", 929 | ] 930 | 931 | [[package]] 932 | name = "security-framework-sys" 933 | version = "0.4.3" 934 | source = "registry+https://github.com/rust-lang/crates.io-index" 935 | checksum = "17bf11d99252f512695eb468de5516e5cf75455521e69dfe343f3b74e4748405" 936 | dependencies = [ 937 | "core-foundation-sys", 938 | "libc", 939 | ] 940 | 941 | [[package]] 942 | name = "semver" 943 | version = "0.9.0" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 946 | dependencies = [ 947 | "semver-parser", 948 | ] 949 | 950 | [[package]] 951 | name = "semver-parser" 952 | version = "0.7.0" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 955 | 956 | [[package]] 957 | name = "serde" 958 | version = "1.0.114" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | checksum = "5317f7588f0a5078ee60ef675ef96735a1442132dc645eb1d12c018620ed8cd3" 961 | 962 | [[package]] 963 | name = "serde_json" 964 | version = "1.0.55" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "ec2c5d7e739bc07a3e73381a39d61fdb5f671c60c1df26a130690665803d8226" 967 | dependencies = [ 968 | "itoa", 969 | "ryu", 970 | "serde", 971 | ] 972 | 973 | [[package]] 974 | name = "serde_urlencoded" 975 | version = "0.6.1" 976 | source = "registry+https://github.com/rust-lang/crates.io-index" 977 | checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" 978 | dependencies = [ 979 | "dtoa", 980 | "itoa", 981 | "serde", 982 | "url", 983 | ] 984 | 985 | [[package]] 986 | name = "slab" 987 | version = "0.4.2" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 990 | 991 | [[package]] 992 | name = "socket2" 993 | version = "0.3.12" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "03088793f677dce356f3ccc2edb1b314ad191ab702a5de3faf49304f7e104918" 996 | dependencies = [ 997 | "cfg-if", 998 | "libc", 999 | "redox_syscall", 1000 | "winapi 0.3.9", 1001 | ] 1002 | 1003 | [[package]] 1004 | name = "strsim" 1005 | version = "0.8.0" 1006 | source = "registry+https://github.com/rust-lang/crates.io-index" 1007 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 1008 | 1009 | [[package]] 1010 | name = "structopt" 1011 | version = "0.3.15" 1012 | source = "registry+https://github.com/rust-lang/crates.io-index" 1013 | checksum = "de2f5e239ee807089b62adce73e48c625e0ed80df02c7ab3f068f5db5281065c" 1014 | dependencies = [ 1015 | "clap", 1016 | "lazy_static", 1017 | "structopt-derive", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "structopt-derive" 1022 | version = "0.4.8" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "510413f9de616762a4fbeab62509bf15c729603b72d7cd71280fbca431b1c118" 1025 | dependencies = [ 1026 | "heck", 1027 | "proc-macro-error", 1028 | "proc-macro2", 1029 | "quote", 1030 | "syn", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "syn" 1035 | version = "1.0.33" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "e8d5d96e8cbb005d6959f119f773bfaebb5684296108fb32600c00cde305b2cd" 1038 | dependencies = [ 1039 | "proc-macro2", 1040 | "quote", 1041 | "unicode-xid", 1042 | ] 1043 | 1044 | [[package]] 1045 | name = "syn-mid" 1046 | version = "0.5.0" 1047 | source = "registry+https://github.com/rust-lang/crates.io-index" 1048 | checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" 1049 | dependencies = [ 1050 | "proc-macro2", 1051 | "quote", 1052 | "syn", 1053 | ] 1054 | 1055 | [[package]] 1056 | name = "tar" 1057 | version = "0.4.29" 1058 | source = "registry+https://github.com/rust-lang/crates.io-index" 1059 | checksum = "c8a4c1d0bee3230179544336c15eefb563cf0302955d962e456542323e8c2e8a" 1060 | dependencies = [ 1061 | "filetime", 1062 | "libc", 1063 | "redox_syscall", 1064 | "xattr", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "tee" 1069 | version = "0.1.0" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | checksum = "37c12559dba7383625faaff75be24becf35bfc885044375bcab931111799a3da" 1072 | 1073 | [[package]] 1074 | name = "tempfile" 1075 | version = "3.1.0" 1076 | source = "registry+https://github.com/rust-lang/crates.io-index" 1077 | checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 1078 | dependencies = [ 1079 | "cfg-if", 1080 | "libc", 1081 | "rand", 1082 | "redox_syscall", 1083 | "remove_dir_all", 1084 | "winapi 0.3.9", 1085 | ] 1086 | 1087 | [[package]] 1088 | name = "textwrap" 1089 | version = "0.11.0" 1090 | source = "registry+https://github.com/rust-lang/crates.io-index" 1091 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 1092 | dependencies = [ 1093 | "unicode-width", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "time" 1098 | version = "0.1.43" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" 1101 | dependencies = [ 1102 | "libc", 1103 | "winapi 0.3.9", 1104 | ] 1105 | 1106 | [[package]] 1107 | name = "tinyvec" 1108 | version = "0.3.3" 1109 | source = "registry+https://github.com/rust-lang/crates.io-index" 1110 | checksum = "53953d2d3a5ad81d9f844a32f14ebb121f50b650cd59d0ee2a07cf13c617efed" 1111 | 1112 | [[package]] 1113 | name = "tokio" 1114 | version = "0.2.21" 1115 | source = "registry+https://github.com/rust-lang/crates.io-index" 1116 | checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58" 1117 | dependencies = [ 1118 | "bytes", 1119 | "fnv", 1120 | "futures-core", 1121 | "iovec", 1122 | "lazy_static", 1123 | "memchr", 1124 | "mio", 1125 | "num_cpus", 1126 | "pin-project-lite", 1127 | "slab", 1128 | ] 1129 | 1130 | [[package]] 1131 | name = "tokio-tls" 1132 | version = "0.3.1" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343" 1135 | dependencies = [ 1136 | "native-tls", 1137 | "tokio", 1138 | ] 1139 | 1140 | [[package]] 1141 | name = "tokio-util" 1142 | version = "0.3.1" 1143 | source = "registry+https://github.com/rust-lang/crates.io-index" 1144 | checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" 1145 | dependencies = [ 1146 | "bytes", 1147 | "futures-core", 1148 | "futures-sink", 1149 | "log", 1150 | "pin-project-lite", 1151 | "tokio", 1152 | ] 1153 | 1154 | [[package]] 1155 | name = "tower-service" 1156 | version = "0.3.0" 1157 | source = "registry+https://github.com/rust-lang/crates.io-index" 1158 | checksum = "e987b6bf443f4b5b3b6f38704195592cca41c5bb7aedd3c3693c7081f8289860" 1159 | 1160 | [[package]] 1161 | name = "try-lock" 1162 | version = "0.2.2" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" 1165 | 1166 | [[package]] 1167 | name = "unicase" 1168 | version = "2.6.0" 1169 | source = "registry+https://github.com/rust-lang/crates.io-index" 1170 | checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" 1171 | dependencies = [ 1172 | "version_check", 1173 | ] 1174 | 1175 | [[package]] 1176 | name = "unicode-bidi" 1177 | version = "0.3.4" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" 1180 | dependencies = [ 1181 | "matches", 1182 | ] 1183 | 1184 | [[package]] 1185 | name = "unicode-normalization" 1186 | version = "0.1.13" 1187 | source = "registry+https://github.com/rust-lang/crates.io-index" 1188 | checksum = "6fb19cf769fa8c6a80a162df694621ebeb4dafb606470b2b2fce0be40a98a977" 1189 | dependencies = [ 1190 | "tinyvec", 1191 | ] 1192 | 1193 | [[package]] 1194 | name = "unicode-segmentation" 1195 | version = "1.6.0" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" 1198 | 1199 | [[package]] 1200 | name = "unicode-width" 1201 | version = "0.1.7" 1202 | source = "registry+https://github.com/rust-lang/crates.io-index" 1203 | checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" 1204 | 1205 | [[package]] 1206 | name = "unicode-xid" 1207 | version = "0.2.1" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" 1210 | 1211 | [[package]] 1212 | name = "url" 1213 | version = "2.1.1" 1214 | source = "registry+https://github.com/rust-lang/crates.io-index" 1215 | checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb" 1216 | dependencies = [ 1217 | "idna", 1218 | "matches", 1219 | "percent-encoding", 1220 | ] 1221 | 1222 | [[package]] 1223 | name = "vcpkg" 1224 | version = "0.2.10" 1225 | source = "registry+https://github.com/rust-lang/crates.io-index" 1226 | checksum = "6454029bf181f092ad1b853286f23e2c507d8e8194d01d92da4a55c274a5508c" 1227 | 1228 | [[package]] 1229 | name = "vec_map" 1230 | version = "0.8.2" 1231 | source = "registry+https://github.com/rust-lang/crates.io-index" 1232 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 1233 | 1234 | [[package]] 1235 | name = "version_check" 1236 | version = "0.9.2" 1237 | source = "registry+https://github.com/rust-lang/crates.io-index" 1238 | checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" 1239 | 1240 | [[package]] 1241 | name = "want" 1242 | version = "0.3.0" 1243 | source = "registry+https://github.com/rust-lang/crates.io-index" 1244 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1245 | dependencies = [ 1246 | "log", 1247 | "try-lock", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "wasi" 1252 | version = "0.9.0+wasi-snapshot-preview1" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1255 | 1256 | [[package]] 1257 | name = "wasm-bindgen" 1258 | version = "0.2.63" 1259 | source = "registry+https://github.com/rust-lang/crates.io-index" 1260 | checksum = "4c2dc4aa152834bc334f506c1a06b866416a8b6697d5c9f75b9a689c8486def0" 1261 | dependencies = [ 1262 | "cfg-if", 1263 | "serde", 1264 | "serde_json", 1265 | "wasm-bindgen-macro", 1266 | ] 1267 | 1268 | [[package]] 1269 | name = "wasm-bindgen-backend" 1270 | version = "0.2.63" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "ded84f06e0ed21499f6184df0e0cb3494727b0c5da89534e0fcc55c51d812101" 1273 | dependencies = [ 1274 | "bumpalo", 1275 | "lazy_static", 1276 | "log", 1277 | "proc-macro2", 1278 | "quote", 1279 | "syn", 1280 | "wasm-bindgen-shared", 1281 | ] 1282 | 1283 | [[package]] 1284 | name = "wasm-bindgen-futures" 1285 | version = "0.4.13" 1286 | source = "registry+https://github.com/rust-lang/crates.io-index" 1287 | checksum = "64487204d863f109eb77e8462189d111f27cb5712cc9fdb3461297a76963a2f6" 1288 | dependencies = [ 1289 | "cfg-if", 1290 | "js-sys", 1291 | "wasm-bindgen", 1292 | "web-sys", 1293 | ] 1294 | 1295 | [[package]] 1296 | name = "wasm-bindgen-macro" 1297 | version = "0.2.63" 1298 | source = "registry+https://github.com/rust-lang/crates.io-index" 1299 | checksum = "838e423688dac18d73e31edce74ddfac468e37b1506ad163ffaf0a46f703ffe3" 1300 | dependencies = [ 1301 | "quote", 1302 | "wasm-bindgen-macro-support", 1303 | ] 1304 | 1305 | [[package]] 1306 | name = "wasm-bindgen-macro-support" 1307 | version = "0.2.63" 1308 | source = "registry+https://github.com/rust-lang/crates.io-index" 1309 | checksum = "3156052d8ec77142051a533cdd686cba889537b213f948cd1d20869926e68e92" 1310 | dependencies = [ 1311 | "proc-macro2", 1312 | "quote", 1313 | "syn", 1314 | "wasm-bindgen-backend", 1315 | "wasm-bindgen-shared", 1316 | ] 1317 | 1318 | [[package]] 1319 | name = "wasm-bindgen-shared" 1320 | version = "0.2.63" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | checksum = "c9ba19973a58daf4db6f352eda73dc0e289493cd29fb2632eb172085b6521acd" 1323 | 1324 | [[package]] 1325 | name = "web-sys" 1326 | version = "0.3.40" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | checksum = "7b72fe77fd39e4bd3eaa4412fd299a0be6b3dfe9d2597e2f1c20beb968f41d17" 1329 | dependencies = [ 1330 | "js-sys", 1331 | "wasm-bindgen", 1332 | ] 1333 | 1334 | [[package]] 1335 | name = "winapi" 1336 | version = "0.2.8" 1337 | source = "registry+https://github.com/rust-lang/crates.io-index" 1338 | checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 1339 | 1340 | [[package]] 1341 | name = "winapi" 1342 | version = "0.3.9" 1343 | source = "registry+https://github.com/rust-lang/crates.io-index" 1344 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1345 | dependencies = [ 1346 | "winapi-i686-pc-windows-gnu", 1347 | "winapi-x86_64-pc-windows-gnu", 1348 | ] 1349 | 1350 | [[package]] 1351 | name = "winapi-build" 1352 | version = "0.1.1" 1353 | source = "registry+https://github.com/rust-lang/crates.io-index" 1354 | checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 1355 | 1356 | [[package]] 1357 | name = "winapi-i686-pc-windows-gnu" 1358 | version = "0.4.0" 1359 | source = "registry+https://github.com/rust-lang/crates.io-index" 1360 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1361 | 1362 | [[package]] 1363 | name = "winapi-x86_64-pc-windows-gnu" 1364 | version = "0.4.0" 1365 | source = "registry+https://github.com/rust-lang/crates.io-index" 1366 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1367 | 1368 | [[package]] 1369 | name = "winreg" 1370 | version = "0.7.0" 1371 | source = "registry+https://github.com/rust-lang/crates.io-index" 1372 | checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" 1373 | dependencies = [ 1374 | "winapi 0.3.9", 1375 | ] 1376 | 1377 | [[package]] 1378 | name = "ws2_32-sys" 1379 | version = "0.2.1" 1380 | source = "registry+https://github.com/rust-lang/crates.io-index" 1381 | checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" 1382 | dependencies = [ 1383 | "winapi 0.2.8", 1384 | "winapi-build", 1385 | ] 1386 | 1387 | [[package]] 1388 | name = "xattr" 1389 | version = "0.2.2" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c" 1392 | dependencies = [ 1393 | "libc", 1394 | ] 1395 | 1396 | [[package]] 1397 | name = "xz2" 1398 | version = "0.1.6" 1399 | source = "registry+https://github.com/rust-lang/crates.io-index" 1400 | checksum = "c179869f34fc7c01830d3ce7ea2086bc3a07e0d35289b667d0a8bf910258926c" 1401 | dependencies = [ 1402 | "lzma-sys", 1403 | ] 1404 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rustup-toolchain-install-master" 3 | version = "1.8.0" 4 | authors = ["kennytm "] 5 | categories = ["development-tools"] 6 | edition = "2018" 7 | keywords = ["rustup"] 8 | license = "MIT" 9 | readme = "README.md" 10 | repository = "https://github.com/kennytm/rustup-toolchain-install-master" 11 | description = "Install master rustc toolchain into rustup" 12 | 13 | [badges] 14 | maintenance = { status = "passively-maintained" } 15 | travis-ci = { repository = "kennytm/rustup-toolchain-install-master" } 16 | is-it-maintained-issue-resolution = { repository = "kennytm/rustup-toolchain-install-master" } 17 | is-it-maintained-open-issues = { repository = "kennytm/rustup-toolchain-install-master" } 18 | 19 | [dependencies] 20 | ansi_term = "0.12" 21 | anyhow = "1.0.31" 22 | home = "0.5" 23 | pbr = "1" 24 | remove_dir_all = "0.5" 25 | reqwest = { version = "0.10", features = ["blocking", "gzip"]} 26 | structopt = "0.3" 27 | tar = "0.4" 28 | tee = "0.1" 29 | tempfile = "3" 30 | xz2 = "0.1" 31 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2018 kennytm 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 4 | associated documentation files (the "Software"), to deal in the Software without restriction, 5 | including without limitation the rights to use, copy, modify, merge, publish, distribute, 6 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 7 | furnished to do so, subject to the following conditions: 8 | 9 | The above copyright notice and this permission notice shall be included in all copies or substantial 10 | portions of the Software. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 13 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 15 | OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | rustup-toolchain-install-master 2 | =============================== 3 | 4 | [![Travis status](https://travis-ci.com/kennytm/rustup-toolchain-install-master.svg?branch=master)](https://travis-ci.com/kennytm/rustup-toolchain-install-master) 5 | 6 | Installs compiler artifacts generated fresh from Rust's CI into `rustup`. 7 | 8 | ``` 9 | USAGE: 10 | rustup-toolchain-install-master [FLAGS] [OPTIONS] [--] [commits]... 11 | 12 | FLAGS: 13 | -a, --alt download the alt build instead of normal build 14 | --dry-run Only log the URLs, without downloading the artifacts 15 | -f, --force Replace an existing toolchain of the same name 16 | -h, --help Prints help information 17 | -k, --keep-going Continue downloading toolchains even if some of them failed 18 | -V, --version Prints version information 19 | 20 | OPTIONS: 21 | --channel specify the channel of the commits instead of detecting it automatically 22 | -c, --component ... additional components to install, besides rustc and rust-std 23 | --github-token An authorization token to access GitHub APIs 24 | -i, --host the triples of host platform 25 | -n, --name the name to call the toolchain 26 | -p, --proxy the HTTP proxy for all download requests 27 | -s, --server the server path which stores the compilers [default: https://ci-artifacts.rust-lang.org] 28 | -t, --targets ... additional target platforms to install rust-std for, besides the host platform 29 | 30 | ARGS: 31 | ... full commit hashes of the rustc builds, all 40 digits are needed; if omitted, the latest master 32 | commit will be installed 33 | ``` 34 | 35 | Installation 36 | ------------ 37 | 38 | Install `rustup`, and then install from Cargo. 39 | 40 | ```console 41 | $ cargo install rustup-toolchain-install-master 42 | ``` 43 | 44 | Usage 45 | ----- 46 | 47 | Download a normal toolchain: 48 | 49 | ```console 50 | $ rustup-toolchain-install-master 4fb54ed484e2239a3e9eff3be17df00d2a162be3 51 | detecting the channel of the `4fb54ed484e2239a3e9eff3be17df00d2a162be3` toolchain... 52 | downloading ... 53 | 47.39 MB / 47.39 MB [=======================================] 100.00 % 10.20 MB/s 54 | downloading ... 55 | 15.91 MB / 15.91 MB [=======================================] 100.00 % 9.95 MB/s 56 | toolchain `4fb54ed484e2239a3e9eff3be17df00d2a162be3` is successfully installed! 57 | ``` 58 | 59 | Use it: 60 | 61 | ```console 62 | $ rustc +4fb54ed484e2239a3e9eff3be17df00d2a162be3 -vV 63 | rustc 1.46.0-nightly (4fb54ed48 2020-06-14) 64 | binary: rustc 65 | commit-hash: 4fb54ed484e2239a3e9eff3be17df00d2a162be3 66 | commit-date: 2020-06-14 67 | host: x86_64-unknown-linux-gnu 68 | release: 1.46.0-nightly 69 | LLVM version: 10.0 70 | ``` 71 | 72 | Remove it using `rustup`: 73 | 74 | ```console 75 | $ rustup uninstall 4fb54ed484e2239a3e9eff3be17df00d2a162be3 76 | info: uninstalling toolchain '4fb54ed484e2239a3e9eff3be17df00d2a162be3' 77 | info: toolchain '4fb54ed484e2239a3e9eff3be17df00d2a162be3' uninstalled 78 | ``` 79 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | fn main() { 4 | println!("cargo:rustc-env=HOST={}", env::var("TARGET").unwrap()); 5 | } 6 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #![warn(rust_2018_idioms)] 2 | 3 | use std::env::set_current_dir; 4 | use std::fs::{create_dir_all, rename}; 5 | use std::io::{stderr, stdout, Write}; 6 | use std::iter::once; 7 | use std::ops::Deref; 8 | use std::path::{Path, PathBuf}; 9 | use std::process::exit; 10 | use std::process::Command; 11 | use std::time::Duration; 12 | 13 | use ansi_term::Color::{Red, Yellow}; 14 | use anyhow::{bail, ensure, Context, Error}; 15 | use pbr::{ProgressBar, Units}; 16 | use remove_dir_all::remove_dir_all; 17 | use reqwest::blocking::{Client, ClientBuilder}; 18 | use reqwest::header::{HeaderMap, HeaderValue, ACCEPT, AUTHORIZATION, CONTENT_LENGTH, USER_AGENT}; 19 | use reqwest::{Proxy, StatusCode}; 20 | use structopt::StructOpt; 21 | use tar::Archive; 22 | use tee::TeeReader; 23 | use tempfile::{tempdir, tempdir_in}; 24 | use xz2::read::XzDecoder; 25 | 26 | static SUPPORTED_CHANNELS: &[&str] = &["nightly", "beta", "stable"]; 27 | 28 | #[allow(clippy::struct_excessive_bools)] 29 | #[derive(StructOpt, Debug)] 30 | #[structopt(set_term_width(0))] 31 | struct Args { 32 | #[structopt( 33 | help = "full commit hashes of the rustc builds, all 40 digits are needed; \ 34 | if omitted, the latest master commit will be installed" 35 | )] 36 | commits: Vec, 37 | 38 | #[structopt(short = "n", long = "name", help = "the name to call the toolchain")] 39 | name: Option, 40 | 41 | #[structopt( 42 | short = "a", 43 | long = "alt", 44 | help = "download the alt build instead of normal build" 45 | )] 46 | alt: bool, 47 | 48 | #[structopt( 49 | short = "s", 50 | long = "server", 51 | help = "the server path which stores the compilers", 52 | default_value = "https://ci-artifacts.rust-lang.org" 53 | )] 54 | server: String, 55 | 56 | #[structopt(short = "i", long = "host", help = "the triples of host platform")] 57 | host: Option, 58 | 59 | #[structopt( 60 | short = "t", 61 | long = "targets", 62 | help = "additional target platforms to install rust-std for, besides the host platform" 63 | )] 64 | targets: Vec, 65 | 66 | #[structopt( 67 | short = "c", 68 | long = "component", 69 | help = "additional components to install, besides rustc and rust-std" 70 | )] 71 | components: Vec, 72 | 73 | #[structopt( 74 | long = "channel", 75 | help = "specify the channel of the commits instead of detecting it automatically" 76 | )] 77 | channel: Option, 78 | 79 | #[structopt( 80 | short = "p", 81 | long = "proxy", 82 | help = "the HTTP proxy for all download requests" 83 | )] 84 | proxy: Option, 85 | 86 | #[structopt( 87 | long = "github-token", 88 | help = "An authorization token to access GitHub APIs" 89 | )] 90 | github_token: Option, 91 | 92 | #[structopt( 93 | long = "dry-run", 94 | help = "Only log the URLs, without downloading the artifacts" 95 | )] 96 | dry_run: bool, 97 | 98 | #[structopt( 99 | long = "force", 100 | short = "f", 101 | help = "Replace an existing toolchain of the same name" 102 | )] 103 | force: bool, 104 | 105 | #[structopt( 106 | long = "keep-going", 107 | short = "k", 108 | help = "Continue downloading toolchains even if some of them failed" 109 | )] 110 | keep_going: bool, 111 | } 112 | 113 | fn download_tar_xz( 114 | client: Option<&Client>, 115 | url: &str, 116 | dest: &Path, 117 | commit: &str, 118 | component: &str, 119 | channel: &str, 120 | target: &str, 121 | ) -> Result<(), Error> { 122 | eprintln!("downloading <{}>...", url); 123 | if let Some(client) = client { 124 | let response = client.get(url).send()?; 125 | 126 | match response.status() { 127 | StatusCode::OK => {} 128 | StatusCode::NOT_FOUND => bail!( 129 | "missing component `{}` on toolchain `{}` on channel `{}` for target `{}`", 130 | component, 131 | commit, 132 | channel, 133 | target, 134 | ), 135 | status => bail!("received status {} for GET {}", status, url), 136 | }; 137 | 138 | let length = response 139 | .headers() 140 | .get(CONTENT_LENGTH) 141 | .and_then(|h| h.to_str().ok()) 142 | .and_then(|h| h.parse().ok()) 143 | .unwrap_or(0); 144 | 145 | let err = stderr(); 146 | let lock = err.lock(); 147 | let mut progress_bar = ProgressBar::on(lock, length); 148 | progress_bar.set_units(Units::Bytes); 149 | progress_bar.set_max_refresh_rate(Some(Duration::from_secs(1))); 150 | 151 | let response = TeeReader::new(response, &mut progress_bar); 152 | let response = XzDecoder::new(response); 153 | for entry in Archive::new(response).entries()? { 154 | let mut entry = entry?; 155 | let relpath = entry.path()?; 156 | 157 | let mut components = relpath.components(); 158 | 159 | // Reject path components that are not normal (.|..|/| etc) 160 | for part in components.clone() { 161 | match part { 162 | std::path::Component::Normal(_) => {} 163 | _ => bail!("bad path in tar: {}", relpath.display()), 164 | } 165 | } 166 | 167 | // Throw away the first two path components: our root was supplied 168 | components.next(); 169 | components.next(); 170 | 171 | let full_path = dest.join(&components.as_path()); 172 | if full_path == dest { 173 | // The tmp dir code makes the root dir for us. 174 | continue; 175 | } 176 | 177 | // Bail out if we get hard links, device nodes or any other unusual content 178 | // - it is most likely an attack, as rusts cross-platform nature precludes 179 | // such artifacts 180 | let kind = entry.header().entry_type(); 181 | 182 | match kind { 183 | tar::EntryType::Directory => { 184 | create_dir_all(full_path)?; 185 | } 186 | tar::EntryType::Regular => { 187 | entry.unpack(full_path)?; 188 | } 189 | _ => bail!("unsupported tar entry: {:?}", kind), 190 | } 191 | } 192 | 193 | progress_bar.finish(); 194 | eprintln!(); 195 | } 196 | 197 | Ok(()) 198 | } 199 | 200 | #[derive(Debug)] 201 | struct Toolchain<'a> { 202 | commit: &'a str, 203 | host_target: &'a str, 204 | rust_std_targets: &'a [&'a str], 205 | components: &'a [&'a str], 206 | dest: PathBuf, 207 | } 208 | 209 | fn install_single_toolchain( 210 | client: &Client, 211 | maybe_dry_client: Option<&Client>, 212 | prefix: &str, 213 | toolchains_path: &Path, 214 | toolchain: &Toolchain<'_>, 215 | override_channel: Option<&str>, 216 | force: bool, 217 | ) -> Result<(), Error> { 218 | let toolchain_path = toolchains_path.join(&toolchain.dest); 219 | if toolchain_path.is_dir() { 220 | if force { 221 | if maybe_dry_client.is_some() { 222 | remove_dir_all(&toolchain_path)?; 223 | } 224 | } else { 225 | eprintln!( 226 | "toolchain `{}` is already installed", 227 | toolchain.dest.display() 228 | ); 229 | return Ok(()); 230 | } 231 | } 232 | 233 | let channel = if let Some(channel) = override_channel { 234 | channel 235 | } else { 236 | get_channel(client, prefix, toolchain.commit)? 237 | }; 238 | 239 | // download every component except rust-std. 240 | for component in once(&"rustc").chain(toolchain.components) { 241 | let component_filename = if *component == "rust-src" { 242 | // rust-src is the only target-independent component 243 | format!("{}-{}", component, channel) 244 | } else { 245 | format!("{}-{}-{}", component, channel, toolchain.host_target) 246 | }; 247 | download_tar_xz( 248 | maybe_dry_client, 249 | &format!( 250 | "{}/{}/{}.tar.xz", 251 | prefix, toolchain.commit, &component_filename 252 | ), 253 | &toolchain.dest, 254 | toolchain.commit, 255 | component, 256 | channel, 257 | toolchain.host_target, 258 | )?; 259 | } 260 | 261 | // download rust-std for every target. 262 | for target in toolchain.rust_std_targets { 263 | let rust_std_filename = format!("rust-std-{}-{}", channel, target); 264 | download_tar_xz( 265 | maybe_dry_client, 266 | &format!( 267 | "{}/{}/{}.tar.xz", 268 | prefix, toolchain.commit, rust_std_filename 269 | ), 270 | &toolchain.dest, 271 | toolchain.commit, 272 | "rust-std", 273 | channel, 274 | target, 275 | )?; 276 | } 277 | 278 | // install 279 | if maybe_dry_client.is_some() { 280 | rename(&toolchain.dest, toolchain_path)?; 281 | eprintln!( 282 | "toolchain `{}` is successfully installed!", 283 | toolchain.dest.display() 284 | ); 285 | } else { 286 | eprintln!( 287 | "toolchain `{}` will be installed to `{}` on real run", 288 | toolchain.dest.display(), 289 | toolchain_path.display() 290 | ); 291 | } 292 | 293 | Ok(()) 294 | } 295 | 296 | fn fetch_master_commit(client: &Client, github_token: Option<&str>) -> Result { 297 | eprintln!("fetching master commit hash... "); 298 | fetch_master_commit_via_git() 299 | .context("unable to fetch master commit via git, falling back to HTTP") 300 | .or_else(|err| { 301 | report_warn(&err); 302 | fetch_master_commit_via_http(client, github_token) 303 | }) 304 | } 305 | 306 | fn fetch_master_commit_via_git() -> Result { 307 | let mut output = Command::new("git") 308 | .args(&[ 309 | "ls-remote", 310 | "https://github.com/rust-lang/rust.git", 311 | "master", 312 | ]) 313 | .output()?; 314 | ensure!(output.status.success(), "git ls-remote exited with error"); 315 | ensure!( 316 | output 317 | .stdout 318 | .get(..40) 319 | .map_or(false, |h| h.iter().all(u8::is_ascii_hexdigit)), 320 | "git ls-remote does not return a commit" 321 | ); 322 | 323 | output.stdout.truncate(40); 324 | Ok(unsafe { String::from_utf8_unchecked(output.stdout) }) 325 | } 326 | 327 | fn fetch_master_commit_via_http( 328 | client: &Client, 329 | github_token: Option<&str>, 330 | ) -> Result { 331 | static URL: &str = "https://api.github.com/repos/rust-lang/rust/commits/master"; 332 | static MEDIA_TYPE: &str = "application/vnd.github.VERSION.sha"; 333 | let mut req = client.get(URL).header(ACCEPT, MEDIA_TYPE); 334 | if let Some(token) = github_token { 335 | req = req.header(AUTHORIZATION, format!("token {}", token)); 336 | } 337 | let response = req.send()?; 338 | match response.status() { 339 | StatusCode::OK => {} 340 | status @ StatusCode::FORBIDDEN => { 341 | let rate_limit = response 342 | .headers() 343 | .get("X-RateLimit-Remaining") 344 | .and_then(|r| r.to_str().ok()) 345 | .and_then(|r| r.parse::().ok()) 346 | .unwrap_or(0); 347 | if rate_limit == 0 { 348 | bail!("GitHub API rate limit exceeded"); 349 | } else { 350 | bail!("status: {} with rate limit: {}", status, rate_limit); 351 | } 352 | } 353 | status => bail!("received status {} for URL {}", status, URL), 354 | } 355 | let master_commit = response.text()?; 356 | if master_commit.len() == 40 357 | && master_commit 358 | .chars() 359 | .all(|c| matches!(c, '0'..='9' | 'a'..='f')) 360 | { 361 | let out = stdout(); 362 | let mut lock = out.lock(); 363 | lock.write_all(master_commit.as_bytes())?; 364 | lock.flush()?; 365 | eprintln!(); 366 | Ok(master_commit) 367 | } else { 368 | bail!("unable to parse `{}` as a commit", master_commit) 369 | } 370 | } 371 | 372 | fn get_channel(client: &Client, prefix: &str, commit: &str) -> Result<&'static str, Error> { 373 | eprintln!("detecting the channel of the `{}` toolchain...", commit); 374 | 375 | for channel in SUPPORTED_CHANNELS { 376 | let url = format!("{}/{}/rust-src-{}.tar.xz", prefix, commit, channel); 377 | let resp = client.head(&url).send()?; 378 | 379 | match resp.status() { 380 | StatusCode::OK => return Ok(channel), 381 | StatusCode::NOT_FOUND | StatusCode::FORBIDDEN => {} 382 | status => bail!("unexpected status code {} for HEAD {}", status, url), 383 | } 384 | } 385 | 386 | bail!("toolchain `{}` doesn't exist in any channel", commit); 387 | } 388 | 389 | fn run() -> Result<(), Error> { 390 | let mut args = Args::from_args(); 391 | 392 | let mut headers = HeaderMap::new(); 393 | headers.insert( 394 | USER_AGENT, 395 | HeaderValue::from_static("rustup-toolchain-install-master"), 396 | ); 397 | 398 | let mut client_builder = ClientBuilder::new().default_headers(headers); 399 | if let Some(proxy) = args.proxy { 400 | client_builder = client_builder.proxy(Proxy::all(&proxy)?); 401 | } 402 | let client = client_builder.build()?; 403 | 404 | let rustup_home = home::rustup_home().expect("$RUSTUP_HOME is undefined?"); 405 | let toolchains_path = rustup_home.join("toolchains"); 406 | if !toolchains_path.is_dir() { 407 | bail!( 408 | "`{}` is not a directory. please reinstall rustup.", 409 | toolchains_path.display() 410 | ); 411 | } 412 | 413 | if args.commits.len() > 1 && args.name.is_some() { 414 | return Err(Error::msg( 415 | "name argument can only be provided with a single commit", 416 | )); 417 | } 418 | 419 | let host = args.host.as_deref().unwrap_or(env!("HOST")); 420 | 421 | let components = args.components.iter().map(Deref::deref).collect::>(); 422 | 423 | let rust_std_targets = args 424 | .targets 425 | .iter() 426 | .map(Deref::deref) 427 | .chain(once(host)) 428 | .collect::>(); 429 | 430 | let toolchains_dir = { 431 | let path = rustup_home.join("tmp"); 432 | if !path.exists() { 433 | create_dir_all(&path)?; 434 | } 435 | if path.is_dir() { 436 | tempdir_in(&path) 437 | } else { 438 | tempdir() 439 | } 440 | }?; 441 | set_current_dir(toolchains_dir.path())?; 442 | 443 | let prefix = format!( 444 | "{}/rustc-builds{}", 445 | args.server, 446 | if args.alt { "-alt" } else { "" } 447 | ); 448 | 449 | if args.commits.is_empty() { 450 | args.commits 451 | .push(fetch_master_commit(&client, args.github_token.as_deref())?); 452 | } 453 | 454 | let dry_run_client = if args.dry_run { None } else { Some(&client) }; 455 | let mut failed = false; 456 | for commit in args.commits { 457 | let dest = if let Some(name) = args.name.as_deref() { 458 | PathBuf::from(name) 459 | } else if args.alt { 460 | PathBuf::from(format!("{}-alt", commit)) 461 | } else { 462 | PathBuf::from(&commit) 463 | }; 464 | 465 | let result = install_single_toolchain( 466 | &client, 467 | dry_run_client, 468 | &prefix, 469 | &toolchains_path, 470 | &Toolchain { 471 | commit: &commit, 472 | host_target: host, 473 | rust_std_targets: &rust_std_targets, 474 | components: &components, 475 | dest, 476 | }, 477 | args.channel.as_deref(), 478 | args.force, 479 | ); 480 | 481 | if args.keep_going { 482 | if let Err(err) = result { 483 | report_warn( 484 | &err.context(format!("skipping toolchain `{}` due to a failure", commit)), 485 | ); 486 | failed = true; 487 | } 488 | } else { 489 | result?; 490 | } 491 | } 492 | 493 | // Return the error only after downloading the toolchains that didn't fail 494 | if failed { 495 | Err(Error::msg("failed to download some toolchains")) 496 | } else { 497 | Ok(()) 498 | } 499 | } 500 | 501 | fn report_error(err: &Error) { 502 | eprintln!("{} {}", Red.bold().paint("error:"), err); 503 | for cause in err.chain().skip(1) { 504 | eprintln!("{} {}", Red.bold().paint("caused by:"), cause); 505 | } 506 | exit(1); 507 | } 508 | 509 | fn report_warn(warn: &Error) { 510 | eprintln!("{} {}", Yellow.bold().paint("warn:"), warn); 511 | for cause in warn.chain().skip(1) { 512 | eprintln!("{} {}", Yellow.bold().paint("caused by:"), cause); 513 | } 514 | eprintln!(); 515 | } 516 | 517 | fn main() { 518 | if let Err(err) = run() { 519 | report_error(&err); 520 | } 521 | } 522 | --------------------------------------------------------------------------------