├── .github └── workflows │ └── ci.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md └── src ├── main.rs └── rib-config.toml /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | release: 9 | types: [published] 10 | 11 | env: 12 | CARGO_TERM_COLOR: always 13 | 14 | jobs: 15 | test: 16 | runs-on: ubuntu-latest 17 | 18 | steps: 19 | - name: Checkout repo 20 | uses: actions/checkout@v3 21 | 22 | - name: Rust caching 23 | uses: Swatinem/rust-cache@v1 24 | 25 | - name: Install toolchain 26 | uses: actions-rs/toolchain@v1 27 | with: 28 | profile: minimal 29 | toolchain: stable 30 | override: true 31 | components: rustfmt, clippy 32 | 33 | - name: Cargo build 34 | uses: actions-rs/cargo@v1 35 | with: 36 | command: build 37 | 38 | - name: Cargo fmt 39 | uses: actions-rs/cargo@v1 40 | with: 41 | command: fmt 42 | args: --all -- --check 43 | 44 | - name: Cargo clippy 45 | uses: actions-rs/cargo@v1 46 | with: 47 | command: clippy 48 | args: -- -D warnings 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "android_system_properties" 7 | version = "0.1.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 10 | dependencies = [ 11 | "libc", 12 | ] 13 | 14 | [[package]] 15 | name = "anyhow" 16 | version = "1.0.66" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "216261ddc8289130e551ddcd5ce8a064710c0d064a4d2895c67151c92b5443f6" 19 | 20 | [[package]] 21 | name = "atty" 22 | version = "0.2.14" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 25 | dependencies = [ 26 | "hermit-abi", 27 | "libc", 28 | "winapi", 29 | ] 30 | 31 | [[package]] 32 | name = "autocfg" 33 | version = "1.1.0" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 36 | 37 | [[package]] 38 | name = "base64" 39 | version = "0.13.1" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" 42 | 43 | [[package]] 44 | name = "bitflags" 45 | version = "1.3.2" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 48 | 49 | [[package]] 50 | name = "bumpalo" 51 | version = "3.11.1" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" 54 | 55 | [[package]] 56 | name = "bytes" 57 | version = "1.3.0" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" 60 | 61 | [[package]] 62 | name = "cc" 63 | version = "1.0.77" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" 66 | 67 | [[package]] 68 | name = "cfg-if" 69 | version = "1.0.0" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 72 | 73 | [[package]] 74 | name = "chrono" 75 | version = "0.4.23" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" 78 | dependencies = [ 79 | "iana-time-zone", 80 | "js-sys", 81 | "num-integer", 82 | "num-traits", 83 | "serde", 84 | "time", 85 | "wasm-bindgen", 86 | "winapi", 87 | ] 88 | 89 | [[package]] 90 | name = "clap" 91 | version = "3.2.23" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" 94 | dependencies = [ 95 | "atty", 96 | "bitflags", 97 | "clap_derive", 98 | "clap_lex", 99 | "indexmap", 100 | "once_cell", 101 | "strsim", 102 | "termcolor", 103 | "textwrap", 104 | ] 105 | 106 | [[package]] 107 | name = "clap_derive" 108 | version = "3.2.18" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" 111 | dependencies = [ 112 | "heck", 113 | "proc-macro-error", 114 | "proc-macro2", 115 | "quote", 116 | "syn", 117 | ] 118 | 119 | [[package]] 120 | name = "clap_lex" 121 | version = "0.2.4" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" 124 | dependencies = [ 125 | "os_str_bytes", 126 | ] 127 | 128 | [[package]] 129 | name = "codespan-reporting" 130 | version = "0.11.1" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 133 | dependencies = [ 134 | "termcolor", 135 | "unicode-width", 136 | ] 137 | 138 | [[package]] 139 | name = "core-foundation" 140 | version = "0.9.3" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 143 | dependencies = [ 144 | "core-foundation-sys", 145 | "libc", 146 | ] 147 | 148 | [[package]] 149 | name = "core-foundation-sys" 150 | version = "0.8.3" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 153 | 154 | [[package]] 155 | name = "cxx" 156 | version = "1.0.82" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "d4a41a86530d0fe7f5d9ea779916b7cadd2d4f9add748b99c2c029cbbdfaf453" 159 | dependencies = [ 160 | "cc", 161 | "cxxbridge-flags", 162 | "cxxbridge-macro", 163 | "link-cplusplus", 164 | ] 165 | 166 | [[package]] 167 | name = "cxx-build" 168 | version = "1.0.82" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "06416d667ff3e3ad2df1cd8cd8afae5da26cf9cec4d0825040f88b5ca659a2f0" 171 | dependencies = [ 172 | "cc", 173 | "codespan-reporting", 174 | "once_cell", 175 | "proc-macro2", 176 | "quote", 177 | "scratch", 178 | "syn", 179 | ] 180 | 181 | [[package]] 182 | name = "cxxbridge-flags" 183 | version = "1.0.82" 184 | source = "registry+https://github.com/rust-lang/crates.io-index" 185 | checksum = "820a9a2af1669deeef27cb271f476ffd196a2c4b6731336011e0ba63e2c7cf71" 186 | 187 | [[package]] 188 | name = "cxxbridge-macro" 189 | version = "1.0.82" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "a08a6e2fcc370a089ad3b4aaf54db3b1b4cee38ddabce5896b33eb693275f470" 192 | dependencies = [ 193 | "proc-macro2", 194 | "quote", 195 | "syn", 196 | ] 197 | 198 | [[package]] 199 | name = "encoding_rs" 200 | version = "0.8.31" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" 203 | dependencies = [ 204 | "cfg-if", 205 | ] 206 | 207 | [[package]] 208 | name = "fastrand" 209 | version = "1.8.0" 210 | source = "registry+https://github.com/rust-lang/crates.io-index" 211 | checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" 212 | dependencies = [ 213 | "instant", 214 | ] 215 | 216 | [[package]] 217 | name = "fnv" 218 | version = "1.0.7" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 221 | 222 | [[package]] 223 | name = "foreign-types" 224 | version = "0.3.2" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 227 | dependencies = [ 228 | "foreign-types-shared", 229 | ] 230 | 231 | [[package]] 232 | name = "foreign-types-shared" 233 | version = "0.1.1" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 236 | 237 | [[package]] 238 | name = "form_urlencoded" 239 | version = "1.1.0" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 242 | dependencies = [ 243 | "percent-encoding", 244 | ] 245 | 246 | [[package]] 247 | name = "futures-channel" 248 | version = "0.3.25" 249 | source = "registry+https://github.com/rust-lang/crates.io-index" 250 | checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" 251 | dependencies = [ 252 | "futures-core", 253 | ] 254 | 255 | [[package]] 256 | name = "futures-core" 257 | version = "0.3.25" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" 260 | 261 | [[package]] 262 | name = "futures-io" 263 | version = "0.3.25" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" 266 | 267 | [[package]] 268 | name = "futures-sink" 269 | version = "0.3.25" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" 272 | 273 | [[package]] 274 | name = "futures-task" 275 | version = "0.3.25" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" 278 | 279 | [[package]] 280 | name = "futures-util" 281 | version = "0.3.25" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" 284 | dependencies = [ 285 | "futures-core", 286 | "futures-io", 287 | "futures-task", 288 | "memchr", 289 | "pin-project-lite", 290 | "pin-utils", 291 | "slab", 292 | ] 293 | 294 | [[package]] 295 | name = "getrandom" 296 | version = "0.2.10" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" 299 | dependencies = [ 300 | "cfg-if", 301 | "libc", 302 | "wasi 0.11.0+wasi-snapshot-preview1", 303 | ] 304 | 305 | [[package]] 306 | name = "h2" 307 | version = "0.3.15" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "5f9f29bc9dda355256b2916cf526ab02ce0aeaaaf2bad60d65ef3f12f11dd0f4" 310 | dependencies = [ 311 | "bytes", 312 | "fnv", 313 | "futures-core", 314 | "futures-sink", 315 | "futures-util", 316 | "http", 317 | "indexmap", 318 | "slab", 319 | "tokio", 320 | "tokio-util", 321 | "tracing", 322 | ] 323 | 324 | [[package]] 325 | name = "hashbrown" 326 | version = "0.12.3" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 329 | 330 | [[package]] 331 | name = "heck" 332 | version = "0.4.0" 333 | source = "registry+https://github.com/rust-lang/crates.io-index" 334 | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" 335 | 336 | [[package]] 337 | name = "hermit-abi" 338 | version = "0.1.19" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 341 | dependencies = [ 342 | "libc", 343 | ] 344 | 345 | [[package]] 346 | name = "http" 347 | version = "0.2.8" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" 350 | dependencies = [ 351 | "bytes", 352 | "fnv", 353 | "itoa", 354 | ] 355 | 356 | [[package]] 357 | name = "http-body" 358 | version = "0.4.5" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 361 | dependencies = [ 362 | "bytes", 363 | "http", 364 | "pin-project-lite", 365 | ] 366 | 367 | [[package]] 368 | name = "httparse" 369 | version = "1.8.0" 370 | source = "registry+https://github.com/rust-lang/crates.io-index" 371 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 372 | 373 | [[package]] 374 | name = "httpdate" 375 | version = "1.0.2" 376 | source = "registry+https://github.com/rust-lang/crates.io-index" 377 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 378 | 379 | [[package]] 380 | name = "hyper" 381 | version = "0.14.23" 382 | source = "registry+https://github.com/rust-lang/crates.io-index" 383 | checksum = "034711faac9d2166cb1baf1a2fb0b60b1f277f8492fd72176c17f3515e1abd3c" 384 | dependencies = [ 385 | "bytes", 386 | "futures-channel", 387 | "futures-core", 388 | "futures-util", 389 | "h2", 390 | "http", 391 | "http-body", 392 | "httparse", 393 | "httpdate", 394 | "itoa", 395 | "pin-project-lite", 396 | "socket2", 397 | "tokio", 398 | "tower-service", 399 | "tracing", 400 | "want", 401 | ] 402 | 403 | [[package]] 404 | name = "hyper-tls" 405 | version = "0.5.0" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 408 | dependencies = [ 409 | "bytes", 410 | "hyper", 411 | "native-tls", 412 | "tokio", 413 | "tokio-native-tls", 414 | ] 415 | 416 | [[package]] 417 | name = "iana-time-zone" 418 | version = "0.1.53" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" 421 | dependencies = [ 422 | "android_system_properties", 423 | "core-foundation-sys", 424 | "iana-time-zone-haiku", 425 | "js-sys", 426 | "wasm-bindgen", 427 | "winapi", 428 | ] 429 | 430 | [[package]] 431 | name = "iana-time-zone-haiku" 432 | version = "0.1.1" 433 | source = "registry+https://github.com/rust-lang/crates.io-index" 434 | checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" 435 | dependencies = [ 436 | "cxx", 437 | "cxx-build", 438 | ] 439 | 440 | [[package]] 441 | name = "idna" 442 | version = "0.3.0" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 445 | dependencies = [ 446 | "unicode-bidi", 447 | "unicode-normalization", 448 | ] 449 | 450 | [[package]] 451 | name = "indexmap" 452 | version = "1.9.2" 453 | source = "registry+https://github.com/rust-lang/crates.io-index" 454 | checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" 455 | dependencies = [ 456 | "autocfg", 457 | "hashbrown", 458 | ] 459 | 460 | [[package]] 461 | name = "instant" 462 | version = "0.1.12" 463 | source = "registry+https://github.com/rust-lang/crates.io-index" 464 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 465 | dependencies = [ 466 | "cfg-if", 467 | ] 468 | 469 | [[package]] 470 | name = "ipnet" 471 | version = "2.5.1" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "f88c5561171189e69df9d98bcf18fd5f9558300f7ea7b801eb8a0fd748bd8745" 474 | 475 | [[package]] 476 | name = "itoa" 477 | version = "1.0.4" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" 480 | 481 | [[package]] 482 | name = "js-sys" 483 | version = "0.3.60" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" 486 | dependencies = [ 487 | "wasm-bindgen", 488 | ] 489 | 490 | [[package]] 491 | name = "lazy_static" 492 | version = "1.4.0" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 495 | 496 | [[package]] 497 | name = "libc" 498 | version = "0.2.148" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" 501 | 502 | [[package]] 503 | name = "link-cplusplus" 504 | version = "1.0.7" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" 507 | dependencies = [ 508 | "cc", 509 | ] 510 | 511 | [[package]] 512 | name = "log" 513 | version = "0.4.17" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 516 | dependencies = [ 517 | "cfg-if", 518 | ] 519 | 520 | [[package]] 521 | name = "memchr" 522 | version = "2.5.0" 523 | source = "registry+https://github.com/rust-lang/crates.io-index" 524 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 525 | 526 | [[package]] 527 | name = "mime" 528 | version = "0.3.16" 529 | source = "registry+https://github.com/rust-lang/crates.io-index" 530 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 531 | 532 | [[package]] 533 | name = "mio" 534 | version = "0.8.5" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" 537 | dependencies = [ 538 | "libc", 539 | "log", 540 | "wasi 0.11.0+wasi-snapshot-preview1", 541 | "windows-sys 0.42.0", 542 | ] 543 | 544 | [[package]] 545 | name = "native-tls" 546 | version = "0.2.11" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" 549 | dependencies = [ 550 | "lazy_static", 551 | "libc", 552 | "log", 553 | "openssl", 554 | "openssl-probe", 555 | "openssl-sys", 556 | "schannel", 557 | "security-framework", 558 | "security-framework-sys", 559 | "tempfile", 560 | ] 561 | 562 | [[package]] 563 | name = "num-integer" 564 | version = "0.1.45" 565 | source = "registry+https://github.com/rust-lang/crates.io-index" 566 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 567 | dependencies = [ 568 | "autocfg", 569 | "num-traits", 570 | ] 571 | 572 | [[package]] 573 | name = "num-traits" 574 | version = "0.2.15" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 577 | dependencies = [ 578 | "autocfg", 579 | ] 580 | 581 | [[package]] 582 | name = "num_cpus" 583 | version = "1.14.0" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5" 586 | dependencies = [ 587 | "hermit-abi", 588 | "libc", 589 | ] 590 | 591 | [[package]] 592 | name = "once_cell" 593 | version = "1.16.0" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" 596 | 597 | [[package]] 598 | name = "openssl" 599 | version = "0.10.43" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "020433887e44c27ff16365eaa2d380547a94544ad509aff6eb5b6e3e0b27b376" 602 | dependencies = [ 603 | "bitflags", 604 | "cfg-if", 605 | "foreign-types", 606 | "libc", 607 | "once_cell", 608 | "openssl-macros", 609 | "openssl-sys", 610 | ] 611 | 612 | [[package]] 613 | name = "openssl-macros" 614 | version = "0.1.0" 615 | source = "registry+https://github.com/rust-lang/crates.io-index" 616 | checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" 617 | dependencies = [ 618 | "proc-macro2", 619 | "quote", 620 | "syn", 621 | ] 622 | 623 | [[package]] 624 | name = "openssl-probe" 625 | version = "0.1.5" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 628 | 629 | [[package]] 630 | name = "openssl-sys" 631 | version = "0.9.78" 632 | source = "registry+https://github.com/rust-lang/crates.io-index" 633 | checksum = "07d5c8cb6e57b3a3612064d7b18b117912b4ce70955c2504d4b741c9e244b132" 634 | dependencies = [ 635 | "autocfg", 636 | "cc", 637 | "libc", 638 | "pkg-config", 639 | "vcpkg", 640 | ] 641 | 642 | [[package]] 643 | name = "os_str_bytes" 644 | version = "6.4.1" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" 647 | 648 | [[package]] 649 | name = "percent-encoding" 650 | version = "2.2.0" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 653 | 654 | [[package]] 655 | name = "pin-project-lite" 656 | version = "0.2.9" 657 | source = "registry+https://github.com/rust-lang/crates.io-index" 658 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 659 | 660 | [[package]] 661 | name = "pin-utils" 662 | version = "0.1.0" 663 | source = "registry+https://github.com/rust-lang/crates.io-index" 664 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 665 | 666 | [[package]] 667 | name = "pkg-config" 668 | version = "0.3.26" 669 | source = "registry+https://github.com/rust-lang/crates.io-index" 670 | checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" 671 | 672 | [[package]] 673 | name = "ppv-lite86" 674 | version = "0.2.17" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 677 | 678 | [[package]] 679 | name = "proc-macro-error" 680 | version = "1.0.4" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 683 | dependencies = [ 684 | "proc-macro-error-attr", 685 | "proc-macro2", 686 | "quote", 687 | "syn", 688 | "version_check", 689 | ] 690 | 691 | [[package]] 692 | name = "proc-macro-error-attr" 693 | version = "1.0.4" 694 | source = "registry+https://github.com/rust-lang/crates.io-index" 695 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 696 | dependencies = [ 697 | "proc-macro2", 698 | "quote", 699 | "version_check", 700 | ] 701 | 702 | [[package]] 703 | name = "proc-macro2" 704 | version = "1.0.66" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" 707 | dependencies = [ 708 | "unicode-ident", 709 | ] 710 | 711 | [[package]] 712 | name = "quote" 713 | version = "1.0.21" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" 716 | dependencies = [ 717 | "proc-macro2", 718 | ] 719 | 720 | [[package]] 721 | name = "rand" 722 | version = "0.8.5" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 725 | dependencies = [ 726 | "libc", 727 | "rand_chacha", 728 | "rand_core", 729 | ] 730 | 731 | [[package]] 732 | name = "rand_chacha" 733 | version = "0.3.1" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 736 | dependencies = [ 737 | "ppv-lite86", 738 | "rand_core", 739 | ] 740 | 741 | [[package]] 742 | name = "rand_core" 743 | version = "0.6.4" 744 | source = "registry+https://github.com/rust-lang/crates.io-index" 745 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 746 | dependencies = [ 747 | "getrandom", 748 | ] 749 | 750 | [[package]] 751 | name = "redox_syscall" 752 | version = "0.2.16" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 755 | dependencies = [ 756 | "bitflags", 757 | ] 758 | 759 | [[package]] 760 | name = "remove_dir_all" 761 | version = "0.5.3" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 764 | dependencies = [ 765 | "winapi", 766 | ] 767 | 768 | [[package]] 769 | name = "reqwest" 770 | version = "0.11.13" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "68cc60575865c7831548863cc02356512e3f1dc2f3f82cb837d7fc4cc8f3c97c" 773 | dependencies = [ 774 | "base64", 775 | "bytes", 776 | "encoding_rs", 777 | "futures-core", 778 | "futures-util", 779 | "h2", 780 | "http", 781 | "http-body", 782 | "hyper", 783 | "hyper-tls", 784 | "ipnet", 785 | "js-sys", 786 | "log", 787 | "mime", 788 | "native-tls", 789 | "once_cell", 790 | "percent-encoding", 791 | "pin-project-lite", 792 | "serde", 793 | "serde_json", 794 | "serde_urlencoded", 795 | "tokio", 796 | "tokio-native-tls", 797 | "tower-service", 798 | "url", 799 | "wasm-bindgen", 800 | "wasm-bindgen-futures", 801 | "web-sys", 802 | "winreg", 803 | ] 804 | 805 | [[package]] 806 | name = "ribbot" 807 | version = "0.1.0" 808 | dependencies = [ 809 | "anyhow", 810 | "chrono", 811 | "clap", 812 | "rand", 813 | "reqwest", 814 | "serde", 815 | "serde_derive", 816 | "serde_json", 817 | "toml", 818 | ] 819 | 820 | [[package]] 821 | name = "ryu" 822 | version = "1.0.11" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" 825 | 826 | [[package]] 827 | name = "schannel" 828 | version = "0.1.20" 829 | source = "registry+https://github.com/rust-lang/crates.io-index" 830 | checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" 831 | dependencies = [ 832 | "lazy_static", 833 | "windows-sys 0.36.1", 834 | ] 835 | 836 | [[package]] 837 | name = "scratch" 838 | version = "1.0.2" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" 841 | 842 | [[package]] 843 | name = "security-framework" 844 | version = "2.7.0" 845 | source = "registry+https://github.com/rust-lang/crates.io-index" 846 | checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" 847 | dependencies = [ 848 | "bitflags", 849 | "core-foundation", 850 | "core-foundation-sys", 851 | "libc", 852 | "security-framework-sys", 853 | ] 854 | 855 | [[package]] 856 | name = "security-framework-sys" 857 | version = "2.6.1" 858 | source = "registry+https://github.com/rust-lang/crates.io-index" 859 | checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" 860 | dependencies = [ 861 | "core-foundation-sys", 862 | "libc", 863 | ] 864 | 865 | [[package]] 866 | name = "serde" 867 | version = "1.0.148" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" 870 | 871 | [[package]] 872 | name = "serde_derive" 873 | version = "1.0.148" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" 876 | dependencies = [ 877 | "proc-macro2", 878 | "quote", 879 | "syn", 880 | ] 881 | 882 | [[package]] 883 | name = "serde_json" 884 | version = "1.0.89" 885 | source = "registry+https://github.com/rust-lang/crates.io-index" 886 | checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" 887 | dependencies = [ 888 | "itoa", 889 | "ryu", 890 | "serde", 891 | ] 892 | 893 | [[package]] 894 | name = "serde_urlencoded" 895 | version = "0.7.1" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 898 | dependencies = [ 899 | "form_urlencoded", 900 | "itoa", 901 | "ryu", 902 | "serde", 903 | ] 904 | 905 | [[package]] 906 | name = "slab" 907 | version = "0.4.7" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 910 | dependencies = [ 911 | "autocfg", 912 | ] 913 | 914 | [[package]] 915 | name = "socket2" 916 | version = "0.4.7" 917 | source = "registry+https://github.com/rust-lang/crates.io-index" 918 | checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" 919 | dependencies = [ 920 | "libc", 921 | "winapi", 922 | ] 923 | 924 | [[package]] 925 | name = "strsim" 926 | version = "0.10.0" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 929 | 930 | [[package]] 931 | name = "syn" 932 | version = "1.0.104" 933 | source = "registry+https://github.com/rust-lang/crates.io-index" 934 | checksum = "4ae548ec36cf198c0ef7710d3c230987c2d6d7bd98ad6edc0274462724c585ce" 935 | dependencies = [ 936 | "proc-macro2", 937 | "quote", 938 | "unicode-ident", 939 | ] 940 | 941 | [[package]] 942 | name = "tempfile" 943 | version = "3.3.0" 944 | source = "registry+https://github.com/rust-lang/crates.io-index" 945 | checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" 946 | dependencies = [ 947 | "cfg-if", 948 | "fastrand", 949 | "libc", 950 | "redox_syscall", 951 | "remove_dir_all", 952 | "winapi", 953 | ] 954 | 955 | [[package]] 956 | name = "termcolor" 957 | version = "1.1.3" 958 | source = "registry+https://github.com/rust-lang/crates.io-index" 959 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 960 | dependencies = [ 961 | "winapi-util", 962 | ] 963 | 964 | [[package]] 965 | name = "textwrap" 966 | version = "0.16.0" 967 | source = "registry+https://github.com/rust-lang/crates.io-index" 968 | checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" 969 | 970 | [[package]] 971 | name = "time" 972 | version = "0.1.45" 973 | source = "registry+https://github.com/rust-lang/crates.io-index" 974 | checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" 975 | dependencies = [ 976 | "libc", 977 | "wasi 0.10.0+wasi-snapshot-preview1", 978 | "winapi", 979 | ] 980 | 981 | [[package]] 982 | name = "tinyvec" 983 | version = "1.6.0" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 986 | dependencies = [ 987 | "tinyvec_macros", 988 | ] 989 | 990 | [[package]] 991 | name = "tinyvec_macros" 992 | version = "0.1.0" 993 | source = "registry+https://github.com/rust-lang/crates.io-index" 994 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 995 | 996 | [[package]] 997 | name = "tokio" 998 | version = "1.22.0" 999 | source = "registry+https://github.com/rust-lang/crates.io-index" 1000 | checksum = "d76ce4a75fb488c605c54bf610f221cea8b0dafb53333c1a67e8ee199dcd2ae3" 1001 | dependencies = [ 1002 | "autocfg", 1003 | "bytes", 1004 | "libc", 1005 | "memchr", 1006 | "mio", 1007 | "num_cpus", 1008 | "pin-project-lite", 1009 | "socket2", 1010 | "winapi", 1011 | ] 1012 | 1013 | [[package]] 1014 | name = "tokio-native-tls" 1015 | version = "0.3.0" 1016 | source = "registry+https://github.com/rust-lang/crates.io-index" 1017 | checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" 1018 | dependencies = [ 1019 | "native-tls", 1020 | "tokio", 1021 | ] 1022 | 1023 | [[package]] 1024 | name = "tokio-util" 1025 | version = "0.7.4" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" 1028 | dependencies = [ 1029 | "bytes", 1030 | "futures-core", 1031 | "futures-sink", 1032 | "pin-project-lite", 1033 | "tokio", 1034 | "tracing", 1035 | ] 1036 | 1037 | [[package]] 1038 | name = "toml" 1039 | version = "0.5.9" 1040 | source = "registry+https://github.com/rust-lang/crates.io-index" 1041 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" 1042 | dependencies = [ 1043 | "serde", 1044 | ] 1045 | 1046 | [[package]] 1047 | name = "tower-service" 1048 | version = "0.3.2" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1051 | 1052 | [[package]] 1053 | name = "tracing" 1054 | version = "0.1.37" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1057 | dependencies = [ 1058 | "cfg-if", 1059 | "pin-project-lite", 1060 | "tracing-core", 1061 | ] 1062 | 1063 | [[package]] 1064 | name = "tracing-core" 1065 | version = "0.1.30" 1066 | source = "registry+https://github.com/rust-lang/crates.io-index" 1067 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 1068 | dependencies = [ 1069 | "once_cell", 1070 | ] 1071 | 1072 | [[package]] 1073 | name = "try-lock" 1074 | version = "0.2.3" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 1077 | 1078 | [[package]] 1079 | name = "unicode-bidi" 1080 | version = "0.3.8" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" 1083 | 1084 | [[package]] 1085 | name = "unicode-ident" 1086 | version = "1.0.5" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" 1089 | 1090 | [[package]] 1091 | name = "unicode-normalization" 1092 | version = "0.1.22" 1093 | source = "registry+https://github.com/rust-lang/crates.io-index" 1094 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1095 | dependencies = [ 1096 | "tinyvec", 1097 | ] 1098 | 1099 | [[package]] 1100 | name = "unicode-width" 1101 | version = "0.1.10" 1102 | source = "registry+https://github.com/rust-lang/crates.io-index" 1103 | checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" 1104 | 1105 | [[package]] 1106 | name = "url" 1107 | version = "2.3.1" 1108 | source = "registry+https://github.com/rust-lang/crates.io-index" 1109 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 1110 | dependencies = [ 1111 | "form_urlencoded", 1112 | "idna", 1113 | "percent-encoding", 1114 | ] 1115 | 1116 | [[package]] 1117 | name = "vcpkg" 1118 | version = "0.2.15" 1119 | source = "registry+https://github.com/rust-lang/crates.io-index" 1120 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1121 | 1122 | [[package]] 1123 | name = "version_check" 1124 | version = "0.9.4" 1125 | source = "registry+https://github.com/rust-lang/crates.io-index" 1126 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1127 | 1128 | [[package]] 1129 | name = "want" 1130 | version = "0.3.0" 1131 | source = "registry+https://github.com/rust-lang/crates.io-index" 1132 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1133 | dependencies = [ 1134 | "log", 1135 | "try-lock", 1136 | ] 1137 | 1138 | [[package]] 1139 | name = "wasi" 1140 | version = "0.10.0+wasi-snapshot-preview1" 1141 | source = "registry+https://github.com/rust-lang/crates.io-index" 1142 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 1143 | 1144 | [[package]] 1145 | name = "wasi" 1146 | version = "0.11.0+wasi-snapshot-preview1" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1149 | 1150 | [[package]] 1151 | name = "wasm-bindgen" 1152 | version = "0.2.83" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" 1155 | dependencies = [ 1156 | "cfg-if", 1157 | "wasm-bindgen-macro", 1158 | ] 1159 | 1160 | [[package]] 1161 | name = "wasm-bindgen-backend" 1162 | version = "0.2.83" 1163 | source = "registry+https://github.com/rust-lang/crates.io-index" 1164 | checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" 1165 | dependencies = [ 1166 | "bumpalo", 1167 | "log", 1168 | "once_cell", 1169 | "proc-macro2", 1170 | "quote", 1171 | "syn", 1172 | "wasm-bindgen-shared", 1173 | ] 1174 | 1175 | [[package]] 1176 | name = "wasm-bindgen-futures" 1177 | version = "0.4.33" 1178 | source = "registry+https://github.com/rust-lang/crates.io-index" 1179 | checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d" 1180 | dependencies = [ 1181 | "cfg-if", 1182 | "js-sys", 1183 | "wasm-bindgen", 1184 | "web-sys", 1185 | ] 1186 | 1187 | [[package]] 1188 | name = "wasm-bindgen-macro" 1189 | version = "0.2.83" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" 1192 | dependencies = [ 1193 | "quote", 1194 | "wasm-bindgen-macro-support", 1195 | ] 1196 | 1197 | [[package]] 1198 | name = "wasm-bindgen-macro-support" 1199 | version = "0.2.83" 1200 | source = "registry+https://github.com/rust-lang/crates.io-index" 1201 | checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" 1202 | dependencies = [ 1203 | "proc-macro2", 1204 | "quote", 1205 | "syn", 1206 | "wasm-bindgen-backend", 1207 | "wasm-bindgen-shared", 1208 | ] 1209 | 1210 | [[package]] 1211 | name = "wasm-bindgen-shared" 1212 | version = "0.2.83" 1213 | source = "registry+https://github.com/rust-lang/crates.io-index" 1214 | checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" 1215 | 1216 | [[package]] 1217 | name = "web-sys" 1218 | version = "0.3.60" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" 1221 | dependencies = [ 1222 | "js-sys", 1223 | "wasm-bindgen", 1224 | ] 1225 | 1226 | [[package]] 1227 | name = "winapi" 1228 | version = "0.3.9" 1229 | source = "registry+https://github.com/rust-lang/crates.io-index" 1230 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1231 | dependencies = [ 1232 | "winapi-i686-pc-windows-gnu", 1233 | "winapi-x86_64-pc-windows-gnu", 1234 | ] 1235 | 1236 | [[package]] 1237 | name = "winapi-i686-pc-windows-gnu" 1238 | version = "0.4.0" 1239 | source = "registry+https://github.com/rust-lang/crates.io-index" 1240 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1241 | 1242 | [[package]] 1243 | name = "winapi-util" 1244 | version = "0.1.5" 1245 | source = "registry+https://github.com/rust-lang/crates.io-index" 1246 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1247 | dependencies = [ 1248 | "winapi", 1249 | ] 1250 | 1251 | [[package]] 1252 | name = "winapi-x86_64-pc-windows-gnu" 1253 | version = "0.4.0" 1254 | source = "registry+https://github.com/rust-lang/crates.io-index" 1255 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1256 | 1257 | [[package]] 1258 | name = "windows-sys" 1259 | version = "0.36.1" 1260 | source = "registry+https://github.com/rust-lang/crates.io-index" 1261 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 1262 | dependencies = [ 1263 | "windows_aarch64_msvc 0.36.1", 1264 | "windows_i686_gnu 0.36.1", 1265 | "windows_i686_msvc 0.36.1", 1266 | "windows_x86_64_gnu 0.36.1", 1267 | "windows_x86_64_msvc 0.36.1", 1268 | ] 1269 | 1270 | [[package]] 1271 | name = "windows-sys" 1272 | version = "0.42.0" 1273 | source = "registry+https://github.com/rust-lang/crates.io-index" 1274 | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" 1275 | dependencies = [ 1276 | "windows_aarch64_gnullvm", 1277 | "windows_aarch64_msvc 0.42.0", 1278 | "windows_i686_gnu 0.42.0", 1279 | "windows_i686_msvc 0.42.0", 1280 | "windows_x86_64_gnu 0.42.0", 1281 | "windows_x86_64_gnullvm", 1282 | "windows_x86_64_msvc 0.42.0", 1283 | ] 1284 | 1285 | [[package]] 1286 | name = "windows_aarch64_gnullvm" 1287 | version = "0.42.0" 1288 | source = "registry+https://github.com/rust-lang/crates.io-index" 1289 | checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" 1290 | 1291 | [[package]] 1292 | name = "windows_aarch64_msvc" 1293 | version = "0.36.1" 1294 | source = "registry+https://github.com/rust-lang/crates.io-index" 1295 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 1296 | 1297 | [[package]] 1298 | name = "windows_aarch64_msvc" 1299 | version = "0.42.0" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" 1302 | 1303 | [[package]] 1304 | name = "windows_i686_gnu" 1305 | version = "0.36.1" 1306 | source = "registry+https://github.com/rust-lang/crates.io-index" 1307 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 1308 | 1309 | [[package]] 1310 | name = "windows_i686_gnu" 1311 | version = "0.42.0" 1312 | source = "registry+https://github.com/rust-lang/crates.io-index" 1313 | checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" 1314 | 1315 | [[package]] 1316 | name = "windows_i686_msvc" 1317 | version = "0.36.1" 1318 | source = "registry+https://github.com/rust-lang/crates.io-index" 1319 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 1320 | 1321 | [[package]] 1322 | name = "windows_i686_msvc" 1323 | version = "0.42.0" 1324 | source = "registry+https://github.com/rust-lang/crates.io-index" 1325 | checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" 1326 | 1327 | [[package]] 1328 | name = "windows_x86_64_gnu" 1329 | version = "0.36.1" 1330 | source = "registry+https://github.com/rust-lang/crates.io-index" 1331 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 1332 | 1333 | [[package]] 1334 | name = "windows_x86_64_gnu" 1335 | version = "0.42.0" 1336 | source = "registry+https://github.com/rust-lang/crates.io-index" 1337 | checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" 1338 | 1339 | [[package]] 1340 | name = "windows_x86_64_gnullvm" 1341 | version = "0.42.0" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" 1344 | 1345 | [[package]] 1346 | name = "windows_x86_64_msvc" 1347 | version = "0.36.1" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 1350 | 1351 | [[package]] 1352 | name = "windows_x86_64_msvc" 1353 | version = "0.42.0" 1354 | source = "registry+https://github.com/rust-lang/crates.io-index" 1355 | checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" 1356 | 1357 | [[package]] 1358 | name = "winreg" 1359 | version = "0.10.1" 1360 | source = "registry+https://github.com/rust-lang/crates.io-index" 1361 | checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" 1362 | dependencies = [ 1363 | "winapi", 1364 | ] 1365 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ribbot" 3 | version = "0.1.0" 4 | authors = ["Aimee Zhu "] 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 | reqwest = { version = "0.11.6", features = ["blocking", "json"] } 11 | anyhow = "1.0.45" 12 | chrono = { version = "0.4.19", features = ["serde"] } 13 | serde_json = "1.0.70" 14 | toml = "0.5.8" 15 | serde_derive = "1.0.130" 16 | serde = "1.0.130" 17 | clap = { version = "3.0.2", features = ["derive"] } 18 | rand = "0.8.5" 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ribbot 2 | 3 | Script for querying merged PRs, open issues, and closed issues from config repos. 4 | 5 | ## How to use it 6 | 7 | Clone ribbot: 8 | 9 | ``` 10 | $ git clone https://github.com/rust-in-blockchain/ribbot.git && cd ribbot/ 11 | $ cargo run pulls --help 12 | 13 | USAGE: 14 | ribbot pulls [OPTIONS] --begin --end 15 | 16 | OPTIONS: 17 | --begin 18 | e.g. 2022-09-01 19 | 20 | --end 21 | e.g. 2022-10-01 22 | 23 | -h, --help 24 | Print help information 25 | 26 | --include-dependabot 27 | If set, include issues/PRs created by dependabot in analysis 28 | 29 | --no-comments 30 | If set, don't sort pull by comment count 31 | 32 | --oauth-token 33 | GitHub token 34 | 35 | --only-project 36 | Project name must be spelled as in rib-config.toml 37 | 38 | --smoke-test 39 | Check if all the repos are good to query 40 | ``` 41 | 42 | Run ribbot: 43 | 44 | ``` 45 | $ cargo run -- pulls --begin 2022-09-01 --end 2022-10-01 --oauth-token --no-comments 46 | 47 | Finished dev [unoptimized + debuginfo] target(s) in 0.11s 48 | Running `target/debug/ribbot pulls --begin 2022-09-01 --end 2022-10-01 --oauth-token --no-comments` 49 | ### General 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | ... 61 | ``` 62 | 63 | To query a specific project, run ribbot with `--only-project `. 64 | The project name must be spelled as in [`rib-config.toml`]: 65 | 66 | ``` 67 | $ cargo run -- pulls --begin 2022-09-01 --end 2022-10-01 --oauth-token --only-project Aleo --no-comments 68 | ``` 69 | 70 | Ribbot filters out activities from `dependabot` as default. 71 | To include `dependabot`, run ribbot with `--include-dependabot`. 72 | 73 | [`rib-config.toml`]: src/rib-config.toml 74 | 75 | ## TODO 76 | 77 | - [ ] Refactor the code 78 | - [ ] Auto update changed repos/orgs' names and URLs 79 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 3 | * All rights reserved. 4 | */ 5 | 6 | #![allow(unused)] 7 | 8 | use anyhow::{bail, Context, Result}; 9 | use chrono::{DateTime, Local, LocalResult, Months, NaiveDate, SecondsFormat, TimeZone, Utc}; 10 | use clap::{Parser, Subcommand}; 11 | use reqwest::{ 12 | blocking::{Client, Response}, 13 | header, 14 | header::{HeaderMap, USER_AGENT}, 15 | Method, StatusCode, 16 | }; 17 | use serde_derive::{Deserialize, Serialize}; 18 | use serde_json::Value; 19 | use std::{collections::HashMap, fs, io::Read, path::PathBuf, str::FromStr, thread, time}; 20 | 21 | static RIB_AGENT: &str = "ribbot (Rust-in-Blockchain; Aimeedeer/ribbot; aimeez@pm.me)"; 22 | static CONFIG: &str = include_str!("rib-config.toml"); 23 | static DELAY_MS: u64 = 10; 24 | static MAX_PAGES: usize = 100; 25 | 26 | #[derive(Parser)] 27 | struct Options { 28 | #[clap(subcommand)] 29 | cmd: Command, 30 | } 31 | 32 | #[derive(Subcommand)] 33 | enum Command { 34 | Pulls(PullCmdOpts), 35 | } 36 | 37 | #[derive(Parser)] 38 | struct PullCmdOpts { 39 | /// e.g. 2022-09-01 40 | #[clap(long, parse(try_from_str = parse_naive_date))] 41 | begin: NaiveDate, 42 | /// e.g. 2022-10-01 43 | #[clap(long, parse(try_from_str = parse_naive_date))] 44 | end: NaiveDate, 45 | /// If set, include issues/PRs created by dependabot in analysis. 46 | #[clap(long)] 47 | include_dependabot: bool, 48 | /// If set, don't sort pull by comment count. 49 | #[clap(long)] 50 | no_comments: bool, 51 | /// Project name must be spelled as in rib-config.toml. 52 | #[clap(long)] 53 | only_project: Option, 54 | /// GitHub token. 55 | #[clap(long)] 56 | oauth_token: Option, 57 | /// Check if all the repos are good to query. 58 | #[clap(long)] 59 | smoke_test: bool, 60 | } 61 | 62 | #[derive(Serialize, Deserialize, Default, Clone, Debug)] 63 | struct Config { 64 | sections: Vec
, 65 | } 66 | 67 | #[derive(Serialize, Deserialize, Clone, Debug)] 68 | struct Section { 69 | name: String, 70 | projects: Vec, 71 | } 72 | 73 | #[derive(Serialize, Deserialize, Clone, Debug)] 74 | struct Project { 75 | name: String, 76 | is_org: bool, 77 | url: String, 78 | repos: Vec, 79 | } 80 | 81 | fn main() -> Result<()> { 82 | let options = Options::parse(); 83 | let config = toml::from_str::(CONFIG).context("parsing configuration")?; 84 | 85 | match options.cmd { 86 | Command::Pulls(opts) => { 87 | let updated_config_file = update_rib_config(&config, &opts.oauth_token)?; 88 | 89 | let mut f = fs::File::open(updated_config_file)?; 90 | let mut buffer = String::new(); 91 | f.read_to_string(&mut buffer)?; 92 | 93 | let updated_config = 94 | toml::from_str::(&buffer).context("parsing new configuration")?; 95 | 96 | fetch_pulls(&updated_config, &opts)?; 97 | } 98 | } 99 | 100 | Ok(()) 101 | } 102 | 103 | #[derive(Deserialize, Debug)] 104 | struct GhProjectRepo { 105 | name: String, 106 | full_name: String, 107 | language: Option, 108 | created_at: Option>, 109 | updated_at: Option>, 110 | private: bool, 111 | fork: bool, 112 | archived: bool, 113 | disabled: bool, 114 | } 115 | 116 | fn update_rib_config(config: &Config, oauth_token: &Option) -> Result { 117 | println!("** Update config file before fetching projects' update."); 118 | 119 | let mut client = GhClient { 120 | client: Client::new(), 121 | limits: None, 122 | calls: 0, 123 | }; 124 | 125 | let mut new_config = Config::default(); 126 | 127 | for section in &config.sections { 128 | let mut new_section = Section { 129 | name: section.name.clone(), 130 | projects: Vec::::new(), 131 | }; 132 | 133 | for project in §ion.projects { 134 | println!("", project.name); 135 | 136 | if !project.is_org { 137 | // keep current repos 138 | new_section.projects.push(project.clone()); 139 | } else { 140 | // do github search and update repos 141 | 142 | assert_eq!(&project.url[..19], "https://github.com/"); 143 | let project_github_name = &project.url[19..]; 144 | let url = format!( 145 | "https://api.github.com/orgs/{}/repos?type=sources&sort=updated", 146 | project_github_name 147 | ); 148 | 149 | // get repos that updated in 12 months 150 | let begin = Utc::now().checked_sub_months(Months::new(12)).unwrap(); 151 | 152 | let project_repos = 153 | do_gh_api_paged_request(&mut client, &url, oauth_token, |body| { 154 | let project_repos: Vec = serde_json::from_str(&body)?; 155 | let project_repos = project_repos 156 | .into_iter() 157 | .filter(|repo| { 158 | match (repo.fork, repo.archived, repo.disabled, repo.private) { 159 | (false, false, false, false) => { 160 | let mut is_rust_repo = false; 161 | if let Some(language) = &repo.language { 162 | if language.contains("Rust") 163 | && repo.updated_at.unwrap() >= begin 164 | { 165 | is_rust_repo = true 166 | } 167 | } 168 | is_rust_repo 169 | } 170 | _ => false, 171 | } 172 | }) 173 | .collect(); 174 | 175 | Ok((project_repos, true)) 176 | })?; 177 | 178 | let mut repos = Vec::::new(); 179 | for repo in project_repos { 180 | repos.push(repo.full_name); 181 | } 182 | 183 | new_section.projects.push(Project { 184 | name: project.name.clone(), 185 | is_org: project.is_org, 186 | url: project.url.clone(), 187 | repos, 188 | }); 189 | } 190 | } 191 | 192 | new_config.sections.push(new_section); 193 | } 194 | 195 | let config_dir = "config"; 196 | fs::create_dir_all(&config_dir)?; 197 | 198 | let now = Utc::now(); 199 | let new_config_file = PathBuf::from(format!( 200 | "{}/{}-{}.toml", 201 | config_dir, 202 | now.date_naive(), 203 | now.timestamp() 204 | )); 205 | 206 | let temp_file = PathBuf::from(format!("{}/{}.temp", config_dir, rand::random::())); 207 | 208 | let file = fs::File::create(&temp_file)?; 209 | let mut writer = std::io::BufWriter::new(file); 210 | 211 | let new_config_str = toml::to_string_pretty(&new_config).unwrap(); 212 | 213 | match fs::write(&temp_file, &new_config_str) { 214 | Err(e) => { 215 | fs::remove_file(temp_file)?; 216 | bail!(e) 217 | } 218 | Ok(()) => { 219 | fs::rename(temp_file, &new_config_file)?; 220 | Ok(new_config_file.into()) 221 | } 222 | } 223 | } 224 | 225 | fn fetch_pulls(config: &Config, opts: &PullCmdOpts) -> Result<()> { 226 | let mut client = GhClient { 227 | client: Client::new(), 228 | limits: None, 229 | calls: 0, 230 | }; 231 | 232 | let mut calls = 0; 233 | for section in &config.sections { 234 | println!("### {}", section.name); 235 | println!(); 236 | 237 | for project in §ion.projects { 238 | if let Some(ref only_project) = opts.only_project { 239 | if project.name != *only_project { 240 | continue; 241 | } 242 | } 243 | 244 | if !opts.smoke_test { 245 | let pulls = if !opts.no_comments { 246 | get_sorted_merged_pulls_with_comments(&mut client, project, opts)? 247 | } else { 248 | get_sorted_merged_pulls_without_comments(&mut client, project, opts)? 249 | }; 250 | let issues = get_closed_issues(&mut client, project, opts)?; 251 | let open_issues = get_open_issues(&mut client, project, opts)?; 252 | let pull_stats = make_pull_stats(project, &pulls)?; 253 | let issue_stats = make_issue_stats(project, &issues)?; 254 | let open_issue_stats = make_issue_stats(project, &open_issues)?; 255 | print_project( 256 | project, 257 | &pulls, 258 | pull_stats, 259 | issue_stats, 260 | open_issue_stats, 261 | opts, 262 | ); 263 | } else { 264 | do_smoke_test(&mut client, project, opts)?; 265 | } 266 | 267 | let new_calls = client.calls - calls; 268 | calls = client.calls; 269 | 270 | println!(""); 271 | println!(); 272 | } 273 | } 274 | 275 | Ok(()) 276 | } 277 | 278 | #[derive(Deserialize, Debug)] 279 | struct GhPull { 280 | html_url: String, 281 | state: String, 282 | title: String, 283 | user: GhUser, 284 | updated_at: DateTime, 285 | merged_at: Option>, 286 | review_comments_url: String, 287 | base: GhPullBase, 288 | } 289 | 290 | #[derive(Deserialize, Debug)] 291 | struct GhUser { 292 | login: String, 293 | } 294 | 295 | #[derive(Deserialize, Debug)] 296 | struct GhPullBase { 297 | repo: GhRepo, 298 | } 299 | 300 | #[derive(Deserialize, Debug)] 301 | struct GhRepo { 302 | html_url: String, 303 | } 304 | 305 | #[derive(Deserialize, Debug)] 306 | struct GhPullWithComments { 307 | pull: GhPull, 308 | comments: usize, 309 | } 310 | 311 | #[derive(Deserialize, Debug)] 312 | struct GhComments {} 313 | 314 | fn do_smoke_test(client: &mut GhClient, project: &Project, opts: &PullCmdOpts) -> Result<()> { 315 | println!("#### [{}]({})", project.name, project.url); 316 | println!(); 317 | 318 | for repo in &project.repos { 319 | let url = format!("https://api.github.com/repos/{repo}/pulls"); 320 | 321 | let res = do_gh_api_request(client, &url, &opts.oauth_token); 322 | 323 | match res { 324 | Ok(_) => { 325 | println!(""); 326 | } 327 | Err(e) => { 328 | println!(""); 329 | } 330 | } 331 | } 332 | 333 | Ok(()) 334 | } 335 | 336 | fn get_sorted_merged_pulls_with_comments( 337 | client: &mut GhClient, 338 | project: &Project, 339 | opts: &PullCmdOpts, 340 | ) -> Result> { 341 | let mut pulls = get_merged_pulls_with_comments(client, project, opts)?; 342 | pulls.sort_by_key(|pull| usize::max_value() - pull.comments); 343 | Ok(pulls) 344 | } 345 | 346 | fn get_sorted_merged_pulls_without_comments( 347 | client: &mut GhClient, 348 | project: &Project, 349 | opts: &PullCmdOpts, 350 | ) -> Result> { 351 | let mut pulls = get_merged_pulls_without_comments(client, project, opts)?; 352 | pulls.sort_by_key(|pull| usize::max_value() - pull.comments); 353 | Ok(pulls) 354 | } 355 | 356 | fn get_merged_pulls_with_comments( 357 | client: &mut GhClient, 358 | project: &Project, 359 | opts: &PullCmdOpts, 360 | ) -> Result> { 361 | get_merged_pulls(client, project, opts)? 362 | .into_iter() 363 | .map(|pull| { 364 | let comments = get_comment_count(client, &pull, opts)?; 365 | Ok(GhPullWithComments { pull, comments }) 366 | }) 367 | .collect() 368 | } 369 | 370 | fn get_merged_pulls_without_comments( 371 | client: &mut GhClient, 372 | project: &Project, 373 | opts: &PullCmdOpts, 374 | ) -> Result> { 375 | get_merged_pulls(client, project, opts)? 376 | .into_iter() 377 | .map(|pull| { 378 | let comments = 0; 379 | Ok(GhPullWithComments { pull, comments }) 380 | }) 381 | .collect() 382 | } 383 | 384 | #[derive(Deserialize, Debug)] 385 | struct GhIssue { 386 | html_url: String, 387 | state: String, 388 | title: String, 389 | user: GhUser, 390 | updated_at: DateTime, 391 | closed_at: Option>, 392 | created_at: Option>, 393 | pull_request: Option, 394 | } 395 | 396 | #[derive(Deserialize, Debug)] 397 | struct GhIssuePull {} 398 | 399 | fn begin_and_end(opts: &PullCmdOpts) -> (DateTime, DateTime) { 400 | let begin = opts.begin.and_hms_opt(0, 0, 0).expect("DateTime"); 401 | let begin = DateTime::::from_utc(begin, Utc); 402 | let end = opts.end.and_hms_opt(0, 0, 0).expect("DateTime"); 403 | let end = DateTime::::from_utc(end, Utc); 404 | (begin, end) 405 | } 406 | 407 | fn get_closed_issues( 408 | client: &mut GhClient, 409 | project: &Project, 410 | opts: &PullCmdOpts, 411 | ) -> Result> { 412 | let (begin, end) = begin_and_end(opts); 413 | 414 | let mut all_issues = vec![]; 415 | 416 | println!("", project.name); 417 | for repo in &project.repos { 418 | println!(""); 419 | 420 | let since = begin.to_rfc3339_opts(SecondsFormat::Millis, true); 421 | let url = format!("https://api.github.com/repos/{repo}/issues?state=closed&sort=updated&direction=desc&since={since}"); 422 | let new_issues = do_gh_api_paged_request(client, &url, &opts.oauth_token, |body| { 423 | let issues: Vec = serde_json::from_str(&body)?; 424 | //println!("{:#?}", pulls); 425 | 426 | let mut any_outdated = false; 427 | let issues = issues 428 | .into_iter() 429 | .filter(|issue| { 430 | if issue.updated_at < begin && !any_outdated { 431 | println!( 432 | "", 433 | issue.html_url, issue.updated_at 434 | ); 435 | any_outdated = true; 436 | } 437 | if let Some(closed_at) = issue.closed_at { 438 | if closed_at < begin { 439 | println!("", issue.html_url); 440 | false 441 | } else if closed_at >= end { 442 | println!("", issue.html_url); 443 | false 444 | } else if issue.pull_request.is_some() { 445 | println!("", issue.html_url); 446 | false 447 | } else if !opts.include_dependabot && issue.user.login == "dependabot[bot]" 448 | { 449 | println!("", issue.html_url); 450 | false 451 | } else { 452 | true 453 | } 454 | } else { 455 | println!("", issue.html_url); 456 | false 457 | } 458 | }) 459 | .collect(); 460 | 461 | let keep_going = !any_outdated; 462 | 463 | Ok((issues, keep_going)) 464 | })?; 465 | 466 | all_issues.extend(new_issues); 467 | } 468 | 469 | Ok(all_issues) 470 | } 471 | 472 | fn get_open_issues( 473 | client: &mut GhClient, 474 | project: &Project, 475 | opts: &PullCmdOpts, 476 | ) -> Result> { 477 | let (begin, end) = begin_and_end(opts); 478 | 479 | let mut all_open_issues = vec![]; 480 | 481 | println!("", project.name); 482 | for repo in &project.repos { 483 | println!(""); 484 | 485 | let since = begin.to_rfc3339_opts(SecondsFormat::Millis, true); 486 | let url = format!("https://api.github.com/repos/{repo}/issues?state=open&sort=updated&direction=desc&since={since}"); 487 | let new_issues = do_gh_api_paged_request(client, &url, &opts.oauth_token, |body| { 488 | let issues: Vec = serde_json::from_str(&body)?; 489 | //println!("{:#?}", issues); 490 | 491 | let mut any_outdated = false; 492 | let issues = issues 493 | .into_iter() 494 | .filter(|issue| { 495 | if issue.updated_at < begin && !any_outdated { 496 | println!( 497 | "", 498 | issue.html_url, issue.updated_at 499 | ); 500 | any_outdated = true; 501 | } 502 | if let Some(created_at) = issue.created_at { 503 | if created_at < begin { 504 | println!("", issue.html_url); 505 | false 506 | } else if created_at >= end { 507 | println!("", issue.html_url); 508 | false 509 | } else if issue.pull_request.is_some() { 510 | println!("", issue.html_url); 511 | false 512 | } else if !opts.include_dependabot && issue.user.login == "dependabot[bot]" 513 | { 514 | println!("", issue.html_url); 515 | false 516 | } else { 517 | true 518 | } 519 | } else { 520 | println!("", issue.html_url); 521 | false 522 | } 523 | }) 524 | .collect(); 525 | 526 | let keep_going = !any_outdated; 527 | 528 | Ok((issues, keep_going)) 529 | })?; 530 | 531 | all_open_issues.extend(new_issues); 532 | } 533 | 534 | Ok(all_open_issues) 535 | } 536 | 537 | fn get_merged_pulls( 538 | client: &mut GhClient, 539 | project: &Project, 540 | opts: &PullCmdOpts, 541 | ) -> Result> { 542 | let (begin, end) = begin_and_end(opts); 543 | 544 | let mut all_pulls = vec![]; 545 | println!("", project.name); 546 | for repo in &project.repos { 547 | println!(""); 548 | 549 | let url = format!( 550 | "https://api.github.com/repos/{repo}/pulls?state=closed&sort=updated&direction=desc" 551 | ); 552 | 553 | let new_pulls = do_gh_api_paged_request(client, &url, &opts.oauth_token, |body| { 554 | let pulls: Vec = serde_json::from_str(&body)?; 555 | //println!("{:#?}", pulls); 556 | 557 | let mut any_outdated = false; 558 | let pulls = pulls 559 | .into_iter() 560 | .filter(|pr| { 561 | if pr.updated_at < begin && !any_outdated { 562 | println!( 563 | "", 564 | pr.html_url, pr.updated_at 565 | ); 566 | any_outdated = true; 567 | } 568 | if let Some(merged_at) = pr.merged_at { 569 | if merged_at < begin { 570 | println!("", pr.html_url); 571 | false 572 | } else if merged_at >= end { 573 | println!("", pr.html_url); 574 | false 575 | } else if !opts.include_dependabot && pr.user.login == "dependabot[bot]" { 576 | println!("", pr.html_url); 577 | false 578 | } else { 579 | true 580 | } 581 | } else { 582 | println!("", pr.html_url); 583 | false 584 | } 585 | }) 586 | .collect(); 587 | 588 | let keep_going = !any_outdated; 589 | 590 | Ok((pulls, keep_going)) 591 | })?; 592 | 593 | all_pulls.extend(new_pulls); 594 | } 595 | 596 | Ok(all_pulls) 597 | } 598 | 599 | fn get_comment_count(client: &mut GhClient, pull: &GhPull, opts: &PullCmdOpts) -> Result { 600 | println!("", pull.html_url); 601 | 602 | let comments = do_gh_api_paged_request( 603 | client, 604 | &pull.review_comments_url, 605 | &opts.oauth_token, 606 | |body| { 607 | let comments: Vec = serde_json::from_str(&body)?; 608 | Ok((comments, true)) 609 | }, 610 | )?; 611 | 612 | Ok(comments.len()) 613 | } 614 | 615 | fn do_gh_api_paged_request( 616 | client: &mut GhClient, 617 | url: &str, 618 | oauth_token: &Option, 619 | f: impl Fn(String) -> Result<(Vec, bool)>, 620 | ) -> Result> { 621 | let mut url = url.to_string(); 622 | 623 | let mut all_results = vec![]; 624 | 625 | for page in 1.. { 626 | println!(""); 627 | 628 | let (body, headers) = do_gh_api_request(client, &url, oauth_token)?; 629 | 630 | let (new_results, keep_going) = f(body)?; 631 | 632 | all_results.extend(new_results); 633 | 634 | if !keep_going { 635 | break; 636 | } 637 | 638 | let next = parse_next(&headers)?.map(ToString::to_string); 639 | 640 | if let Some(next) = next { 641 | url = next; 642 | } else { 643 | break; 644 | } 645 | 646 | if page >= MAX_PAGES { 647 | println!(""); 648 | break; 649 | } 650 | } 651 | 652 | Ok(all_results) 653 | } 654 | 655 | struct GhClient { 656 | client: Client, 657 | limits: Option, 658 | calls: u64, 659 | } 660 | 661 | fn do_gh_api_request( 662 | client: &mut GhClient, 663 | url: &str, 664 | oauth_token: &Option, 665 | ) -> Result<(String, HeaderMap)> { 666 | do_gh_rate_limit(client)?; 667 | 668 | loop { 669 | let builder = client.client.request(Method::GET, url); 670 | let builder = builder.header(USER_AGENT, RIB_AGENT); 671 | let builder = if let Some(ref oauth_token) = *oauth_token { 672 | builder.header("Authorization", format!("token {oauth_token}")) 673 | } else { 674 | builder 675 | }; 676 | let resp = builder.send()?; 677 | let headers = resp.headers().clone(); 678 | let status = resp.status(); 679 | 680 | if status == StatusCode::BAD_GATEWAY { 681 | // 2021/11/02 - GitHub seems to be having internal server errors 682 | // that return 502, and resolve themselves after some seconds. 683 | println!(""); 684 | delay_ms(5000); 685 | continue; 686 | } 687 | 688 | let limits = get_rate_limit_values(&headers)?; 689 | 690 | // println!("", limits); 691 | // println!(""); 692 | // for (k, v) in &headers { 693 | // println!("", k, v); 694 | // } 695 | 696 | client.calls += 1; 697 | do_gh_rate_limit_bookkeeping(client, &headers)?; 698 | 699 | match status { 700 | StatusCode::OK => { 701 | let body = resp.text()?; 702 | 703 | // let json_body = Value::from_str(&body)?; 704 | // println!("{}", serde_json::to_string_pretty(&json_body[0])?); 705 | 706 | return Ok((body, headers)); 707 | } 708 | StatusCode::FORBIDDEN => { 709 | // Probably rate limited 710 | let rate_limited = limits.remaining == 0; 711 | if rate_limited { 712 | do_gh_rate_limit_delay(&limits); 713 | continue; 714 | } else { 715 | println!("{resp:#?}"); 716 | bail!("unexpected forbidden status"); 717 | } 718 | } 719 | _ => { 720 | println!("{resp:#?}"); 721 | bail!("unexpected response"); 722 | } 723 | } 724 | } 725 | 726 | unreachable!() 727 | } 728 | 729 | #[derive(Debug)] 730 | struct RateLimitValues { 731 | limit: u64, 732 | remaining: u64, 733 | reset: DateTime, 734 | reset_local: DateTime, 735 | } 736 | 737 | fn get_rate_limit_values(headers: &HeaderMap) -> Result { 738 | let limit: u64 = headers 739 | .get("X-RateLimit-Limit") 740 | .expect("X-RateLimit-Limit") 741 | .to_str()? 742 | .parse()?; 743 | let remaining: u64 = headers 744 | .get("X-RateLimit-Remaining") 745 | .expect("X-RateLimit-Remaining") 746 | .to_str()? 747 | .parse()?; 748 | let reset: u64 = headers 749 | .get("X-RateLimit-Reset") 750 | .expect("X-RateLimit-Reset") 751 | .to_str()? 752 | .parse()?; 753 | // FIXME 'as' conversion 754 | let reset = Utc.timestamp_opt(reset as i64, 0).unwrap(); 755 | let reset_local: DateTime = reset.into(); 756 | 757 | Ok(RateLimitValues { 758 | limit, 759 | remaining, 760 | reset, 761 | reset_local, 762 | }) 763 | } 764 | 765 | fn do_gh_rate_limit(client: &mut GhClient) -> Result<()> { 766 | if let Some(ref limits) = client.limits { 767 | if limits.remaining == 0 { 768 | do_gh_rate_limit_delay(limits); 769 | } 770 | } 771 | Ok(()) 772 | } 773 | 774 | fn do_gh_rate_limit_delay(limits: &RateLimitValues) { 775 | println!(""); 873 | } 874 | } 875 | println!(); 876 | 877 | Ok(()) 878 | } 879 | 880 | fn parse_next(headers: &HeaderMap) -> Result> { 881 | if let Some(link_header) = headers.get(header::LINK) { 882 | let link_header = link_header.to_str()?; 883 | for entry in link_header.split(',') { 884 | if let Some((url, maybe_rel)) = split_2_trim(entry, ';') { 885 | if let Some((rel_word, rel_value)) = split_2_trim(maybe_rel, '=') { 886 | if rel_word == "rel" { 887 | if rel_value == "\"next\"" { 888 | return Ok(Some(parse_link_url(url)?)); 889 | } 890 | } else { 891 | bail!("unexpected link rel word"); 892 | } 893 | } else { 894 | bail!("unexpected link rel pair"); 895 | } 896 | } else { 897 | bail!("unexpected link header"); 898 | } 899 | } 900 | 901 | Ok(None) 902 | } else { 903 | Ok(None) 904 | } 905 | } 906 | 907 | fn parse_link_url(s: &str) -> Result<&str> { 908 | trim_ends(s, b'<', b'>') 909 | } 910 | 911 | fn split_2_trim(s: &str, at: char) -> Option<(&str, &str)> { 912 | let mut elts = s.splitn(2, at); 913 | let one = elts.next(); 914 | let two = elts.next(); 915 | if let (Some(one), Some(two)) = (one, two) { 916 | Some((one.trim(), two.trim())) 917 | } else { 918 | None 919 | } 920 | } 921 | 922 | fn trim_ends(s: &str, front: u8, back: u8) -> Result<&str> { 923 | let s = s.trim(); 924 | if s.len() < 2 || s.as_bytes()[0] != front || s.as_bytes()[s.len() - 1] != back { 925 | bail!("bad trim"); 926 | } 927 | Ok(&s[1..s.len() - 1]) 928 | } 929 | 930 | fn parse_naive_date(s: &str) -> Result { 931 | Ok(NaiveDate::parse_from_str(s, "%Y-%m-%d")?) 932 | } 933 | 934 | fn delay() { 935 | delay_ms(DELAY_MS); 936 | } 937 | 938 | fn delay_ms(ms: u64) { 939 | let one_second = time::Duration::from_millis(ms); 940 | thread::sleep(one_second); 941 | } 942 | 943 | fn delay_until(date: DateTime) { 944 | let now = Utc::now(); 945 | if now < date { 946 | let wait_time = date - now; 947 | let wait_time = wait_time.to_std().expect("duration conversion"); 948 | thread::sleep(wait_time); 949 | } 950 | thread::sleep(time::Duration::from_secs(5)); 951 | } 952 | 953 | struct PullStats { 954 | stats: Vec, 955 | } 956 | 957 | struct PullStat { 958 | repo: String, 959 | count: usize, 960 | } 961 | 962 | fn make_issue_stats(project: &Project, issues: &[GhIssue]) -> Result { 963 | let mut map = HashMap::new(); 964 | 965 | for issue in issues { 966 | let repo = repo_from_issue(&issue.html_url); 967 | let counter = map.entry(repo).or_insert(0); 968 | *counter += 1; 969 | } 970 | 971 | let mut stats = vec![]; 972 | for repo in &project.repos { 973 | let repo = repo_name_to_url(repo); 974 | let count = map.remove(&repo).unwrap_or(0); 975 | if count != 0 { 976 | stats.push(PullStat { 977 | repo: repo.to_string(), 978 | count, 979 | }); 980 | } 981 | } 982 | 983 | for k in map.keys() { 984 | println!("repo mismatch during issue stats: {k}"); 985 | } 986 | 987 | if !map.is_empty() { 988 | bail!("repo mismatch during issue stats for {}", project.name); 989 | } 990 | 991 | Ok(PullStats { stats }) 992 | } 993 | 994 | fn repo_from_issue(issue: &str) -> String { 995 | let parts = issue.split('/').collect::>(); 996 | assert!(parts.len() > 2); 997 | let new_parts_count = parts.len() - 2; 998 | let parts = &parts[0..new_parts_count]; 999 | parts.join("/") 1000 | } 1001 | 1002 | fn make_pull_stats(project: &Project, pulls: &[GhPullWithComments]) -> Result { 1003 | let mut map = HashMap::new(); 1004 | 1005 | for pull in pulls { 1006 | let repo = &pull.pull.base.repo.html_url; 1007 | let counter = map.entry(repo).or_insert(0); 1008 | *counter += 1; 1009 | } 1010 | 1011 | let mut stats = vec![]; 1012 | for repo in &project.repos { 1013 | let repo = repo_name_to_url(repo); 1014 | let count = map.remove(&repo).unwrap_or(0); 1015 | if count != 0 { 1016 | stats.push(PullStat { 1017 | repo: repo.to_string(), 1018 | count, 1019 | }); 1020 | } 1021 | } 1022 | 1023 | for k in map.keys() { 1024 | println!("repo mismatch during pull stats: {k}"); 1025 | } 1026 | 1027 | if !map.is_empty() { 1028 | bail!("repo mismatch during pull stats for {}", project.name); 1029 | } 1030 | 1031 | Ok(PullStats { stats }) 1032 | } 1033 | 1034 | fn repo_name_to_url(repo: &str) -> String { 1035 | format!("https://github.com/{repo}") 1036 | } 1037 | 1038 | fn make_stubname(project: &Project) -> String { 1039 | let lower = project.name.to_ascii_lowercase(); 1040 | lower.replace(' ', "_") 1041 | } 1042 | -------------------------------------------------------------------------------- /src/rib-config.toml: -------------------------------------------------------------------------------- 1 | # Projects are listed alphabetically, but bitcoin- and ethereum-related projects 2 | # have their own sections at the end. 3 | 4 | # Non-Bitcoin / non-Ethereum 5 | 6 | [[sections]] 7 | name = "General" 8 | 9 | [[sections.projects]] 10 | name = "Aleo" 11 | is_org = true 12 | url = "https://github.com/AleoHQ" 13 | repos = [ 14 | "AleoHQ/leo", 15 | "AleoHQ/snarkOS", 16 | "AleoHQ/snarkVM", 17 | "AleoHQ/aleo-rust", 18 | "AleoHQ/aleo-std", 19 | "AleoHQ/sdk", 20 | "AleoHQ/aleo-setup-integration-test", 21 | "howardwu/wagyu", 22 | "howardwu/wagyu-zcash-parameters", 23 | ] 24 | 25 | [[sections.projects]] 26 | name = "Anoma" 27 | is_org = true 28 | url = "https://github.com/anoma" 29 | repos = [ 30 | "anoma/namada", 31 | "anoma/namada-sdk-starter", 32 | "anoma/taiga", 33 | "anoma/zkp-compiler-shootout", 34 | "anoma/masp", 35 | "anoma/vamp-ir", 36 | "anoma/namada-masp-verification", 37 | "anoma/namada-masp-params", 38 | "anoma/anoma", 39 | "anoma/ethereum-bridge-e2e-tests", 40 | "anoma/ferveo", 41 | "anoma/anoma-wasm-multitoken", 42 | "anoma/using-namada-sdk-poc", 43 | "anoma/building-namada-sdk-to-wasm", 44 | "anoma/using-namada-sdk-poc-2", 45 | "anoma/masp-mpc", 46 | "anoma/verify-beacon", 47 | ] 48 | 49 | [[sections.projects]] 50 | name = "Aptos" 51 | is_org = true 52 | url = "https://github.com/aptos-labs" 53 | repos = [ 54 | "aptos-labs/aptos-core", 55 | "aptos-labs/aptos-indexer-processors", 56 | "aptos-labs/move", 57 | "aptos-labs/bcs", 58 | ] 59 | 60 | [[sections.projects]] 61 | name = "Casper" 62 | is_org = true 63 | url= "https://github.com/casper-network" 64 | repos = [ 65 | "casper-network/casper-node", 66 | "casper-network/casper-node-launcher", 67 | "casper-network/casper-db-utils", 68 | ] 69 | 70 | [[sections.projects]] 71 | name = "Chainflip" 72 | is_org = true 73 | url = "https://github.com/chainflip-io" 74 | repos = [ 75 | "chainflip-io/chainflip-backend", 76 | "chainflip-io/rust-zmq", 77 | ] 78 | 79 | [[sections.projects]] 80 | name = "COMIT" 81 | is_org = true 82 | url = "https://github.com/comit-network" 83 | repos = [ 84 | "comit-network/xmr-btc-swap", 85 | "comit-network/rendezvous-server", 86 | "comit-network/maia", 87 | "comit-network/malax", 88 | "comit-network/xtra-productivity", 89 | "comit-network/waves", 90 | ] 91 | 92 | [[sections.projects]] 93 | name = "Concordium" 94 | is_org = true 95 | url = "https://github.com/Concordium" 96 | repos = [ 97 | "Concordium/concordium-rust-smart-contracts", 98 | "Concordium/concordium-base", 99 | "Concordium/concordium-misc-tools", 100 | "Concordium/concordium-rust-sdk", 101 | "Concordium/concordium-smart-contract-tools", 102 | "Concordium/concordium-rosetta", 103 | "Concordium/concordium-transaction-logger", 104 | "Concordium/concordium-euro2ccd-service", 105 | "Concordium/voting-workshop", 106 | "Concordium/concordium-use-case-examples", 107 | ] 108 | 109 | [[sections.projects]] 110 | name = "Conflux" 111 | is_org = true 112 | url = "https://github.com/Conflux-Chain" 113 | repos = [ 114 | "Conflux-Chain/conflux-rust", 115 | "Conflux-Chain/cfx-evm", 116 | ] 117 | 118 | [[sections.projects]] 119 | name = "DarkFi" 120 | is_org = false 121 | url = "https://github.com/darkrenaissance" 122 | repos = [ 123 | "darkrenaissance/darkfi", 124 | ] 125 | 126 | [[sections.projects]] 127 | name = "Dfinity" 128 | is_org = true 129 | url = "https://github.com/dfinity" 130 | repos = [ 131 | "dfinity/nns-dapp", 132 | "dfinity/canister-profiling", 133 | "dfinity/sdk", 134 | "dfinity/ic", 135 | "dfinity/agent-rs", 136 | "dfinity/ICRC-1", 137 | "dfinity/internet-identity", 138 | "dfinity/stable-structures", 139 | "dfinity/ic-websocket-poc", 140 | "dfinity/bitcoin-canister", 141 | "dfinity/experimental-minting-tool", 142 | "dfinity/cdk-rs", 143 | "dfinity/response-verification", 144 | "dfinity/idl2json", 145 | "dfinity/dfx-extensions", 146 | "dfinity/ic-repl", 147 | "dfinity/ic-wasm", 148 | "dfinity/candid", 149 | "dfinity/erc20-icp", 150 | "dfinity/cns", 151 | "dfinity/motoko.rs", 152 | "dfinity/vessel", 153 | "dfinity/exchange-rate-canister", 154 | "dfinity/test-state-machine-client", 155 | "dfinity/bitcoin-developer-preview", 156 | "dfinity/icx-nns", 157 | "dfinity/quill", 158 | "dfinity/ic-quickjs-demo", 159 | "dfinity/verify-bls-signatures", 160 | "dfinity/ic-docutrack", 161 | "dfinity/metrics-encoder", 162 | "dfinity/miracl_core_bls12381", 163 | "dfinity/ic-mo-vm", 164 | ] 165 | 166 | [[sections.projects]] 167 | name = "Dusk Network" 168 | is_org = true 169 | url = "https://github.com/dusk-network" 170 | repos = [ 171 | "dusk-network/rusk", 172 | "dusk-network/wallet-cli", 173 | "dusk-network/piecrust", 174 | "dusk-network/wallet-core", 175 | "dusk-network/kadcast", 176 | "dusk-network/plonk", 177 | "dusk-network/merkle", 178 | "dusk-network/phoenix-core", 179 | "dusk-network/Poseidon252", 180 | "dusk-network/schnorr", 181 | "dusk-network/dusk-pki", 182 | "dusk-network/Hades252", 183 | "dusk-network/phoenix", 184 | "dusk-network/bls12_381-sign", 185 | "dusk-network/microkelvin", 186 | "dusk-network/nstack", 187 | "dusk-network/rusk-vm", 188 | "dusk-network/ranno", 189 | ] 190 | 191 | [[sections.projects]] 192 | name = "Espresso Systems" 193 | is_org = true 194 | url = "https://github.com/EspressoSystems" 195 | repos = [ 196 | "EspressoSystems/reef", 197 | "EspressoSystems/HotShot", 198 | "EspressoSystems/seahorse", 199 | "EspressoSystems/espresso-sequencer", 200 | "EspressoSystems/hyperplonk", 201 | "EspressoSystems/commit", 202 | "EspressoSystems/hotshot-query-service", 203 | "EspressoSystems/espresso-polygon-zkevm-demo", 204 | "EspressoSystems/cape", 205 | "EspressoSystems/discord-faucet", 206 | "EspressoSystems/espresso", 207 | "EspressoSystems/jellyfish", 208 | "EspressoSystems/async-compatibility-layer", 209 | "EspressoSystems/espresso-macros", 210 | "EspressoSystems/tide-disco", 211 | "EspressoSystems/surf-disco", 212 | "EspressoSystems/net", 213 | "EspressoSystems/tagged-base64", 214 | "EspressoSystems/espresso-systems-common", 215 | "EspressoSystems/arbitrary-wrappers", 216 | "EspressoSystems/cap", 217 | "EspressoSystems/atomicstore", 218 | "EspressoSystems/key-set", 219 | "EspressoSystems/veri-zexe", 220 | ] 221 | 222 | [[sections.projects]] 223 | name = "Filecoin" 224 | is_org = true 225 | url = "https://github.com/filecoin-project" 226 | repos = [ 227 | "filecoin-project/builtin-actors", 228 | "filecoin-project/ref-fvm", 229 | "filecoin-project/filecoin-ffi", 230 | "filecoin-project/rust-fil-proofs", 231 | "filecoin-project/rust-filecoin-proofs-api", 232 | "filecoin-project/rust-sha2ni", 233 | "filecoin-project/blstrs", 234 | "filecoin-project/bls-signatures", 235 | "filecoin-project/builtin-actors-bundler", 236 | "filecoin-project/rust-gpu-tools", 237 | "filecoin-project/ec-gpu", 238 | "filecoin-project/fil-sppark", 239 | "filecoin-project/fvm-bench", 240 | "filecoin-project/rust-fil-logger", 241 | "filecoin-project/taupipp", 242 | "filecoin-project/filecoin-phase2", 243 | "lurk-lab/neptune", 244 | "ChainSafe/forest", 245 | "ChainSafe/filecoindot", 246 | ] 247 | 248 | [[sections.projects]] 249 | name = "Findora" 250 | is_org = true 251 | url = "https://github.com/FindoraNetwork" 252 | repos = [ 253 | "FindoraNetwork/rt-evm", 254 | "FindoraNetwork/platform-lib-noah", 255 | "FindoraNetwork/platform-lib-utils", 256 | "FindoraNetwork/zkcard-mini-sdk", 257 | "FindoraNetwork/platform-lib-sparse-merkle", 258 | "FindoraNetwork/enterprise-web3", 259 | "FindoraNetwork/noah", 260 | "FindoraNetwork/eth-utils", 261 | "FindoraNetwork/generate_secp256k1_priv_validator_key", 262 | "FindoraNetwork/findorad-past", 263 | "FindoraNetwork/platform-lib-credentials", 264 | "FindoraNetwork/platform-lib-merkle", 265 | "FindoraNetwork/platform-lib-bitmap", 266 | "FindoraNetwork/ark-ed-on-bn254-mixed-radix", 267 | "FindoraNetwork/ark-bn254-mixed-radix", 268 | "FindoraNetwork/export-setup-parameters", 269 | "FindoraNetwork/storage", 270 | "FindoraNetwork/findora-poker", 271 | "FindoraNetwork/web3-rpc-core", 272 | "FindoraNetwork/ark-bulletproofs", 273 | "FindoraNetwork/bulletproofs", 274 | "FindoraNetwork/platform-lib-slidingset", 275 | "FindoraNetwork/platform-lib-cryptohash", 276 | "FindoraNetwork/zei", 277 | "FindoraNetwork/findora-exporter", 278 | "FindoraNetwork/tendermint-abci", 279 | "FindoraNetwork/tendermint-rs", 280 | "FindoraNetwork/fmerk", 281 | "FindoraNetwork/prikey2keystore", 282 | "FindoraNetwork/eip1962", 283 | "FindoraNetwork/platform", 284 | "FindoraNetwork/nft-issue-transaction", 285 | "FindoraNetwork/findora-scanner", 286 | ] 287 | 288 | [[sections.projects]] 289 | name = "Fluence" 290 | is_org = true 291 | url = "https://github.com/fluencelabs" 292 | repos = [ 293 | "fluencelabs/nox", 294 | "fluencelabs/spell", 295 | "fluencelabs/decider", 296 | "fluencelabs/registry", 297 | "fluencelabs/aquavm", 298 | "fluencelabs/marine-rs-sdk", 299 | "fluencelabs/examples", 300 | "fluencelabs/aqua-ipfs", 301 | "fluencelabs/trust-graph", 302 | "fluencelabs/fRPC-Substrate", 303 | "fluencelabs/marine-rs-sdk-test", 304 | "fluencelabs/marine", 305 | "fluencelabs/benchmark-service", 306 | "fluencelabs/release-flow-demo", 307 | ] 308 | 309 | [[sections.projects]] 310 | name = "Fuel" 311 | is_org = true 312 | url = "https://github.com/FuelLabs" 313 | repos = [ 314 | "FuelLabs/faucet", 315 | "FuelLabs/forc-wallet", 316 | "FuelLabs/fuel-bft", 317 | "FuelLabs/fuel-core", 318 | "FuelLabs/fuel-debugger", 319 | "FuelLabs/fuel-indexer", 320 | "FuelLabs/fuel-vm", 321 | "FuelLabs/fuels-rs", 322 | "FuelLabs/fuelup", 323 | "FuelLabs/sway", 324 | "FuelLabs/sway-standards", 325 | "FuelLabs/sway-libs", 326 | "FuelLabs/releasy", 327 | "FuelLabs/sway-applications", 328 | "FuelLabs/fuel-block-committer", 329 | "FuelLabs/fuel-abi-types", 330 | "FuelLabs/sway-by-example-lib", 331 | "FuelLabs/fuel-canary-watchtower", 332 | "FuelLabs/bridge-message-executor", 333 | ] 334 | 335 | [[sections.projects]] 336 | name = "Golem" 337 | is_org = true 338 | url = "https://github.com/golemfactory" 339 | repos = [ 340 | "golemfactory/ya-runtime-http-auth", 341 | "golemfactory/yagna", 342 | "golemfactory/ya-service-bus", 343 | "golemfactory/ya-client", 344 | "golemfactory/ya-relay", 345 | "golemfactory/ya-runtime-sdk", 346 | "golemfactory/ya-runtime-vm", 347 | "golemfactory/ya-vm-file-server", 348 | "golemfactory/erc20_payment_lib", 349 | "golemfactory/ansible-role-ya-requestor", 350 | "golemfactory/ya-runtime-wasi", 351 | "golemfactory/gvmkit-build-rs", 352 | "golemfactory/devops-ya-relay-e2e-test", 353 | "golemfactory/ya-self-test-img", 354 | "golemfactory/golem-certificate", 355 | "golemfactory/ya-packet-trace", 356 | "golemfactory/ya-vpn-connector", 357 | "golemfactory/ya-runtime-outbound", 358 | "golemfactory/ya-runtime-outbound-gateway", 359 | "golemfactory/g-flite", 360 | "golemfactory/gwasm-runner", 361 | "golemfactory/ProofOfDevice", 362 | "golemfactory/gudot", 363 | "golemfactory/munin-plugin-pgp-expiration", 364 | ] 365 | 366 | [[sections.projects]] 367 | name = "Grin" 368 | is_org = true 369 | url = "https://github.com/mimblewimble" 370 | repos = [ 371 | "mimblewimble/grin", 372 | "mimblewimble/grin-wallet", 373 | "mimblewimble/mwixnet", 374 | "mimblewimble/grin-gui", 375 | "mimblewimble/grin-miner", 376 | "mimblewimble/rust-secp256k1-zkp", 377 | ] 378 | 379 | [[sections.projects]] 380 | name = "Helium" 381 | is_org = true 382 | url = "https://github.com/helium" 383 | repos = [ 384 | "helium/oracles", 385 | "helium/xorf-generator", 386 | "helium/gateway-rs", 387 | "helium/helium-crypto-rs", 388 | "helium/helium-wallet-rs", 389 | "helium/account-compression-anchor-gen", 390 | "helium/helium-data", 391 | "helium/ecc608-linux-rs", 392 | "helium/etl-extract", 393 | "helium/helium-config-service-cli", 394 | "helium/virtual-lorawan-device", 395 | "helium/gateway-mfr-rs", 396 | "helium/gwmp-mux", 397 | "helium/semtech-udp", 398 | "helium/helium-packet-router-ingest", 399 | "helium/gateway-security-rs", 400 | "helium/lorawan-h3", 401 | "helium/cortex-mpu", 402 | "helium/helium-api-rs", 403 | ] 404 | 405 | [[sections.projects]] 406 | name = "Holochain" 407 | is_org = true 408 | url = "https://github.com/holochain" 409 | repos = [ 410 | "holochain/holochain", 411 | "holochain/holochain-client-rust", 412 | "holochain/holochain-wasmer", 413 | "holochain/hackathon-happs", 414 | "holochain/scaffolding", 415 | "holochain/app-store-dnas", 416 | "holochain/tx5", 417 | "holochain/hc-test-utils", 418 | "holochain/hc-zome-lib", 419 | "holochain/hc-utils", 420 | "holochain/deepkey", 421 | "holochain/nix-cache-check", 422 | "holochain/devhub-dnas", 423 | "holochain/lair", 424 | "holochain/holochain-serialization", 425 | "holochain/influxive", 426 | "holochain/portal-dna", 427 | "holochain/spike-influx", 428 | "holochain/ametrics", 429 | "holochain/hc-tel", 430 | "holochain/ghost_actor", 431 | "holochain/sodoken", 432 | "holochain/task-motel-rs", 433 | "holochain/integrity-template", 434 | "holochain/absquic", 435 | "holochain/launcher", 436 | ] 437 | 438 | [[sections.projects]] 439 | name = "IOTA" 440 | is_org = true 441 | url = "https://github.com/iotaledger" 442 | repos = [ 443 | "iotaledger/iota-sdk", 444 | "iotaledger/inx-chronicle", 445 | "iotaledger/identity.rs", 446 | "iotaledger/common-rs", 447 | "iotaledger/ledger.rs", 448 | "iotaledger/wallet.rs", 449 | "iotaledger/iota.rs", 450 | "iotaledger/stronghold.rs", 451 | "iotaledger/crypto.rs", 452 | "iotaledger/streams", 453 | "iotaledger/chronicle.rs", 454 | "iotaledger/bee", 455 | "iotaledger/cli-wallet", 456 | ] 457 | 458 | [[sections.projects]] 459 | name = "Lurk" 460 | is_org = true 461 | url = "https://github.com/lurk-lab" 462 | repos = [ 463 | "lurk-lab/lurk-rs", 464 | "lurk-lab/arecibo", 465 | "lurk-lab/neptune", 466 | "lurk-lab/bellpepper", 467 | "lurk-lab/bellpepper-gadgets", 468 | "lurk-lab/grumpkin-msm", 469 | "lurk-lab/solidity-verifier", 470 | "lurk-lab/circom-scotia", 471 | "lurk-lab/abomonation_derive", 472 | "lurk-lab/elsa", 473 | ] 474 | 475 | [[sections.projects]] 476 | name = "Maidsafe" 477 | is_org = true 478 | url = "https://github.com/maidsafe" 479 | repos = [ 480 | "maidsafe/safe_network", 481 | "maidsafe/sn-testnet-deploy", 482 | "maidsafe/sn_dbc", 483 | "maidsafe/self_encryption", 484 | "maidsafe/safeup", 485 | "maidsafe/sn_nodejs", 486 | "maidsafe/sn_authd", 487 | "maidsafe/temp_safe_network", 488 | "maidsafe/sn_consensus", 489 | "maidsafe/sn_sdkg", 490 | "maidsafe/qp2p", 491 | "maidsafe/stableset-experiments", 492 | "maidsafe/sn_launch_tool", 493 | "maidsafe/blsttc", 494 | "maidsafe/rfcs", 495 | ] 496 | 497 | [[sections.projects]] 498 | name = "Mina" 499 | is_org = true 500 | url = "https://github.com/openmina" 501 | repos = [ 502 | "openmina/openmina", 503 | "openmina/mina-p2p-messages-rs", 504 | "openmina/openmina-archive", 505 | "openmina/redux-rs", 506 | "openmina/openmina-poc", 507 | "openmina/mina-ci", 508 | "openmina/mina-network-debugger", 509 | "openmina/snark-coordinator-rs", 510 | "openmina/internal-tracing-rs", 511 | "openmina/mina-logs-service", 512 | "openmina/alloc-test", 513 | "openmina/mina-gossip-rs", 514 | ] 515 | 516 | [[sections.projects]] 517 | name = "MobileCoin" 518 | is_org = true 519 | url = "https://github.com/mobilecoinfoundation" 520 | repos = [ 521 | "mobilecoinfoundation/mobilecoin", 522 | "mobilecoinfoundation/sgx", 523 | "mobilecoinfoundation/rust-mbedtls", 524 | "mobilecoinfoundation/attestation", 525 | "mobilecoinfoundation/mc-oblivious", 526 | "mobilecoinfoundation/sgx-std", 527 | "mobilecoinfoundation/build-rs", 528 | "mobilecoinfoundation/sgx-sigstruct", 529 | "mobilecoinfoundation/protobufs", 530 | "mobilecoinfoundation/rand", 531 | "mobilecoinfoundation/serial", 532 | "mobilecoinfoundation/from-random", 533 | "mobilecoinfoundation/compliance", 534 | "mobilecoinfoundation/chronometer", 535 | "mobilecoinfoundation/oblivious-aes-gcm", 536 | ] 537 | 538 | [[sections.projects]] 539 | name = "MultiversX" 540 | is_org = true 541 | url = "https://github.com/multiversx" 542 | repos = [ 543 | "multiversx/mx-subscription-fee-rs", 544 | "multiversx/mx-exchange-tools-sc", 545 | "multiversx/mx-metabonding-sc", 546 | "multiversx/mx-contracts-rs", 547 | "multiversx/mx-exchange-sc", 548 | "multiversx/mx-sdk-rs", 549 | "multiversx/mx-nft-collection-minter-sc", 550 | "multiversx/mx-reproducible-contract-build-example-sc", 551 | "multiversx/mx-vm-executor-rs", 552 | "multiversx/mx-bridge-eth-sc-rs", 553 | "multiversx/mx-ping-pong-sc", 554 | "multiversx/mx-launchpad-sc", 555 | "multiversx/mx-liquid-staking-sc", 556 | "multiversx/mx-human-sc", 557 | "multiversx/mx-lend-sc", 558 | "multiversx/mx-dns-sc", 559 | "multiversx/mx-nft-marketplace-sc", 560 | "multiversx/mx-energy-competition-winners-extraction-sc", 561 | "multiversx/mx-delegation-sc", 562 | "multiversx/mx-band-bridge-sc", 563 | ] 564 | 565 | [[sections.projects]] 566 | name = "NEAR" 567 | is_org = true 568 | url = "https://github.com/near" 569 | repos = [ 570 | "near/near-workspaces-rs", 571 | "near/nearcore", 572 | "near/near-cli-rs", 573 | "near/borsh-rs", 574 | "near/near-sdk-rs", 575 | "near/read-rpc", 576 | "near/near-microindexers", 577 | "near/neardevhub-contract", 578 | "near/pagoda-relayer-rs", 579 | "near/near-indexer-for-explorer", 580 | "near/cargo-near", 581 | "near/near-abi-rs", 582 | "near/near-memory-tracker", 583 | "near/near-lake-indexer", 584 | "near/core-contracts", 585 | "near/near-lake-framework-rs", 586 | "near/near-jsonrpc-client-rs", 587 | "near/near-account-id", 588 | "near/bos-loader", 589 | "near/wasmer", 590 | "near/near-linkdrop", 591 | "near/near-enhanced-api-server", 592 | "near/dkim-auth", 593 | "near/sdk-rs-gas-benchmark", 594 | "near/near-sdk-abi", 595 | "near/near-abi-client-rs", 596 | ] 597 | 598 | [[sections.projects]] 599 | name = "Nervos" 600 | is_org = true 601 | url = "https://github.com/nervosnetwork" 602 | repos = [ 603 | "nervosnetwork/ckb", 604 | "nervosnetwork/ckb-light-client", 605 | "nervosnetwork/ckb-vm", 606 | "nervosnetwork/ckb-standalone-debugger", 607 | "nervosnetwork/ckb-integration-test", 608 | "nervosnetwork/ckb-sdk-rust", 609 | "nervosnetwork/ckb-cli", 610 | "nervosnetwork/ckb-std", 611 | "nervosnetwork/faster-hex", 612 | "nervosnetwork/overlord", 613 | "nervosnetwork/molecule", 614 | "nervosnetwork/ckb-x64-simulator", 615 | "nervosnetwork/merkle-mountain-range", 616 | "nervosnetwork/wasm-secp256k1-test", 617 | "nervosnetwork/sparse-merkle-tree", 618 | "nervosnetwork/capsule", 619 | "nervosnetwork/mercury", 620 | "nervosnetwork/ckb-indexer", 621 | "nervosnetwork/force-bridge-btc", 622 | "nervosnetwork/golomb-coded-set", 623 | "godwokenrises/godwoken", 624 | ] 625 | 626 | [[sections.projects]] 627 | name = "Oasis" 628 | is_org = true 629 | url = "https://github.com/oasisprotocol" 630 | repos = [ 631 | "oasisprotocol/oasis-sdk", 632 | "oasisprotocol/keymanager-paratime", 633 | "oasisprotocol/cipher-paratime", 634 | "oasisprotocol/emerald-paratime", 635 | ] 636 | 637 | [[sections.projects]] 638 | name = "Parity" 639 | is_org = true 640 | url = "https://github.com/paritytech" 641 | repos = [ 642 | "paritytech/polkadot-sdk", 643 | "paritytech/zombienet-sdk", 644 | "paritytech/ink", 645 | "paritytech/cargo-contract", 646 | "paritytech/xcm", 647 | "paritytech/trappist", 648 | "paritytech/parity-signer", 649 | "paritytech/parity-scale-codec", 650 | "paritytech/substrate-dex", 651 | "paritytech/jsonrpsee", 652 | "paritytech/parity-bridges-common", 653 | "paritytech/mixnet", 654 | "paritytech/staking-miner-v2", 655 | "paritytech/pvf-checker", 656 | "paritytech/polkadot-introspector", 657 | "paritytech/subxt", 658 | "paritytech/subport", 659 | "paritytech/substrate-telemetry", 660 | "paritytech/frontier", 661 | "paritytech/extended-parachain-template", 662 | "paritytech/trie", 663 | "paritytech/polkadot-sdk-docs", 664 | "paritytech/subxt-explorer", 665 | "paritytech/parity-publish", 666 | "paritytech/reed-solomon-novelpoly", 667 | "paritytech/substrate-curves", 668 | "paritytech/ark-substrate", 669 | "paritytech/try-runtime-cli", 670 | "paritytech/wasmi", 671 | "paritytech/soketto", 672 | "paritytech/frame-metadata", 673 | "paritytech/substrate-contracts-node", 674 | "paritytech/parachain-utils", 675 | "paritytech/smart-bench", 676 | "paritytech/parity-common", 677 | "paritytech/orchestra", 678 | "paritytech/ink-playground", 679 | "paritytech/diener", 680 | "paritytech/ink-examples", 681 | "paritytech/frontier-parachain-template", 682 | "paritytech/wasm-instrument", 683 | "paritytech/pvf-executor", 684 | "paritytech/parity-db", 685 | "paritytech/prdoc", 686 | "paritytech/unsigned-varint", 687 | "paritytech/scale-decode", 688 | "paritytech/polkadot-stps", 689 | "paritytech/ss58-registry", 690 | "paritytech/verifiable", 691 | "paritytech/polkapobal", 692 | "paritytech/parity-processbot", 693 | "paritytech/subpub", 694 | "paritytech/reref", 695 | "paritytech/scale-info", 696 | "paritytech/libsecp256k1", 697 | "paritytech/parity-tokio-ipc", 698 | "paritytech/polkadot-identicon-rust", 699 | "paritytech/scale-value", 700 | "paritytech/scale-encode", 701 | "paritytech/squink-splash-beginner", 702 | "paritytech/co2-passport", 703 | "paritytech/finality-grandpa", 704 | "paritytech/ink-waterfall", 705 | "paritytech/pallet-contracts-xcm", 706 | "paritytech/appsec_ctf_playground", 707 | "paritytech/desub", 708 | "paritytech/polkadot-developer-data", 709 | "paritytech/blockstats", 710 | "paritytech/scale-bits", 711 | "paritytech/parity-bitcoin", 712 | "paritytech/banana-recovery-rust", 713 | "paritytech/banana_split", 714 | "paritytech/secret-store", 715 | "paritytech/rustc-codesize-min", 716 | "paritytech/polkadot-interaction-examples-rs", 717 | "paritytech/substrate-test-runner", 718 | "paritytech/smoldot", 719 | "paritytech/cargo-unleash", 720 | "paritytech/substrate-template-generator", 721 | "paritytech/metadata-portal", 722 | ] 723 | 724 | [[sections.projects]] 725 | name = "Radix" 726 | is_org = true 727 | url = "https://github.com/radixdlt" 728 | repos = [ 729 | "radixdlt/radixdlt-scrypto", 730 | "radixdlt/scrypto-examples", 731 | "radixdlt/community-scrypto-examples", 732 | "radixdlt/radix-engine-toolkit", 733 | "radixdlt/create-scrypto-dapp", 734 | "radixdlt/babylon-ledger-app", 735 | "radixdlt/scrypto101-exercises", 736 | "radixdlt/scrypto-challenges", 737 | "radixdlt/scrypto-demos", 738 | ] 739 | 740 | [[sections.projects]] 741 | name = "Secret Network" 742 | is_org = true 743 | url = "https://github.com/scrtlabs" 744 | repos = [ 745 | "scrtlabs/SecretNetwork", 746 | "scrtlabs/examples", 747 | "scrtlabs/snip20-reference-impl", 748 | "scrtlabs/secret-toolkit", 749 | "scrtlabs/ibc-hooks-snip20-auto-wrap-proxy-contract", 750 | "scrtlabs/shielded-voting", 751 | "scrtlabs/tm-secret-enclave", 752 | "scrtlabs/seed-rotation-service", 753 | "scrtlabs/secretSCRT", 754 | "scrtlabs/secret-vrf-challenge-contract", 755 | "scrtlabs/random-ibc-example", 756 | "scrtlabs/unstoppable-secrets", 757 | "scrtlabs/ics20-for-axelar", 758 | "scrtlabs/SecretSwap", 759 | "scrtlabs/mobile-video-example", 760 | "scrtlabs/crosschain-contract-demo", 761 | "scrtlabs/MillionaireProblemTutorial", 762 | ] 763 | 764 | [[sections.projects]] 765 | name = "Solana" 766 | is_org = true 767 | url = "https://github.com/solana-labs" 768 | repos = [ 769 | "solana-labs/solana", 770 | "solana-labs/solana-program-library", 771 | "solana-labs/cargo-run-solana-tests", 772 | "solana-labs/solana-accountsdb-plugin-postgres", 773 | "solana-labs/interns-codehub", 774 | "solana-labs/governance-program-library", 775 | "solana-labs/solana-accountsdb-plugin-postgres", 776 | "solana-labs/perpetuals", 777 | ] 778 | 779 | [[sections.projects]] 780 | name = "Soroban" 781 | is_org = true 782 | url = "https://github.com/stellar" 783 | repos = [ 784 | "stellar/rs-soroban-sdk", 785 | "stellar/rs-soroban-env", 786 | "stellar/scaffold-soroban", 787 | "stellar/soroban-tools", 788 | "stellar/xdrgen", 789 | "stellar/soroban-example-dapp", 790 | "stellar/rs-stellar-strkey", 791 | "stellar/rs-stellar-xdr", 792 | "stellar/soroban-examples", 793 | "stellar/soroban-quest", 794 | "stellar/fca00c-asteroids", 795 | "stellar/soroflare", 796 | "stellar/bytes-lit", 797 | "stellar/crate-git-revision", 798 | "stellar/soroban-name-service", 799 | ] 800 | 801 | [[sections.projects]] 802 | name = "Spacemesh" 803 | is_org = true 804 | url = "https://github.com/spacemeshos" 805 | repos = [ 806 | "spacemeshos/post-rs", 807 | "spacemeshos/spacemesh-sdk", 808 | "spacemeshos/scrypt-jane-rs", 809 | "spacemeshos/spacemesh-rs", 810 | ] 811 | 812 | [[sections.projects]] 813 | name = "Subspace Network" 814 | is_org = true 815 | url = "https://github.com/subspace" 816 | repos = [ 817 | "subspace/subspace", 818 | "subspace/pulsar", 819 | "subspace/subspace-sdk", 820 | "subspace/layerzero_testnet_bridge", 821 | ] 822 | 823 | [[sections.projects]] 824 | name = "Sui" 825 | is_org = true 826 | url = "https://github.com/MystenLabs" 827 | repos = [ 828 | "MystenLabs/sui", 829 | "MystenLabs/narwhal", 830 | "MystenLabs/fastcrypto", 831 | "MystenLabs/dapol", 832 | "MystenLabs/mysten-sim", 833 | "MystenLabs/ed25519-unsafe-libs", 834 | "MystenLabs/base64pemkey", 835 | ] 836 | 837 | [[sections.projects]] 838 | name = "TezEdge" 839 | is_org = true 840 | url = "https://github.com/tezedge" 841 | repos = [ 842 | "tezedge/tezedge", 843 | "tezedge/tezedge-snapshots", 844 | ] 845 | 846 | [[sections.projects]] 847 | name = "Vara" 848 | is_org = true 849 | url = "https://github.com/gear-tech" 850 | repos = [ 851 | "https://github.com/gear-tech/gear", 852 | ] 853 | 854 | [[sections.projects]] 855 | name = "Zcash" 856 | is_org = true 857 | url = "https://github.com/zcash" 858 | repos = [ 859 | "zcash/librustzcash", 860 | "zcash/incrementalmerkletree", 861 | "zcash/orchard", 862 | "zcash/pasta_curves", 863 | "zcash/halo2", 864 | "zcash/halo2_legacy_pdqsort", 865 | "ZcashFoundation/zebra", 866 | "ZcashFoundation/reddsa", 867 | "ZcashFoundation/frost", 868 | "ZcashFoundation/ed25519-zebra", 869 | "ZcashFoundation/frost-zcash-demo", 870 | "ZcashFoundation/zcash-sync", 871 | "ZcashFoundation/redjubjub", 872 | ] 873 | 874 | 875 | # Bitcoin 876 | 877 | [[sections]] 878 | name = "Bitcoin" 879 | 880 | [[sections.projects]] 881 | name = "AluVM" 882 | is_org = true 883 | url = "https://github.com/AluVM" 884 | repos = [ 885 | "AluVM/rust-aluvm", 886 | "AluVM/aluasm", 887 | "AluVM/alure", 888 | ] 889 | 890 | [[sections.projects]] 891 | name = "BDK" 892 | is_org = true 893 | url = "https://github.com/bitcoindevkit" 894 | repos = [ 895 | "bitcoindevkit/rust-esplora-client", 896 | "bitcoindevkit/bdk", 897 | "bitcoindevkit/rust-hwi", 898 | "bitcoindevkit/bdk-ffi", 899 | "bitcoindevkit/bdk-cli", 900 | "bitcoindevkit/rust-electrum-client", 901 | "bitcoindevkit/bdk-reserves", 902 | "bitcoindevkit/elephant", 903 | ] 904 | 905 | [[sections.projects]] 906 | name = "Bitcoin Protocol" 907 | is_org = true 908 | url = "https://github.com/BP-WG" 909 | repos = [ 910 | 'BP-WG/bitcoin_foundation', 911 | 'BP-WG/bp-core', 912 | 'BP-WG/descriptor-wallet', 913 | 'BP-WG/bp-node', 914 | 'BP-WG/bp-wallet', 915 | 'BP-WG/bp-std', 916 | 'BP-WG/bitcoin_hwi', 917 | ] 918 | 919 | [[sections.projects]] 920 | name = "BitMask" 921 | is_org = false 922 | url = "https://github.com/diba-io" 923 | repos = [ 924 | "diba-io/bitmask-core", 925 | ] 926 | 927 | [[sections.projects]] 928 | name = "Bitswap" 929 | is_org = true 930 | url = "https://github.com/BitSwap-BiFi" 931 | repos = [ 932 | "BitSwap-BiFi/Bitswap-core", 933 | ] 934 | 935 | [[sections.projects]] 936 | name = "CivKit" 937 | is_org = true 938 | url = "https://github.com/civkit" 939 | repos = [ 940 | 'civkit/civkit-node', 941 | 'civkit/orage', 942 | 'civkit/staking-credentials', 943 | ] 944 | 945 | [[sections.projects]] 946 | name = "Cyphernet" 947 | is_org = true 948 | url = "https://github.com/cyphernet-dao" 949 | repos = [ 950 | "cyphernet-dao/rust-netservices", 951 | "cyphernet-dao/rust-internet2", 952 | "cyphernet-dao/rust-microservices", 953 | "cyphernet-dao/rust-cyphernet", 954 | "cyphernet-dao/nsh", 955 | "cyphernet-dao/ssi", 956 | ] 957 | 958 | [[sections.projects]] 959 | name = "Electrs" 960 | is_org = false 961 | url = "https://github.com/romanz" 962 | repos = [ 963 | "romanz/electrs", 964 | ] 965 | 966 | [[sections.projects]] 967 | name = "Fedimint" 968 | is_org = false 969 | url = "https://github.com/fedimint" 970 | repos = [ 971 | "fedimint/fedimint", 972 | "fedimint/fedimint-custom-modules-example", 973 | ] 974 | 975 | [[sections.projects]] 976 | name = "LDK" 977 | is_org = true 978 | url = "https://github.com/lightningdevkit" 979 | repos = [ 980 | "lightningdevkit/rust-lightning", 981 | "lightningdevkit/ldk-node", 982 | "lightningdevkit/ldk-lsp-client", 983 | "lightningdevkit/vss-rust-client", 984 | "lightningdevkit/rapid-gossip-sync-server", 985 | "lightningdevkit/ldk-sample", 986 | "lightningdevkit/ldk-c-bindings", 987 | ] 988 | 989 | [[sections.projects]] 990 | name = "LNP/BP" 991 | is_org = true 992 | url = "https://github.com/LNP-BP" 993 | repos = [ 994 | "LNP-BP/client_side_validation", 995 | "LNP-BP/rust-lnpbp", 996 | "LNP-BP/invoices", 997 | "rust-amplify/rust-amplify", 998 | ] 999 | 1000 | [[sections.projects]] 1001 | name = "LNP WG" 1002 | is_org = true 1003 | url = "https://github.com/LNP-WG" 1004 | repos = [ 1005 | "LNP-WG/lnp-core", 1006 | "LNP-WG/lnp-node", 1007 | "LNP-WG/lightning_encoding", 1008 | "LNP-WG/ln-types", 1009 | ] 1010 | 1011 | [[sections.projects]] 1012 | name = "MyCitadel" 1013 | is_org = true 1014 | url = "https://github.com/mycitadel" 1015 | repos = [ 1016 | "mycitadel/citadel-runtime", 1017 | "mycitadel/libcitadel", 1018 | "mycitadel/mycitadel-desktop", 1019 | "mycitadel/mycitadel-node", 1020 | ] 1021 | 1022 | [[sections.projects]] 1023 | name = "Nakamoto" 1024 | is_org = false 1025 | url = "https://github.com/cloudhead" 1026 | repos = [ 1027 | "cloudhead/nakamoto", 1028 | ] 1029 | 1030 | [[sections.projects]] 1031 | name = "Nomic" 1032 | is_org = false 1033 | url = "https://github.com/nomic-io" 1034 | repos = [ 1035 | "nomic-io/nomic", 1036 | "turbofish-org/merk", 1037 | "turbofish-org/orga", 1038 | "turbofish-org/abci2", 1039 | "turbofish-org/ed", 1040 | "turbofish-org/node-merk", 1041 | ] 1042 | 1043 | [[sections.projects]] 1044 | name = "RGB" 1045 | is_org = true 1046 | url = "https://github.com/RGB-WG" 1047 | repos = [ 1048 | "RGB-WG/rgb-core", 1049 | "RGB-WG/rgb-node", 1050 | "RGB-WG/rgb", 1051 | "RGB-WG/rgb-wallet", 1052 | "RGB-WG/rgb-schemata", 1053 | ] 1054 | 1055 | [[sections.projects]] 1056 | name = "Rust Bitcoin" 1057 | is_org = true 1058 | url = "https://github.com/rust-bitcoin" 1059 | repos = [ 1060 | "rust-bitcoin/rust-bitcoin", 1061 | "rust-bitcoin/rust-miniscript", 1062 | "rust-bitcoin/rust-bech32", 1063 | "rust-bitcoin/rust-bip39", 1064 | "rust-bitcoin/rust-bitcoincore-rpc", 1065 | "rust-bitcoin/hex-conservative", 1066 | "rust-bitcoin/rust-wallet", 1067 | "rust-bitcoin/rust-bech32-bitcoin", 1068 | "rust-bitcoin/rust-secp256k1", 1069 | ] 1070 | 1071 | [[sections.projects]] 1072 | name = "Rust Payjoin" 1073 | is_org = false 1074 | url = "https://github.com/payjoin/rust-payjoin" 1075 | repos = [ 1076 | "payjoin/rust-payjoin", 1077 | ] 1078 | 1079 | [[sections.projects]] 1080 | name = "Rust Simplicity" 1081 | is_org = false 1082 | url = "https://github.com/BlockstreamResearch" 1083 | repos = [ 1084 | "BlockstreamResearch/rust-simplicity", 1085 | ] 1086 | 1087 | [[sections.projects]] 1088 | name = "Sapio" 1089 | is_org = false 1090 | url = "https://github.com/sapio-lang" 1091 | repos = [ 1092 | "sapio-lang/sapio", 1093 | ] 1094 | 1095 | [[sections.projects]] 1096 | name = "Strict types" 1097 | is_org = true 1098 | url = "https://github.com/strict-types" 1099 | repos = [ 1100 | 'strict-types/strict-types', 1101 | 'strict-types/strict-encoding', 1102 | 'strict-types/stenc', 1103 | 'strict-types/encoding_derive_helpers', 1104 | ] 1105 | 1106 | [[sections.projects]] 1107 | name = "Talaia" 1108 | is_org = false 1109 | url = "https://github.com/talaia-labs" 1110 | repos = [ 1111 | "talaia-labs/rust-teos", 1112 | ] 1113 | 1114 | 1115 | # Ethereum 1116 | 1117 | [[sections]] 1118 | name = "Ethereum" 1119 | 1120 | [[sections.projects]] 1121 | name = "Ethers-rs" 1122 | is_org = false 1123 | url = "https://github.com/gakonst" 1124 | repos = [ 1125 | "gakonst/ethers-rs", 1126 | ] 1127 | 1128 | [[sections.projects]] 1129 | name = "Foundry" 1130 | is_org = true 1131 | url = "https://github.com/foundry-rs" 1132 | repos = [ 1133 | "foundry-rs/foundry", 1134 | "foundry-rs/starknet-foundry", 1135 | "foundry-rs/foundry-rust-template", 1136 | ] 1137 | 1138 | [[sections.projects]] 1139 | name = "Lighthouse" 1140 | is_org = true 1141 | url = "https://github.com/sigp" 1142 | repos = [ 1143 | "sigp/lighthouse", 1144 | "sigp/discv5", 1145 | "sigp/enr", 1146 | "sigp/eleel", 1147 | "sigp/milhouse", 1148 | "sigp/tree_hash", 1149 | "sigp/metastruct", 1150 | "sigp/ssz_types", 1151 | "sigp/gossipsub-testground", 1152 | "sigp/ethereum_serde_utils", 1153 | ] 1154 | 1155 | [[sections.projects]] 1156 | name = "Polygon Zero" 1157 | is_org = true 1158 | url = "https://github.com/0xPolygonZero" 1159 | repos = [ 1160 | "0xPolygonZero/plonky2", 1161 | "0xPolygonZero/evm-tests", 1162 | "0xPolygonZero/proof-protocol-decoder", 1163 | "0xPolygonZero/plonky-edge-block-trace-parser", 1164 | "0xPolygonZero/plonky2-u32", 1165 | "0xPolygonZero/plonky2-ecdsa", 1166 | "0xPolygonZero/plonky-block-proof-gen", 1167 | "0xPolygonZero/eth_trie_utils", 1168 | "0xPolygonZero/system-zero", 1169 | "0xPolygonZero/plonky2-insertion", 1170 | "0xPolygonZero/plonky2-waksman", 1171 | ] 1172 | 1173 | [[sections.projects]] 1174 | name = "Reth" 1175 | is_org = false 1176 | url = "https://github.com/paradigmxyz" 1177 | repos = [ 1178 | "paradigmxyz/reth", 1179 | ] 1180 | 1181 | [[sections.projects]] 1182 | name = "Rust Ethereum" 1183 | is_org = true 1184 | url = "https://github.com/rust-ethereum" 1185 | repos = [ 1186 | "rust-ethereum/ethabi", 1187 | "rust-ethereum/ethash", 1188 | ] 1189 | 1190 | [[sections.projects]] 1191 | name = "Rust Web3" 1192 | is_org = false 1193 | url = "https://github.com/tomusdrw" 1194 | repos = [ 1195 | "tomusdrw/rust-web3", 1196 | ] 1197 | 1198 | [[sections.projects]] 1199 | name = "Starkware" 1200 | is_org = true 1201 | url = "https://github.com/starkware-libs" 1202 | repos = [ 1203 | "starkware-libs/cairo", 1204 | "starkware-libs/papyrus", 1205 | "starkware-libs/blockifier", 1206 | "starkware-libs/starknet-api", 1207 | ] 1208 | 1209 | [[sections.projects]] 1210 | name = "zkSync Era" 1211 | is_org = true 1212 | url = "https://github.com/matter-labs" 1213 | repos = [ 1214 | "matter-labs/demo-circuit", 1215 | "matter-labs/eip1962", 1216 | "matter-labs/era-boojum", 1217 | "matter-labs/era-boojum-cuda", 1218 | "matter-labs/era-boojum-validator-cli", 1219 | "matter-labs/era-circuit_testing", 1220 | "matter-labs/era-compiler-llvm-context", 1221 | "matter-labs/era-compiler-llvm-builder", 1222 | "matter-labs/era-compiler-solidity", 1223 | "matter-labs/era-compiler-tester", 1224 | "matter-labs/era-compiler-vyper", 1225 | "matter-labs/era-compiler-common", 1226 | "matter-labs/era-heavy-ops-service", 1227 | "matter-labs/era-revm", 1228 | "matter-labs/era-shivini", 1229 | "matter-labs/era-sync_vm", 1230 | "matter-labs/era-test-node", 1231 | "matter-labs/era-zkevm_opcode_defs", 1232 | "matter-labs/era-zkevm_test_harness", 1233 | "matter-labs/era-zk_evm", 1234 | "matter-labs/era-zk_evm_abstractions", 1235 | "matter-labs/era-zkEVM-assembly", 1236 | "matter-labs/era-zkevm_circuits", 1237 | "matter-labs/era-zkevm_tester", 1238 | "matter-labs/foundry-zksync", 1239 | "matter-labs/franklin-crypto", 1240 | "matter-labs/hodor", 1241 | "matter-labs/rescue-poseidon", 1242 | "matter-labs/risc_v_simulator", 1243 | "matter-labs/schnorr-musig", 1244 | "matter-labs/snark-wrapper", 1245 | "matter-labs/vise", 1246 | "matter-labs/zksync-era", 1247 | "matter-labs/zksync", 1248 | "matter-labs/zk_os", 1249 | ] 1250 | --------------------------------------------------------------------------------