├── .github └── workflows │ └── build.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── Cartfile ├── Cartfile.resolved ├── Makefile ├── Punfile ├── README.md ├── assets ├── demo.gif └── elephant_2.png └── src ├── cache.rs ├── cache └── s3.rs ├── commands.rs ├── lib.rs ├── main.rs ├── punfile.rs ├── utils.rs └── utils ├── archive.rs ├── download.rs ├── scan.rs └── upload.rs /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build punic 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | 9 | jobs: 10 | build_and_test: 11 | name: Rust project 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v2 15 | - uses: actions-rs/toolchain@v1 16 | with: 17 | toolchain: stable 18 | - uses: actions-rs/cargo@v1 19 | with: 20 | command: build 21 | args: --release --all-features 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .DS_Store 3 | .idea 4 | *.orig 5 | /Carthage 6 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "adler32" 5 | version = "1.2.0" 6 | source = "registry+https://github.com/rust-lang/crates.io-index" 7 | checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" 8 | 9 | [[package]] 10 | name = "aho-corasick" 11 | version = "0.7.15" 12 | source = "registry+https://github.com/rust-lang/crates.io-index" 13 | checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" 14 | dependencies = [ 15 | "memchr", 16 | ] 17 | 18 | [[package]] 19 | name = "ansi_term" 20 | version = "0.11.0" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" 23 | dependencies = [ 24 | "winapi", 25 | ] 26 | 27 | [[package]] 28 | name = "async-channel" 29 | version = "1.6.1" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" 32 | dependencies = [ 33 | "concurrent-queue", 34 | "event-listener", 35 | "futures-core", 36 | ] 37 | 38 | [[package]] 39 | name = "async-executor" 40 | version = "1.4.0" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "eb877970c7b440ead138f6321a3b5395d6061183af779340b65e20c0fede9146" 43 | dependencies = [ 44 | "async-task", 45 | "concurrent-queue", 46 | "fastrand", 47 | "futures-lite", 48 | "once_cell", 49 | "vec-arena", 50 | ] 51 | 52 | [[package]] 53 | name = "async-global-executor" 54 | version = "2.0.2" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "9586ec52317f36de58453159d48351bc244bc24ced3effc1fce22f3d48664af6" 57 | dependencies = [ 58 | "async-channel", 59 | "async-executor", 60 | "async-io", 61 | "async-mutex", 62 | "blocking", 63 | "futures-lite", 64 | "num_cpus", 65 | "once_cell", 66 | ] 67 | 68 | [[package]] 69 | name = "async-io" 70 | version = "1.3.1" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "9315f8f07556761c3e48fec2e6b276004acf426e6dc068b2c2251854d65ee0fd" 73 | dependencies = [ 74 | "concurrent-queue", 75 | "fastrand", 76 | "futures-lite", 77 | "libc", 78 | "log", 79 | "nb-connect", 80 | "once_cell", 81 | "parking", 82 | "polling", 83 | "vec-arena", 84 | "waker-fn", 85 | "winapi", 86 | ] 87 | 88 | [[package]] 89 | name = "async-lock" 90 | version = "2.3.0" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "1996609732bde4a9988bc42125f55f2af5f3c36370e27c778d5191a4a1b63bfb" 93 | dependencies = [ 94 | "event-listener", 95 | ] 96 | 97 | [[package]] 98 | name = "async-mutex" 99 | version = "1.4.0" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "479db852db25d9dbf6204e6cb6253698f175c15726470f78af0d918e99d6156e" 102 | dependencies = [ 103 | "event-listener", 104 | ] 105 | 106 | [[package]] 107 | name = "async-std" 108 | version = "1.9.0" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "d9f06685bad74e0570f5213741bea82158279a4103d988e57bfada11ad230341" 111 | dependencies = [ 112 | "async-channel", 113 | "async-global-executor", 114 | "async-io", 115 | "async-lock", 116 | "crossbeam-utils", 117 | "futures-channel", 118 | "futures-core", 119 | "futures-io", 120 | "futures-lite", 121 | "gloo-timers", 122 | "kv-log-macro", 123 | "log", 124 | "memchr", 125 | "num_cpus", 126 | "once_cell", 127 | "pin-project-lite", 128 | "pin-utils", 129 | "slab", 130 | "wasm-bindgen-futures", 131 | ] 132 | 133 | [[package]] 134 | name = "async-task" 135 | version = "4.0.3" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" 138 | 139 | [[package]] 140 | name = "async-trait" 141 | version = "0.1.48" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf" 144 | dependencies = [ 145 | "proc-macro2", 146 | "quote", 147 | "syn", 148 | ] 149 | 150 | [[package]] 151 | name = "atomic-waker" 152 | version = "1.0.0" 153 | source = "registry+https://github.com/rust-lang/crates.io-index" 154 | checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a" 155 | 156 | [[package]] 157 | name = "atty" 158 | version = "0.2.14" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 161 | dependencies = [ 162 | "hermit-abi", 163 | "libc", 164 | "winapi", 165 | ] 166 | 167 | [[package]] 168 | name = "autocfg" 169 | version = "1.0.1" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 172 | 173 | [[package]] 174 | name = "base-x" 175 | version = "0.2.8" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" 178 | 179 | [[package]] 180 | name = "base64" 181 | version = "0.13.0" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 184 | 185 | [[package]] 186 | name = "bitflags" 187 | version = "1.2.1" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" 190 | 191 | [[package]] 192 | name = "block-buffer" 193 | version = "0.9.0" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 196 | dependencies = [ 197 | "generic-array", 198 | ] 199 | 200 | [[package]] 201 | name = "blocking" 202 | version = "1.0.2" 203 | source = "registry+https://github.com/rust-lang/crates.io-index" 204 | checksum = "c5e170dbede1f740736619b776d7251cb1b9095c435c34d8ca9f57fcd2f335e9" 205 | dependencies = [ 206 | "async-channel", 207 | "async-task", 208 | "atomic-waker", 209 | "fastrand", 210 | "futures-lite", 211 | "once_cell", 212 | ] 213 | 214 | [[package]] 215 | name = "bumpalo" 216 | version = "3.6.1" 217 | source = "registry+https://github.com/rust-lang/crates.io-index" 218 | checksum = "63396b8a4b9de3f4fdfb320ab6080762242f66a8ef174c49d8e19b674db4cdbe" 219 | 220 | [[package]] 221 | name = "byteorder" 222 | version = "1.4.2" 223 | source = "registry+https://github.com/rust-lang/crates.io-index" 224 | checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" 225 | 226 | [[package]] 227 | name = "bytes" 228 | version = "1.0.1" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" 231 | 232 | [[package]] 233 | name = "bzip2" 234 | version = "0.3.3" 235 | source = "registry+https://github.com/rust-lang/crates.io-index" 236 | checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" 237 | dependencies = [ 238 | "bzip2-sys", 239 | "libc", 240 | ] 241 | 242 | [[package]] 243 | name = "bzip2-sys" 244 | version = "0.1.10+1.0.8" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "17fa3d1ac1ca21c5c4e36a97f3c3eb25084576f6fc47bf0139c1123434216c6c" 247 | dependencies = [ 248 | "cc", 249 | "libc", 250 | "pkg-config", 251 | ] 252 | 253 | [[package]] 254 | name = "cache-padded" 255 | version = "1.1.1" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba" 258 | 259 | [[package]] 260 | name = "cc" 261 | version = "1.0.67" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" 264 | 265 | [[package]] 266 | name = "cfg-if" 267 | version = "0.1.10" 268 | source = "registry+https://github.com/rust-lang/crates.io-index" 269 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 270 | 271 | [[package]] 272 | name = "cfg-if" 273 | version = "1.0.0" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 276 | 277 | [[package]] 278 | name = "chrono" 279 | version = "0.4.19" 280 | source = "registry+https://github.com/rust-lang/crates.io-index" 281 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" 282 | dependencies = [ 283 | "libc", 284 | "num-integer", 285 | "num-traits", 286 | "serde", 287 | "winapi", 288 | ] 289 | 290 | [[package]] 291 | name = "clap" 292 | version = "2.33.3" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" 295 | dependencies = [ 296 | "ansi_term", 297 | "atty", 298 | "bitflags", 299 | "strsim", 300 | "textwrap", 301 | "unicode-width", 302 | "vec_map", 303 | ] 304 | 305 | [[package]] 306 | name = "concurrent-queue" 307 | version = "1.2.2" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3" 310 | dependencies = [ 311 | "cache-padded", 312 | ] 313 | 314 | [[package]] 315 | name = "const_fn" 316 | version = "0.4.5" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" 319 | 320 | [[package]] 321 | name = "core-foundation" 322 | version = "0.9.1" 323 | source = "registry+https://github.com/rust-lang/crates.io-index" 324 | checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" 325 | dependencies = [ 326 | "core-foundation-sys", 327 | "libc", 328 | ] 329 | 330 | [[package]] 331 | name = "core-foundation-sys" 332 | version = "0.8.2" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" 335 | 336 | [[package]] 337 | name = "cpuid-bool" 338 | version = "0.1.2" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" 341 | 342 | [[package]] 343 | name = "crc32fast" 344 | version = "1.2.1" 345 | source = "registry+https://github.com/rust-lang/crates.io-index" 346 | checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" 347 | dependencies = [ 348 | "cfg-if 1.0.0", 349 | ] 350 | 351 | [[package]] 352 | name = "crossbeam-utils" 353 | version = "0.8.3" 354 | source = "registry+https://github.com/rust-lang/crates.io-index" 355 | checksum = "e7e9d99fa91428effe99c5c6d4634cdeba32b8cf784fc428a2a687f61a952c49" 356 | dependencies = [ 357 | "autocfg", 358 | "cfg-if 1.0.0", 359 | "lazy_static", 360 | ] 361 | 362 | [[package]] 363 | name = "crypto-mac" 364 | version = "0.10.0" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "4857fd85a0c34b3c3297875b747c1e02e06b6a0ea32dd892d8192b9ce0813ea6" 367 | dependencies = [ 368 | "generic-array", 369 | "subtle", 370 | ] 371 | 372 | [[package]] 373 | name = "ctor" 374 | version = "0.1.19" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "e8f45d9ad417bcef4817d614a501ab55cdd96a6fdb24f49aab89a54acfd66b19" 377 | dependencies = [ 378 | "quote", 379 | "syn", 380 | ] 381 | 382 | [[package]] 383 | name = "digest" 384 | version = "0.9.0" 385 | source = "registry+https://github.com/rust-lang/crates.io-index" 386 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 387 | dependencies = [ 388 | "generic-array", 389 | ] 390 | 391 | [[package]] 392 | name = "dirs-next" 393 | version = "2.0.0" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" 396 | dependencies = [ 397 | "cfg-if 1.0.0", 398 | "dirs-sys-next", 399 | ] 400 | 401 | [[package]] 402 | name = "dirs-sys-next" 403 | version = "0.1.2" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" 406 | dependencies = [ 407 | "libc", 408 | "redox_users", 409 | "winapi", 410 | ] 411 | 412 | [[package]] 413 | name = "discard" 414 | version = "1.0.4" 415 | source = "registry+https://github.com/rust-lang/crates.io-index" 416 | checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" 417 | 418 | [[package]] 419 | name = "dtoa" 420 | version = "0.4.7" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e" 423 | 424 | [[package]] 425 | name = "event-listener" 426 | version = "2.5.1" 427 | source = "registry+https://github.com/rust-lang/crates.io-index" 428 | checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" 429 | 430 | [[package]] 431 | name = "fastrand" 432 | version = "1.4.0" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "ca5faf057445ce5c9d4329e382b2ce7ca38550ef3b73a5348362d5f24e0c7fe3" 435 | dependencies = [ 436 | "instant", 437 | ] 438 | 439 | [[package]] 440 | name = "flate2" 441 | version = "1.0.14" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" 444 | dependencies = [ 445 | "cfg-if 0.1.10", 446 | "crc32fast", 447 | "libc", 448 | "miniz_oxide", 449 | ] 450 | 451 | [[package]] 452 | name = "fnv" 453 | version = "1.0.7" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 456 | 457 | [[package]] 458 | name = "foreign-types" 459 | version = "0.3.2" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 462 | dependencies = [ 463 | "foreign-types-shared", 464 | ] 465 | 466 | [[package]] 467 | name = "foreign-types-shared" 468 | version = "0.1.1" 469 | source = "registry+https://github.com/rust-lang/crates.io-index" 470 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 471 | 472 | [[package]] 473 | name = "futures" 474 | version = "0.3.13" 475 | source = "registry+https://github.com/rust-lang/crates.io-index" 476 | checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1" 477 | dependencies = [ 478 | "futures-channel", 479 | "futures-core", 480 | "futures-executor", 481 | "futures-io", 482 | "futures-sink", 483 | "futures-task", 484 | "futures-util", 485 | ] 486 | 487 | [[package]] 488 | name = "futures-channel" 489 | version = "0.3.13" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939" 492 | dependencies = [ 493 | "futures-core", 494 | "futures-sink", 495 | ] 496 | 497 | [[package]] 498 | name = "futures-core" 499 | version = "0.3.13" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94" 502 | 503 | [[package]] 504 | name = "futures-executor" 505 | version = "0.3.13" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "891a4b7b96d84d5940084b2a37632dd65deeae662c114ceaa2c879629c9c0ad1" 508 | dependencies = [ 509 | "futures-core", 510 | "futures-task", 511 | "futures-util", 512 | ] 513 | 514 | [[package]] 515 | name = "futures-io" 516 | version = "0.3.13" 517 | source = "registry+https://github.com/rust-lang/crates.io-index" 518 | checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59" 519 | 520 | [[package]] 521 | name = "futures-lite" 522 | version = "1.11.3" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "b4481d0cd0de1d204a4fa55e7d45f07b1d958abcb06714b3446438e2eff695fb" 525 | dependencies = [ 526 | "fastrand", 527 | "futures-core", 528 | "futures-io", 529 | "memchr", 530 | "parking", 531 | "pin-project-lite", 532 | "waker-fn", 533 | ] 534 | 535 | [[package]] 536 | name = "futures-macro" 537 | version = "0.3.13" 538 | source = "registry+https://github.com/rust-lang/crates.io-index" 539 | checksum = "ea405816a5139fb39af82c2beb921d52143f556038378d6db21183a5c37fbfb7" 540 | dependencies = [ 541 | "proc-macro-hack", 542 | "proc-macro2", 543 | "quote", 544 | "syn", 545 | ] 546 | 547 | [[package]] 548 | name = "futures-sink" 549 | version = "0.3.13" 550 | source = "registry+https://github.com/rust-lang/crates.io-index" 551 | checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3" 552 | 553 | [[package]] 554 | name = "futures-task" 555 | version = "0.3.13" 556 | source = "registry+https://github.com/rust-lang/crates.io-index" 557 | checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80" 558 | 559 | [[package]] 560 | name = "futures-util" 561 | version = "0.3.13" 562 | source = "registry+https://github.com/rust-lang/crates.io-index" 563 | checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1" 564 | dependencies = [ 565 | "futures-channel", 566 | "futures-core", 567 | "futures-io", 568 | "futures-macro", 569 | "futures-sink", 570 | "futures-task", 571 | "memchr", 572 | "pin-project-lite", 573 | "pin-utils", 574 | "proc-macro-hack", 575 | "proc-macro-nested", 576 | "slab", 577 | ] 578 | 579 | [[package]] 580 | name = "generic-array" 581 | version = "0.14.4" 582 | source = "registry+https://github.com/rust-lang/crates.io-index" 583 | checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" 584 | dependencies = [ 585 | "typenum", 586 | "version_check", 587 | ] 588 | 589 | [[package]] 590 | name = "getrandom" 591 | version = "0.2.2" 592 | source = "registry+https://github.com/rust-lang/crates.io-index" 593 | checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" 594 | dependencies = [ 595 | "cfg-if 1.0.0", 596 | "libc", 597 | "wasi", 598 | ] 599 | 600 | [[package]] 601 | name = "gloo-timers" 602 | version = "0.2.1" 603 | source = "registry+https://github.com/rust-lang/crates.io-index" 604 | checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" 605 | dependencies = [ 606 | "futures-channel", 607 | "futures-core", 608 | "js-sys", 609 | "wasm-bindgen", 610 | "web-sys", 611 | ] 612 | 613 | [[package]] 614 | name = "hermit-abi" 615 | version = "0.1.18" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" 618 | dependencies = [ 619 | "libc", 620 | ] 621 | 622 | [[package]] 623 | name = "hex" 624 | version = "0.4.3" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 627 | 628 | [[package]] 629 | name = "hmac" 630 | version = "0.10.1" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" 633 | dependencies = [ 634 | "crypto-mac", 635 | "digest", 636 | ] 637 | 638 | [[package]] 639 | name = "http" 640 | version = "0.2.3" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747" 643 | dependencies = [ 644 | "bytes", 645 | "fnv", 646 | "itoa", 647 | ] 648 | 649 | [[package]] 650 | name = "http-body" 651 | version = "0.4.0" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "2861bd27ee074e5ee891e8b539837a9430012e249d7f0ca2d795650f579c1994" 654 | dependencies = [ 655 | "bytes", 656 | "http", 657 | ] 658 | 659 | [[package]] 660 | name = "httparse" 661 | version = "1.3.5" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691" 664 | 665 | [[package]] 666 | name = "httpdate" 667 | version = "0.3.2" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" 670 | 671 | [[package]] 672 | name = "hyper" 673 | version = "0.14.4" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "e8e946c2b1349055e0b72ae281b238baf1a3ea7307c7e9f9d64673bdd9c26ac7" 676 | dependencies = [ 677 | "bytes", 678 | "futures-channel", 679 | "futures-core", 680 | "futures-util", 681 | "http", 682 | "http-body", 683 | "httparse", 684 | "httpdate", 685 | "itoa", 686 | "pin-project", 687 | "socket2", 688 | "tokio", 689 | "tower-service", 690 | "tracing", 691 | "want", 692 | ] 693 | 694 | [[package]] 695 | name = "hyper-tls" 696 | version = "0.5.0" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 699 | dependencies = [ 700 | "bytes", 701 | "hyper", 702 | "native-tls", 703 | "tokio", 704 | "tokio-native-tls", 705 | ] 706 | 707 | [[package]] 708 | name = "instant" 709 | version = "0.1.9" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" 712 | dependencies = [ 713 | "cfg-if 1.0.0", 714 | ] 715 | 716 | [[package]] 717 | name = "itoa" 718 | version = "0.4.7" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" 721 | 722 | [[package]] 723 | name = "js-sys" 724 | version = "0.3.48" 725 | source = "registry+https://github.com/rust-lang/crates.io-index" 726 | checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78" 727 | dependencies = [ 728 | "wasm-bindgen", 729 | ] 730 | 731 | [[package]] 732 | name = "kv-log-macro" 733 | version = "1.0.7" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" 736 | dependencies = [ 737 | "log", 738 | ] 739 | 740 | [[package]] 741 | name = "lazy_static" 742 | version = "1.4.0" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 745 | 746 | [[package]] 747 | name = "libc" 748 | version = "0.2.88" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a" 751 | 752 | [[package]] 753 | name = "linked-hash-map" 754 | version = "0.5.4" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" 757 | 758 | [[package]] 759 | name = "lock_api" 760 | version = "0.4.2" 761 | source = "registry+https://github.com/rust-lang/crates.io-index" 762 | checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312" 763 | dependencies = [ 764 | "scopeguard", 765 | ] 766 | 767 | [[package]] 768 | name = "log" 769 | version = "0.4.14" 770 | source = "registry+https://github.com/rust-lang/crates.io-index" 771 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" 772 | dependencies = [ 773 | "cfg-if 1.0.0", 774 | "value-bag", 775 | ] 776 | 777 | [[package]] 778 | name = "md5" 779 | version = "0.7.0" 780 | source = "registry+https://github.com/rust-lang/crates.io-index" 781 | checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" 782 | 783 | [[package]] 784 | name = "memchr" 785 | version = "2.3.4" 786 | source = "registry+https://github.com/rust-lang/crates.io-index" 787 | checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" 788 | 789 | [[package]] 790 | name = "miniz_oxide" 791 | version = "0.3.7" 792 | source = "registry+https://github.com/rust-lang/crates.io-index" 793 | checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" 794 | dependencies = [ 795 | "adler32", 796 | ] 797 | 798 | [[package]] 799 | name = "mio" 800 | version = "0.7.9" 801 | source = "registry+https://github.com/rust-lang/crates.io-index" 802 | checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a" 803 | dependencies = [ 804 | "libc", 805 | "log", 806 | "miow", 807 | "ntapi", 808 | "winapi", 809 | ] 810 | 811 | [[package]] 812 | name = "miow" 813 | version = "0.3.6" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" 816 | dependencies = [ 817 | "socket2", 818 | "winapi", 819 | ] 820 | 821 | [[package]] 822 | name = "native-tls" 823 | version = "0.2.7" 824 | source = "registry+https://github.com/rust-lang/crates.io-index" 825 | checksum = "b8d96b2e1c8da3957d58100b09f102c6d9cfdfced01b7ec5a8974044bb09dbd4" 826 | dependencies = [ 827 | "lazy_static", 828 | "libc", 829 | "log", 830 | "openssl", 831 | "openssl-probe", 832 | "openssl-sys", 833 | "schannel", 834 | "security-framework", 835 | "security-framework-sys", 836 | "tempfile", 837 | ] 838 | 839 | [[package]] 840 | name = "nb-connect" 841 | version = "1.0.3" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "670361df1bc2399ee1ff50406a0d422587dd3bb0da596e1978fe8e05dabddf4f" 844 | dependencies = [ 845 | "libc", 846 | "socket2", 847 | ] 848 | 849 | [[package]] 850 | name = "ntapi" 851 | version = "0.3.6" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" 854 | dependencies = [ 855 | "winapi", 856 | ] 857 | 858 | [[package]] 859 | name = "num-integer" 860 | version = "0.1.44" 861 | source = "registry+https://github.com/rust-lang/crates.io-index" 862 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 863 | dependencies = [ 864 | "autocfg", 865 | "num-traits", 866 | ] 867 | 868 | [[package]] 869 | name = "num-traits" 870 | version = "0.2.14" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 873 | dependencies = [ 874 | "autocfg", 875 | ] 876 | 877 | [[package]] 878 | name = "num_cpus" 879 | version = "1.13.0" 880 | source = "registry+https://github.com/rust-lang/crates.io-index" 881 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" 882 | dependencies = [ 883 | "hermit-abi", 884 | "libc", 885 | ] 886 | 887 | [[package]] 888 | name = "once_cell" 889 | version = "1.7.2" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" 892 | 893 | [[package]] 894 | name = "opaque-debug" 895 | version = "0.3.0" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 898 | 899 | [[package]] 900 | name = "openssl" 901 | version = "0.10.32" 902 | source = "registry+https://github.com/rust-lang/crates.io-index" 903 | checksum = "038d43985d1ddca7a9900630d8cd031b56e4794eecc2e9ea39dd17aa04399a70" 904 | dependencies = [ 905 | "bitflags", 906 | "cfg-if 1.0.0", 907 | "foreign-types", 908 | "lazy_static", 909 | "libc", 910 | "openssl-sys", 911 | ] 912 | 913 | [[package]] 914 | name = "openssl-probe" 915 | version = "0.1.2" 916 | source = "registry+https://github.com/rust-lang/crates.io-index" 917 | checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" 918 | 919 | [[package]] 920 | name = "openssl-sys" 921 | version = "0.9.60" 922 | source = "registry+https://github.com/rust-lang/crates.io-index" 923 | checksum = "921fc71883267538946025deffb622905ecad223c28efbfdef9bb59a0175f3e6" 924 | dependencies = [ 925 | "autocfg", 926 | "cc", 927 | "libc", 928 | "pkg-config", 929 | "vcpkg", 930 | ] 931 | 932 | [[package]] 933 | name = "parking" 934 | version = "2.0.0" 935 | source = "registry+https://github.com/rust-lang/crates.io-index" 936 | checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" 937 | 938 | [[package]] 939 | name = "parking_lot" 940 | version = "0.11.1" 941 | source = "registry+https://github.com/rust-lang/crates.io-index" 942 | checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" 943 | dependencies = [ 944 | "instant", 945 | "lock_api", 946 | "parking_lot_core", 947 | ] 948 | 949 | [[package]] 950 | name = "parking_lot_core" 951 | version = "0.8.3" 952 | source = "registry+https://github.com/rust-lang/crates.io-index" 953 | checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" 954 | dependencies = [ 955 | "cfg-if 1.0.0", 956 | "instant", 957 | "libc", 958 | "redox_syscall", 959 | "smallvec", 960 | "winapi", 961 | ] 962 | 963 | [[package]] 964 | name = "percent-encoding" 965 | version = "2.1.0" 966 | source = "registry+https://github.com/rust-lang/crates.io-index" 967 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 968 | 969 | [[package]] 970 | name = "pin-project" 971 | version = "1.0.5" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "96fa8ebb90271c4477f144354485b8068bd8f6b78b428b01ba892ca26caf0b63" 974 | dependencies = [ 975 | "pin-project-internal", 976 | ] 977 | 978 | [[package]] 979 | name = "pin-project-internal" 980 | version = "1.0.5" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | checksum = "758669ae3558c6f74bd2a18b41f7ac0b5a195aea6639d6a9b5e5d1ad5ba24c0b" 983 | dependencies = [ 984 | "proc-macro2", 985 | "quote", 986 | "syn", 987 | ] 988 | 989 | [[package]] 990 | name = "pin-project-lite" 991 | version = "0.2.6" 992 | source = "registry+https://github.com/rust-lang/crates.io-index" 993 | checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" 994 | 995 | [[package]] 996 | name = "pin-utils" 997 | version = "0.1.0" 998 | source = "registry+https://github.com/rust-lang/crates.io-index" 999 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1000 | 1001 | [[package]] 1002 | name = "pkg-config" 1003 | version = "0.3.19" 1004 | source = "registry+https://github.com/rust-lang/crates.io-index" 1005 | checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" 1006 | 1007 | [[package]] 1008 | name = "polling" 1009 | version = "2.0.2" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | checksum = "a2a7bc6b2a29e632e45451c941832803a18cce6781db04de8a04696cdca8bde4" 1012 | dependencies = [ 1013 | "cfg-if 0.1.10", 1014 | "libc", 1015 | "log", 1016 | "wepoll-sys", 1017 | "winapi", 1018 | ] 1019 | 1020 | [[package]] 1021 | name = "ppv-lite86" 1022 | version = "0.2.10" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" 1025 | 1026 | [[package]] 1027 | name = "proc-macro-hack" 1028 | version = "0.5.19" 1029 | source = "registry+https://github.com/rust-lang/crates.io-index" 1030 | checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" 1031 | 1032 | [[package]] 1033 | name = "proc-macro-nested" 1034 | version = "0.1.7" 1035 | source = "registry+https://github.com/rust-lang/crates.io-index" 1036 | checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" 1037 | 1038 | [[package]] 1039 | name = "proc-macro2" 1040 | version = "1.0.24" 1041 | source = "registry+https://github.com/rust-lang/crates.io-index" 1042 | checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" 1043 | dependencies = [ 1044 | "unicode-xid", 1045 | ] 1046 | 1047 | [[package]] 1048 | name = "punic" 1049 | version = "0.1.0" 1050 | dependencies = [ 1051 | "async-std", 1052 | "async-trait", 1053 | "clap", 1054 | "futures", 1055 | "regex", 1056 | "rusoto_core", 1057 | "rusoto_s3", 1058 | "serde", 1059 | "serde_yaml", 1060 | "shellexpand", 1061 | "tinytemplate", 1062 | "tokio", 1063 | "tokio-util", 1064 | "walkdir", 1065 | "yaml-rust", 1066 | "zip", 1067 | ] 1068 | 1069 | [[package]] 1070 | name = "quote" 1071 | version = "1.0.9" 1072 | source = "registry+https://github.com/rust-lang/crates.io-index" 1073 | checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" 1074 | dependencies = [ 1075 | "proc-macro2", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "rand" 1080 | version = "0.8.3" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" 1083 | dependencies = [ 1084 | "libc", 1085 | "rand_chacha", 1086 | "rand_core", 1087 | "rand_hc", 1088 | ] 1089 | 1090 | [[package]] 1091 | name = "rand_chacha" 1092 | version = "0.3.0" 1093 | source = "registry+https://github.com/rust-lang/crates.io-index" 1094 | checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" 1095 | dependencies = [ 1096 | "ppv-lite86", 1097 | "rand_core", 1098 | ] 1099 | 1100 | [[package]] 1101 | name = "rand_core" 1102 | version = "0.6.2" 1103 | source = "registry+https://github.com/rust-lang/crates.io-index" 1104 | checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" 1105 | dependencies = [ 1106 | "getrandom", 1107 | ] 1108 | 1109 | [[package]] 1110 | name = "rand_hc" 1111 | version = "0.3.0" 1112 | source = "registry+https://github.com/rust-lang/crates.io-index" 1113 | checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" 1114 | dependencies = [ 1115 | "rand_core", 1116 | ] 1117 | 1118 | [[package]] 1119 | name = "redox_syscall" 1120 | version = "0.2.5" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "94341e4e44e24f6b591b59e47a8a027df12e008d73fd5672dbea9cc22f4507d9" 1123 | dependencies = [ 1124 | "bitflags", 1125 | ] 1126 | 1127 | [[package]] 1128 | name = "redox_users" 1129 | version = "0.4.0" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" 1132 | dependencies = [ 1133 | "getrandom", 1134 | "redox_syscall", 1135 | ] 1136 | 1137 | [[package]] 1138 | name = "regex" 1139 | version = "1.4.6" 1140 | source = "registry+https://github.com/rust-lang/crates.io-index" 1141 | checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" 1142 | dependencies = [ 1143 | "aho-corasick", 1144 | "memchr", 1145 | "regex-syntax", 1146 | ] 1147 | 1148 | [[package]] 1149 | name = "regex-syntax" 1150 | version = "0.6.25" 1151 | source = "registry+https://github.com/rust-lang/crates.io-index" 1152 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 1153 | 1154 | [[package]] 1155 | name = "remove_dir_all" 1156 | version = "0.5.3" 1157 | source = "registry+https://github.com/rust-lang/crates.io-index" 1158 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 1159 | dependencies = [ 1160 | "winapi", 1161 | ] 1162 | 1163 | [[package]] 1164 | name = "rusoto_core" 1165 | version = "0.46.0" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "02aff20978970d47630f08de5f0d04799497818d16cafee5aec90c4b4d0806cf" 1168 | dependencies = [ 1169 | "async-trait", 1170 | "base64", 1171 | "bytes", 1172 | "crc32fast", 1173 | "futures", 1174 | "http", 1175 | "hyper", 1176 | "hyper-tls", 1177 | "lazy_static", 1178 | "log", 1179 | "rusoto_credential", 1180 | "rusoto_signature", 1181 | "rustc_version", 1182 | "serde", 1183 | "serde_json", 1184 | "tokio", 1185 | "xml-rs", 1186 | ] 1187 | 1188 | [[package]] 1189 | name = "rusoto_credential" 1190 | version = "0.46.0" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "8e91e4c25ea8bfa6247684ff635299015845113baaa93ba8169b9e565701b58e" 1193 | dependencies = [ 1194 | "async-trait", 1195 | "chrono", 1196 | "dirs-next", 1197 | "futures", 1198 | "hyper", 1199 | "serde", 1200 | "serde_json", 1201 | "shlex", 1202 | "tokio", 1203 | "zeroize", 1204 | ] 1205 | 1206 | [[package]] 1207 | name = "rusoto_s3" 1208 | version = "0.46.0" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | checksum = "abc3f56f14ccf91f880b9a9c2d0556d8523e8c155041c54db155b384a1dd1119" 1211 | dependencies = [ 1212 | "async-trait", 1213 | "bytes", 1214 | "futures", 1215 | "rusoto_core", 1216 | "xml-rs", 1217 | ] 1218 | 1219 | [[package]] 1220 | name = "rusoto_signature" 1221 | version = "0.46.0" 1222 | source = "registry+https://github.com/rust-lang/crates.io-index" 1223 | checksum = "5486e6b1673ab3e0ba1ded284fb444845fe1b7f41d13989a54dd60f62a7b2baa" 1224 | dependencies = [ 1225 | "base64", 1226 | "bytes", 1227 | "futures", 1228 | "hex", 1229 | "hmac", 1230 | "http", 1231 | "hyper", 1232 | "log", 1233 | "md5", 1234 | "percent-encoding", 1235 | "pin-project-lite", 1236 | "rusoto_credential", 1237 | "rustc_version", 1238 | "serde", 1239 | "sha2", 1240 | "time 0.2.25", 1241 | "tokio", 1242 | ] 1243 | 1244 | [[package]] 1245 | name = "rustc_version" 1246 | version = "0.2.3" 1247 | source = "registry+https://github.com/rust-lang/crates.io-index" 1248 | checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" 1249 | dependencies = [ 1250 | "semver", 1251 | ] 1252 | 1253 | [[package]] 1254 | name = "ryu" 1255 | version = "1.0.5" 1256 | source = "registry+https://github.com/rust-lang/crates.io-index" 1257 | checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" 1258 | 1259 | [[package]] 1260 | name = "same-file" 1261 | version = "1.0.6" 1262 | source = "registry+https://github.com/rust-lang/crates.io-index" 1263 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1264 | dependencies = [ 1265 | "winapi-util", 1266 | ] 1267 | 1268 | [[package]] 1269 | name = "schannel" 1270 | version = "0.1.19" 1271 | source = "registry+https://github.com/rust-lang/crates.io-index" 1272 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" 1273 | dependencies = [ 1274 | "lazy_static", 1275 | "winapi", 1276 | ] 1277 | 1278 | [[package]] 1279 | name = "scopeguard" 1280 | version = "1.1.0" 1281 | source = "registry+https://github.com/rust-lang/crates.io-index" 1282 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1283 | 1284 | [[package]] 1285 | name = "security-framework" 1286 | version = "2.1.2" 1287 | source = "registry+https://github.com/rust-lang/crates.io-index" 1288 | checksum = "d493c5f39e02dfb062cd8f33301f90f9b13b650e8c1b1d0fd75c19dd64bff69d" 1289 | dependencies = [ 1290 | "bitflags", 1291 | "core-foundation", 1292 | "core-foundation-sys", 1293 | "libc", 1294 | "security-framework-sys", 1295 | ] 1296 | 1297 | [[package]] 1298 | name = "security-framework-sys" 1299 | version = "2.1.1" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "dee48cdde5ed250b0d3252818f646e174ab414036edb884dde62d80a3ac6082d" 1302 | dependencies = [ 1303 | "core-foundation-sys", 1304 | "libc", 1305 | ] 1306 | 1307 | [[package]] 1308 | name = "semver" 1309 | version = "0.9.0" 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" 1311 | checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" 1312 | dependencies = [ 1313 | "semver-parser", 1314 | ] 1315 | 1316 | [[package]] 1317 | name = "semver-parser" 1318 | version = "0.7.0" 1319 | source = "registry+https://github.com/rust-lang/crates.io-index" 1320 | checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" 1321 | 1322 | [[package]] 1323 | name = "serde" 1324 | version = "1.0.124" 1325 | source = "registry+https://github.com/rust-lang/crates.io-index" 1326 | checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f" 1327 | dependencies = [ 1328 | "serde_derive", 1329 | ] 1330 | 1331 | [[package]] 1332 | name = "serde_derive" 1333 | version = "1.0.124" 1334 | source = "registry+https://github.com/rust-lang/crates.io-index" 1335 | checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b" 1336 | dependencies = [ 1337 | "proc-macro2", 1338 | "quote", 1339 | "syn", 1340 | ] 1341 | 1342 | [[package]] 1343 | name = "serde_json" 1344 | version = "1.0.64" 1345 | source = "registry+https://github.com/rust-lang/crates.io-index" 1346 | checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" 1347 | dependencies = [ 1348 | "itoa", 1349 | "ryu", 1350 | "serde", 1351 | ] 1352 | 1353 | [[package]] 1354 | name = "serde_yaml" 1355 | version = "0.8.17" 1356 | source = "registry+https://github.com/rust-lang/crates.io-index" 1357 | checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23" 1358 | dependencies = [ 1359 | "dtoa", 1360 | "linked-hash-map", 1361 | "serde", 1362 | "yaml-rust", 1363 | ] 1364 | 1365 | [[package]] 1366 | name = "sha1" 1367 | version = "0.6.0" 1368 | source = "registry+https://github.com/rust-lang/crates.io-index" 1369 | checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" 1370 | 1371 | [[package]] 1372 | name = "sha2" 1373 | version = "0.9.3" 1374 | source = "registry+https://github.com/rust-lang/crates.io-index" 1375 | checksum = "fa827a14b29ab7f44778d14a88d3cb76e949c45083f7dbfa507d0cb699dc12de" 1376 | dependencies = [ 1377 | "block-buffer", 1378 | "cfg-if 1.0.0", 1379 | "cpuid-bool", 1380 | "digest", 1381 | "opaque-debug", 1382 | ] 1383 | 1384 | [[package]] 1385 | name = "shellexpand" 1386 | version = "2.1.0" 1387 | source = "registry+https://github.com/rust-lang/crates.io-index" 1388 | checksum = "83bdb7831b2d85ddf4a7b148aa19d0587eddbe8671a436b7bd1182eaad0f2829" 1389 | dependencies = [ 1390 | "dirs-next", 1391 | ] 1392 | 1393 | [[package]] 1394 | name = "shlex" 1395 | version = "0.1.1" 1396 | source = "registry+https://github.com/rust-lang/crates.io-index" 1397 | checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2" 1398 | 1399 | [[package]] 1400 | name = "signal-hook-registry" 1401 | version = "1.3.0" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" 1404 | dependencies = [ 1405 | "libc", 1406 | ] 1407 | 1408 | [[package]] 1409 | name = "slab" 1410 | version = "0.4.2" 1411 | source = "registry+https://github.com/rust-lang/crates.io-index" 1412 | checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" 1413 | 1414 | [[package]] 1415 | name = "smallvec" 1416 | version = "1.6.1" 1417 | source = "registry+https://github.com/rust-lang/crates.io-index" 1418 | checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" 1419 | 1420 | [[package]] 1421 | name = "socket2" 1422 | version = "0.3.19" 1423 | source = "registry+https://github.com/rust-lang/crates.io-index" 1424 | checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" 1425 | dependencies = [ 1426 | "cfg-if 1.0.0", 1427 | "libc", 1428 | "winapi", 1429 | ] 1430 | 1431 | [[package]] 1432 | name = "standback" 1433 | version = "0.2.15" 1434 | source = "registry+https://github.com/rust-lang/crates.io-index" 1435 | checksum = "a2beb4d1860a61f571530b3f855a1b538d0200f7871c63331ecd6f17b1f014f8" 1436 | dependencies = [ 1437 | "version_check", 1438 | ] 1439 | 1440 | [[package]] 1441 | name = "stdweb" 1442 | version = "0.4.20" 1443 | source = "registry+https://github.com/rust-lang/crates.io-index" 1444 | checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" 1445 | dependencies = [ 1446 | "discard", 1447 | "rustc_version", 1448 | "stdweb-derive", 1449 | "stdweb-internal-macros", 1450 | "stdweb-internal-runtime", 1451 | "wasm-bindgen", 1452 | ] 1453 | 1454 | [[package]] 1455 | name = "stdweb-derive" 1456 | version = "0.5.3" 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" 1458 | checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" 1459 | dependencies = [ 1460 | "proc-macro2", 1461 | "quote", 1462 | "serde", 1463 | "serde_derive", 1464 | "syn", 1465 | ] 1466 | 1467 | [[package]] 1468 | name = "stdweb-internal-macros" 1469 | version = "0.2.9" 1470 | source = "registry+https://github.com/rust-lang/crates.io-index" 1471 | checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" 1472 | dependencies = [ 1473 | "base-x", 1474 | "proc-macro2", 1475 | "quote", 1476 | "serde", 1477 | "serde_derive", 1478 | "serde_json", 1479 | "sha1", 1480 | "syn", 1481 | ] 1482 | 1483 | [[package]] 1484 | name = "stdweb-internal-runtime" 1485 | version = "0.1.5" 1486 | source = "registry+https://github.com/rust-lang/crates.io-index" 1487 | checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" 1488 | 1489 | [[package]] 1490 | name = "strsim" 1491 | version = "0.8.0" 1492 | source = "registry+https://github.com/rust-lang/crates.io-index" 1493 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" 1494 | 1495 | [[package]] 1496 | name = "subtle" 1497 | version = "2.4.0" 1498 | source = "registry+https://github.com/rust-lang/crates.io-index" 1499 | checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" 1500 | 1501 | [[package]] 1502 | name = "syn" 1503 | version = "1.0.63" 1504 | source = "registry+https://github.com/rust-lang/crates.io-index" 1505 | checksum = "8fd9bc7ccc2688b3344c2f48b9b546648b25ce0b20fc717ee7fa7981a8ca9717" 1506 | dependencies = [ 1507 | "proc-macro2", 1508 | "quote", 1509 | "unicode-xid", 1510 | ] 1511 | 1512 | [[package]] 1513 | name = "tempfile" 1514 | version = "3.2.0" 1515 | source = "registry+https://github.com/rust-lang/crates.io-index" 1516 | checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" 1517 | dependencies = [ 1518 | "cfg-if 1.0.0", 1519 | "libc", 1520 | "rand", 1521 | "redox_syscall", 1522 | "remove_dir_all", 1523 | "winapi", 1524 | ] 1525 | 1526 | [[package]] 1527 | name = "textwrap" 1528 | version = "0.11.0" 1529 | source = "registry+https://github.com/rust-lang/crates.io-index" 1530 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" 1531 | dependencies = [ 1532 | "unicode-width", 1533 | ] 1534 | 1535 | [[package]] 1536 | name = "thiserror" 1537 | version = "1.0.24" 1538 | source = "registry+https://github.com/rust-lang/crates.io-index" 1539 | checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" 1540 | dependencies = [ 1541 | "thiserror-impl", 1542 | ] 1543 | 1544 | [[package]] 1545 | name = "thiserror-impl" 1546 | version = "1.0.24" 1547 | source = "registry+https://github.com/rust-lang/crates.io-index" 1548 | checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" 1549 | dependencies = [ 1550 | "proc-macro2", 1551 | "quote", 1552 | "syn", 1553 | ] 1554 | 1555 | [[package]] 1556 | name = "time" 1557 | version = "0.1.43" 1558 | source = "registry+https://github.com/rust-lang/crates.io-index" 1559 | checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" 1560 | dependencies = [ 1561 | "libc", 1562 | "winapi", 1563 | ] 1564 | 1565 | [[package]] 1566 | name = "time" 1567 | version = "0.2.25" 1568 | source = "registry+https://github.com/rust-lang/crates.io-index" 1569 | checksum = "1195b046942c221454c2539395f85413b33383a067449d78aab2b7b052a142f7" 1570 | dependencies = [ 1571 | "const_fn", 1572 | "libc", 1573 | "standback", 1574 | "stdweb", 1575 | "time-macros", 1576 | "version_check", 1577 | "winapi", 1578 | ] 1579 | 1580 | [[package]] 1581 | name = "time-macros" 1582 | version = "0.1.1" 1583 | source = "registry+https://github.com/rust-lang/crates.io-index" 1584 | checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" 1585 | dependencies = [ 1586 | "proc-macro-hack", 1587 | "time-macros-impl", 1588 | ] 1589 | 1590 | [[package]] 1591 | name = "time-macros-impl" 1592 | version = "0.1.1" 1593 | source = "registry+https://github.com/rust-lang/crates.io-index" 1594 | checksum = "e5c3be1edfad6027c69f5491cf4cb310d1a71ecd6af742788c6ff8bced86b8fa" 1595 | dependencies = [ 1596 | "proc-macro-hack", 1597 | "proc-macro2", 1598 | "quote", 1599 | "standback", 1600 | "syn", 1601 | ] 1602 | 1603 | [[package]] 1604 | name = "tinytemplate" 1605 | version = "1.2.1" 1606 | source = "registry+https://github.com/rust-lang/crates.io-index" 1607 | checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" 1608 | dependencies = [ 1609 | "serde", 1610 | "serde_json", 1611 | ] 1612 | 1613 | [[package]] 1614 | name = "tokio" 1615 | version = "1.3.0" 1616 | source = "registry+https://github.com/rust-lang/crates.io-index" 1617 | checksum = "8d56477f6ed99e10225f38f9f75f872f29b8b8bd8c0b946f63345bb144e9eeda" 1618 | dependencies = [ 1619 | "autocfg", 1620 | "bytes", 1621 | "libc", 1622 | "memchr", 1623 | "mio", 1624 | "num_cpus", 1625 | "once_cell", 1626 | "parking_lot", 1627 | "pin-project-lite", 1628 | "signal-hook-registry", 1629 | "tokio-macros", 1630 | "winapi", 1631 | ] 1632 | 1633 | [[package]] 1634 | name = "tokio-macros" 1635 | version = "1.1.0" 1636 | source = "registry+https://github.com/rust-lang/crates.io-index" 1637 | checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57" 1638 | dependencies = [ 1639 | "proc-macro2", 1640 | "quote", 1641 | "syn", 1642 | ] 1643 | 1644 | [[package]] 1645 | name = "tokio-native-tls" 1646 | version = "0.3.0" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" 1649 | dependencies = [ 1650 | "native-tls", 1651 | "tokio", 1652 | ] 1653 | 1654 | [[package]] 1655 | name = "tokio-util" 1656 | version = "0.6.4" 1657 | source = "registry+https://github.com/rust-lang/crates.io-index" 1658 | checksum = "ec31e5cc6b46e653cf57762f36f71d5e6386391d88a72fd6db4508f8f676fb29" 1659 | dependencies = [ 1660 | "bytes", 1661 | "futures-core", 1662 | "futures-io", 1663 | "futures-sink", 1664 | "log", 1665 | "pin-project-lite", 1666 | "slab", 1667 | "tokio", 1668 | ] 1669 | 1670 | [[package]] 1671 | name = "tower-service" 1672 | version = "0.3.1" 1673 | source = "registry+https://github.com/rust-lang/crates.io-index" 1674 | checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" 1675 | 1676 | [[package]] 1677 | name = "tracing" 1678 | version = "0.1.25" 1679 | source = "registry+https://github.com/rust-lang/crates.io-index" 1680 | checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f" 1681 | dependencies = [ 1682 | "cfg-if 1.0.0", 1683 | "pin-project-lite", 1684 | "tracing-core", 1685 | ] 1686 | 1687 | [[package]] 1688 | name = "tracing-core" 1689 | version = "0.1.17" 1690 | source = "registry+https://github.com/rust-lang/crates.io-index" 1691 | checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" 1692 | dependencies = [ 1693 | "lazy_static", 1694 | ] 1695 | 1696 | [[package]] 1697 | name = "try-lock" 1698 | version = "0.2.3" 1699 | source = "registry+https://github.com/rust-lang/crates.io-index" 1700 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 1701 | 1702 | [[package]] 1703 | name = "typenum" 1704 | version = "1.12.0" 1705 | source = "registry+https://github.com/rust-lang/crates.io-index" 1706 | checksum = "373c8a200f9e67a0c95e62a4f52fbf80c23b4381c05a17845531982fa99e6b33" 1707 | 1708 | [[package]] 1709 | name = "unicode-width" 1710 | version = "0.1.8" 1711 | source = "registry+https://github.com/rust-lang/crates.io-index" 1712 | checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" 1713 | 1714 | [[package]] 1715 | name = "unicode-xid" 1716 | version = "0.2.1" 1717 | source = "registry+https://github.com/rust-lang/crates.io-index" 1718 | checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" 1719 | 1720 | [[package]] 1721 | name = "value-bag" 1722 | version = "1.0.0-alpha.6" 1723 | source = "registry+https://github.com/rust-lang/crates.io-index" 1724 | checksum = "6b676010e055c99033117c2343b33a40a30b91fecd6c49055ac9cd2d6c305ab1" 1725 | dependencies = [ 1726 | "ctor", 1727 | ] 1728 | 1729 | [[package]] 1730 | name = "vcpkg" 1731 | version = "0.2.11" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" 1734 | 1735 | [[package]] 1736 | name = "vec-arena" 1737 | version = "1.0.0" 1738 | source = "registry+https://github.com/rust-lang/crates.io-index" 1739 | checksum = "eafc1b9b2dfc6f5529177b62cf806484db55b32dc7c9658a118e11bbeb33061d" 1740 | 1741 | [[package]] 1742 | name = "vec_map" 1743 | version = "0.8.2" 1744 | source = "registry+https://github.com/rust-lang/crates.io-index" 1745 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 1746 | 1747 | [[package]] 1748 | name = "version_check" 1749 | version = "0.9.2" 1750 | source = "registry+https://github.com/rust-lang/crates.io-index" 1751 | checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" 1752 | 1753 | [[package]] 1754 | name = "waker-fn" 1755 | version = "1.1.0" 1756 | source = "registry+https://github.com/rust-lang/crates.io-index" 1757 | checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" 1758 | 1759 | [[package]] 1760 | name = "walkdir" 1761 | version = "2.3.1" 1762 | source = "registry+https://github.com/rust-lang/crates.io-index" 1763 | checksum = "777182bc735b6424e1a57516d35ed72cb8019d85c8c9bf536dccb3445c1a2f7d" 1764 | dependencies = [ 1765 | "same-file", 1766 | "winapi", 1767 | "winapi-util", 1768 | ] 1769 | 1770 | [[package]] 1771 | name = "want" 1772 | version = "0.3.0" 1773 | source = "registry+https://github.com/rust-lang/crates.io-index" 1774 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1775 | dependencies = [ 1776 | "log", 1777 | "try-lock", 1778 | ] 1779 | 1780 | [[package]] 1781 | name = "wasi" 1782 | version = "0.10.2+wasi-snapshot-preview1" 1783 | source = "registry+https://github.com/rust-lang/crates.io-index" 1784 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 1785 | 1786 | [[package]] 1787 | name = "wasm-bindgen" 1788 | version = "0.2.71" 1789 | source = "registry+https://github.com/rust-lang/crates.io-index" 1790 | checksum = "7ee1280240b7c461d6a0071313e08f34a60b0365f14260362e5a2b17d1d31aa7" 1791 | dependencies = [ 1792 | "cfg-if 1.0.0", 1793 | "wasm-bindgen-macro", 1794 | ] 1795 | 1796 | [[package]] 1797 | name = "wasm-bindgen-backend" 1798 | version = "0.2.71" 1799 | source = "registry+https://github.com/rust-lang/crates.io-index" 1800 | checksum = "5b7d8b6942b8bb3a9b0e73fc79b98095a27de6fa247615e59d096754a3bc2aa8" 1801 | dependencies = [ 1802 | "bumpalo", 1803 | "lazy_static", 1804 | "log", 1805 | "proc-macro2", 1806 | "quote", 1807 | "syn", 1808 | "wasm-bindgen-shared", 1809 | ] 1810 | 1811 | [[package]] 1812 | name = "wasm-bindgen-futures" 1813 | version = "0.4.21" 1814 | source = "registry+https://github.com/rust-lang/crates.io-index" 1815 | checksum = "8e67a5806118af01f0d9045915676b22aaebecf4178ae7021bc171dab0b897ab" 1816 | dependencies = [ 1817 | "cfg-if 1.0.0", 1818 | "js-sys", 1819 | "wasm-bindgen", 1820 | "web-sys", 1821 | ] 1822 | 1823 | [[package]] 1824 | name = "wasm-bindgen-macro" 1825 | version = "0.2.71" 1826 | source = "registry+https://github.com/rust-lang/crates.io-index" 1827 | checksum = "e5ac38da8ef716661f0f36c0d8320b89028efe10c7c0afde65baffb496ce0d3b" 1828 | dependencies = [ 1829 | "quote", 1830 | "wasm-bindgen-macro-support", 1831 | ] 1832 | 1833 | [[package]] 1834 | name = "wasm-bindgen-macro-support" 1835 | version = "0.2.71" 1836 | source = "registry+https://github.com/rust-lang/crates.io-index" 1837 | checksum = "cc053ec74d454df287b9374ee8abb36ffd5acb95ba87da3ba5b7d3fe20eb401e" 1838 | dependencies = [ 1839 | "proc-macro2", 1840 | "quote", 1841 | "syn", 1842 | "wasm-bindgen-backend", 1843 | "wasm-bindgen-shared", 1844 | ] 1845 | 1846 | [[package]] 1847 | name = "wasm-bindgen-shared" 1848 | version = "0.2.71" 1849 | source = "registry+https://github.com/rust-lang/crates.io-index" 1850 | checksum = "7d6f8ec44822dd71f5f221a5847fb34acd9060535c1211b70a05844c0f6383b1" 1851 | 1852 | [[package]] 1853 | name = "web-sys" 1854 | version = "0.3.48" 1855 | source = "registry+https://github.com/rust-lang/crates.io-index" 1856 | checksum = "ec600b26223b2948cedfde2a0aa6756dcf1fef616f43d7b3097aaf53a6c4d92b" 1857 | dependencies = [ 1858 | "js-sys", 1859 | "wasm-bindgen", 1860 | ] 1861 | 1862 | [[package]] 1863 | name = "wepoll-sys" 1864 | version = "3.0.1" 1865 | source = "registry+https://github.com/rust-lang/crates.io-index" 1866 | checksum = "0fcb14dea929042224824779fbc82d9fab8d2e6d3cbc0ac404de8edf489e77ff" 1867 | dependencies = [ 1868 | "cc", 1869 | ] 1870 | 1871 | [[package]] 1872 | name = "winapi" 1873 | version = "0.3.9" 1874 | source = "registry+https://github.com/rust-lang/crates.io-index" 1875 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1876 | dependencies = [ 1877 | "winapi-i686-pc-windows-gnu", 1878 | "winapi-x86_64-pc-windows-gnu", 1879 | ] 1880 | 1881 | [[package]] 1882 | name = "winapi-i686-pc-windows-gnu" 1883 | version = "0.4.0" 1884 | source = "registry+https://github.com/rust-lang/crates.io-index" 1885 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1886 | 1887 | [[package]] 1888 | name = "winapi-util" 1889 | version = "0.1.5" 1890 | source = "registry+https://github.com/rust-lang/crates.io-index" 1891 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1892 | dependencies = [ 1893 | "winapi", 1894 | ] 1895 | 1896 | [[package]] 1897 | name = "winapi-x86_64-pc-windows-gnu" 1898 | version = "0.4.0" 1899 | source = "registry+https://github.com/rust-lang/crates.io-index" 1900 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1901 | 1902 | [[package]] 1903 | name = "xml-rs" 1904 | version = "0.8.3" 1905 | source = "registry+https://github.com/rust-lang/crates.io-index" 1906 | checksum = "b07db065a5cf61a7e4ba64f29e67db906fb1787316516c4e6e5ff0fea1efcd8a" 1907 | 1908 | [[package]] 1909 | name = "yaml-rust" 1910 | version = "0.4.5" 1911 | source = "registry+https://github.com/rust-lang/crates.io-index" 1912 | checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" 1913 | dependencies = [ 1914 | "linked-hash-map", 1915 | ] 1916 | 1917 | [[package]] 1918 | name = "zeroize" 1919 | version = "1.2.0" 1920 | source = "registry+https://github.com/rust-lang/crates.io-index" 1921 | checksum = "81a974bcdd357f0dca4d41677db03436324d45a4c9ed2d0b873a5a360ce41c36" 1922 | 1923 | [[package]] 1924 | name = "zip" 1925 | version = "0.5.11" 1926 | source = "registry+https://github.com/rust-lang/crates.io-index" 1927 | checksum = "8264fcea9b7a036a4a5103d7153e988dbc2ebbafb34f68a3c2d404b6b82d74b6" 1928 | dependencies = [ 1929 | "byteorder", 1930 | "bzip2", 1931 | "crc32fast", 1932 | "flate2", 1933 | "thiserror", 1934 | "time 0.1.43", 1935 | ] 1936 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "punic" 3 | version = "0.1.0" 4 | authors = ["Johnson Cheung "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | regex = "1" 11 | tinytemplate = "1.1" 12 | tokio = { version = "1.2.0", features = ["full"] } 13 | rusoto_core = "0.46.0" 14 | rusoto_s3 = "0.46.0" 15 | yaml-rust = "0.4.5" 16 | serde = "1.0.123" 17 | serde_yaml = "0.8.17" 18 | clap = "2.33.3" 19 | futures = "0.3.5" 20 | zip = "0.5" 21 | walkdir = "2" 22 | tokio-util = {version = "0.6.3", features = ["full"]} 23 | async-std = "1.9.0" 24 | shellexpand = "2.1.0" 25 | async-trait = "0.1.48" 26 | -------------------------------------------------------------------------------- /Cartfile: -------------------------------------------------------------------------------- 1 | 2 | github "Alamofire/Alamofire" "5.2.2" -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "Alamofire/Alamofire" "5.2.2" 2 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build: 2 | cargo build 3 | cp -f target/debug/punic /usr/local/bin/punic 4 | 5 | release: 6 | cargo build --release 7 | cd target/release \ 8 | && tar -cvf punic.tar.gz punic \ 9 | && shasum -a 256 punic.tar.gz 10 | -------------------------------------------------------------------------------- /Punfile: -------------------------------------------------------------------------------- 1 | configuration: 2 | prefix: test 3 | local: ~/Library/Caches/Punic 4 | output: Carthage/Build 5 | s3Bucket: shred-ios-carthage-cache 6 | dependencies: 7 | - Alamofire: 8 | - name: Alamofire 9 | version: 1.0.0 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Punic 2 | 3 | ![elephant](assets/elephant_2.png) 4 | 5 | **Punic** is a remote caching CLI built for [Carthage](https://github.com/Carthage/Carthage) 6 | that exclusively supports [Apple's](https://developer.apple.com/documentation/swift_packages/distributing_binary_frameworks_as_swift_packages) `.xcframeworks`. 7 | 8 | **Features** 9 | - ✅ Easy remote caching via [AWS S3](https://aws.amazon.com/s3/) 10 | - ✅ Easy CI/CD integration 11 | - ✅ Support for versioned dependencies 12 | 13 | Please give us a ⭐️ if you find this CLI useful! 14 | 15 | ### Example Usage 16 | 17 | ![elephant](assets/demo.gif) 18 | 19 | # Installation 20 | 21 | ```bash 22 | brew tap summerlabs/homebrew-punic 23 | brew install punic 24 | ``` 25 | 26 | **AWS Credentials** 27 | 28 | Make sure you have your AWS config and credentials [setup](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html). 29 | 30 | They are keys that **Punic** uses to upload your frameworks into AWS 31 | and will be automatically setup for you when you run `aws configure`. 32 | 33 | Here is an example after you run the setup successfully. 34 | 35 | `~/.aws/config` 36 | ```bash 37 | [default] 38 | region = us-west-1 39 | output = json 40 | ``` 41 | `~/.aws/credentials` 42 | ```bash 43 | [default] 44 | aws_access_key_id = {SOME_ACCESS_KEY_ID} 45 | aws_secret_access_key = {SOME_SECRET_KEY} 46 | ``` 47 | 48 | 49 | 50 | # Documentation 51 | 52 | ### Punfile 53 | 54 | **Punic** looks for a `Punfile` in your top-level project to determine which dependencies to download 55 | as well as configuring the path of your local cache. 56 | 57 | 58 | **Example Punfile** 59 | 60 | ```yaml 61 | # Configure Punic 62 | configuration: 63 | # save dependencies into this AWS bucket directory 64 | # 65 | # ie. //some-remote-bucket/1.0.1/Alamofire/Alamofire.xcframework 66 | # 67 | # defaults to `output` 68 | # 69 | prefix: 1.0.1 70 | # local cache location 71 | local: ~/Library/Caches/Punic 72 | # output cache location 73 | output: Carthage/Build 74 | # aws bucket location 75 | s3Bucket: some-remote-bucket 76 | 77 | # Search your output directory for these .xcframeworks 78 | dependencies: 79 | # single framework definition 80 | - AlamoFire: 81 | - name: AlamoFire 82 | # support for explicit versioning 83 | version: 0.1.9 84 | # multiple frameworks definition sometimes created by one library 85 | - CocoaLumberjack: 86 | # having no version defaults to a versionless dependency cache 87 | - name: CocoaLumberjack 88 | - name: CocoaLumberjackSwift 89 | - name: CocoaAsyncSocket 90 | version: {COCOA_VERSION} 91 | ``` 92 | we also support basic templating with environment variables the best way to do this is create 93 | a .env file and source it before running punfile 94 | 95 | ## Commands 96 | 97 | After building your `.xcframeworks` using 98 | ```bash 99 | carthage update --use-xcframeworks 100 | ``` 101 | They will be located in the top level `Carthage/Build` directory. 102 | 103 | **Download .xcframeworks** 104 | ```bash 105 | punic download 106 | ``` 107 | **Upload .xcframeworks** 108 | ```bash 109 | punic upload 110 | ``` 111 | 112 | **Miscellaneous** 113 | ```bash 114 | # The `output cache` is the Carthage/Build folder 115 | 116 | # ignore the local cache and zip directly from the output cache 117 | punic upload --ignore-local 118 | 119 | # ignore the local cache and download anyway then copy 120 | punic download --ignore-local 121 | 122 | # ignore the output cache and copy anyway 123 | punic download --ignore-output 124 | 125 | # use an override cache prefix 126 | punic {command} --cache-prefix {some_other_path_key} 127 | 128 | # target specific dependencies 129 | punic {command} --dependencies Alamofre,CocoaLumberjack 130 | ``` 131 | 132 | ## Carthage-less Support 133 | 134 | **Punic** is capable of copying the downloaded/cached frameworks into a 135 | separate folder, you don't have to necessarily use `Carthage/Build` if you 136 | want to copy the files into a separate directory for your own reasons. 137 | 138 | Feel free to change the `output` key in the `Punfile` to achieve this. 139 | 140 | ## Developer Support 141 | 142 | **Punic** is a new framework that was made to help our team 143 | achieve remote caching with Apple's latest `.xcframework` change. 144 | If you find any issues using the CLI, don't hesitate to open one up 145 | to help us bug splash. 146 | 147 | For all you `Rust` developers, feel free to contribute to this framework 148 | and help us grow the CLI. 149 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /assets/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/summerlabs/punic/1d1919e472c487f505c340658485059c34ce6333/assets/demo.gif -------------------------------------------------------------------------------- /assets/elephant_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/summerlabs/punic/1d1919e472c487f505c340658485059c34ce6333/assets/elephant_2.png -------------------------------------------------------------------------------- /src/cache.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | pub mod s3; 4 | 5 | -------------------------------------------------------------------------------- /src/cache/s3.rs: -------------------------------------------------------------------------------- 1 | use rusoto_core::Region; 2 | use rusoto_s3::{GetObjectRequest, PutObjectRequest, S3Client, StreamingBody, S3}; 3 | use std::fs::File; 4 | use tokio::io::AsyncReadExt; 5 | 6 | pub async fn download_from_s3( 7 | filename: String, 8 | prefix: String, 9 | bucket: String, 10 | ) -> Result<(), Box> { 11 | let s3_client = S3Client::new(Region::default()); 12 | 13 | let f_name = { filename.clone() }; 14 | let path_str = f_name.split("/").last().unwrap_or(""); 15 | let object_key = format!("{}/{}", prefix, path_str).to_string(); 16 | let _bucket = bucket.clone(); 17 | let _object_key = object_key.clone(); 18 | 19 | println!("Downloading {}/{}...", bucket.clone(), object_key); 20 | 21 | let request = GetObjectRequest { 22 | bucket, 23 | key: object_key, 24 | ..Default::default() 25 | }; 26 | 27 | let stream = s3_client.get_object(request).await; 28 | 29 | let mut output = match stream { 30 | Ok(output) => output, 31 | Err(error) => panic!(error.to_string()), 32 | }; 33 | 34 | let stream = output.body.take().expect("No Content"); 35 | 36 | let mut body = stream.into_async_read(); 37 | let mut file = tokio::fs::File::create(filename).await.unwrap(); 38 | tokio::io::copy(&mut body, &mut file).await.ok(); 39 | 40 | println!("Downloaded {}/{}", _bucket, _object_key); 41 | 42 | Ok(()) 43 | } 44 | 45 | pub async fn upload( 46 | filename: String, 47 | prefix: String, 48 | bucket: String, 49 | ) -> Result<(), Box> { 50 | let s3_client = S3Client::new(Region::default()); 51 | let mut buffer = Vec::new(); 52 | let f_name = { filename.clone() }; 53 | let path_str = f_name.split("/").last().unwrap().to_string(); 54 | let file = File::open(f_name).unwrap(); 55 | let mut tokio_file = tokio::fs::File::from_std(file); 56 | tokio_file.read_to_end(&mut buffer).await.ok(); 57 | let object_key = format!("{}/{}", prefix, path_str).to_string(); 58 | let object_key2 = object_key.clone(); 59 | let bucket2 = bucket.clone(); 60 | println!("Uploading {}/{}...", bucket, object_key); 61 | s3_client 62 | .put_object(PutObjectRequest { 63 | bucket, 64 | key: object_key, 65 | body: Some(StreamingBody::from(buffer)), 66 | ..Default::default() 67 | }) 68 | .await 69 | .ok(); 70 | println!("Uploaded {}/{}", bucket2, object_key2); 71 | 72 | Ok(()) 73 | } 74 | -------------------------------------------------------------------------------- /src/commands.rs: -------------------------------------------------------------------------------- 1 | 2 | 3 | fn handle_command(command str) { 4 | 5 | match command { 6 | "" => print!(command), 7 | _ => println!("no command given") 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate futures; 2 | extern crate rusoto_core; 3 | extern crate rusoto_s3; 4 | extern crate serde; 5 | extern crate shellexpand; 6 | extern crate tokio; 7 | 8 | use crate::punfile::parse_pun_file; 9 | use crate::punfile::print_pun_deps; 10 | use crate::utils::download::download_dependencies; 11 | use crate::utils::upload::upload_dependencies; 12 | use clap::{App, Arg}; 13 | use std::borrow::Borrow; 14 | 15 | mod cache; 16 | mod punfile; 17 | mod utils; 18 | 19 | const OVERRIDE_DEPENDENCIES_COMMAND: &str = "OVERRIDE_DEPENDENCIES"; 20 | const IGNORE_LOCAL_CACHE: &str = "IGNORE_LOCAL_CACHE"; 21 | const IGNORE_OUTPUT_CACHE: &str = "IGNORE_OUTPUT_CACHE"; 22 | const CACHE_PREFIX: &str = "CACHE_PREFIX"; 23 | 24 | #[tokio::main] 25 | async fn main() { 26 | let matches = App::new("Punic Carthage") 27 | .version("1.1.1") 28 | .about("ios dependency caching made great again") 29 | .author("Johnson Cheung") 30 | .subcommand( 31 | 32 | App::new("download") 33 | .about("scan your punfile and download dependencies") 34 | .arg( 35 | Arg::with_name(crate::IGNORE_LOCAL_CACHE) 36 | .short("l") 37 | .long("ignore-local") 38 | .help("ignore the local cache and download anyway then copy") 39 | .takes_value(false), 40 | ) 41 | .arg( 42 | Arg::with_name(crate::IGNORE_OUTPUT_CACHE) 43 | .short("o") 44 | .long("ignore-output") 45 | .help("ignore the output cache and copy anyway") 46 | .takes_value(false), 47 | ) 48 | .arg( 49 | Arg::with_name(crate::OVERRIDE_DEPENDENCIES_COMMAND) 50 | .short("d") 51 | .long("dependencies") 52 | .multiple(true) 53 | .allow_hyphen_values(true) 54 | .value_delimiter(" ") 55 | .value_terminator(";"), 56 | ) 57 | .arg( 58 | Arg::with_name(crate::CACHE_PREFIX) 59 | .short("p") 60 | .long("cache-prefix") 61 | .value_name(crate::CACHE_PREFIX) 62 | .help("set custom prefix for directory") 63 | .takes_value(true), 64 | ), 65 | ) 66 | .subcommand( 67 | App::new("upload") 68 | .about("upload to s3") 69 | .arg( 70 | Arg::with_name(crate::IGNORE_LOCAL_CACHE) 71 | .short("l") 72 | .long("ignore-local") 73 | .help("ignore the local cache and zip anyway") 74 | .takes_value(false), 75 | ) 76 | .arg( 77 | Arg::with_name(crate::OVERRIDE_DEPENDENCIES_COMMAND) 78 | .short("d") 79 | .long("dependencies") 80 | .multiple(true) 81 | .allow_hyphen_values(true) 82 | .value_delimiter(";"), 83 | ) 84 | .arg( 85 | Arg::with_name(crate::CACHE_PREFIX) 86 | .short("p") 87 | .long("cache-prefix") 88 | .value_name(crate::CACHE_PREFIX) 89 | .help("set custom prefix for directory") 90 | .takes_value(true), 91 | ), 92 | ) 93 | .subcommand( 94 | App::new("list") 95 | .about("list parsed out dependencies from punfile"), 96 | ).get_matches(); 97 | 98 | let punfile = parse_pun_file(matches.borrow()); 99 | let local_cache = punfile.configuration.local.clone(); 100 | 101 | let cache_dir = shellexpand::tilde(local_cache.as_str()); 102 | let output_dir = format!("{}/build/{}", cache_dir, punfile.configuration.prefix); 103 | 104 | std::fs::create_dir_all(output_dir).unwrap(); 105 | 106 | // create Carthage build path if it does not exist 107 | std::fs::create_dir_all(punfile.configuration.output.clone()).unwrap(); 108 | 109 | if let Some(ref matches) = matches.subcommand_matches("download") { 110 | download_dependencies(punfile, matches, cache_dir).await; 111 | } else if let Some(ref matches) = matches.subcommand_matches("upload") { 112 | upload_dependencies(punfile, matches, cache_dir).await; 113 | } else if let Some(ref matches) = matches.subcommand_matches("list"){ 114 | print_pun_deps(&punfile); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /src/punfile.rs: -------------------------------------------------------------------------------- 1 | use crate::punfile; 2 | use crate::punfile::data::{Configuration, PunFile, Repository}; 3 | use clap::ArgMatches; 4 | use serde_yaml::Value; 5 | use regex::Regex; 6 | use std::env; 7 | use std::collections::HashMap; 8 | use tinytemplate::TinyTemplate; 9 | 10 | 11 | pub mod data { 12 | 13 | pub struct Configuration { 14 | pub prefix: String, 15 | pub local: String, 16 | pub output: String, 17 | pub s3_bucket: String, 18 | } 19 | 20 | pub struct PunFile { 21 | pub configuration: Configuration, 22 | pub frameworks: Vec, 23 | } 24 | 25 | pub struct Repository { 26 | pub repo_name: String, 27 | pub name: String, 28 | pub version: String 29 | } 30 | } 31 | 32 | 33 | pub fn build_template(content: &str) -> String { 34 | 35 | 36 | let mut data = HashMap::new(); 37 | 38 | for cap in Regex::new(r"\{(.*?)}").unwrap().captures_iter(content) { 39 | println!("{:#?}", cap.get(1).unwrap().as_str()); 40 | let key = cap.get(1).unwrap().as_str(); 41 | let value = env::var(key).unwrap_or(String::from("")); 42 | data.insert(key.to_string(),value.to_string()); 43 | } 44 | 45 | let mut tt = TinyTemplate::new(); 46 | tt.add_template("hello", content); 47 | let rendered = tt.render("hello", &data).unwrap(); 48 | return String::from(rendered); 49 | } 50 | 51 | 52 | pub fn parse_pun_file(matches: &ArgMatches) -> punfile::data::PunFile { 53 | let contents = std::fs::read_to_string("Punfile") 54 | .expect("Unable to read Punfile, make sure one exists in your project."); 55 | 56 | let rendered = build_template(&contents); 57 | 58 | 59 | let contents_yaml: serde_yaml::Value = serde_yaml::from_str(rendered.as_str()).unwrap(); 60 | let configuration = contents_yaml 61 | .get("configuration") 62 | .expect("Unable to read key `configuration` in Punfile."); 63 | let prefix = get_cache_prefix(matches, configuration); 64 | let local = configuration 65 | .get("local") 66 | .expect("Unable to read key `local` in Punfile.") 67 | .as_str() 68 | .unwrap_or("~/Library/Caches/Punic"); 69 | let output = configuration 70 | .get("output") 71 | .expect("Unable to read key `output` in Punfile.") 72 | .as_str() 73 | .unwrap_or("Carthage/Build"); 74 | let s3_bucket = configuration 75 | .get("s3Bucket") 76 | .expect("Unable to read key `s3Bucket` in Punfile.") 77 | .as_str() 78 | .unwrap(); 79 | 80 | let mut punfile = PunFile { 81 | configuration: Configuration { 82 | prefix, 83 | local: String::from(local), 84 | output: String::from(output), 85 | s3_bucket: String::from(s3_bucket), 86 | }, 87 | frameworks: Vec::new(), 88 | }; 89 | 90 | println!("Cache Prefix\t\t: {}", punfile.configuration.prefix); 91 | println!("Cache Local Path\t: {}", punfile.configuration.local); 92 | println!("Cache Output Path\t: {}", punfile.configuration.output); 93 | println!("S3 Bucket\t\t: {} \n", punfile.configuration.s3_bucket); 94 | 95 | let repository_map = contents_yaml 96 | .get("dependencies") 97 | .expect("Unable to read key `dependencies` in Punfile.") 98 | .as_sequence() 99 | .expect("Key `dependencies` in Punfile must be an array"); 100 | 101 | for repo in repository_map { 102 | let name = repo.as_mapping().unwrap(); 103 | for (key, value) in name.iter() { 104 | let repo_name = key.as_str().unwrap(); 105 | for seq in value.as_sequence().unwrap().iter() { 106 | let map_name = seq 107 | .as_mapping() 108 | .unwrap() 109 | .get(&serde_yaml::Value::from("name")); 110 | let version = seq.as_mapping().unwrap().get(&serde_yaml::Value::from("version")); 111 | let repository = Repository { 112 | repo_name: String::from(repo_name), 113 | name: String::from(map_name.unwrap().as_str().unwrap()), 114 | version: String::from(version.unwrap_or(&serde_yaml::Value::String("".into())).as_str().unwrap()) 115 | }; 116 | punfile.frameworks.push(repository); 117 | } 118 | } 119 | } 120 | return punfile; 121 | } 122 | 123 | fn get_cache_prefix(matches: &ArgMatches, configuration: &Value) -> String { 124 | let default_prefix = &Value::String("output".into()); 125 | let punfile_prefix = configuration 126 | .get("prefix") 127 | .unwrap_or(default_prefix) 128 | .as_str() 129 | .unwrap_or("output"); 130 | if let Some(ref matches) = matches.subcommand_matches("download") { 131 | matches 132 | .value_of(crate::CACHE_PREFIX) 133 | .unwrap_or(punfile_prefix) 134 | .to_string() 135 | } else if let Some(ref matches) = matches.subcommand_matches("upload") { 136 | matches 137 | .value_of(crate::CACHE_PREFIX) 138 | .unwrap_or(punfile_prefix) 139 | .to_string() 140 | } else { 141 | punfile_prefix.to_string() 142 | } 143 | } 144 | 145 | 146 | pub fn print_pun_deps(punfile: &PunFile) { 147 | let frameworks = &punfile.frameworks; 148 | println!("Listing dependencies in Punfile"); 149 | 150 | frameworks.iter().enumerate().for_each(|(i, framework)|{ 151 | println!("{}. Group: {}, Artifact: {}, Version: {}", 152 | i + 1, 153 | framework.repo_name, 154 | framework.name, 155 | framework.version); 156 | 157 | }); 158 | 159 | } 160 | 161 | -------------------------------------------------------------------------------- /src/utils.rs: -------------------------------------------------------------------------------- 1 | pub mod archive; 2 | pub mod download; 3 | pub mod scan; 4 | pub mod upload; 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/utils/archive.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use std::fs::File; 3 | use std::io::{Read, Seek, Write}; 4 | use std::path::Path; 5 | use walkdir::DirEntry; 6 | use zip::write::FileOptions; 7 | 8 | pub fn zip_dir( 9 | it: &mut dyn Iterator, 10 | prefix: &str, 11 | writer: T, 12 | method: zip::CompressionMethod, 13 | ) -> zip::result::ZipResult<()> 14 | where 15 | T: Write + Seek, 16 | { 17 | let mut zip = zip::ZipWriter::new(writer); 18 | let options = FileOptions::default() 19 | .compression_method(method) 20 | .unix_permissions(0o755); 21 | 22 | let mut buffer = Vec::new(); 23 | 24 | println!("Zipping {}", prefix); 25 | 26 | for entry in it { 27 | let path = entry.path(); 28 | 29 | let name = path.strip_prefix(Path::new(prefix)).unwrap(); 30 | 31 | // Write file or directory explicitly 32 | // Some unzip tools unzip files with directory paths correctly, some do not! 33 | if path.is_file() { 34 | #[allow(deprecated)] 35 | zip.start_file_from_path(name, options)?; 36 | let mut f = File::open(path)?; 37 | f.read_to_end(&mut buffer)?; 38 | zip.write_all(&*buffer)?; 39 | buffer.clear(); 40 | } else if name.as_os_str().len() != 0 { 41 | // Only if not root! Avoids path spec / warning 42 | // and mapname conversion failed error on unzip 43 | #[allow(deprecated)] 44 | zip.add_directory_from_path(name, options)?; 45 | } 46 | } 47 | zip.finish()?; 48 | 49 | println!("Zipped {}", prefix); 50 | 51 | Result::Ok(()) 52 | } 53 | 54 | pub fn extract_zip(root: &str, path: &str, dest: &str) { 55 | 56 | println!("Unzipping {}...", path); 57 | let file = fs::File::open(path).unwrap(); 58 | let mut archive = zip::ZipArchive::new(file).unwrap(); 59 | 60 | 61 | for i in 0..archive.len() { 62 | let mut file = archive.by_index(i).unwrap(); 63 | let outpath = match file.enclosed_name() { 64 | Some(path) => path.to_owned(), 65 | None => continue, 66 | }; 67 | if (&*file.name()).ends_with('/') { 68 | let output = format!("{}/{}/{}", root, dest, outpath.display()); 69 | fs::create_dir_all(output).unwrap(); 70 | } else { 71 | if let Some(p) = outpath.parent() { 72 | if !p.exists() { 73 | let output = format!("{}/{}/{}", root, dest, p.display()); 74 | fs::create_dir_all(output).unwrap(); 75 | } 76 | } 77 | let output = format!("{}/{}/{}", root, dest, outpath.display()); 78 | let mut outfile = fs::File::create(&output).unwrap(); 79 | std::io::copy(&mut file, &mut outfile).unwrap(); 80 | } 81 | // Get and Set permissions 82 | #[cfg(unix)] 83 | { 84 | use std::os::unix::fs::PermissionsExt; 85 | if let Some(mode) = file.unix_mode() { 86 | let output = format!("{}/{}/{}", root, dest, outpath.display()); 87 | fs::set_permissions(output, fs::Permissions::from_mode(mode)).unwrap(); 88 | } 89 | } 90 | } 91 | 92 | println!("Unzipped to {}/{}", root, dest); 93 | } 94 | -------------------------------------------------------------------------------- /src/utils/download.rs: -------------------------------------------------------------------------------- 1 | use crate::punfile::data::{PunFile, Repository}; 2 | use crate::{cache, utils}; 3 | use clap::{ArgMatches, Values}; 4 | use futures::future::join_all; 5 | use std::borrow::Cow; 6 | use std::path::Path; 7 | 8 | pub async fn download_dependencies<'a>( 9 | punfile: PunFile, 10 | matches: &&ArgMatches<'a>, 11 | cache_dir: Cow<'a, str>, 12 | ) { 13 | let ignore_local_cache = matches.is_present(crate::IGNORE_LOCAL_CACHE); 14 | let ignore_output_cache = matches.is_present(crate::IGNORE_OUTPUT_CACHE); 15 | let mut children = vec![]; 16 | let requested_frameworks: Vec = matches 17 | .values_of(crate::OVERRIDE_DEPENDENCIES_COMMAND) 18 | .unwrap_or(Values::default()) 19 | .map(|it| Repository { 20 | repo_name: String::from(it), 21 | name: String::from(it), 22 | version: String::from(it) 23 | }) 24 | .collect(); 25 | let mut frameworks = punfile.frameworks; 26 | if !requested_frameworks.is_empty() { 27 | let mut filtered_frameworks: Vec = Vec::new(); 28 | for dep in &requested_frameworks { 29 | let temp = frameworks 30 | .iter() 31 | .find(|item| item.repo_name.eq(&dep.repo_name)); 32 | if temp.is_none() { 33 | println!("{} is not a dependency in the Punfile.", dep.repo_name); 34 | } else { 35 | let frame = temp.unwrap(); 36 | filtered_frameworks.push(Repository { 37 | repo_name: frame.repo_name.to_string(), 38 | name: frame.name.to_string(), 39 | version: frame.version.to_string() 40 | }); 41 | } 42 | } 43 | frameworks = filtered_frameworks; 44 | } 45 | 46 | for dependencies in frameworks { 47 | let output = punfile.configuration.output.clone(); 48 | let cache_prefix = punfile.configuration.prefix.clone(); 49 | let framework_name = format!("{}.xcframework", dependencies.name); 50 | let version = dependencies.version.clone(); 51 | let xcf_cache_dir = format!( 52 | "{}/build/{}/{}.xcframework.zip", 53 | cache_dir, cache_prefix, dependencies.name 54 | ) 55 | .to_string(); 56 | let xcf_cache_path = Path::new(xcf_cache_dir.as_str()); 57 | // If the framework does not exist or we're ignoring the local cache -> download 58 | if !xcf_cache_path.exists() || ignore_local_cache { 59 | if !xcf_cache_path.exists() { 60 | println!("Not found {}", xcf_cache_dir); 61 | } else if ignore_local_cache { 62 | println!("Ignoring {}", xcf_cache_dir); 63 | } 64 | let s3_bucket = punfile.configuration.s3_bucket.clone(); 65 | let prefix = match dependencies.version.as_str() { 66 | "" => cache_prefix.clone(), 67 | _ => format!("{}/{}",cache_prefix.clone(), version.clone()) 68 | }; 69 | 70 | let task = tokio::spawn(async move { 71 | cache::s3::download_from_s3( 72 | xcf_cache_dir.to_string(), 73 | prefix.to_string(), 74 | s3_bucket, 75 | ) 76 | .await 77 | .ok(); 78 | let path = Path::new(xcf_cache_dir.as_str()); 79 | if path.exists() { 80 | utils::archive::extract_zip( 81 | &output, 82 | xcf_cache_dir.as_str(), 83 | framework_name.as_str(), 84 | ); 85 | } 86 | }); 87 | children.push(task); 88 | } else { 89 | let xfr_output_dir = format!("{}/{}.xcframework", output, dependencies.name); 90 | let xcf_output_path = Path::new(xfr_output_dir.as_str()); 91 | // If the output path does not exist or we're ignoring it -> copy files over 92 | if !xcf_output_path.exists() || ignore_output_cache { 93 | if !xcf_output_path.exists() { 94 | println!("Not found {}", xfr_output_dir); 95 | } else if ignore_output_cache { 96 | println!("Ignoring {}", xfr_output_dir); 97 | } 98 | let task = tokio::spawn(async move { 99 | utils::archive::extract_zip( 100 | &output, 101 | xcf_cache_dir.as_str(), 102 | framework_name.as_str(), 103 | ); 104 | }); 105 | children.push(task); 106 | } else { 107 | println!("Already downloaded {}", xcf_cache_path.display()); 108 | } 109 | } 110 | } 111 | join_all(children).await; 112 | } 113 | -------------------------------------------------------------------------------- /src/utils/scan.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | 3 | pub fn scan_xcframeworks(output: String) -> Vec { 4 | println!("Scanning for .xcframeworks in {}...", output); 5 | let mut frameworks = vec![]; 6 | for entry in fs::read_dir(output).unwrap() { 7 | let en = entry.unwrap(); 8 | let path = en.path(); 9 | if path.is_dir() && path.to_str().unwrap().contains("xcframework") { 10 | let path_string = path 11 | .to_str() 12 | .unwrap() 13 | .to_string() 14 | .split("/") 15 | .last() 16 | .unwrap() 17 | .to_string(); 18 | frameworks.push(path_string); 19 | } 20 | } 21 | return frameworks; 22 | } 23 | -------------------------------------------------------------------------------- /src/utils/upload.rs: -------------------------------------------------------------------------------- 1 | use crate::punfile::data::PunFile; 2 | use crate::utils::scan::scan_xcframeworks; 3 | use crate::{cache, utils}; 4 | use clap::{ArgMatches, Values}; 5 | use futures::future::join_all; 6 | use std::borrow::Cow; 7 | use std::fs::File; 8 | use std::path::Path; 9 | use walkdir::WalkDir; 10 | use crate::punfile::data::Repository; 11 | use std::collections::HashMap; 12 | 13 | 14 | 15 | pub async fn upload_dependencies<'a>( 16 | punfile: PunFile, 17 | matches: &&ArgMatches<'a>, 18 | expanded_str: Cow<'a, str>, 19 | ) { 20 | let ignore_local_cache = matches.is_present(crate::IGNORE_LOCAL_CACHE); 21 | let mut children = vec![]; 22 | let requested_frameworks: Vec<&str> = matches 23 | .values_of(crate::OVERRIDE_DEPENDENCIES_COMMAND) 24 | .unwrap_or(Values::default()) 25 | .collect(); 26 | let mut frameworks = scan_xcframeworks(punfile.configuration.output.clone()); 27 | 28 | if !requested_frameworks.is_empty() { 29 | let mut filtered_frameworks: Vec = Vec::new(); 30 | for dep in &requested_frameworks { 31 | let temp = frameworks.iter().find(|item| item.contains(dep)); 32 | if temp.is_none() { 33 | println!("{} is not a dependency", dep); 34 | } else { 35 | let frame = temp.unwrap(); 36 | filtered_frameworks.push(frame.to_string()); 37 | } 38 | } 39 | frameworks = filtered_frameworks; 40 | } 41 | for frame in frameworks { 42 | let output = punfile.configuration.output.clone(); 43 | let cache_prefix = punfile.configuration.prefix.clone(); 44 | let bucket_name = punfile.configuration.s3_bucket.clone(); 45 | let default_repo = Repository { 46 | name: "".to_string(), 47 | repo_name: "".to_string(), 48 | version: "".to_string() 49 | }; 50 | 51 | let expanded_frameworks: Vec<&str> = frame.split(".").collect(); 52 | 53 | 54 | let framework_key = expanded_frameworks.get(0).unwrap(); 55 | 56 | let framework = punfile.frameworks.iter().find(|item| item.name.contains(framework_key)).unwrap_or(&default_repo); 57 | 58 | if framework.version.is_empty() { 59 | println!("Found {}/{}", &output, frame); 60 | } else { 61 | println!("Found {}/{} @version {}", &output, frame, framework.version); 62 | } 63 | 64 | let src_dir = format!("{}/{}", output, frame); 65 | let dest_dir = { format!("{}/build/{}/{}.zip", expanded_str, cache_prefix, frame) }; 66 | let prefix = cache_prefix.clone(); 67 | let version = framework.version.clone(); 68 | let _empty_string = String::from(""); 69 | let prefix = match framework.version.as_str() { 70 | "" => cache_prefix.clone(), 71 | _ => format!("{}/{}",cache_prefix.clone(),version) 72 | }; 73 | // If the cache does not exist or we're ignoring the cache -> zip the files 74 | if ignore_local_cache || !Path::new(&dest_dir).exists() { 75 | let dest = dest_dir.clone(); 76 | let task = tokio::spawn(async move { 77 | let file = File::create(dest).unwrap(); 78 | let walk_dir = WalkDir::new(src_dir.to_string()); 79 | let it = walk_dir.into_iter(); 80 | utils::archive::zip_dir( 81 | &mut it.filter_map(|e| e.ok()), 82 | src_dir.as_str(), 83 | file, 84 | zip::CompressionMethod::DEFLATE, 85 | ) 86 | .ok(); 87 | cache::s3::upload(dest_dir, prefix.to_string(), bucket_name) 88 | .await 89 | .ok(); 90 | }); 91 | children.push(task); 92 | } else { 93 | println!("Already zipped {}", frame); 94 | let dest = dest_dir; 95 | let pref = prefix.to_string(); 96 | let task = tokio::spawn(async move { 97 | cache::s3::upload(dest, pref, bucket_name).await.ok(); 98 | }); 99 | children.push(task); 100 | } 101 | } 102 | join_all(children).await; 103 | } 104 | --------------------------------------------------------------------------------