├── .github ├── dependabot.yml └── workflows │ └── release.yaml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── src ├── cli.rs ├── ghapi.rs ├── lib.rs ├── main.rs ├── sysinfo.rs └── utils.rs └── static └── demo.gif /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "cargo" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/workflows/release.yaml: -------------------------------------------------------------------------------- 1 | name: releaser 2 | 3 | on: 4 | release: 5 | types: 6 | - created 7 | 8 | jobs: 9 | release-to-cargo: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - 13 | name: Chekout 14 | uses: actions/checkout@v2 15 | with: 16 | fetch-depth: 0 17 | - 18 | uses: actions-rs/toolchain@v1 19 | with: 20 | toolchain: stable 21 | - 22 | name: Publish to crates.io 23 | shell: bash 24 | env: 25 | CRATES_API_KEY: ${{ secrets.CRATES_API_KEY }} 26 | run: | 27 | cargo login "$CRATES_API_KEY" 28 | cargo publish --dry-run 29 | cargo publish 30 | release_for_mac: 31 | name: MacOS 32 | runs-on: macos-10.15 33 | steps: 34 | - uses: actions/checkout@master 35 | - uses: actions-rs/cargo@v1 36 | with: 37 | command: build 38 | args: --release 39 | - name: Rename binary 40 | run: mv target/release/github-bin-downloader github-bin-downloader-macos64 41 | - name: Upload to release 42 | env: 43 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 44 | run: | 45 | curl \ 46 | -f \ 47 | -sSL \ 48 | -XPOST \ 49 | -H "Authorization: token $GITHUB_TOKEN" \ 50 | -H "Content-Length: $(stat -f%z github-bin-downloader-macos64)" \ 51 | -H "Content-Type: application/octet-stream" \ 52 | --upload-file "github-bin-downloader-macos64" \ 53 | "https://uploads.github.com/repos/$GITHUB_REPOSITORY/releases/$(jq --raw-output '.release.id' $GITHUB_EVENT_PATH)/assets?name=github-bin-downloader-macos64" 54 | release_for_linux: 55 | name: Linux 56 | runs-on: ubuntu-18.04 57 | steps: 58 | - uses: actions/checkout@master 59 | - uses: actions-rs/cargo@v1 60 | with: 61 | command: build 62 | args: --release 63 | - name: Rename binary 64 | run: mv target/release/github-bin-downloader github-bin-downloader-linux-amd64 65 | - name: Upload to release 66 | uses: JasonEtco/upload-to-release@d648f1babf776de9cad881320bd9e9818fc3b262 67 | with: 68 | args: github-bin-downloader-linux-amd64 application/octet-stream 69 | env: 70 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 71 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ansi_term" 7 | version = "0.11.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 10 | dependencies = [ 11 | "winapi", 12 | ] 13 | 14 | [[package]] 15 | name = "atty" 16 | version = "0.2.14" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 19 | dependencies = [ 20 | "hermit-abi", 21 | "libc", 22 | "winapi", 23 | ] 24 | 25 | [[package]] 26 | name = "autocfg" 27 | version = "1.0.1" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 30 | 31 | [[package]] 32 | name = "base64" 33 | version = "0.13.0" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 36 | 37 | [[package]] 38 | name = "bitflags" 39 | version = "1.2.1" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 42 | 43 | [[package]] 44 | name = "bumpalo" 45 | version = "3.7.0" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "9c59e7af012c713f529e7a3ee57ce9b31ddd858d4b512923602f74608b009631" 48 | 49 | [[package]] 50 | name = "bytes" 51 | version = "1.0.1" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" 54 | 55 | [[package]] 56 | name = "cc" 57 | version = "1.0.68" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" 60 | 61 | [[package]] 62 | name = "cfg-if" 63 | version = "1.0.0" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 66 | 67 | [[package]] 68 | name = "clap" 69 | version = "2.33.3" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" 72 | dependencies = [ 73 | "ansi_term", 74 | "atty", 75 | "bitflags", 76 | "strsim", 77 | "textwrap", 78 | "unicode-width", 79 | "vec_map", 80 | ] 81 | 82 | [[package]] 83 | name = "console" 84 | version = "0.14.1" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45" 87 | dependencies = [ 88 | "encode_unicode", 89 | "lazy_static", 90 | "libc", 91 | "regex", 92 | "terminal_size", 93 | "unicode-width", 94 | "winapi", 95 | ] 96 | 97 | [[package]] 98 | name = "core-foundation" 99 | version = "0.9.1" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" 102 | dependencies = [ 103 | "core-foundation-sys", 104 | "libc", 105 | ] 106 | 107 | [[package]] 108 | name = "core-foundation-sys" 109 | version = "0.8.2" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" 112 | 113 | [[package]] 114 | name = "dialoguer" 115 | version = "0.8.0" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | checksum = "c9dd058f8b65922819fabb4a41e7d1964e56344042c26efbccd465202c23fa0c" 118 | dependencies = [ 119 | "console", 120 | "lazy_static", 121 | "tempfile", 122 | "zeroize", 123 | ] 124 | 125 | [[package]] 126 | name = "encode_unicode" 127 | version = "0.3.6" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 130 | 131 | [[package]] 132 | name = "encoding_rs" 133 | version = "0.8.28" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" 136 | dependencies = [ 137 | "cfg-if", 138 | ] 139 | 140 | [[package]] 141 | name = "fnv" 142 | version = "1.0.7" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 145 | 146 | [[package]] 147 | name = "foreign-types" 148 | version = "0.3.2" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 151 | dependencies = [ 152 | "foreign-types-shared", 153 | ] 154 | 155 | [[package]] 156 | name = "foreign-types-shared" 157 | version = "0.1.1" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 160 | 161 | [[package]] 162 | name = "form_urlencoded" 163 | version = "1.0.1" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" 166 | dependencies = [ 167 | "matches", 168 | "percent-encoding", 169 | ] 170 | 171 | [[package]] 172 | name = "futures-channel" 173 | version = "0.3.15" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "e682a68b29a882df0545c143dc3646daefe80ba479bcdede94d5a703de2871e2" 176 | dependencies = [ 177 | "futures-core", 178 | ] 179 | 180 | [[package]] 181 | name = "futures-core" 182 | version = "0.3.15" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "0402f765d8a89a26043b889b26ce3c4679d268fa6bb22cd7c6aad98340e179d1" 185 | 186 | [[package]] 187 | name = "futures-sink" 188 | version = "0.3.15" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "a57bead0ceff0d6dde8f465ecd96c9338121bb7717d3e7b108059531870c4282" 191 | 192 | [[package]] 193 | name = "futures-task" 194 | version = "0.3.15" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "8a16bef9fc1a4dddb5bee51c989e3fbba26569cbb0e31f5b303c184e3dd33dae" 197 | 198 | [[package]] 199 | name = "futures-util" 200 | version = "0.3.15" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "feb5c238d27e2bf94ffdfd27b2c29e3df4a68c4193bb6427384259e2bf191967" 203 | dependencies = [ 204 | "autocfg", 205 | "futures-core", 206 | "futures-task", 207 | "pin-project-lite", 208 | "pin-utils", 209 | ] 210 | 211 | [[package]] 212 | name = "getrandom" 213 | version = "0.2.3" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" 216 | dependencies = [ 217 | "cfg-if", 218 | "libc", 219 | "wasi", 220 | ] 221 | 222 | [[package]] 223 | name = "github-bin-downloader" 224 | version = "0.1.2" 225 | dependencies = [ 226 | "dialoguer", 227 | "indicatif", 228 | "nix", 229 | "reqwest", 230 | "serde_json", 231 | "structopt", 232 | "thiserror", 233 | "tokio", 234 | ] 235 | 236 | [[package]] 237 | name = "h2" 238 | version = "0.3.3" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726" 241 | dependencies = [ 242 | "bytes", 243 | "fnv", 244 | "futures-core", 245 | "futures-sink", 246 | "futures-util", 247 | "http", 248 | "indexmap", 249 | "slab", 250 | "tokio", 251 | "tokio-util", 252 | "tracing", 253 | ] 254 | 255 | [[package]] 256 | name = "hashbrown" 257 | version = "0.9.1" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" 260 | 261 | [[package]] 262 | name = "heck" 263 | version = "0.3.3" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 266 | dependencies = [ 267 | "unicode-segmentation", 268 | ] 269 | 270 | [[package]] 271 | name = "hermit-abi" 272 | version = "0.1.18" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" 275 | dependencies = [ 276 | "libc", 277 | ] 278 | 279 | [[package]] 280 | name = "http" 281 | version = "0.2.4" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "527e8c9ac747e28542699a951517aa9a6945af506cd1f2e1b53a576c17b6cc11" 284 | dependencies = [ 285 | "bytes", 286 | "fnv", 287 | "itoa", 288 | ] 289 | 290 | [[package]] 291 | name = "http-body" 292 | version = "0.4.2" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9" 295 | dependencies = [ 296 | "bytes", 297 | "http", 298 | "pin-project-lite", 299 | ] 300 | 301 | [[package]] 302 | name = "httparse" 303 | version = "1.4.1" 304 | source = "registry+https://github.com/rust-lang/crates.io-index" 305 | checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68" 306 | 307 | [[package]] 308 | name = "httpdate" 309 | version = "1.0.1" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" 312 | 313 | [[package]] 314 | name = "hyper" 315 | version = "0.14.9" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "07d6baa1b441335f3ce5098ac421fb6547c46dda735ca1bc6d0153c838f9dd83" 318 | dependencies = [ 319 | "bytes", 320 | "futures-channel", 321 | "futures-core", 322 | "futures-util", 323 | "h2", 324 | "http", 325 | "http-body", 326 | "httparse", 327 | "httpdate", 328 | "itoa", 329 | "pin-project-lite", 330 | "socket2", 331 | "tokio", 332 | "tower-service", 333 | "tracing", 334 | "want", 335 | ] 336 | 337 | [[package]] 338 | name = "hyper-tls" 339 | version = "0.5.0" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 342 | dependencies = [ 343 | "bytes", 344 | "hyper", 345 | "native-tls", 346 | "tokio", 347 | "tokio-native-tls", 348 | ] 349 | 350 | [[package]] 351 | name = "idna" 352 | version = "0.2.3" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" 355 | dependencies = [ 356 | "matches", 357 | "unicode-bidi", 358 | "unicode-normalization", 359 | ] 360 | 361 | [[package]] 362 | name = "indexmap" 363 | version = "1.6.2" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" 366 | dependencies = [ 367 | "autocfg", 368 | "hashbrown", 369 | ] 370 | 371 | [[package]] 372 | name = "indicatif" 373 | version = "0.16.2" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" 376 | dependencies = [ 377 | "console", 378 | "lazy_static", 379 | "number_prefix", 380 | "regex", 381 | ] 382 | 383 | [[package]] 384 | name = "instant" 385 | version = "0.1.9" 386 | source = "registry+https://github.com/rust-lang/crates.io-index" 387 | checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" 388 | dependencies = [ 389 | "cfg-if", 390 | ] 391 | 392 | [[package]] 393 | name = "ipnet" 394 | version = "2.3.1" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" 397 | 398 | [[package]] 399 | name = "itoa" 400 | version = "0.4.7" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" 403 | 404 | [[package]] 405 | name = "js-sys" 406 | version = "0.3.51" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "83bdfbace3a0e81a4253f73b49e960b053e396a11012cbd49b9b74d6a2b67062" 409 | dependencies = [ 410 | "wasm-bindgen", 411 | ] 412 | 413 | [[package]] 414 | name = "lazy_static" 415 | version = "1.4.0" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 418 | 419 | [[package]] 420 | name = "libc" 421 | version = "0.2.97" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" 424 | 425 | [[package]] 426 | name = "lock_api" 427 | version = "0.4.4" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" 430 | dependencies = [ 431 | "scopeguard", 432 | ] 433 | 434 | [[package]] 435 | name = "log" 436 | version = "0.4.14" 437 | source = "registry+https://github.com/rust-lang/crates.io-index" 438 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" 439 | dependencies = [ 440 | "cfg-if", 441 | ] 442 | 443 | [[package]] 444 | name = "matches" 445 | version = "0.1.8" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 448 | 449 | [[package]] 450 | name = "memchr" 451 | version = "2.4.0" 452 | source = "registry+https://github.com/rust-lang/crates.io-index" 453 | checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc" 454 | 455 | [[package]] 456 | name = "memoffset" 457 | version = "0.6.4" 458 | source = "registry+https://github.com/rust-lang/crates.io-index" 459 | checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" 460 | dependencies = [ 461 | "autocfg", 462 | ] 463 | 464 | [[package]] 465 | name = "mime" 466 | version = "0.3.16" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 469 | 470 | [[package]] 471 | name = "mio" 472 | version = "0.7.13" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" 475 | dependencies = [ 476 | "libc", 477 | "log", 478 | "miow", 479 | "ntapi", 480 | "winapi", 481 | ] 482 | 483 | [[package]] 484 | name = "miow" 485 | version = "0.3.7" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" 488 | dependencies = [ 489 | "winapi", 490 | ] 491 | 492 | [[package]] 493 | name = "native-tls" 494 | version = "0.2.7" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4" 497 | dependencies = [ 498 | "lazy_static", 499 | "libc", 500 | "log", 501 | "openssl", 502 | "openssl-probe", 503 | "openssl-sys", 504 | "schannel", 505 | "security-framework", 506 | "security-framework-sys", 507 | "tempfile", 508 | ] 509 | 510 | [[package]] 511 | name = "nix" 512 | version = "0.21.0" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | checksum = "5c3728fec49d363a50a8828a190b379a446cc5cf085c06259bbbeb34447e4ec7" 515 | dependencies = [ 516 | "bitflags", 517 | "cc", 518 | "cfg-if", 519 | "libc", 520 | "memoffset", 521 | ] 522 | 523 | [[package]] 524 | name = "ntapi" 525 | version = "0.3.6" 526 | source = "registry+https://github.com/rust-lang/crates.io-index" 527 | checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" 528 | dependencies = [ 529 | "winapi", 530 | ] 531 | 532 | [[package]] 533 | name = "num_cpus" 534 | version = "1.13.0" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" 537 | dependencies = [ 538 | "hermit-abi", 539 | "libc", 540 | ] 541 | 542 | [[package]] 543 | name = "number_prefix" 544 | version = "0.4.0" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 547 | 548 | [[package]] 549 | name = "once_cell" 550 | version = "1.8.0" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" 553 | 554 | [[package]] 555 | name = "openssl" 556 | version = "0.10.34" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "6d7830286ad6a3973c0f1d9b73738f69c76b739301d0229c4b96501695cbe4c8" 559 | dependencies = [ 560 | "bitflags", 561 | "cfg-if", 562 | "foreign-types", 563 | "libc", 564 | "once_cell", 565 | "openssl-sys", 566 | ] 567 | 568 | [[package]] 569 | name = "openssl-probe" 570 | version = "0.1.4" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" 573 | 574 | [[package]] 575 | name = "openssl-sys" 576 | version = "0.9.63" 577 | source = "registry+https://github.com/rust-lang/crates.io-index" 578 | checksum = "b6b0d6fb7d80f877617dfcb014e605e2b5ab2fb0afdf27935219bb6bd984cb98" 579 | dependencies = [ 580 | "autocfg", 581 | "cc", 582 | "libc", 583 | "pkg-config", 584 | "vcpkg", 585 | ] 586 | 587 | [[package]] 588 | name = "parking_lot" 589 | version = "0.11.1" 590 | source = "registry+https://github.com/rust-lang/crates.io-index" 591 | checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" 592 | dependencies = [ 593 | "instant", 594 | "lock_api", 595 | "parking_lot_core", 596 | ] 597 | 598 | [[package]] 599 | name = "parking_lot_core" 600 | version = "0.8.3" 601 | source = "registry+https://github.com/rust-lang/crates.io-index" 602 | checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" 603 | dependencies = [ 604 | "cfg-if", 605 | "instant", 606 | "libc", 607 | "redox_syscall", 608 | "smallvec", 609 | "winapi", 610 | ] 611 | 612 | [[package]] 613 | name = "percent-encoding" 614 | version = "2.1.0" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 617 | 618 | [[package]] 619 | name = "pin-project-lite" 620 | version = "0.2.6" 621 | source = "registry+https://github.com/rust-lang/crates.io-index" 622 | checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" 623 | 624 | [[package]] 625 | name = "pin-utils" 626 | version = "0.1.0" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 629 | 630 | [[package]] 631 | name = "pkg-config" 632 | version = "0.3.19" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" 635 | 636 | [[package]] 637 | name = "ppv-lite86" 638 | version = "0.2.10" 639 | source = "registry+https://github.com/rust-lang/crates.io-index" 640 | checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" 641 | 642 | [[package]] 643 | name = "proc-macro-error" 644 | version = "1.0.4" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 647 | dependencies = [ 648 | "proc-macro-error-attr", 649 | "proc-macro2", 650 | "quote", 651 | "syn", 652 | "version_check", 653 | ] 654 | 655 | [[package]] 656 | name = "proc-macro-error-attr" 657 | version = "1.0.4" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 660 | dependencies = [ 661 | "proc-macro2", 662 | "quote", 663 | "version_check", 664 | ] 665 | 666 | [[package]] 667 | name = "proc-macro2" 668 | version = "1.0.27" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038" 671 | dependencies = [ 672 | "unicode-xid", 673 | ] 674 | 675 | [[package]] 676 | name = "quote" 677 | version = "1.0.9" 678 | source = "registry+https://github.com/rust-lang/crates.io-index" 679 | checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" 680 | dependencies = [ 681 | "proc-macro2", 682 | ] 683 | 684 | [[package]] 685 | name = "rand" 686 | version = "0.8.3" 687 | source = "registry+https://github.com/rust-lang/crates.io-index" 688 | checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" 689 | dependencies = [ 690 | "libc", 691 | "rand_chacha", 692 | "rand_core", 693 | "rand_hc", 694 | ] 695 | 696 | [[package]] 697 | name = "rand_chacha" 698 | version = "0.3.1" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 701 | dependencies = [ 702 | "ppv-lite86", 703 | "rand_core", 704 | ] 705 | 706 | [[package]] 707 | name = "rand_core" 708 | version = "0.6.2" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" 711 | dependencies = [ 712 | "getrandom", 713 | ] 714 | 715 | [[package]] 716 | name = "rand_hc" 717 | version = "0.3.0" 718 | source = "registry+https://github.com/rust-lang/crates.io-index" 719 | checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" 720 | dependencies = [ 721 | "rand_core", 722 | ] 723 | 724 | [[package]] 725 | name = "redox_syscall" 726 | version = "0.2.8" 727 | source = "registry+https://github.com/rust-lang/crates.io-index" 728 | checksum = "742739e41cd49414de871ea5e549afb7e2a3ac77b589bcbebe8c82fab37147fc" 729 | dependencies = [ 730 | "bitflags", 731 | ] 732 | 733 | [[package]] 734 | name = "regex" 735 | version = "1.5.4" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" 738 | dependencies = [ 739 | "regex-syntax", 740 | ] 741 | 742 | [[package]] 743 | name = "regex-syntax" 744 | version = "0.6.25" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 747 | 748 | [[package]] 749 | name = "remove_dir_all" 750 | version = "0.5.3" 751 | source = "registry+https://github.com/rust-lang/crates.io-index" 752 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 753 | dependencies = [ 754 | "winapi", 755 | ] 756 | 757 | [[package]] 758 | name = "reqwest" 759 | version = "0.11.3" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "2296f2fac53979e8ccbc4a1136b25dcefd37be9ed7e4a1f6b05a6029c84ff124" 762 | dependencies = [ 763 | "base64", 764 | "bytes", 765 | "encoding_rs", 766 | "futures-core", 767 | "futures-util", 768 | "http", 769 | "http-body", 770 | "hyper", 771 | "hyper-tls", 772 | "ipnet", 773 | "js-sys", 774 | "lazy_static", 775 | "log", 776 | "mime", 777 | "native-tls", 778 | "percent-encoding", 779 | "pin-project-lite", 780 | "serde", 781 | "serde_json", 782 | "serde_urlencoded", 783 | "tokio", 784 | "tokio-native-tls", 785 | "url", 786 | "wasm-bindgen", 787 | "wasm-bindgen-futures", 788 | "web-sys", 789 | "winreg", 790 | ] 791 | 792 | [[package]] 793 | name = "ryu" 794 | version = "1.0.5" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 797 | 798 | [[package]] 799 | name = "schannel" 800 | version = "0.1.19" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" 803 | dependencies = [ 804 | "lazy_static", 805 | "winapi", 806 | ] 807 | 808 | [[package]] 809 | name = "scopeguard" 810 | version = "1.1.0" 811 | source = "registry+https://github.com/rust-lang/crates.io-index" 812 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 813 | 814 | [[package]] 815 | name = "security-framework" 816 | version = "2.3.1" 817 | source = "registry+https://github.com/rust-lang/crates.io-index" 818 | checksum = "23a2ac85147a3a11d77ecf1bc7166ec0b92febfa4461c37944e180f319ece467" 819 | dependencies = [ 820 | "bitflags", 821 | "core-foundation", 822 | "core-foundation-sys", 823 | "libc", 824 | "security-framework-sys", 825 | ] 826 | 827 | [[package]] 828 | name = "security-framework-sys" 829 | version = "2.3.0" 830 | source = "registry+https://github.com/rust-lang/crates.io-index" 831 | checksum = "7e4effb91b4b8b6fb7732e670b6cee160278ff8e6bf485c7805d9e319d76e284" 832 | dependencies = [ 833 | "core-foundation-sys", 834 | "libc", 835 | ] 836 | 837 | [[package]] 838 | name = "serde" 839 | version = "1.0.126" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "ec7505abeacaec74ae4778d9d9328fe5a5d04253220a85c4ee022239fc996d03" 842 | 843 | [[package]] 844 | name = "serde_json" 845 | version = "1.0.64" 846 | source = "registry+https://github.com/rust-lang/crates.io-index" 847 | checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" 848 | dependencies = [ 849 | "itoa", 850 | "ryu", 851 | "serde", 852 | ] 853 | 854 | [[package]] 855 | name = "serde_urlencoded" 856 | version = "0.7.0" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" 859 | dependencies = [ 860 | "form_urlencoded", 861 | "itoa", 862 | "ryu", 863 | "serde", 864 | ] 865 | 866 | [[package]] 867 | name = "signal-hook-registry" 868 | version = "1.4.0" 869 | source = "registry+https://github.com/rust-lang/crates.io-index" 870 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 871 | dependencies = [ 872 | "libc", 873 | ] 874 | 875 | [[package]] 876 | name = "slab" 877 | version = "0.4.3" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" 880 | 881 | [[package]] 882 | name = "smallvec" 883 | version = "1.6.1" 884 | source = "registry+https://github.com/rust-lang/crates.io-index" 885 | checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" 886 | 887 | [[package]] 888 | name = "socket2" 889 | version = "0.4.0" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2" 892 | dependencies = [ 893 | "libc", 894 | "winapi", 895 | ] 896 | 897 | [[package]] 898 | name = "strsim" 899 | version = "0.8.0" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 902 | 903 | [[package]] 904 | name = "structopt" 905 | version = "0.3.21" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c" 908 | dependencies = [ 909 | "clap", 910 | "lazy_static", 911 | "structopt-derive", 912 | ] 913 | 914 | [[package]] 915 | name = "structopt-derive" 916 | version = "0.4.14" 917 | source = "registry+https://github.com/rust-lang/crates.io-index" 918 | checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" 919 | dependencies = [ 920 | "heck", 921 | "proc-macro-error", 922 | "proc-macro2", 923 | "quote", 924 | "syn", 925 | ] 926 | 927 | [[package]] 928 | name = "syn" 929 | version = "1.0.73" 930 | source = "registry+https://github.com/rust-lang/crates.io-index" 931 | checksum = "f71489ff30030d2ae598524f61326b902466f72a0fb1a8564c001cc63425bcc7" 932 | dependencies = [ 933 | "proc-macro2", 934 | "quote", 935 | "unicode-xid", 936 | ] 937 | 938 | [[package]] 939 | name = "tempfile" 940 | version = "3.2.0" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" 943 | dependencies = [ 944 | "cfg-if", 945 | "libc", 946 | "rand", 947 | "redox_syscall", 948 | "remove_dir_all", 949 | "winapi", 950 | ] 951 | 952 | [[package]] 953 | name = "terminal_size" 954 | version = "0.1.17" 955 | source = "registry+https://github.com/rust-lang/crates.io-index" 956 | checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" 957 | dependencies = [ 958 | "libc", 959 | "winapi", 960 | ] 961 | 962 | [[package]] 963 | name = "textwrap" 964 | version = "0.11.0" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 967 | dependencies = [ 968 | "unicode-width", 969 | ] 970 | 971 | [[package]] 972 | name = "thiserror" 973 | version = "1.0.25" 974 | source = "registry+https://github.com/rust-lang/crates.io-index" 975 | checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" 976 | dependencies = [ 977 | "thiserror-impl", 978 | ] 979 | 980 | [[package]] 981 | name = "thiserror-impl" 982 | version = "1.0.25" 983 | source = "registry+https://github.com/rust-lang/crates.io-index" 984 | checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" 985 | dependencies = [ 986 | "proc-macro2", 987 | "quote", 988 | "syn", 989 | ] 990 | 991 | [[package]] 992 | name = "tinyvec" 993 | version = "1.2.0" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "5b5220f05bb7de7f3f53c7c065e1199b3172696fe2db9f9c4d8ad9b4ee74c342" 996 | dependencies = [ 997 | "tinyvec_macros", 998 | ] 999 | 1000 | [[package]] 1001 | name = "tinyvec_macros" 1002 | version = "0.1.0" 1003 | source = "registry+https://github.com/rust-lang/crates.io-index" 1004 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 1005 | 1006 | [[package]] 1007 | name = "tokio" 1008 | version = "1.6.2" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | checksum = "aea337f72e96efe29acc234d803a5981cd9a2b6ed21655cd7fc21cfe021e8ec7" 1011 | dependencies = [ 1012 | "autocfg", 1013 | "bytes", 1014 | "libc", 1015 | "memchr", 1016 | "mio", 1017 | "num_cpus", 1018 | "once_cell", 1019 | "parking_lot", 1020 | "pin-project-lite", 1021 | "signal-hook-registry", 1022 | "tokio-macros", 1023 | "winapi", 1024 | ] 1025 | 1026 | [[package]] 1027 | name = "tokio-macros" 1028 | version = "1.2.0" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "c49e3df43841dafb86046472506755d8501c5615673955f6aa17181125d13c37" 1031 | dependencies = [ 1032 | "proc-macro2", 1033 | "quote", 1034 | "syn", 1035 | ] 1036 | 1037 | [[package]] 1038 | name = "tokio-native-tls" 1039 | version = "0.3.0" 1040 | source = "registry+https://github.com/rust-lang/crates.io-index" 1041 | checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" 1042 | dependencies = [ 1043 | "native-tls", 1044 | "tokio", 1045 | ] 1046 | 1047 | [[package]] 1048 | name = "tokio-util" 1049 | version = "0.6.7" 1050 | source = "registry+https://github.com/rust-lang/crates.io-index" 1051 | checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592" 1052 | dependencies = [ 1053 | "bytes", 1054 | "futures-core", 1055 | "futures-sink", 1056 | "log", 1057 | "pin-project-lite", 1058 | "tokio", 1059 | ] 1060 | 1061 | [[package]] 1062 | name = "tower-service" 1063 | version = "0.3.1" 1064 | source = "registry+https://github.com/rust-lang/crates.io-index" 1065 | checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" 1066 | 1067 | [[package]] 1068 | name = "tracing" 1069 | version = "0.1.26" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | checksum = "09adeb8c97449311ccd28a427f96fb563e7fd31aabf994189879d9da2394b89d" 1072 | dependencies = [ 1073 | "cfg-if", 1074 | "pin-project-lite", 1075 | "tracing-core", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "tracing-core" 1080 | version = "0.1.18" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "a9ff14f98b1a4b289c6248a023c1c2fa1491062964e9fed67ab29c4e4da4a052" 1083 | dependencies = [ 1084 | "lazy_static", 1085 | ] 1086 | 1087 | [[package]] 1088 | name = "try-lock" 1089 | version = "0.2.3" 1090 | source = "registry+https://github.com/rust-lang/crates.io-index" 1091 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 1092 | 1093 | [[package]] 1094 | name = "unicode-bidi" 1095 | version = "0.3.5" 1096 | source = "registry+https://github.com/rust-lang/crates.io-index" 1097 | checksum = "eeb8be209bb1c96b7c177c7420d26e04eccacb0eeae6b980e35fcb74678107e0" 1098 | dependencies = [ 1099 | "matches", 1100 | ] 1101 | 1102 | [[package]] 1103 | name = "unicode-normalization" 1104 | version = "0.1.19" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" 1107 | dependencies = [ 1108 | "tinyvec", 1109 | ] 1110 | 1111 | [[package]] 1112 | name = "unicode-segmentation" 1113 | version = "1.7.1" 1114 | source = "registry+https://github.com/rust-lang/crates.io-index" 1115 | checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" 1116 | 1117 | [[package]] 1118 | name = "unicode-width" 1119 | version = "0.1.8" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" 1122 | 1123 | [[package]] 1124 | name = "unicode-xid" 1125 | version = "0.2.2" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 1128 | 1129 | [[package]] 1130 | name = "url" 1131 | version = "2.2.2" 1132 | source = "registry+https://github.com/rust-lang/crates.io-index" 1133 | checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" 1134 | dependencies = [ 1135 | "form_urlencoded", 1136 | "idna", 1137 | "matches", 1138 | "percent-encoding", 1139 | ] 1140 | 1141 | [[package]] 1142 | name = "vcpkg" 1143 | version = "0.2.13" 1144 | source = "registry+https://github.com/rust-lang/crates.io-index" 1145 | checksum = "025ce40a007e1907e58d5bc1a594def78e5573bb0b1160bc389634e8f12e4faa" 1146 | 1147 | [[package]] 1148 | name = "vec_map" 1149 | version = "0.8.2" 1150 | source = "registry+https://github.com/rust-lang/crates.io-index" 1151 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 1152 | 1153 | [[package]] 1154 | name = "version_check" 1155 | version = "0.9.3" 1156 | source = "registry+https://github.com/rust-lang/crates.io-index" 1157 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 1158 | 1159 | [[package]] 1160 | name = "want" 1161 | version = "0.3.0" 1162 | source = "registry+https://github.com/rust-lang/crates.io-index" 1163 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1164 | dependencies = [ 1165 | "log", 1166 | "try-lock", 1167 | ] 1168 | 1169 | [[package]] 1170 | name = "wasi" 1171 | version = "0.10.2+wasi-snapshot-preview1" 1172 | source = "registry+https://github.com/rust-lang/crates.io-index" 1173 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 1174 | 1175 | [[package]] 1176 | name = "wasm-bindgen" 1177 | version = "0.2.74" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | checksum = "d54ee1d4ed486f78874278e63e4069fc1ab9f6a18ca492076ffb90c5eb2997fd" 1180 | dependencies = [ 1181 | "cfg-if", 1182 | "serde", 1183 | "serde_json", 1184 | "wasm-bindgen-macro", 1185 | ] 1186 | 1187 | [[package]] 1188 | name = "wasm-bindgen-backend" 1189 | version = "0.2.74" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "3b33f6a0694ccfea53d94db8b2ed1c3a8a4c86dd936b13b9f0a15ec4a451b900" 1192 | dependencies = [ 1193 | "bumpalo", 1194 | "lazy_static", 1195 | "log", 1196 | "proc-macro2", 1197 | "quote", 1198 | "syn", 1199 | "wasm-bindgen-shared", 1200 | ] 1201 | 1202 | [[package]] 1203 | name = "wasm-bindgen-futures" 1204 | version = "0.4.24" 1205 | source = "registry+https://github.com/rust-lang/crates.io-index" 1206 | checksum = "5fba7978c679d53ce2d0ac80c8c175840feb849a161664365d1287b41f2e67f1" 1207 | dependencies = [ 1208 | "cfg-if", 1209 | "js-sys", 1210 | "wasm-bindgen", 1211 | "web-sys", 1212 | ] 1213 | 1214 | [[package]] 1215 | name = "wasm-bindgen-macro" 1216 | version = "0.2.74" 1217 | source = "registry+https://github.com/rust-lang/crates.io-index" 1218 | checksum = "088169ca61430fe1e58b8096c24975251700e7b1f6fd91cc9d59b04fb9b18bd4" 1219 | dependencies = [ 1220 | "quote", 1221 | "wasm-bindgen-macro-support", 1222 | ] 1223 | 1224 | [[package]] 1225 | name = "wasm-bindgen-macro-support" 1226 | version = "0.2.74" 1227 | source = "registry+https://github.com/rust-lang/crates.io-index" 1228 | checksum = "be2241542ff3d9f241f5e2cb6dd09b37efe786df8851c54957683a49f0987a97" 1229 | dependencies = [ 1230 | "proc-macro2", 1231 | "quote", 1232 | "syn", 1233 | "wasm-bindgen-backend", 1234 | "wasm-bindgen-shared", 1235 | ] 1236 | 1237 | [[package]] 1238 | name = "wasm-bindgen-shared" 1239 | version = "0.2.74" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "d7cff876b8f18eed75a66cf49b65e7f967cb354a7aa16003fb55dbfd25b44b4f" 1242 | 1243 | [[package]] 1244 | name = "web-sys" 1245 | version = "0.3.51" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | checksum = "e828417b379f3df7111d3a2a9e5753706cae29c41f7c4029ee9fd77f3e09e582" 1248 | dependencies = [ 1249 | "js-sys", 1250 | "wasm-bindgen", 1251 | ] 1252 | 1253 | [[package]] 1254 | name = "winapi" 1255 | version = "0.3.9" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1258 | dependencies = [ 1259 | "winapi-i686-pc-windows-gnu", 1260 | "winapi-x86_64-pc-windows-gnu", 1261 | ] 1262 | 1263 | [[package]] 1264 | name = "winapi-i686-pc-windows-gnu" 1265 | version = "0.4.0" 1266 | source = "registry+https://github.com/rust-lang/crates.io-index" 1267 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1268 | 1269 | [[package]] 1270 | name = "winapi-x86_64-pc-windows-gnu" 1271 | version = "0.4.0" 1272 | source = "registry+https://github.com/rust-lang/crates.io-index" 1273 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1274 | 1275 | [[package]] 1276 | name = "winreg" 1277 | version = "0.7.0" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" 1280 | dependencies = [ 1281 | "winapi", 1282 | ] 1283 | 1284 | [[package]] 1285 | name = "zeroize" 1286 | version = "1.3.0" 1287 | source = "registry+https://github.com/rust-lang/crates.io-index" 1288 | checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" 1289 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "github-bin-downloader" 3 | version = "0.1.2" 4 | authors = ["353fc443 <353fc443@pm.me>"] 5 | edition = "2018" 6 | license = "GPL-3.0" 7 | readme = "README.md" 8 | repository = "https://github.com/353fc443/github-bin-downloader" 9 | description = "Download binary for your OS from Github." 10 | exclude = [ 11 | ".github/", 12 | "static", 13 | ] 14 | 15 | [dependencies] 16 | reqwest = { version = "0.11", features = ["json"] } 17 | tokio = { version = "1", features = ["full"] } 18 | serde_json = "1.0" 19 | thiserror = "1.0" 20 | indicatif = " 0.16.2" 21 | nix = "0.21.0" 22 | structopt = "0.3" 23 | dialoguer = "0.8.0" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | 676 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![releaser](https://github.com/353fc443/github-bin-downloader/actions/workflows/release.yaml/badge.svg)](https://github.com/353fc443/github-bin-downloader/actions/workflows/release.yaml) 2 | [![GitHub license](https://img.shields.io/github/license/353fc443/github-bin-downloader)](https://github.com/353fc443/github-bin-downloader/blob/main/LICENSE) 3 | Version info
4 | 5 | # github-bin-downloader 6 | 7 | Download binary for your OS from Github. 8 | ## Installation 9 | 10 | Install github-bin-downloader using cargo 11 | 12 | ```shell 13 | cargo install github-bin-downloader 14 | ``` 15 | 16 | ## Demo 17 | 18 | ![Demo](static/demo.gif) 19 | 20 | ## Usage 21 | 22 | ```shell 23 | github-bin-downloader 0.1.0 24 | 25 | USAGE: 26 | github-bin-downloader [FLAGS] --url 27 | 28 | FLAGS: 29 | -h, --help Prints help information 30 | --latest Check for the latest release including prerelease 31 | --list View all files as a list 32 | -V, --version Prints version information 33 | 34 | OPTIONS: 35 | -u, --url Github repository URL 36 | ``` 37 | 38 | ## License 39 | [GNU GPL](https://choosealicense.com/licenses/gpl-3.0/) 40 | -------------------------------------------------------------------------------- /src/cli.rs: -------------------------------------------------------------------------------- 1 | use dialoguer::Select; 2 | use structopt::StructOpt; 3 | 4 | use crate::ghapi::Release; 5 | use crate::show_error; 6 | use crate::GBDResult; 7 | 8 | #[derive(StructOpt, Debug)] 9 | #[structopt( 10 | name = "github-bin-downloader", 11 | about = "Download binary for your OS from Github releases." 12 | )] 13 | pub struct Opt { 14 | #[structopt(short, long, required = true, help = "Github repository URL")] 15 | pub url: String, 16 | #[structopt(long, help = "Check for the latest release including prerelease")] 17 | pub latest: bool, 18 | #[structopt(long, help = "View all files as a list")] 19 | pub list: bool, 20 | } 21 | 22 | pub fn run_cli() -> Opt { 23 | Opt::from_args() 24 | } 25 | 26 | pub async fn display_all_options(releases: &[Release]) -> GBDResult { 27 | if releases.is_empty() { 28 | show_error!("No releases available!"); 29 | std::process::exit(1) 30 | } 31 | println!("Select the release you want to download!"); 32 | let selection = Select::new().items(&releases).default(0).interact()?; 33 | Ok(releases[selection].clone()) 34 | } 35 | -------------------------------------------------------------------------------- /src/ghapi.rs: -------------------------------------------------------------------------------- 1 | use crate::sysinfo; 2 | use crate::utils; 3 | 4 | use crate::GBDResult; 5 | use reqwest::{StatusCode, Url}; 6 | use serde_json::Value; 7 | use thiserror::Error; 8 | 9 | #[derive(Debug, Default)] 10 | pub struct RepoInfo { 11 | user_name: String, 12 | repo_name: String, 13 | url: String, 14 | releases_api_url: String, 15 | pub releases: Vec, 16 | } 17 | 18 | #[derive(Clone, Debug, PartialEq)] 19 | pub struct Release { 20 | pub name: String, 21 | pub url: String, 22 | } 23 | 24 | impl Release { 25 | // Download the release 26 | pub async fn download_release(&self) -> GBDResult<()> { 27 | let url = Url::parse(self.url.as_str())?; 28 | println!("Downloading {} from {}", self.name, url); 29 | utils::download_file_from_url(url, &self.name).await?; 30 | Ok(()) 31 | } 32 | } 33 | 34 | impl ToString for Release { 35 | fn to_string(&self) -> String { 36 | self.name.to_string() 37 | } 38 | } 39 | 40 | #[derive(Error, Debug)] 41 | pub enum GithubError { 42 | #[error("Repo Not Found")] 43 | NotFound(StatusCode), 44 | } 45 | 46 | impl RepoInfo { 47 | pub async fn from_url(url: &str) -> GBDResult { 48 | let mut url = url.to_string(); 49 | if !url.contains("https://") && !url.contains("http://") { 50 | url = format!("https://{}", url); 51 | } 52 | if !url.contains("github") { 53 | return Err(Box::new(GithubError::NotFound(StatusCode::NOT_IMPLEMENTED))); 54 | } 55 | let resp = reqwest::get(&url).await?; 56 | if resp.status() == StatusCode::OK { 57 | let path = resp.url().path(); 58 | let repoinfo_vec: Vec<&str> = path.split('/').collect(); 59 | let releases_api_url = format!( 60 | "https://api.github.com/repos/{}/{}/releases", 61 | repoinfo_vec[1].to_string(), 62 | repoinfo_vec[2].to_string() 63 | ); 64 | Ok(RepoInfo { 65 | user_name: repoinfo_vec[1].to_string(), 66 | repo_name: repoinfo_vec[2].to_string(), 67 | url, 68 | releases_api_url, 69 | ..Default::default() 70 | }) 71 | } else { 72 | Err(Box::new(GithubError::NotFound(resp.status()))) 73 | } 74 | } 75 | 76 | // Fetch the latest release from Github including Pre-release 77 | pub async fn get_latest_release(&mut self) -> GBDResult<()> { 78 | let client = reqwest::Client::builder() 79 | .user_agent("github-bin-downloader") 80 | .build()?; 81 | let resp = client 82 | .get(&self.releases_api_url) 83 | .send() 84 | .await? 85 | .text() 86 | .await?; 87 | let repo: Value = serde_json::from_str(&resp)?; 88 | let length = repo[0]["assets"] 89 | .as_array() 90 | .expect("Cannot convert to Array") 91 | .len(); 92 | let mut releases: Vec = Vec::new(); 93 | for i in 0..length { 94 | releases.push(Release { 95 | name: utils::sanitize_str_to_string(&repo[0]["assets"][i]["name"]), 96 | url: utils::sanitize_str_to_string(&repo[0]["assets"][i]["browser_download_url"]), 97 | }); 98 | } 99 | self.releases = releases; 100 | Ok(()) 101 | } 102 | 103 | // Get all the latest stable releases from Github releases 104 | pub async fn get_latest_stable_release(&mut self) -> GBDResult<()> { 105 | let client = reqwest::Client::builder() 106 | .user_agent("github-bin-downloader") 107 | .build()?; 108 | let resp = client 109 | .get(&self.releases_api_url) 110 | .send() 111 | .await? 112 | .text() 113 | .await?; 114 | let repo: Value = serde_json::from_str(&resp)?; 115 | let length = repo.as_array().expect("Cannot convert to Array").len(); 116 | let mut releases: Vec = Vec::new(); 117 | for i in 0..length { 118 | if !repo[i]["prerelease"] 119 | .as_bool() 120 | .expect("Cannot convert to bool") 121 | { 122 | let length = repo[i]["assets"] 123 | .as_array() 124 | .expect("Cannot convert to Array") 125 | .len(); 126 | for j in 0..length { 127 | releases.push(Release { 128 | name: utils::sanitize_str_to_string(&repo[i]["assets"][j]["name"]), 129 | url: utils::sanitize_str_to_string( 130 | &repo[i]["assets"][j]["browser_download_url"], 131 | ), 132 | }); 133 | } 134 | self.releases = releases; 135 | return Ok(()); 136 | } 137 | } 138 | Ok(()) 139 | } 140 | 141 | // Search the releases for the host OS 142 | pub async fn search_releases_for_os(&self) -> GBDResult> { 143 | let sys_info = sysinfo::SystemInfo::new(); 144 | let mut releases: Vec = Vec::new(); 145 | match sys_info.platform_os() { 146 | sysinfo::PlatformOS::Darwin => { 147 | sysinfo::APPLE.iter().for_each(|mac| { 148 | self.releases.iter().for_each(|release| { 149 | if release.name.to_lowercase().contains(mac) { 150 | releases.push(release.clone()); 151 | } 152 | }); 153 | }); 154 | } 155 | sysinfo::PlatformOS::Linux => { 156 | sysinfo::LINUX.iter().for_each(|linux| { 157 | self.releases.iter().for_each(|release| { 158 | if release.name.to_lowercase().contains(linux) { 159 | releases.push(release.clone()); 160 | } 161 | }); 162 | }); 163 | } 164 | _ => {} 165 | } 166 | Ok(releases) 167 | } 168 | 169 | // Search the releases for the host Arch 170 | pub async fn search_releases_for_arch(&self) -> GBDResult> { 171 | let sys_info = sysinfo::SystemInfo::new(); 172 | let mut releases: Vec = Vec::new(); 173 | match sys_info.platform_arch() { 174 | sysinfo::PlatformArch::X8664 => { 175 | sysinfo::AMD64.iter().for_each(|arch| { 176 | self.releases.iter().for_each(|release| { 177 | if release.name.contains(arch) { 178 | releases.push(release.clone()); 179 | } 180 | }); 181 | }); 182 | } 183 | sysinfo::PlatformArch::Arm64 => { 184 | sysinfo::ARM64.iter().for_each(|arch| { 185 | self.releases.iter().for_each(|release| { 186 | if release.name.contains(arch) { 187 | releases.push(release.clone()); 188 | } 189 | }); 190 | }); 191 | } 192 | _ => {} 193 | } 194 | Ok(releases) 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | pub type GBDResult = std::result::Result>; 2 | 3 | pub mod cli; 4 | pub mod ghapi; 5 | pub mod sysinfo; 6 | pub mod utils; 7 | 8 | #[macro_export] 9 | macro_rules! show_error( 10 | ($($args:tt)+) => ({ 11 | eprintln!($($args)+); 12 | }) 13 | ); 14 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use github_bin_downloader::{cli, ghapi, show_error, utils, GBDResult}; 2 | 3 | #[tokio::main] 4 | async fn main() -> GBDResult<()> { 5 | let opt = cli::run_cli(); 6 | let mut repo = ghapi::RepoInfo::from_url(&opt.url).await?; 7 | if opt.latest { 8 | repo.get_latest_release().await?; 9 | if opt.list { 10 | cli::display_all_options(&repo.releases) 11 | .await? 12 | .download_release() 13 | .await?; 14 | return Ok(()); 15 | } 16 | match utils::compare_two_vector( 17 | &repo.search_releases_for_os().await?, 18 | &repo.search_releases_for_arch().await?, 19 | ) { 20 | Some(releases) => { 21 | cli::display_all_options(&releases).await? 22 | .download_release().await?; 23 | return Ok(()); 24 | }, 25 | None => show_error!("Cannot find a release for your OS and Arch\n Use --list flag to list all available options"), 26 | } 27 | } else { 28 | repo.get_latest_stable_release().await?; 29 | if opt.list { 30 | cli::display_all_options(&repo.releases) 31 | .await? 32 | .download_release() 33 | .await?; 34 | return Ok(()); 35 | } 36 | match utils::compare_two_vector( 37 | &repo.search_releases_for_os().await?, 38 | &repo.search_releases_for_arch().await?, 39 | ) { 40 | Some(releases) => { 41 | cli::display_all_options(&releases).await? 42 | .download_release().await?; 43 | return Ok(()); 44 | }, 45 | None => show_error!("Cannot find a release for your OS and Arch\n Use --list flag to list all available options"), 46 | } 47 | } 48 | Ok(()) 49 | } 50 | -------------------------------------------------------------------------------- /src/sysinfo.rs: -------------------------------------------------------------------------------- 1 | use nix::sys::utsname; 2 | 3 | pub const APPLE: [&str; 4] = ["macos", "darwin", "mac", "dmg"]; 4 | pub const LINUX: [&str; 1] = ["linux"]; 5 | pub const AMD64: [&str; 4] = ["x64", "x86_64", "amd64", "64bit"]; 6 | pub const ARM64: [&str; 2] = ["aarch64", "arm64"]; 7 | 8 | #[derive(Debug, Default)] 9 | pub struct SystemInfo { 10 | pub arch: String, 11 | pub os: String, 12 | } 13 | 14 | #[derive(Debug)] 15 | pub enum PlatformOS { 16 | Windows, 17 | Linux, 18 | Darwin, 19 | Unknown, 20 | } 21 | 22 | #[derive(Debug)] 23 | pub enum PlatformArch { 24 | X8664, 25 | Arm64, 26 | Unknown, 27 | } 28 | 29 | impl SystemInfo { 30 | pub fn new() -> Self { 31 | let uts_name = utsname::uname(); 32 | Self { 33 | os: uts_name.sysname().to_lowercase(), 34 | arch: uts_name.machine().to_lowercase(), 35 | } 36 | } 37 | 38 | pub fn platform_os(&self) -> PlatformOS { 39 | for apple in APPLE.iter() { 40 | if self.os.contains(apple) { 41 | return PlatformOS::Darwin; 42 | } 43 | } 44 | for linux in LINUX.iter() { 45 | if self.os.contains(linux) { 46 | return PlatformOS::Linux; 47 | } 48 | } 49 | PlatformOS::Unknown 50 | } 51 | 52 | pub fn platform_arch(&self) -> PlatformArch { 53 | for amd64 in AMD64.iter() { 54 | if self.arch.contains(amd64) { 55 | return PlatformArch::X8664; 56 | } 57 | } 58 | 59 | for arm64 in ARM64.iter() { 60 | if self.arch.contains(arm64) { 61 | return PlatformArch::Arm64; 62 | } 63 | } 64 | PlatformArch::Unknown 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | use crate::GBDResult; 2 | use indicatif::{ProgressBar, ProgressStyle}; 3 | use reqwest::IntoUrl; 4 | use serde_json::Value; 5 | use std::{cmp::min, fs::File, io::Write}; 6 | 7 | pub fn humanize_bytes(bytes: u64) -> String { 8 | let values = ["bytes", "KB", "MB", "GB", "TB"]; 9 | let pair = values 10 | .iter() 11 | .enumerate() 12 | .take_while(|x| bytes as usize / (1000_usize).pow(x.0 as u32) > 10) 13 | .last(); 14 | if let Some((i, unit)) = pair { 15 | format!("{} {}", bytes as usize / (1000_usize).pow(i as u32), unit) 16 | } else { 17 | format!("{} {}", bytes, values[0]) 18 | } 19 | } 20 | 21 | pub fn trim_newline(mut s: String) -> String { 22 | if s.ends_with('\n') { 23 | s.pop(); 24 | if s.ends_with('\r') { 25 | s.pop(); 26 | } 27 | } 28 | s 29 | } 30 | 31 | pub fn compare_two_vector(vec1: &[T], vec2: &[T]) -> Option> 32 | where 33 | T: PartialEq + Clone, 34 | { 35 | let mut result: Vec = Vec::new(); 36 | for v1 in vec1 { 37 | for v2 in vec2 { 38 | if v1 == v2 { 39 | result.push(v1.clone()); 40 | } 41 | } 42 | } 43 | if !result.is_empty() { 44 | Some(result) 45 | } else { 46 | None 47 | } 48 | } 49 | 50 | pub fn sanitize_str_to_string(string: &Value) -> String { 51 | string.to_string().replace('"', "") 52 | } 53 | 54 | pub async fn download_file_from_url(url: T, name: &str) -> GBDResult<()> 55 | where 56 | T: IntoUrl, 57 | { 58 | let mut resp = reqwest::get(url).await?; 59 | resp.content_length(); 60 | let mut f = File::create(name)?; 61 | let mut downloaded = 0; 62 | let total_size = resp 63 | .content_length() 64 | .expect("Cannot determine size of the content!"); 65 | let pb = ProgressBar::new(total_size); 66 | pb.set_style(ProgressStyle::default_bar() 67 | .template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta})") 68 | .progress_chars("#>-")); 69 | while let Some(chunk) = resp.chunk().await? { 70 | let new = min(downloaded + chunk.len() as u64, total_size); 71 | downloaded = new; 72 | pb.set_position(new); 73 | f.write_all(&chunk[..])?; 74 | } 75 | Ok(()) 76 | } 77 | -------------------------------------------------------------------------------- /static/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefins/github-bin-downloader/2089ddbbafe1c268f35e747404364da53a25ee80/static/demo.gif --------------------------------------------------------------------------------