├── .envrc ├── .github └── workflows │ └── rust.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── flake.lock ├── flake.nix ├── src ├── dump_git.rs ├── git_parsing.rs └── main.rs └── test-data ├── object-blob ├── object-commit └── object-tree /.envrc: -------------------------------------------------------------------------------- 1 | use flake 2 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | jobs: 8 | test: 9 | name: cargo test 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | target: [x86_64-pc-windows-gnu, x86_64-unknown-linux-musl] 14 | steps: 15 | - uses: actions/checkout@v4 16 | - uses: actions-rust-lang/setup-rust-toolchain@v1 17 | with: 18 | target: ${{ matrix.target }} 19 | - run: cargo test --all-features 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | .direnv 3 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "anstream" 31 | version = "0.6.18" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 34 | dependencies = [ 35 | "anstyle", 36 | "anstyle-parse", 37 | "anstyle-query", 38 | "anstyle-wincon", 39 | "colorchoice", 40 | "is_terminal_polyfill", 41 | "utf8parse", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle" 46 | version = "1.0.10" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 49 | 50 | [[package]] 51 | name = "anstyle-parse" 52 | version = "0.2.6" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 55 | dependencies = [ 56 | "utf8parse", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle-query" 61 | version = "1.1.2" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 64 | dependencies = [ 65 | "windows-sys 0.59.0", 66 | ] 67 | 68 | [[package]] 69 | name = "anstyle-wincon" 70 | version = "3.0.8" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa" 73 | dependencies = [ 74 | "anstyle", 75 | "once_cell_polyfill", 76 | "windows-sys 0.59.0", 77 | ] 78 | 79 | [[package]] 80 | name = "anyhow" 81 | version = "1.0.98" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" 84 | 85 | [[package]] 86 | name = "atomic-waker" 87 | version = "1.1.2" 88 | source = "registry+https://github.com/rust-lang/crates.io-index" 89 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 90 | 91 | [[package]] 92 | name = "autocfg" 93 | version = "1.4.0" 94 | source = "registry+https://github.com/rust-lang/crates.io-index" 95 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 96 | 97 | [[package]] 98 | name = "backtrace" 99 | version = "0.3.75" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" 102 | dependencies = [ 103 | "addr2line", 104 | "cfg-if", 105 | "libc", 106 | "miniz_oxide", 107 | "object", 108 | "rustc-demangle", 109 | "windows-targets 0.52.6", 110 | ] 111 | 112 | [[package]] 113 | name = "base64" 114 | version = "0.22.1" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 117 | 118 | [[package]] 119 | name = "bitflags" 120 | version = "2.9.1" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" 123 | 124 | [[package]] 125 | name = "bumpalo" 126 | version = "3.17.0" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" 129 | 130 | [[package]] 131 | name = "bytes" 132 | version = "1.10.1" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 135 | 136 | [[package]] 137 | name = "cc" 138 | version = "1.2.25" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951" 141 | dependencies = [ 142 | "shlex", 143 | ] 144 | 145 | [[package]] 146 | name = "cfg-if" 147 | version = "1.0.0" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 150 | 151 | [[package]] 152 | name = "clap" 153 | version = "4.5.39" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f" 156 | dependencies = [ 157 | "clap_builder", 158 | "clap_derive", 159 | ] 160 | 161 | [[package]] 162 | name = "clap_builder" 163 | version = "4.5.39" 164 | source = "registry+https://github.com/rust-lang/crates.io-index" 165 | checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51" 166 | dependencies = [ 167 | "anstream", 168 | "anstyle", 169 | "clap_lex", 170 | "strsim", 171 | ] 172 | 173 | [[package]] 174 | name = "clap_derive" 175 | version = "4.5.32" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" 178 | dependencies = [ 179 | "heck", 180 | "proc-macro2", 181 | "quote", 182 | "syn", 183 | ] 184 | 185 | [[package]] 186 | name = "clap_lex" 187 | version = "0.7.4" 188 | source = "registry+https://github.com/rust-lang/crates.io-index" 189 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 190 | 191 | [[package]] 192 | name = "colorchoice" 193 | version = "1.0.3" 194 | source = "registry+https://github.com/rust-lang/crates.io-index" 195 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 196 | 197 | [[package]] 198 | name = "core-foundation" 199 | version = "0.9.4" 200 | source = "registry+https://github.com/rust-lang/crates.io-index" 201 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 202 | dependencies = [ 203 | "core-foundation-sys", 204 | "libc", 205 | ] 206 | 207 | [[package]] 208 | name = "core-foundation-sys" 209 | version = "0.8.7" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 212 | 213 | [[package]] 214 | name = "displaydoc" 215 | version = "0.2.5" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 218 | dependencies = [ 219 | "proc-macro2", 220 | "quote", 221 | "syn", 222 | ] 223 | 224 | [[package]] 225 | name = "encoding_rs" 226 | version = "0.8.35" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" 229 | dependencies = [ 230 | "cfg-if", 231 | ] 232 | 233 | [[package]] 234 | name = "equivalent" 235 | version = "1.0.2" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 238 | 239 | [[package]] 240 | name = "errno" 241 | version = "0.3.12" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" 244 | dependencies = [ 245 | "libc", 246 | "windows-sys 0.59.0", 247 | ] 248 | 249 | [[package]] 250 | name = "fastrand" 251 | version = "2.3.0" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 254 | 255 | [[package]] 256 | name = "fnv" 257 | version = "1.0.7" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 260 | 261 | [[package]] 262 | name = "foreign-types" 263 | version = "0.3.2" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 266 | dependencies = [ 267 | "foreign-types-shared", 268 | ] 269 | 270 | [[package]] 271 | name = "foreign-types-shared" 272 | version = "0.1.1" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 275 | 276 | [[package]] 277 | name = "form_urlencoded" 278 | version = "1.2.1" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 281 | dependencies = [ 282 | "percent-encoding", 283 | ] 284 | 285 | [[package]] 286 | name = "futures-channel" 287 | version = "0.3.31" 288 | source = "registry+https://github.com/rust-lang/crates.io-index" 289 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 290 | dependencies = [ 291 | "futures-core", 292 | ] 293 | 294 | [[package]] 295 | name = "futures-core" 296 | version = "0.3.31" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 299 | 300 | [[package]] 301 | name = "futures-sink" 302 | version = "0.3.31" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 305 | 306 | [[package]] 307 | name = "futures-task" 308 | version = "0.3.31" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 311 | 312 | [[package]] 313 | name = "futures-util" 314 | version = "0.3.31" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 317 | dependencies = [ 318 | "futures-core", 319 | "futures-task", 320 | "pin-project-lite", 321 | "pin-utils", 322 | ] 323 | 324 | [[package]] 325 | name = "getrandom" 326 | version = "0.2.16" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" 329 | dependencies = [ 330 | "cfg-if", 331 | "libc", 332 | "wasi 0.11.0+wasi-snapshot-preview1", 333 | ] 334 | 335 | [[package]] 336 | name = "getrandom" 337 | version = "0.3.3" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 340 | dependencies = [ 341 | "cfg-if", 342 | "libc", 343 | "r-efi", 344 | "wasi 0.14.2+wasi-0.2.4", 345 | ] 346 | 347 | [[package]] 348 | name = "gimli" 349 | version = "0.31.1" 350 | source = "registry+https://github.com/rust-lang/crates.io-index" 351 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 352 | 353 | [[package]] 354 | name = "git-dumper" 355 | version = "0.1.2" 356 | dependencies = [ 357 | "anyhow", 358 | "clap", 359 | "lazy_static", 360 | "miniz_oxide", 361 | "regex", 362 | "reqwest", 363 | "tokio", 364 | ] 365 | 366 | [[package]] 367 | name = "h2" 368 | version = "0.4.10" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" 371 | dependencies = [ 372 | "atomic-waker", 373 | "bytes", 374 | "fnv", 375 | "futures-core", 376 | "futures-sink", 377 | "http", 378 | "indexmap", 379 | "slab", 380 | "tokio", 381 | "tokio-util", 382 | "tracing", 383 | ] 384 | 385 | [[package]] 386 | name = "hashbrown" 387 | version = "0.15.3" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" 390 | 391 | [[package]] 392 | name = "heck" 393 | version = "0.5.0" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 396 | 397 | [[package]] 398 | name = "http" 399 | version = "1.3.1" 400 | source = "registry+https://github.com/rust-lang/crates.io-index" 401 | checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" 402 | dependencies = [ 403 | "bytes", 404 | "fnv", 405 | "itoa", 406 | ] 407 | 408 | [[package]] 409 | name = "http-body" 410 | version = "1.0.1" 411 | source = "registry+https://github.com/rust-lang/crates.io-index" 412 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 413 | dependencies = [ 414 | "bytes", 415 | "http", 416 | ] 417 | 418 | [[package]] 419 | name = "http-body-util" 420 | version = "0.1.3" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" 423 | dependencies = [ 424 | "bytes", 425 | "futures-core", 426 | "http", 427 | "http-body", 428 | "pin-project-lite", 429 | ] 430 | 431 | [[package]] 432 | name = "httparse" 433 | version = "1.10.1" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 436 | 437 | [[package]] 438 | name = "hyper" 439 | version = "1.6.0" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 442 | dependencies = [ 443 | "bytes", 444 | "futures-channel", 445 | "futures-util", 446 | "h2", 447 | "http", 448 | "http-body", 449 | "httparse", 450 | "itoa", 451 | "pin-project-lite", 452 | "smallvec", 453 | "tokio", 454 | "want", 455 | ] 456 | 457 | [[package]] 458 | name = "hyper-rustls" 459 | version = "0.27.6" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "03a01595e11bdcec50946522c32dde3fc6914743000a68b93000965f2f02406d" 462 | dependencies = [ 463 | "http", 464 | "hyper", 465 | "hyper-util", 466 | "rustls", 467 | "rustls-pki-types", 468 | "tokio", 469 | "tokio-rustls", 470 | "tower-service", 471 | ] 472 | 473 | [[package]] 474 | name = "hyper-tls" 475 | version = "0.6.0" 476 | source = "registry+https://github.com/rust-lang/crates.io-index" 477 | checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 478 | dependencies = [ 479 | "bytes", 480 | "http-body-util", 481 | "hyper", 482 | "hyper-util", 483 | "native-tls", 484 | "tokio", 485 | "tokio-native-tls", 486 | "tower-service", 487 | ] 488 | 489 | [[package]] 490 | name = "hyper-util" 491 | version = "0.1.13" 492 | source = "registry+https://github.com/rust-lang/crates.io-index" 493 | checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8" 494 | dependencies = [ 495 | "base64", 496 | "bytes", 497 | "futures-channel", 498 | "futures-core", 499 | "futures-util", 500 | "http", 501 | "http-body", 502 | "hyper", 503 | "ipnet", 504 | "libc", 505 | "percent-encoding", 506 | "pin-project-lite", 507 | "socket2", 508 | "system-configuration", 509 | "tokio", 510 | "tower-service", 511 | "tracing", 512 | "windows-registry", 513 | ] 514 | 515 | [[package]] 516 | name = "icu_collections" 517 | version = "2.0.0" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" 520 | dependencies = [ 521 | "displaydoc", 522 | "potential_utf", 523 | "yoke", 524 | "zerofrom", 525 | "zerovec", 526 | ] 527 | 528 | [[package]] 529 | name = "icu_locale_core" 530 | version = "2.0.0" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" 533 | dependencies = [ 534 | "displaydoc", 535 | "litemap", 536 | "tinystr", 537 | "writeable", 538 | "zerovec", 539 | ] 540 | 541 | [[package]] 542 | name = "icu_normalizer" 543 | version = "2.0.0" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" 546 | dependencies = [ 547 | "displaydoc", 548 | "icu_collections", 549 | "icu_normalizer_data", 550 | "icu_properties", 551 | "icu_provider", 552 | "smallvec", 553 | "zerovec", 554 | ] 555 | 556 | [[package]] 557 | name = "icu_normalizer_data" 558 | version = "2.0.0" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" 561 | 562 | [[package]] 563 | name = "icu_properties" 564 | version = "2.0.1" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" 567 | dependencies = [ 568 | "displaydoc", 569 | "icu_collections", 570 | "icu_locale_core", 571 | "icu_properties_data", 572 | "icu_provider", 573 | "potential_utf", 574 | "zerotrie", 575 | "zerovec", 576 | ] 577 | 578 | [[package]] 579 | name = "icu_properties_data" 580 | version = "2.0.1" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" 583 | 584 | [[package]] 585 | name = "icu_provider" 586 | version = "2.0.0" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" 589 | dependencies = [ 590 | "displaydoc", 591 | "icu_locale_core", 592 | "stable_deref_trait", 593 | "tinystr", 594 | "writeable", 595 | "yoke", 596 | "zerofrom", 597 | "zerotrie", 598 | "zerovec", 599 | ] 600 | 601 | [[package]] 602 | name = "idna" 603 | version = "1.0.3" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 606 | dependencies = [ 607 | "idna_adapter", 608 | "smallvec", 609 | "utf8_iter", 610 | ] 611 | 612 | [[package]] 613 | name = "idna_adapter" 614 | version = "1.2.1" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" 617 | dependencies = [ 618 | "icu_normalizer", 619 | "icu_properties", 620 | ] 621 | 622 | [[package]] 623 | name = "indexmap" 624 | version = "2.9.0" 625 | source = "registry+https://github.com/rust-lang/crates.io-index" 626 | checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" 627 | dependencies = [ 628 | "equivalent", 629 | "hashbrown", 630 | ] 631 | 632 | [[package]] 633 | name = "ipnet" 634 | version = "2.11.0" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" 637 | 638 | [[package]] 639 | name = "iri-string" 640 | version = "0.7.8" 641 | source = "registry+https://github.com/rust-lang/crates.io-index" 642 | checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" 643 | dependencies = [ 644 | "memchr", 645 | "serde", 646 | ] 647 | 648 | [[package]] 649 | name = "is_terminal_polyfill" 650 | version = "1.70.1" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 653 | 654 | [[package]] 655 | name = "itoa" 656 | version = "1.0.15" 657 | source = "registry+https://github.com/rust-lang/crates.io-index" 658 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 659 | 660 | [[package]] 661 | name = "js-sys" 662 | version = "0.3.77" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 665 | dependencies = [ 666 | "once_cell", 667 | "wasm-bindgen", 668 | ] 669 | 670 | [[package]] 671 | name = "lazy_static" 672 | version = "1.5.0" 673 | source = "registry+https://github.com/rust-lang/crates.io-index" 674 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 675 | 676 | [[package]] 677 | name = "libc" 678 | version = "0.2.172" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" 681 | 682 | [[package]] 683 | name = "linux-raw-sys" 684 | version = "0.9.4" 685 | source = "registry+https://github.com/rust-lang/crates.io-index" 686 | checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" 687 | 688 | [[package]] 689 | name = "litemap" 690 | version = "0.8.0" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" 693 | 694 | [[package]] 695 | name = "log" 696 | version = "0.4.27" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" 699 | 700 | [[package]] 701 | name = "memchr" 702 | version = "2.7.4" 703 | source = "registry+https://github.com/rust-lang/crates.io-index" 704 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 705 | 706 | [[package]] 707 | name = "mime" 708 | version = "0.3.17" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 711 | 712 | [[package]] 713 | name = "miniz_oxide" 714 | version = "0.8.8" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" 717 | dependencies = [ 718 | "adler2", 719 | ] 720 | 721 | [[package]] 722 | name = "mio" 723 | version = "1.0.4" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" 726 | dependencies = [ 727 | "libc", 728 | "wasi 0.11.0+wasi-snapshot-preview1", 729 | "windows-sys 0.59.0", 730 | ] 731 | 732 | [[package]] 733 | name = "native-tls" 734 | version = "0.2.14" 735 | source = "registry+https://github.com/rust-lang/crates.io-index" 736 | checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" 737 | dependencies = [ 738 | "libc", 739 | "log", 740 | "openssl", 741 | "openssl-probe", 742 | "openssl-sys", 743 | "schannel", 744 | "security-framework", 745 | "security-framework-sys", 746 | "tempfile", 747 | ] 748 | 749 | [[package]] 750 | name = "object" 751 | version = "0.36.7" 752 | source = "registry+https://github.com/rust-lang/crates.io-index" 753 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 754 | dependencies = [ 755 | "memchr", 756 | ] 757 | 758 | [[package]] 759 | name = "once_cell" 760 | version = "1.21.3" 761 | source = "registry+https://github.com/rust-lang/crates.io-index" 762 | checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" 763 | 764 | [[package]] 765 | name = "once_cell_polyfill" 766 | version = "1.70.1" 767 | source = "registry+https://github.com/rust-lang/crates.io-index" 768 | checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" 769 | 770 | [[package]] 771 | name = "openssl" 772 | version = "0.10.73" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" 775 | dependencies = [ 776 | "bitflags", 777 | "cfg-if", 778 | "foreign-types", 779 | "libc", 780 | "once_cell", 781 | "openssl-macros", 782 | "openssl-sys", 783 | ] 784 | 785 | [[package]] 786 | name = "openssl-macros" 787 | version = "0.1.1" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 790 | dependencies = [ 791 | "proc-macro2", 792 | "quote", 793 | "syn", 794 | ] 795 | 796 | [[package]] 797 | name = "openssl-probe" 798 | version = "0.1.6" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" 801 | 802 | [[package]] 803 | name = "openssl-sys" 804 | version = "0.9.109" 805 | source = "registry+https://github.com/rust-lang/crates.io-index" 806 | checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" 807 | dependencies = [ 808 | "cc", 809 | "libc", 810 | "pkg-config", 811 | "vcpkg", 812 | ] 813 | 814 | [[package]] 815 | name = "percent-encoding" 816 | version = "2.3.1" 817 | source = "registry+https://github.com/rust-lang/crates.io-index" 818 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 819 | 820 | [[package]] 821 | name = "pin-project-lite" 822 | version = "0.2.16" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 825 | 826 | [[package]] 827 | name = "pin-utils" 828 | version = "0.1.0" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 831 | 832 | [[package]] 833 | name = "pkg-config" 834 | version = "0.3.32" 835 | source = "registry+https://github.com/rust-lang/crates.io-index" 836 | checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 837 | 838 | [[package]] 839 | name = "potential_utf" 840 | version = "0.1.2" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" 843 | dependencies = [ 844 | "zerovec", 845 | ] 846 | 847 | [[package]] 848 | name = "proc-macro2" 849 | version = "1.0.95" 850 | source = "registry+https://github.com/rust-lang/crates.io-index" 851 | checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" 852 | dependencies = [ 853 | "unicode-ident", 854 | ] 855 | 856 | [[package]] 857 | name = "quote" 858 | version = "1.0.40" 859 | source = "registry+https://github.com/rust-lang/crates.io-index" 860 | checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" 861 | dependencies = [ 862 | "proc-macro2", 863 | ] 864 | 865 | [[package]] 866 | name = "r-efi" 867 | version = "5.2.0" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" 870 | 871 | [[package]] 872 | name = "regex" 873 | version = "1.11.1" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 876 | dependencies = [ 877 | "aho-corasick", 878 | "memchr", 879 | "regex-automata", 880 | "regex-syntax", 881 | ] 882 | 883 | [[package]] 884 | name = "regex-automata" 885 | version = "0.4.9" 886 | source = "registry+https://github.com/rust-lang/crates.io-index" 887 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 888 | dependencies = [ 889 | "aho-corasick", 890 | "memchr", 891 | "regex-syntax", 892 | ] 893 | 894 | [[package]] 895 | name = "regex-syntax" 896 | version = "0.8.5" 897 | source = "registry+https://github.com/rust-lang/crates.io-index" 898 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 899 | 900 | [[package]] 901 | name = "reqwest" 902 | version = "0.12.19" 903 | source = "registry+https://github.com/rust-lang/crates.io-index" 904 | checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119" 905 | dependencies = [ 906 | "base64", 907 | "bytes", 908 | "encoding_rs", 909 | "futures-core", 910 | "h2", 911 | "http", 912 | "http-body", 913 | "http-body-util", 914 | "hyper", 915 | "hyper-rustls", 916 | "hyper-tls", 917 | "hyper-util", 918 | "ipnet", 919 | "js-sys", 920 | "log", 921 | "mime", 922 | "native-tls", 923 | "once_cell", 924 | "percent-encoding", 925 | "pin-project-lite", 926 | "rustls-pki-types", 927 | "serde", 928 | "serde_json", 929 | "serde_urlencoded", 930 | "sync_wrapper", 931 | "tokio", 932 | "tokio-native-tls", 933 | "tower", 934 | "tower-http", 935 | "tower-service", 936 | "url", 937 | "wasm-bindgen", 938 | "wasm-bindgen-futures", 939 | "web-sys", 940 | ] 941 | 942 | [[package]] 943 | name = "ring" 944 | version = "0.17.14" 945 | source = "registry+https://github.com/rust-lang/crates.io-index" 946 | checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" 947 | dependencies = [ 948 | "cc", 949 | "cfg-if", 950 | "getrandom 0.2.16", 951 | "libc", 952 | "untrusted", 953 | "windows-sys 0.52.0", 954 | ] 955 | 956 | [[package]] 957 | name = "rustc-demangle" 958 | version = "0.1.24" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 961 | 962 | [[package]] 963 | name = "rustix" 964 | version = "1.0.7" 965 | source = "registry+https://github.com/rust-lang/crates.io-index" 966 | checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" 967 | dependencies = [ 968 | "bitflags", 969 | "errno", 970 | "libc", 971 | "linux-raw-sys", 972 | "windows-sys 0.59.0", 973 | ] 974 | 975 | [[package]] 976 | name = "rustls" 977 | version = "0.23.27" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" 980 | dependencies = [ 981 | "once_cell", 982 | "rustls-pki-types", 983 | "rustls-webpki", 984 | "subtle", 985 | "zeroize", 986 | ] 987 | 988 | [[package]] 989 | name = "rustls-pki-types" 990 | version = "1.12.0" 991 | source = "registry+https://github.com/rust-lang/crates.io-index" 992 | checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" 993 | dependencies = [ 994 | "zeroize", 995 | ] 996 | 997 | [[package]] 998 | name = "rustls-webpki" 999 | version = "0.103.3" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" 1002 | dependencies = [ 1003 | "ring", 1004 | "rustls-pki-types", 1005 | "untrusted", 1006 | ] 1007 | 1008 | [[package]] 1009 | name = "rustversion" 1010 | version = "1.0.21" 1011 | source = "registry+https://github.com/rust-lang/crates.io-index" 1012 | checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" 1013 | 1014 | [[package]] 1015 | name = "ryu" 1016 | version = "1.0.20" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 1019 | 1020 | [[package]] 1021 | name = "schannel" 1022 | version = "0.1.27" 1023 | source = "registry+https://github.com/rust-lang/crates.io-index" 1024 | checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" 1025 | dependencies = [ 1026 | "windows-sys 0.59.0", 1027 | ] 1028 | 1029 | [[package]] 1030 | name = "security-framework" 1031 | version = "2.11.1" 1032 | source = "registry+https://github.com/rust-lang/crates.io-index" 1033 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 1034 | dependencies = [ 1035 | "bitflags", 1036 | "core-foundation", 1037 | "core-foundation-sys", 1038 | "libc", 1039 | "security-framework-sys", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "security-framework-sys" 1044 | version = "2.14.0" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" 1047 | dependencies = [ 1048 | "core-foundation-sys", 1049 | "libc", 1050 | ] 1051 | 1052 | [[package]] 1053 | name = "serde" 1054 | version = "1.0.219" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" 1057 | dependencies = [ 1058 | "serde_derive", 1059 | ] 1060 | 1061 | [[package]] 1062 | name = "serde_derive" 1063 | version = "1.0.219" 1064 | source = "registry+https://github.com/rust-lang/crates.io-index" 1065 | checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" 1066 | dependencies = [ 1067 | "proc-macro2", 1068 | "quote", 1069 | "syn", 1070 | ] 1071 | 1072 | [[package]] 1073 | name = "serde_json" 1074 | version = "1.0.140" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 1077 | dependencies = [ 1078 | "itoa", 1079 | "memchr", 1080 | "ryu", 1081 | "serde", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "serde_urlencoded" 1086 | version = "0.7.1" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1089 | dependencies = [ 1090 | "form_urlencoded", 1091 | "itoa", 1092 | "ryu", 1093 | "serde", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "shlex" 1098 | version = "1.3.0" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1101 | 1102 | [[package]] 1103 | name = "slab" 1104 | version = "0.4.9" 1105 | source = "registry+https://github.com/rust-lang/crates.io-index" 1106 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1107 | dependencies = [ 1108 | "autocfg", 1109 | ] 1110 | 1111 | [[package]] 1112 | name = "smallvec" 1113 | version = "1.15.0" 1114 | source = "registry+https://github.com/rust-lang/crates.io-index" 1115 | checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" 1116 | 1117 | [[package]] 1118 | name = "socket2" 1119 | version = "0.5.10" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" 1122 | dependencies = [ 1123 | "libc", 1124 | "windows-sys 0.52.0", 1125 | ] 1126 | 1127 | [[package]] 1128 | name = "stable_deref_trait" 1129 | version = "1.2.0" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 1132 | 1133 | [[package]] 1134 | name = "strsim" 1135 | version = "0.11.1" 1136 | source = "registry+https://github.com/rust-lang/crates.io-index" 1137 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1138 | 1139 | [[package]] 1140 | name = "subtle" 1141 | version = "2.6.1" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1144 | 1145 | [[package]] 1146 | name = "syn" 1147 | version = "2.0.101" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" 1150 | dependencies = [ 1151 | "proc-macro2", 1152 | "quote", 1153 | "unicode-ident", 1154 | ] 1155 | 1156 | [[package]] 1157 | name = "sync_wrapper" 1158 | version = "1.0.2" 1159 | source = "registry+https://github.com/rust-lang/crates.io-index" 1160 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 1161 | dependencies = [ 1162 | "futures-core", 1163 | ] 1164 | 1165 | [[package]] 1166 | name = "synstructure" 1167 | version = "0.13.2" 1168 | source = "registry+https://github.com/rust-lang/crates.io-index" 1169 | checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" 1170 | dependencies = [ 1171 | "proc-macro2", 1172 | "quote", 1173 | "syn", 1174 | ] 1175 | 1176 | [[package]] 1177 | name = "system-configuration" 1178 | version = "0.6.1" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" 1181 | dependencies = [ 1182 | "bitflags", 1183 | "core-foundation", 1184 | "system-configuration-sys", 1185 | ] 1186 | 1187 | [[package]] 1188 | name = "system-configuration-sys" 1189 | version = "0.6.0" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" 1192 | dependencies = [ 1193 | "core-foundation-sys", 1194 | "libc", 1195 | ] 1196 | 1197 | [[package]] 1198 | name = "tempfile" 1199 | version = "3.20.0" 1200 | source = "registry+https://github.com/rust-lang/crates.io-index" 1201 | checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" 1202 | dependencies = [ 1203 | "fastrand", 1204 | "getrandom 0.3.3", 1205 | "once_cell", 1206 | "rustix", 1207 | "windows-sys 0.59.0", 1208 | ] 1209 | 1210 | [[package]] 1211 | name = "tinystr" 1212 | version = "0.8.1" 1213 | source = "registry+https://github.com/rust-lang/crates.io-index" 1214 | checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" 1215 | dependencies = [ 1216 | "displaydoc", 1217 | "zerovec", 1218 | ] 1219 | 1220 | [[package]] 1221 | name = "tokio" 1222 | version = "1.45.1" 1223 | source = "registry+https://github.com/rust-lang/crates.io-index" 1224 | checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" 1225 | dependencies = [ 1226 | "backtrace", 1227 | "bytes", 1228 | "libc", 1229 | "mio", 1230 | "pin-project-lite", 1231 | "socket2", 1232 | "tokio-macros", 1233 | "windows-sys 0.52.0", 1234 | ] 1235 | 1236 | [[package]] 1237 | name = "tokio-macros" 1238 | version = "2.5.0" 1239 | source = "registry+https://github.com/rust-lang/crates.io-index" 1240 | checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" 1241 | dependencies = [ 1242 | "proc-macro2", 1243 | "quote", 1244 | "syn", 1245 | ] 1246 | 1247 | [[package]] 1248 | name = "tokio-native-tls" 1249 | version = "0.3.1" 1250 | source = "registry+https://github.com/rust-lang/crates.io-index" 1251 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 1252 | dependencies = [ 1253 | "native-tls", 1254 | "tokio", 1255 | ] 1256 | 1257 | [[package]] 1258 | name = "tokio-rustls" 1259 | version = "0.26.2" 1260 | source = "registry+https://github.com/rust-lang/crates.io-index" 1261 | checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" 1262 | dependencies = [ 1263 | "rustls", 1264 | "tokio", 1265 | ] 1266 | 1267 | [[package]] 1268 | name = "tokio-util" 1269 | version = "0.7.15" 1270 | source = "registry+https://github.com/rust-lang/crates.io-index" 1271 | checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" 1272 | dependencies = [ 1273 | "bytes", 1274 | "futures-core", 1275 | "futures-sink", 1276 | "pin-project-lite", 1277 | "tokio", 1278 | ] 1279 | 1280 | [[package]] 1281 | name = "tower" 1282 | version = "0.5.2" 1283 | source = "registry+https://github.com/rust-lang/crates.io-index" 1284 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 1285 | dependencies = [ 1286 | "futures-core", 1287 | "futures-util", 1288 | "pin-project-lite", 1289 | "sync_wrapper", 1290 | "tokio", 1291 | "tower-layer", 1292 | "tower-service", 1293 | ] 1294 | 1295 | [[package]] 1296 | name = "tower-http" 1297 | version = "0.6.6" 1298 | source = "registry+https://github.com/rust-lang/crates.io-index" 1299 | checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" 1300 | dependencies = [ 1301 | "bitflags", 1302 | "bytes", 1303 | "futures-util", 1304 | "http", 1305 | "http-body", 1306 | "iri-string", 1307 | "pin-project-lite", 1308 | "tower", 1309 | "tower-layer", 1310 | "tower-service", 1311 | ] 1312 | 1313 | [[package]] 1314 | name = "tower-layer" 1315 | version = "0.3.3" 1316 | source = "registry+https://github.com/rust-lang/crates.io-index" 1317 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 1318 | 1319 | [[package]] 1320 | name = "tower-service" 1321 | version = "0.3.3" 1322 | source = "registry+https://github.com/rust-lang/crates.io-index" 1323 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 1324 | 1325 | [[package]] 1326 | name = "tracing" 1327 | version = "0.1.41" 1328 | source = "registry+https://github.com/rust-lang/crates.io-index" 1329 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 1330 | dependencies = [ 1331 | "pin-project-lite", 1332 | "tracing-core", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "tracing-core" 1337 | version = "0.1.33" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 1340 | dependencies = [ 1341 | "once_cell", 1342 | ] 1343 | 1344 | [[package]] 1345 | name = "try-lock" 1346 | version = "0.2.5" 1347 | source = "registry+https://github.com/rust-lang/crates.io-index" 1348 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1349 | 1350 | [[package]] 1351 | name = "unicode-ident" 1352 | version = "1.0.18" 1353 | source = "registry+https://github.com/rust-lang/crates.io-index" 1354 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 1355 | 1356 | [[package]] 1357 | name = "untrusted" 1358 | version = "0.9.0" 1359 | source = "registry+https://github.com/rust-lang/crates.io-index" 1360 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1361 | 1362 | [[package]] 1363 | name = "url" 1364 | version = "2.5.4" 1365 | source = "registry+https://github.com/rust-lang/crates.io-index" 1366 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 1367 | dependencies = [ 1368 | "form_urlencoded", 1369 | "idna", 1370 | "percent-encoding", 1371 | ] 1372 | 1373 | [[package]] 1374 | name = "utf8_iter" 1375 | version = "1.0.4" 1376 | source = "registry+https://github.com/rust-lang/crates.io-index" 1377 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 1378 | 1379 | [[package]] 1380 | name = "utf8parse" 1381 | version = "0.2.2" 1382 | source = "registry+https://github.com/rust-lang/crates.io-index" 1383 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 1384 | 1385 | [[package]] 1386 | name = "vcpkg" 1387 | version = "0.2.15" 1388 | source = "registry+https://github.com/rust-lang/crates.io-index" 1389 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1390 | 1391 | [[package]] 1392 | name = "want" 1393 | version = "0.3.1" 1394 | source = "registry+https://github.com/rust-lang/crates.io-index" 1395 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 1396 | dependencies = [ 1397 | "try-lock", 1398 | ] 1399 | 1400 | [[package]] 1401 | name = "wasi" 1402 | version = "0.11.0+wasi-snapshot-preview1" 1403 | source = "registry+https://github.com/rust-lang/crates.io-index" 1404 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1405 | 1406 | [[package]] 1407 | name = "wasi" 1408 | version = "0.14.2+wasi-0.2.4" 1409 | source = "registry+https://github.com/rust-lang/crates.io-index" 1410 | checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" 1411 | dependencies = [ 1412 | "wit-bindgen-rt", 1413 | ] 1414 | 1415 | [[package]] 1416 | name = "wasm-bindgen" 1417 | version = "0.2.100" 1418 | source = "registry+https://github.com/rust-lang/crates.io-index" 1419 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 1420 | dependencies = [ 1421 | "cfg-if", 1422 | "once_cell", 1423 | "rustversion", 1424 | "wasm-bindgen-macro", 1425 | ] 1426 | 1427 | [[package]] 1428 | name = "wasm-bindgen-backend" 1429 | version = "0.2.100" 1430 | source = "registry+https://github.com/rust-lang/crates.io-index" 1431 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 1432 | dependencies = [ 1433 | "bumpalo", 1434 | "log", 1435 | "proc-macro2", 1436 | "quote", 1437 | "syn", 1438 | "wasm-bindgen-shared", 1439 | ] 1440 | 1441 | [[package]] 1442 | name = "wasm-bindgen-futures" 1443 | version = "0.4.50" 1444 | source = "registry+https://github.com/rust-lang/crates.io-index" 1445 | checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" 1446 | dependencies = [ 1447 | "cfg-if", 1448 | "js-sys", 1449 | "once_cell", 1450 | "wasm-bindgen", 1451 | "web-sys", 1452 | ] 1453 | 1454 | [[package]] 1455 | name = "wasm-bindgen-macro" 1456 | version = "0.2.100" 1457 | source = "registry+https://github.com/rust-lang/crates.io-index" 1458 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 1459 | dependencies = [ 1460 | "quote", 1461 | "wasm-bindgen-macro-support", 1462 | ] 1463 | 1464 | [[package]] 1465 | name = "wasm-bindgen-macro-support" 1466 | version = "0.2.100" 1467 | source = "registry+https://github.com/rust-lang/crates.io-index" 1468 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 1469 | dependencies = [ 1470 | "proc-macro2", 1471 | "quote", 1472 | "syn", 1473 | "wasm-bindgen-backend", 1474 | "wasm-bindgen-shared", 1475 | ] 1476 | 1477 | [[package]] 1478 | name = "wasm-bindgen-shared" 1479 | version = "0.2.100" 1480 | source = "registry+https://github.com/rust-lang/crates.io-index" 1481 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 1482 | dependencies = [ 1483 | "unicode-ident", 1484 | ] 1485 | 1486 | [[package]] 1487 | name = "web-sys" 1488 | version = "0.3.77" 1489 | source = "registry+https://github.com/rust-lang/crates.io-index" 1490 | checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" 1491 | dependencies = [ 1492 | "js-sys", 1493 | "wasm-bindgen", 1494 | ] 1495 | 1496 | [[package]] 1497 | name = "windows-link" 1498 | version = "0.1.1" 1499 | source = "registry+https://github.com/rust-lang/crates.io-index" 1500 | checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" 1501 | 1502 | [[package]] 1503 | name = "windows-registry" 1504 | version = "0.4.0" 1505 | source = "registry+https://github.com/rust-lang/crates.io-index" 1506 | checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" 1507 | dependencies = [ 1508 | "windows-result", 1509 | "windows-strings", 1510 | "windows-targets 0.53.0", 1511 | ] 1512 | 1513 | [[package]] 1514 | name = "windows-result" 1515 | version = "0.3.4" 1516 | source = "registry+https://github.com/rust-lang/crates.io-index" 1517 | checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" 1518 | dependencies = [ 1519 | "windows-link", 1520 | ] 1521 | 1522 | [[package]] 1523 | name = "windows-strings" 1524 | version = "0.3.1" 1525 | source = "registry+https://github.com/rust-lang/crates.io-index" 1526 | checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" 1527 | dependencies = [ 1528 | "windows-link", 1529 | ] 1530 | 1531 | [[package]] 1532 | name = "windows-sys" 1533 | version = "0.52.0" 1534 | source = "registry+https://github.com/rust-lang/crates.io-index" 1535 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 1536 | dependencies = [ 1537 | "windows-targets 0.52.6", 1538 | ] 1539 | 1540 | [[package]] 1541 | name = "windows-sys" 1542 | version = "0.59.0" 1543 | source = "registry+https://github.com/rust-lang/crates.io-index" 1544 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 1545 | dependencies = [ 1546 | "windows-targets 0.52.6", 1547 | ] 1548 | 1549 | [[package]] 1550 | name = "windows-targets" 1551 | version = "0.52.6" 1552 | source = "registry+https://github.com/rust-lang/crates.io-index" 1553 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 1554 | dependencies = [ 1555 | "windows_aarch64_gnullvm 0.52.6", 1556 | "windows_aarch64_msvc 0.52.6", 1557 | "windows_i686_gnu 0.52.6", 1558 | "windows_i686_gnullvm 0.52.6", 1559 | "windows_i686_msvc 0.52.6", 1560 | "windows_x86_64_gnu 0.52.6", 1561 | "windows_x86_64_gnullvm 0.52.6", 1562 | "windows_x86_64_msvc 0.52.6", 1563 | ] 1564 | 1565 | [[package]] 1566 | name = "windows-targets" 1567 | version = "0.53.0" 1568 | source = "registry+https://github.com/rust-lang/crates.io-index" 1569 | checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" 1570 | dependencies = [ 1571 | "windows_aarch64_gnullvm 0.53.0", 1572 | "windows_aarch64_msvc 0.53.0", 1573 | "windows_i686_gnu 0.53.0", 1574 | "windows_i686_gnullvm 0.53.0", 1575 | "windows_i686_msvc 0.53.0", 1576 | "windows_x86_64_gnu 0.53.0", 1577 | "windows_x86_64_gnullvm 0.53.0", 1578 | "windows_x86_64_msvc 0.53.0", 1579 | ] 1580 | 1581 | [[package]] 1582 | name = "windows_aarch64_gnullvm" 1583 | version = "0.52.6" 1584 | source = "registry+https://github.com/rust-lang/crates.io-index" 1585 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 1586 | 1587 | [[package]] 1588 | name = "windows_aarch64_gnullvm" 1589 | version = "0.53.0" 1590 | source = "registry+https://github.com/rust-lang/crates.io-index" 1591 | checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" 1592 | 1593 | [[package]] 1594 | name = "windows_aarch64_msvc" 1595 | version = "0.52.6" 1596 | source = "registry+https://github.com/rust-lang/crates.io-index" 1597 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 1598 | 1599 | [[package]] 1600 | name = "windows_aarch64_msvc" 1601 | version = "0.53.0" 1602 | source = "registry+https://github.com/rust-lang/crates.io-index" 1603 | checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" 1604 | 1605 | [[package]] 1606 | name = "windows_i686_gnu" 1607 | version = "0.52.6" 1608 | source = "registry+https://github.com/rust-lang/crates.io-index" 1609 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 1610 | 1611 | [[package]] 1612 | name = "windows_i686_gnu" 1613 | version = "0.53.0" 1614 | source = "registry+https://github.com/rust-lang/crates.io-index" 1615 | checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" 1616 | 1617 | [[package]] 1618 | name = "windows_i686_gnullvm" 1619 | version = "0.52.6" 1620 | source = "registry+https://github.com/rust-lang/crates.io-index" 1621 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 1622 | 1623 | [[package]] 1624 | name = "windows_i686_gnullvm" 1625 | version = "0.53.0" 1626 | source = "registry+https://github.com/rust-lang/crates.io-index" 1627 | checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" 1628 | 1629 | [[package]] 1630 | name = "windows_i686_msvc" 1631 | version = "0.52.6" 1632 | source = "registry+https://github.com/rust-lang/crates.io-index" 1633 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 1634 | 1635 | [[package]] 1636 | name = "windows_i686_msvc" 1637 | version = "0.53.0" 1638 | source = "registry+https://github.com/rust-lang/crates.io-index" 1639 | checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" 1640 | 1641 | [[package]] 1642 | name = "windows_x86_64_gnu" 1643 | version = "0.52.6" 1644 | source = "registry+https://github.com/rust-lang/crates.io-index" 1645 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 1646 | 1647 | [[package]] 1648 | name = "windows_x86_64_gnu" 1649 | version = "0.53.0" 1650 | source = "registry+https://github.com/rust-lang/crates.io-index" 1651 | checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" 1652 | 1653 | [[package]] 1654 | name = "windows_x86_64_gnullvm" 1655 | version = "0.52.6" 1656 | source = "registry+https://github.com/rust-lang/crates.io-index" 1657 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 1658 | 1659 | [[package]] 1660 | name = "windows_x86_64_gnullvm" 1661 | version = "0.53.0" 1662 | source = "registry+https://github.com/rust-lang/crates.io-index" 1663 | checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" 1664 | 1665 | [[package]] 1666 | name = "windows_x86_64_msvc" 1667 | version = "0.52.6" 1668 | source = "registry+https://github.com/rust-lang/crates.io-index" 1669 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 1670 | 1671 | [[package]] 1672 | name = "windows_x86_64_msvc" 1673 | version = "0.53.0" 1674 | source = "registry+https://github.com/rust-lang/crates.io-index" 1675 | checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" 1676 | 1677 | [[package]] 1678 | name = "wit-bindgen-rt" 1679 | version = "0.39.0" 1680 | source = "registry+https://github.com/rust-lang/crates.io-index" 1681 | checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" 1682 | dependencies = [ 1683 | "bitflags", 1684 | ] 1685 | 1686 | [[package]] 1687 | name = "writeable" 1688 | version = "0.6.1" 1689 | source = "registry+https://github.com/rust-lang/crates.io-index" 1690 | checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" 1691 | 1692 | [[package]] 1693 | name = "yoke" 1694 | version = "0.8.0" 1695 | source = "registry+https://github.com/rust-lang/crates.io-index" 1696 | checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" 1697 | dependencies = [ 1698 | "serde", 1699 | "stable_deref_trait", 1700 | "yoke-derive", 1701 | "zerofrom", 1702 | ] 1703 | 1704 | [[package]] 1705 | name = "yoke-derive" 1706 | version = "0.8.0" 1707 | source = "registry+https://github.com/rust-lang/crates.io-index" 1708 | checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" 1709 | dependencies = [ 1710 | "proc-macro2", 1711 | "quote", 1712 | "syn", 1713 | "synstructure", 1714 | ] 1715 | 1716 | [[package]] 1717 | name = "zerofrom" 1718 | version = "0.1.6" 1719 | source = "registry+https://github.com/rust-lang/crates.io-index" 1720 | checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 1721 | dependencies = [ 1722 | "zerofrom-derive", 1723 | ] 1724 | 1725 | [[package]] 1726 | name = "zerofrom-derive" 1727 | version = "0.1.6" 1728 | source = "registry+https://github.com/rust-lang/crates.io-index" 1729 | checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 1730 | dependencies = [ 1731 | "proc-macro2", 1732 | "quote", 1733 | "syn", 1734 | "synstructure", 1735 | ] 1736 | 1737 | [[package]] 1738 | name = "zeroize" 1739 | version = "1.8.1" 1740 | source = "registry+https://github.com/rust-lang/crates.io-index" 1741 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 1742 | 1743 | [[package]] 1744 | name = "zerotrie" 1745 | version = "0.2.2" 1746 | source = "registry+https://github.com/rust-lang/crates.io-index" 1747 | checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" 1748 | dependencies = [ 1749 | "displaydoc", 1750 | "yoke", 1751 | "zerofrom", 1752 | ] 1753 | 1754 | [[package]] 1755 | name = "zerovec" 1756 | version = "0.11.2" 1757 | source = "registry+https://github.com/rust-lang/crates.io-index" 1758 | checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" 1759 | dependencies = [ 1760 | "yoke", 1761 | "zerofrom", 1762 | "zerovec-derive", 1763 | ] 1764 | 1765 | [[package]] 1766 | name = "zerovec-derive" 1767 | version = "0.11.1" 1768 | source = "registry+https://github.com/rust-lang/crates.io-index" 1769 | checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" 1770 | dependencies = [ 1771 | "proc-macro2", 1772 | "quote", 1773 | "syn", 1774 | ] 1775 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "git-dumper" 3 | version = "0.1.2" 4 | edition = "2021" 5 | description = "A tool to dump exposed .git directories" 6 | license = "MIT" 7 | repository = "https://github.com/HoLLy-HaCKeR/git-dumper" 8 | keywords = ["git", "security", "scrapers"] 9 | categories = ["command-line-utilities"] 10 | exclude = ["test-data"] 11 | 12 | [profile.release] 13 | lto = true 14 | 15 | [dependencies] 16 | anyhow = "1.0.65" 17 | clap = { version = "4.2.5", features = ["derive"] } 18 | lazy_static = "1.4.0" 19 | miniz_oxide = "0.8.8" 20 | regex = "1.6" 21 | reqwest = "0.12.19" 22 | tokio = { version = "1.21", features = [ 23 | "net", 24 | "sync", 25 | "rt", 26 | "rt-multi-thread", 27 | "macros", 28 | ] } 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 HoLLy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # git-dumper 2 | 3 | This repository houses a tool to dump exposed .git repositories. This is a rewrite from the original [GitTools](https://github.com/internetwache/GitTools/)'s Dumper project, but in a real programming language with parallelism for massive speed gains (over 10x faster). 4 | 5 | ## Why? 6 | Many (lazy?) developers deploy their projects to their webservers through git: they run `git clone https://url/to/my-repo.git` in their web server's content directory. Doing this often leaves a `.git` folder exposed which an attacker can scrape and use to reconstruct your website's source code and version history. This tool does exactly that: scrape the .git directory so you can have a copy locally. 7 | 8 | ## Limitations 9 | Git may run "garbage collection" on your repository which causes it to compact multiple object files into "pack" files. While object files can be found fairly easily through references from other object files, pack files dont seem to have explicit references to them and can not be downloaded without having a directory listing. If you do have a directory listing, you dont need this tool and can download the repository using `wget` :) 10 | 11 | ## Related projects 12 | - [GitTools](https://github.com/internetwache/GitTools/), which inspired this project. 13 | - [DotGit](https://github.com/davtur19/DotGit), a browser extension that automatically checks for exposed .git directories. 14 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "flake-utils": { 4 | "inputs": { 5 | "systems": "systems" 6 | }, 7 | "locked": { 8 | "lastModified": 1731533236, 9 | "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 10 | "owner": "numtide", 11 | "repo": "flake-utils", 12 | "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 13 | "type": "github" 14 | }, 15 | "original": { 16 | "owner": "numtide", 17 | "repo": "flake-utils", 18 | "type": "github" 19 | } 20 | }, 21 | "nixpkgs": { 22 | "locked": { 23 | "lastModified": 1748856973, 24 | "narHash": "sha256-RlTsJUvvr8ErjPBsiwrGbbHYW8XbB/oek0Gi78XdWKg=", 25 | "owner": "NixOS", 26 | "repo": "nixpkgs", 27 | "rev": "e4b09e47ace7d87de083786b404bf232eb6c89d8", 28 | "type": "github" 29 | }, 30 | "original": { 31 | "owner": "NixOS", 32 | "ref": "nixpkgs-unstable", 33 | "repo": "nixpkgs", 34 | "type": "github" 35 | } 36 | }, 37 | "root": { 38 | "inputs": { 39 | "flake-utils": "flake-utils", 40 | "nixpkgs": "nixpkgs", 41 | "rust-overlay": "rust-overlay" 42 | } 43 | }, 44 | "rust-overlay": { 45 | "inputs": { 46 | "nixpkgs": [ 47 | "nixpkgs" 48 | ] 49 | }, 50 | "locked": { 51 | "lastModified": 1747332411, 52 | "narHash": "sha256-2LOxMLddhMoJphMU/72Ls6Rvp38aJUrp7OhWwyvslek=", 53 | "owner": "oxalica", 54 | "repo": "rust-overlay", 55 | "rev": "10d4529b7ead35863caa77993915104345524bed", 56 | "type": "github" 57 | }, 58 | "original": { 59 | "owner": "oxalica", 60 | "ref": "stable", 61 | "repo": "rust-overlay", 62 | "type": "github" 63 | } 64 | }, 65 | "systems": { 66 | "locked": { 67 | "lastModified": 1681028828, 68 | "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 69 | "owner": "nix-systems", 70 | "repo": "default", 71 | "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 72 | "type": "github" 73 | }, 74 | "original": { 75 | "owner": "nix-systems", 76 | "repo": "default", 77 | "type": "github" 78 | } 79 | } 80 | }, 81 | "root": "root", 82 | "version": 7 83 | } 84 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | inputs = { 3 | nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; 4 | flake-utils.url = "github:numtide/flake-utils"; 5 | rust-overlay = { 6 | url = "github:oxalica/rust-overlay/stable"; 7 | inputs.nixpkgs.follows = "nixpkgs"; 8 | }; 9 | }; 10 | 11 | outputs = { 12 | self, 13 | nixpkgs, 14 | flake-utils, 15 | rust-overlay, 16 | ... 17 | }: 18 | flake-utils.lib.eachDefaultSystem (system: let 19 | overlays = [(import rust-overlay)]; 20 | pkgs = import nixpkgs {inherit system overlays;}; 21 | in 22 | with pkgs; rec { 23 | devShells.default = mkShell rec { 24 | nativeBuildInputs = [ 25 | (rust-bin.stable.latest.default.override { 26 | extensions = ["rust-analyzer" "rust-src"]; 27 | }) 28 | pkg-config 29 | openssl 30 | ]; 31 | buildInputs = []; 32 | packages = []; 33 | }; 34 | }); 35 | } 36 | -------------------------------------------------------------------------------- /src/dump_git.rs: -------------------------------------------------------------------------------- 1 | use std::{collections::HashSet, path::Path, sync::Arc, time::Duration}; 2 | 3 | use anyhow::{bail, Context, Result}; 4 | use regex::Regex; 5 | use reqwest::{Client, StatusCode}; 6 | use tokio::{ 7 | sync::mpsc::{self, UnboundedSender}, 8 | time::sleep, 9 | }; 10 | 11 | use crate::{ 12 | git_parsing::{parse_hash, parse_head, parse_log, parse_object, GitObject}, 13 | Args, 14 | }; 15 | 16 | lazy_static::lazy_static! { 17 | static ref REGEX_OBJECT_PATH: Regex = Regex::new(r"[\da-f]{2}/[\da-f]{38}").unwrap(); 18 | } 19 | 20 | const START_FILES: &[&str] = &[ 21 | "info/exclude", 22 | "logs/HEAD", 23 | "objects/info/packs", // TODO: this does not seem to be present anymore? 24 | "config", 25 | "COMMIT_EDITMSG", 26 | "description", 27 | "FETCH_HEAD", 28 | "HEAD", 29 | "index", 30 | "ORIG_HEAD", 31 | "packed-refs", 32 | "refs/remotes/origin/HEAD", // guessing remote names seems pointless, it's `origin` 99% of the time 33 | ]; 34 | 35 | // TODO: brute-force files based on known and unknown branch names 36 | 37 | #[derive(Debug)] 38 | struct DownloadedFile { 39 | pub path: String, 40 | pub tx: UnboundedSender, 41 | } 42 | 43 | pub async fn download_all(args: Arc) { 44 | let base_url = &args.url; 45 | let base_path = &args.path; 46 | let mut cache = HashSet::::new(); 47 | 48 | // TODO: try out unbounded channel too 49 | // TODO: maybe just have a cli option that determines the limit of concurrent downloads instead? 50 | let (tx, mut rx) = mpsc::unbounded_channel(); 51 | 52 | for &file in START_FILES { 53 | // let new_tx = tx.clone(); 54 | // cache.download(file, new_tx); 55 | tx.send(DownloadedFile { 56 | path: file.into(), 57 | tx: tx.clone(), 58 | }) 59 | .unwrap(); 60 | } 61 | 62 | // drop the sender object so all senders can be out of scope by the end of the download 63 | drop(tx); 64 | 65 | // every time we downloaded a new file, see what other files we can derive from it 66 | let mut threads = vec![]; 67 | while let Some(message) = rx.recv().await { 68 | // TODO: if this file is already downloaded, continue 69 | if cache.contains(&message.path) { 70 | // println!("Skipping download of file {file_name} as it's already downloaded"); 71 | continue; 72 | } 73 | 74 | cache.insert(message.path.clone()); 75 | 76 | let url = format!("{}{}", &base_url, &message.path); 77 | let base_path = base_path.clone(); 78 | let cloned_args = args.clone(); 79 | let handle = tokio::spawn(async move { 80 | let file_bytes = match download(&url, cloned_args).await { 81 | Ok(content) => content, 82 | Err(e) => { 83 | println!("Error while downloading file {url}: {}", e); 84 | return; 85 | } 86 | }; 87 | 88 | println!("Downloaded '{}' ({} bytes)", message.path, file_bytes.len()); 89 | 90 | // write this file to disk 91 | if let Err(e) = write_file(&base_path, &message.path, &file_bytes) { 92 | println!("Failed to write file {} to disk: {}", &message.path, e) 93 | } 94 | 95 | // match on the file name and queue new messages 96 | if let Err(e) = queue_new_references(message.path.as_str(), &file_bytes, message.tx) { 97 | println!("Error while trying to find new references: {e}"); 98 | } 99 | }); 100 | 101 | threads.push(handle); 102 | 103 | while threads.len() >= (args.tasks as usize) { 104 | // sleep 105 | sleep(Duration::from_millis(10)).await; 106 | 107 | // remove dead threads 108 | threads.retain(|h| !h.is_finished()); 109 | } 110 | } 111 | } 112 | 113 | async fn download(url: &str, args: Arc) -> Result> { 114 | let client = Client::new(); 115 | let req = client 116 | .get(url) 117 | .header( 118 | "User-Agent", 119 | args.user_agent 120 | .clone() 121 | .unwrap_or( 122 | "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 123 | .into(), 124 | ) 125 | .clone(), 126 | ) 127 | .build() 128 | .expect("Failed to build the request"); 129 | 130 | let resp = client.execute(req).await; 131 | match resp { 132 | Ok(resp) => match resp.status() { 133 | StatusCode::OK => { 134 | let bytes = resp.bytes().await.unwrap(); 135 | Ok(bytes.to_vec()) 136 | } 137 | StatusCode::NOT_FOUND => { 138 | bail!("Got 404 while trying to download {url}") 139 | } 140 | _ => { 141 | bail!( 142 | "Error while trying to download {url}: status code is {}", 143 | resp.status() 144 | ) 145 | } 146 | }, 147 | Err(e) => { 148 | bail!("Error while trying to download {url}: {e}"); 149 | } 150 | } 151 | } 152 | 153 | fn write_file(base_path: &Path, message_name: &str, message_content: &[u8]) -> Result<()> { 154 | let path = base_path.join(".git").join(message_name); 155 | let path_parent = path 156 | .parent() 157 | .expect("There should be at least .git as parent"); 158 | 159 | std::fs::create_dir_all(path_parent).with_context(|| { 160 | format!( 161 | "Error while trying to create directory {}", 162 | path_parent.to_string_lossy() 163 | ) 164 | })?; 165 | std::fs::write(path, message_content) 166 | .with_context(|| format!("Error while trying to write {} to disk", message_name))?; 167 | 168 | Ok(()) 169 | } 170 | 171 | fn queue_new_references( 172 | name: &str, 173 | content: &[u8], 174 | tx: UnboundedSender, 175 | ) -> Result<()> { 176 | match name { 177 | "HEAD" | "refs/remotes/origin/HEAD" => { 178 | let ref_path = parse_head(content)?; 179 | println!("\tFound ref path {ref_path}"); 180 | 181 | tx.send(DownloadedFile { 182 | path: ref_path.into(), 183 | tx: tx.clone(), 184 | }) 185 | .unwrap(); 186 | } 187 | n if n.starts_with("refs/heads/") || n == "ORIG_HEAD" => { 188 | let hash = parse_hash(content)?; 189 | println!("\tFound object hash {hash}"); 190 | 191 | tx.send(DownloadedFile { 192 | path: hash_to_url(hash), 193 | tx: tx.clone(), 194 | }) 195 | .unwrap(); 196 | } 197 | // TODO: handle FETCH_HEAD, detect branches 198 | // TODO: handle config, detect branches 199 | n if n.starts_with("logs/") => { 200 | let hashes = parse_log(content)?; 201 | 202 | println!("\tFound log with {} hashes", hashes.len()); 203 | for hash in hashes { 204 | tx.send(DownloadedFile { 205 | path: hash_to_url(&hash), 206 | tx: tx.clone(), 207 | }) 208 | .unwrap(); 209 | } 210 | } 211 | n if n.starts_with("objects/") && REGEX_OBJECT_PATH.is_match(n) => { 212 | match parse_object(content)? { 213 | GitObject::Blob => { 214 | println!("\tFound blob object"); 215 | } 216 | GitObject::Tree(hashes) => { 217 | println!("\tFound tree object with {} hashes", hashes.len()); 218 | for hash in hashes { 219 | tx.send(DownloadedFile { 220 | path: hash_to_url(&hash), 221 | tx: tx.clone(), 222 | }) 223 | .unwrap(); 224 | } 225 | } 226 | GitObject::Commit(hashes) => { 227 | println!("\tFound commit object with {} hashes", hashes.len()); 228 | for hash in hashes { 229 | tx.send(DownloadedFile { 230 | path: hash_to_url(&hash), 231 | tx: tx.clone(), 232 | }) 233 | .unwrap(); 234 | } 235 | } 236 | } 237 | } 238 | n => { 239 | println!("\tNot using file '{n}' for anything right now"); 240 | } 241 | } 242 | Ok(()) 243 | } 244 | 245 | fn hash_to_url(hash: &str) -> String { 246 | assert_eq!(hash.len(), 40, "Hash is not 40 characters long"); 247 | assert!( 248 | hash.chars().all(|c| c.is_ascii_hexdigit()), 249 | "Hash is not hexadecimal" 250 | ); 251 | let hash_start = &hash[0..2]; 252 | let hash_end = &hash[2..]; 253 | let path = format!("objects/{hash_start}/{hash_end}"); 254 | path 255 | } 256 | -------------------------------------------------------------------------------- /src/git_parsing.rs: -------------------------------------------------------------------------------- 1 | use anyhow::{anyhow, bail, Result}; 2 | use miniz_oxide::inflate::TINFLStatus; 3 | use regex::Regex; 4 | use std::{collections::HashSet, fmt::Write}; 5 | 6 | lazy_static::lazy_static! { 7 | static ref REGEX_HASH: Regex = Regex::new(r"^[a-f\d]{40}$").unwrap(); 8 | static ref REGEX_REFS_PATH: Regex = Regex::new(r"^refs/heads/(\S+)$").unwrap(); 9 | } 10 | 11 | const EMPTY_HASH: &str = "0000000000000000000000000000000000000000"; 12 | 13 | pub enum GitObject { 14 | Tree(Vec), 15 | Commit(Vec), 16 | Blob, 17 | } 18 | 19 | pub fn parse_head(data: &[u8]) -> Result<&str> { 20 | let content = std::str::from_utf8(data)?; 21 | 22 | if !content.starts_with("ref: ") { 23 | bail!("HEAD file must start with \"ref: \""); 24 | } 25 | 26 | let content = content[5..].trim_end(); 27 | 28 | if !REGEX_REFS_PATH.is_match(content) { 29 | bail!("Failed to match refs path in HEAD file"); 30 | } 31 | 32 | // check for potential path traversal 33 | // a normal git setup should never emit paths with `..` segments 34 | if content.split(['/', '\\']).any(|segment| segment == "..") { 35 | bail!( 36 | "Unexpected path traversal detected in HEAD file: {}", 37 | content 38 | ); 39 | } 40 | 41 | Ok(content) 42 | } 43 | 44 | pub fn parse_hash(data: &[u8]) -> Result<&str> { 45 | let content = std::str::from_utf8(data)?; 46 | let content = content.trim_end(); 47 | 48 | if !REGEX_HASH.is_match(content) { 49 | bail!("Failed to match hash"); 50 | } 51 | 52 | Ok(content) 53 | } 54 | 55 | pub fn parse_object(data: &[u8]) -> Result { 56 | let peek = peek_object_type(data)?; 57 | match peek { 58 | [b'b', b'l', b'o', b'b', _, _] => Ok(GitObject::Blob), 59 | [b't', b'r', b'e', b'e', _, _] => { 60 | let decompressed = miniz_oxide::inflate::decompress_to_vec_zlib(data) 61 | .map_err(|e| anyhow!("Problem while decompressing git object: {}", e))?; 62 | let decompressed = decompressed.as_slice(); 63 | 64 | let mut hashes = vec![]; 65 | 66 | // TODO: this is ugly, use a slice-based approach instead 67 | let mut decompressed_iter = split_object_at_zero(decompressed)?.iter().peekable(); 68 | while decompressed_iter.peek().is_some() { 69 | let bytes: Vec = (&mut decompressed_iter) 70 | .skip_while(|&&b| b != b'\0') 71 | .skip(1) 72 | .take(0x14) 73 | .cloned() 74 | .collect(); 75 | hashes.push(slice_to_hex(&bytes)); 76 | } 77 | 78 | Ok(GitObject::Tree(hashes)) 79 | } 80 | [b'c', b'o', b'm', b'm', b'i', b't'] => { 81 | let decompressed = miniz_oxide::inflate::decompress_to_vec_zlib(data) 82 | .map_err(|e| anyhow!("Problem while decompressing git object: {}", e))?; 83 | 84 | let decompressed = split_object_at_zero(&decompressed)?; 85 | let commit_message = String::from_utf8_lossy(decompressed); 86 | 87 | let hashes = commit_message 88 | .lines() 89 | .take_while(|&line| !line.trim().is_empty()) 90 | .filter_map(|line| match line.split_once(' ') { 91 | Some(("tree", hash)) => Some(hash.into()), 92 | Some(("parent", hash)) => Some(hash.into()), 93 | _ => None, 94 | }) 95 | .collect(); 96 | 97 | Ok(GitObject::Commit(hashes)) 98 | } 99 | _ => bail!( 100 | "Unknown git object header: {}", 101 | String::from_utf8_lossy(&peek) 102 | ), 103 | } 104 | } 105 | 106 | pub fn parse_log(data: &[u8]) -> Result> { 107 | let mut set = HashSet::new(); 108 | 109 | let content = String::from_utf8_lossy(data); 110 | 111 | for line in content.lines() { 112 | let (hash1, rest) = line.split_once(' ').unwrap_or(("", "")); 113 | let (hash2, _) = rest.split_once(' ').unwrap_or(("", "")); 114 | 115 | if REGEX_HASH.is_match(hash1) && hash1 != EMPTY_HASH { 116 | set.insert(hash1.into()); 117 | } 118 | 119 | if REGEX_HASH.is_match(hash2) && hash2 != EMPTY_HASH { 120 | set.insert(hash2.into()); 121 | } 122 | } 123 | 124 | Ok(set) 125 | } 126 | 127 | // pub fn 128 | 129 | fn peek_object_type(data: &[u8]) -> Result<[u8; 6]> { 130 | let mut array = [0u8; 6]; 131 | match miniz_oxide::inflate::decompress_slice_iter_to_slice( 132 | &mut array, 133 | data.chunks(16), 134 | true, 135 | true, 136 | ) { 137 | Ok(_) | Err(TINFLStatus::HasMoreOutput) => Ok(array), 138 | Err(e) => bail!("Error while decompressing object file for peek: {:?}", e), 139 | } 140 | } 141 | 142 | fn split_object_at_zero(data: &[u8]) -> Result<&[u8]> { 143 | let idx_zero = data 144 | .iter() 145 | .enumerate() 146 | .find(|(_, &val)| val == b'\0') 147 | .map(|(idx, _)| idx) 148 | .ok_or_else(|| anyhow!("Malformed object file, could not find null separator"))?; 149 | let data = &data[idx_zero + 1..]; 150 | Ok(data) 151 | } 152 | 153 | fn slice_to_hex(data: &[u8]) -> String { 154 | let mut s = String::with_capacity(data.len() * 2); 155 | for byte in data { 156 | write!(s, "{:02x}", byte).expect("writing hex should not fail"); 157 | } 158 | s 159 | } 160 | 161 | #[cfg(test)] 162 | mod tests { 163 | use super::*; 164 | 165 | #[test] 166 | fn parse_commit_blob() { 167 | let bytes = include_bytes!("../test-data/object-blob"); 168 | let parsed = parse_object(bytes).unwrap(); 169 | assert!(matches!(parsed, GitObject::Blob)); 170 | } 171 | 172 | #[test] 173 | fn parse_tree_object() { 174 | let bytes = include_bytes!("../test-data/object-tree"); 175 | let parsed = parse_object(bytes).unwrap(); 176 | assert!(matches!(parsed, GitObject::Tree(_))); 177 | 178 | if let GitObject::Tree(vec) = parsed { 179 | assert_eq!( 180 | vec, 181 | vec![ 182 | "93748a31e8df89b80ab5ebe4ad19ea62899a28fa".to_string(), 183 | "920512d27e4df0c79ca4a929bc5d4254b3d05c4c".to_string(), 184 | "f5463e0d810357c84bdb956dcfe70b8015d6fb24".to_string(), 185 | ] 186 | ); 187 | } 188 | } 189 | 190 | #[test] 191 | fn parse_commit_object() { 192 | let bytes = include_bytes!("../test-data/object-commit"); 193 | let parsed = parse_object(bytes).unwrap(); 194 | assert!(matches!(parsed, GitObject::Commit(_))); 195 | 196 | if let GitObject::Commit(vec) = parsed { 197 | assert_eq!( 198 | vec, 199 | vec![ 200 | "faf660b3b793f359495ad23ea2c449da6b3b64a0".to_string(), 201 | "1712bc7d3a0e6cf9920541e616310bd30f431728".to_string(), 202 | ] 203 | ); 204 | } 205 | } 206 | } 207 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use std::{path::PathBuf, sync::Arc}; 2 | 3 | use clap::Parser; 4 | 5 | mod dump_git; 6 | mod git_parsing; 7 | 8 | #[derive(Parser, Debug)] 9 | #[command(author, version, about, long_about = None)] 10 | pub struct Args { 11 | /// The url of the exposed .git directory 12 | #[arg()] 13 | url: String, 14 | 15 | #[arg(short, long)] 16 | user_agent: Option, 17 | /// The directory to download to 18 | #[arg(default_value = "git-dumped")] 19 | path: PathBuf, 20 | 21 | /// Sets the maximum of concurrent download tasks that can be running 22 | #[arg(short, long, default_value_t = 8)] 23 | tasks: u16, 24 | } 25 | 26 | #[tokio::main] 27 | async fn main() -> Result<(), Box> { 28 | let mut args = Args::parse(); 29 | 30 | if dbg!(!args.url.ends_with("/")) { 31 | args.url.push('/'); 32 | } 33 | 34 | std::fs::create_dir_all(args.path.join(".git"))?; 35 | dump_git::download_all(Arc::new(args)).await; 36 | 37 | Ok(()) 38 | } 39 | -------------------------------------------------------------------------------- /test-data/object-blob: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holly-hacker/git-dumper/660483e877f46dcba70aeaf9c9d909b8ab268f03/test-data/object-blob -------------------------------------------------------------------------------- /test-data/object-commit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holly-hacker/git-dumper/660483e877f46dcba70aeaf9c9d909b8ab268f03/test-data/object-commit -------------------------------------------------------------------------------- /test-data/object-tree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/holly-hacker/git-dumper/660483e877f46dcba70aeaf9c9d909b8ab268f03/test-data/object-tree --------------------------------------------------------------------------------