diff --git a/.github/workflows/report.yaml b/.github/workflows/report.yaml new file mode 100644 index 0000000..b49a580 --- /dev/null +++ b/.github/workflows/report.yaml @@ -0,0 +1,42 @@ +name: Weekly Report + +on: + schedule: + - cron: '0 0 * * *' + +jobs: + build: + + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v4 + + - name: Install Deps + run: | + sudo apt-get update; + sudo apt-get install -y \ + automake \ + autoconf \ + libtool \ + autogen \ + bison \ + flex \ + libgmp3-dev \ + libmpfr-dev \ + libmpc-dev \ + build-essential \ + gcc-multilib \ + g++-multilib \ + dejagnu \ + rustc + + - name: Generate report + run: | + cd util/generator; \ + ./weekly.sh > "weekly_report"; + + - name: Archive report + uses: actions/upload-artifact@v4 + with: + name: weekly_report + path: util/generator/weekly_report diff --git a/util/generator/.gitignore b/util/generator/.gitignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/util/generator/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/util/generator/Cargo.lock b/util/generator/Cargo.lock new file mode 100644 index 0000000..c8adfc8 --- /dev/null +++ b/util/generator/Cargo.lock @@ -0,0 +1,2024 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "arc-swap" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "983cd8b9d4b02a6dc6ffa557262eb5858a27a0038ffffe21a0f133eaa819a164" + +[[package]] +name = "async-trait" +version = "0.1.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6e93155431f3931513b243d371981bb2770112b370c82745a1d19d2f99364" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.105", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bumpalo" +version = "3.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba" + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "cc" +version = "1.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +dependencies = [ + "jobserver", + "libc", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-integer", + "num-traits", + "serde", + "time 0.1.45", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "clap" +version = "4.0.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d" +dependencies = [ + "bitflags 1.3.2", + "clap_derive", + "clap_lex", + "is-terminal", + "once_cell", + "strsim", + "termcolor", +] + +[[package]] +name = "clap_derive" +version = "4.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.105", +] + +[[package]] +name = "clap_lex" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.45.0", +] + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "cxx" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn 1.0.105", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.105", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "errno" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +dependencies = [ + "errno-dragonfly", + "libc", + "winapi", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" + +[[package]] +name = "futures-executor" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.105", +] + +[[package]] +name = "futures-sink" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" + +[[package]] +name = "futures-task" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" + +[[package]] +name = "futures-util" +version = "0.3.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generator" +version = "0.1.0" +dependencies = [ + "async-trait", + "chrono", + "clap", + "git2", + "indicatif", + "octocrab", + "rand", + "serde", + "serde_json", + "tinytemplate", + "tokio", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" + +[[package]] +name = "git2" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf7f68c2995f392c49fffb4f95ae2c873297830eb25c6bc4c114ce8f4562acc" +dependencies = [ + "bitflags 1.3.2", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "hyper" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "log", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-timeout" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" +dependencies = [ + "hyper", + "hyper-util", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "winapi", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +dependencies = [ + "cxx", + "cxx-build", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indicatif" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +dependencies = [ + "libc", + "windows-sys 0.42.0", +] + +[[package]] +name = "iri-string" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc0f0a572e8ffe56e2ff4f769f32ffe919282c3916799f8b68688b6030063bea" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is-terminal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" +dependencies = [ + "hermit-abi 0.2.6", + "io-lifetimes", + "rustix", + "windows-sys 0.42.0", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonwebtoken" +version = "9.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" +dependencies = [ + "base64 0.21.7", + "js-sys", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "libgit2-sys" +version = "0.14.2+1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f3d95f6b51075fe9810a7ae22c7095f12b98005ab364d8544797a825ce946a4" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + +[[package]] +name = "libssh2-sys" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "link-cplusplus" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9272ab7b96c9046fbc5bc56c06c117cb639fe2d509df0c421cad82d2915cf369" +dependencies = [ + "cc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" + +[[package]] +name = "lock_api" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "miniz_oxide" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "object" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +dependencies = [ + "memchr", +] + +[[package]] +name = "octocrab" +version = "0.41.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2dfd11f6efbd39491d71a3864496f0b6f45e2d01b73b26c55d631c4e0dafaef" +dependencies = [ + "arc-swap", + "async-trait", + "base64 0.22.1", + "bytes", + "cfg-if", + "chrono", + "either", + "futures", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-timeout", + "hyper-util", + "jsonwebtoken", + "once_cell", + "percent-encoding", + "pin-project", + "secrecy", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "snafu", + "tokio", + "tower", + "tower-http", + "tracing", + "url", +] + +[[package]] +name = "once_cell" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "os_str_bytes" +version = "6.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys 0.42.0", +] + +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64 0.22.1", + "serde", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" + +[[package]] +name = "portable-atomic" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.105", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustix" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.42.0", +] + +[[package]] +name = "rustls" +version = "0.23.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "schannel" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +dependencies = [ + "lazy_static", + "windows-sys 0.36.1", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "scratch" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8132065adcfd6e02db789d9285a0deb2f3fcb04002865ab67d5fb103533898" + +[[package]] +name = "secrecy" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a" +dependencies = [ + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc1bb97804af6631813c55739f771071e0f2ed33ee20b68c86ec505d906356c" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "serde" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "serde_json" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "184c643044780f7ceb59104cef98a5a6f12cb2288a7bc701ab93a362b49fd47d" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time 0.3.17", +] + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "snafu" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" +dependencies = [ + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.105", +] + +[[package]] +name = "time" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" +dependencies = [ + "libc", + "wasi 0.10.0+wasi-snapshot-preview1", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8437150ab6bbc8c5f0f519e3d5ed4aa883a83dd4cdd3d1b21f9482936046cb97" +dependencies = [ + "bitflags 2.6.0", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +dependencies = [ + "cfg-if", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.85", +] + +[[package]] +name = "tracing-core" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fe195a4f217c25b25cb5058ced57059824a678474874038dc88d211bf508d3" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.10.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 1.0.105", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.105", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc 0.36.1", + "windows_i686_gnu 0.36.1", + "windows_i686_msvc 0.36.1", + "windows_x86_64_gnu 0.36.1", + "windows_x86_64_msvc 0.36.1", +] + +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/util/generator/Cargo.toml b/util/generator/Cargo.toml new file mode 100644 index 0000000..ad153a6 --- /dev/null +++ b/util/generator/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "generator" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +async-trait = "0.1.59" +chrono = "0.4.23" +clap = { version = "4.0.29", features = ["derive"] } +octocrab = "0.41.2" +serde = { version = "1.0.150", features = ["derive"] } +tinytemplate = "1.2.1" +tokio = { version = "1.32.0", features = ["full"] } +git2 = "0.16.1" +rand = "0.8.5" +indicatif = "0.17" +serde_json = "1.0.89" diff --git a/util/generator/Dockerfile b/util/generator/Dockerfile new file mode 100644 index 0000000..85d569f --- /dev/null +++ b/util/generator/Dockerfile @@ -0,0 +1,76 @@ +FROM debian:12 AS gcc-builder + +RUN apt-get update; \ + DEBIAN_FRONTEND="noninteractive" apt-get install -y --no-install-recommends \ + autoconf \ + automake \ + bzip2\ + cargo\ + dpkg-dev \ + file \ + wget \ + curl \ + build-essential \ + imagemagick \ + libbz2-dev \ + libc6-dev \ + libcurl4-openssl-dev \ + libdb-dev \ + libevent-dev \ + libffi-dev \ + libgdbm-dev \ + libglib2.0-dev \ + libgmp-dev \ + libjpeg-dev \ + libkrb5-dev \ + liblzma-dev \ + libmagickcore-dev \ + libmagickwand-dev \ + libmaxminddb-dev \ + libncurses5-dev \ + libncursesw5-dev \ + libpng-dev \ + libpq-dev \ + libreadline-dev \ + libsqlite3-dev \ + libssl-dev \ + libtool \ + libwebp-dev \ + libxml2-dev \ + libxslt-dev \ + libyaml-dev \ + gcc-multilib\ + make \ + patch \ + unzip \ + xz-utils \ + zlib1g-dev \ + flex \ + bison \ + dejagnu\ + gawk \ + git + +ADD . /usr/src/gcc +RUN /bin/sh -c set -ex; \ + cd /usr/src/gcc; \ + git log -1 --format="%h" > /GCCRS_BUILD; \ + ./contrib/download_prerequisites; { rm *.tar.* || true; }; \ + mkdir -p /usr/src/gcc/gcc-build; \ + cd /usr/src/gcc/gcc-build; \ + /usr/src/gcc/configure --disable-bootstrap --disable-multilib --enable-languages=rust; \ + make -j "$(nproc)"; \ + make install-strip; \ + cd /root; \ + rm -rf /usr/src/gcc + +RUN /bin/sh -c set -ex; \ + echo '/usr/local/lib64' > /etc/ld.so.conf.d/local-lib64.conf; \ + ldconfig -v + +FROM rust:latest +COPY --from=gcc-builder /usr/ /usr/ +COPY --from=gcc-builder /GCCRS_BUILD /GCCRS_BUILD +RUN cargo install --git https://github.com/Rust-GCC/cargo-gccrs cargo-gccrs + +CMD ["bash"] diff --git a/util/generator/README.md b/util/generator/README.md new file mode 100644 index 0000000..deb6770 --- /dev/null +++ b/util/generator/README.md @@ -0,0 +1,23 @@ +# Report Generator + +Print on stdout a report for GCCRS + +## Usage + +### With the shell script + +./weekly.sh \: make a report for the last week, first argument is a path to the local repository of gccrs + +./monthly.sh \: make a report for the last month, first argument is a path to the local repository of gccrs + +### With cargo + +cargo r -- --kind \ --date \ --author \ --token \ + +> KIND: "monthly"/"weekly" +> +> DATE: YYYY-MM-DD (you can use `date -I` to get the good format) +> +> AUTHOR: String specifying the author +> +> TOKEN: GitHub token used to access the repository diff --git a/util/generator/monthly.sh b/util/generator/monthly.sh new file mode 100755 index 0000000..29ca8c6 --- /dev/null +++ b/util/generator/monthly.sh @@ -0,0 +1,17 @@ +#!/bin/sh +DATE=$(date -I) +AUTHOR="Philip Herron, Pierre-Emmanuel Patry, Arthur Cohen" + +if [ ! -z $1 ]; then + PATH_TO_SRC="-l $1" +fi + + +if [ -f "Cargo.toml" ]; then + + CMD="cargo run -- " +else + CMD="./generator" +fi + +$CMD -k monthly -d "$DATE" -a "$AUTHOR" $PATH_TO_SRC diff --git a/util/generator/src/error.rs b/util/generator/src/error.rs new file mode 100644 index 0000000..b8ff94a --- /dev/null +++ b/util/generator/src/error.rs @@ -0,0 +1,52 @@ +use crate::repository::CloneError; +use crate::testcase::ReportError; +use std::{fmt, io}; +use serde_json::Error as sejs_Error; + +// TODO: Cleanup, improve +#[derive(Debug)] +pub enum Error { + GitHubRequest(octocrab::Error), + Template(tinytemplate::error::Error), + Clone(CloneError), + Test(ReportError), + Workspace(io::Error), + Repository(git2::Error), + RepoNotUpToDate(& 'static str), + SerdeNotFound(sejs_Error) +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use Error::*; + match self { + GitHubRequest(why) => write!(f, "Error whilst contacting github: {why}"), + Template(why) => write!(f, "Templating error: {why}"), + Clone(why) => write!(f, "Clone error: {why}"), + Test(why) => write!(f, "Testsuite error: {why}"), + Workspace(why) => write!(f, "Workspace management error: {why}"), + Repository(why) => write!(f, "Repository management error: {why}"), + RepoNotUpToDate(why) => write!(f, "{why}"), + SerdeNotFound(why) => write!(f, "Json serializing error: {why}") + } + } +} + +impl std::error::Error for Error {} + +impl From for Error { + fn from(e: octocrab::Error) -> Error { + Error::GitHubRequest(e) + } +} + +impl From for Error { + fn from(e: tinytemplate::error::Error) -> Error { + Error::Template(e) + } +} +impl From for Error { + fn from(e: sejs_Error) -> Error { + Error::SerdeNotFound(e) + } +} diff --git a/util/generator/src/github.rs b/util/generator/src/github.rs new file mode 100644 index 0000000..55e36f1 --- /dev/null +++ b/util/generator/src/github.rs @@ -0,0 +1,6 @@ +//! A module containing github related operations. + +pub mod milestone; +pub mod pr; +pub mod contrib; +pub mod issues; diff --git a/util/generator/src/github/contrib.rs b/util/generator/src/github/contrib.rs new file mode 100644 index 0000000..a2bc43e --- /dev/null +++ b/util/generator/src/github/contrib.rs @@ -0,0 +1,26 @@ + +use std::fmt::{Display, Formatter, Result as FmtResult}; + +use octocrab::{models::pulls::PullRequest, params::State, Octocrab }; + +#[derive(Hash, Eq, PartialEq)] +pub struct Contrib { + name: String, + url: String, +} + +impl From for Contrib { + fn from(pr: PullRequest) -> Contrib { + let user = *(pr.user.unwrap()); + Contrib { + name: user.login, + url: user.url.to_string(), + } + } +} + +impl Display for Contrib { + fn fmt(&self, f: &mut Formatter <'_>) -> FmtResult { + write!(f, "[[{}][{}]]", self.name, self.url) + } +} diff --git a/util/generator/src/github/issues.rs b/util/generator/src/github/issues.rs new file mode 100644 index 0000000..db89e29 --- /dev/null +++ b/util/generator/src/github/issues.rs @@ -0,0 +1,148 @@ +//! Module related to github pull requests. +use crate::{ + error::Error, + naming::{ORGANISATION, REPOSITORY}, +}; +use octocrab::{models::{issues::Issue, IssueState}, Octocrab, Page}; +use serde::Serialize; + +use std::fmt::{Display, Formatter, Result as FmtResult}; + +use serde_json::Value; + +#[derive(Clone, Debug)] +pub struct Issues{ + number: u64, + title: String, + pub state: IssueState, +} + +impl From for Issues{ + fn from(is: Issue) -> Issues{ + Issues { + number: is.number, + title: is.title, + state: is.state, + } + } +} + +impl Display for Issues{ + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + write!(f, "{}", self.title) + } +} + +/// Fetch all issues +/// +/// # Arguments +/// +/// * `gh` - Octocrab instance that should be used to fetch data. +pub async fn fetch_issues( + gh: &Octocrab, +) -> Result, Error> { + let mut pages = gh + .issues(ORGANISATION, REPOSITORY) + .list() + .state(octocrab::params::State::Closed) + .per_page(100) + .send() + .await?; + Ok(pages) +} + +pub async fn get_in_progress( + gh: &Octocrab, + bug: bool + ) -> Result { + + let mut all_uri = String::from("https://api.github.com/search/issues?q=repo:Rust-GCC/gccrs+type:issue+state:open"); + let mut no_assignee_uri = String::from("https://api.github.com/search/issues?q=repo:Rust-GCC/gccrs+type:issue+state:open+no:assignee"); + + if bug + { + all_uri.push_str("+label:bug"); + no_assignee_uri.push_str("+label:bug"); + } + + let all = gh._get(all_uri).await.unwrap(); + let no_assignee = gh._get(no_assignee_uri).await.unwrap(); + + let serres: Value = serde_json::from_str(gh.body_to_string(all).await.unwrap().as_str())?; + let serres_no: Value = serde_json::from_str(gh.body_to_string(no_assignee).await.unwrap().as_str())?; + + let nb_all = if let Some(x) = serres["total_count"].as_u64() + { + x + } + else + { + 0 + }; + let nb_no = if let Some(x) = serres_no["total_count"].as_u64() + { + x + } + else + { + 0 + }; + + Ok(nb_all - nb_no) + } + + pub async fn get_TODO( + gh: &Octocrab, + bug :bool + ) -> Result { + + let mut no_assignee_uri = String::from("https://api.github.com/search/issues?q=repo:Rust-GCC/gccrs+type:issue+state:open+no:assignee"); + + if bug + { + no_assignee_uri.push_str("+label:bug") + } + + let no_assignee = gh._get(no_assignee_uri).await.unwrap(); + + let serres_no: Value = serde_json::from_str(gh.body_to_string(no_assignee).await.unwrap().as_str())?; + + let nb_no = if let Some(x) = serres_no["total_count"].as_u64() + { + x + } + else + { + 0 + }; + + Ok(nb_no) + } + + pub async fn get_closed( + gh: &Octocrab, + bug: bool + ) -> Result { + + let mut no_assignee_uri = String::from("https://api.github.com/search/issues?q=repo:Rust-GCC/gccrs+type:issue+state:closed"); + + if bug + { + no_assignee_uri.push_str("+label:bug") + } + + let no_assignee = gh._get(no_assignee_uri).await.unwrap(); + + let serres_no: Value = serde_json::from_str(gh.body_to_string(no_assignee).await.unwrap().as_str())?; + + let nb_no = if let Some(x) = serres_no["total_count"].as_u64() + { + x + } + else + { + 0 + }; + + Ok(nb_no) + } diff --git a/util/generator/src/github/milestone.rs b/util/generator/src/github/milestone.rs new file mode 100644 index 0000000..6f49218 --- /dev/null +++ b/util/generator/src/github/milestone.rs @@ -0,0 +1,66 @@ +//! Module related to github milestones. +use crate::{ + error::Error, + naming::{ORGANISATION, REPOSITORY}, +}; +use async_trait::async_trait; +use chrono::NaiveDate; +use std::fmt::{Display, Formatter, Result as FmtResult}; + +use octocrab::{models::Milestone, Octocrab, Page}; + +#[async_trait] +trait MilestoneExt { + async fn milestones(&self, owner: &str, repo: &str) + -> Result, octocrab::Error>; +} + +#[async_trait] +impl MilestoneExt for Octocrab { + async fn milestones( + &self, + owner: &str, + repo: &str, + ) -> Result, octocrab::Error> { + self.get(format!("https://api.github.com/repos/{owner}/{repo}/milestones"), None::<&()>) + .await + } +} + +pub struct MStone { + title: String, + open_issues: i64, + closed_issues: i64, + created_at: NaiveDate, + closed_at: Option, + due_on: Option, +} + +impl From for MStone { + fn from(ms: Milestone) -> MStone { + MStone { + title: ms.title, + open_issues: ms.open_issues.unwrap(), + closed_issues: ms.closed_issues.unwrap(), + created_at: ms.created_at.date_naive(), + // FIXME: This is bad: No unwrap. It's valid to not have one + closed_at: ms.closed_at.map(|date| date.date_naive()), + // FIXME: This is bad: No unwrap. It's valid to not have one + due_on: ms.due_on.map(|date| date.date_naive()), + } + } +} + +impl Display for MStone { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + // TODO: Add checker that this is valid org-mode? unit tests? + write!(f, "|{}|", self.title) + } +} + +/// Fetch all milestones +/// +/// * `gh` - Octocrab instance that should be used to fetch data. +pub async fn fetch_all(gh: &Octocrab) -> Result, Error> { + Ok(gh.milestones(ORGANISATION, REPOSITORY).await?.take_items()) +} diff --git a/util/generator/src/github/pr.rs b/util/generator/src/github/pr.rs new file mode 100644 index 0000000..c0d7396 --- /dev/null +++ b/util/generator/src/github/pr.rs @@ -0,0 +1,87 @@ +//! Module related to github pull requests. +use crate::{ + error::Error, + naming::{ORGANISATION, REPOSITORY}, +}; +use chrono::{offset::Utc, DateTime, NaiveDate}; +use octocrab::{models::pulls::PullRequest, params::State, Octocrab}; + +use std::fmt::{Display, Formatter, Result as FmtResult}; + +#[derive(Clone, Debug)] +pub struct Pr { + number: u64, + url: String, + title: String, +} + +impl From for Pr { + fn from(pr: PullRequest) -> Pr { + Pr { + number: pr.number, + url: pr.url, + // FIXME: This contains HTML character references, like ' + // Figure out how to remove them. This is blocking for this to be used + title: pr.title.unwrap(), + } + } +} + +impl Display for Pr { + fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { + // TODO: Add checker that this is valid org-mode? unit tests? + write!(f, "- {} [[{}][PR{}]]", self.title, self.url, self.number) + } +} + +/// Fetch all merged pull requests merged a week or a month before the given date +/// +/// # Arguments +/// +/// * `gh` - Octocrab instance that should be used to fetch data. +/// * `from` - Start date for the time period containing the merged pull requests. +/// * `to` - End date for the time period containing the merged pull requests. +pub async fn fetch_merged( + gh: &Octocrab, + from: &NaiveDate, + to: &NaiveDate, +) -> Result, Error> { + let mut pages = gh + .pulls(ORGANISATION, REPOSITORY) + .list() + .state(State::All) + .per_page(100) + .send() + .await?; + + + Ok(pages + .take_items() + .into_iter() + .filter(|pr| { + pr.merged_at + .map(|e| { + let merge_date = &e.date_naive(); + // Is the inclusive range okay? + merge_date > from && merge_date < to + }) + .unwrap_or(false) + }) + .collect()) +} + +pub async fn find_oldest_pr_merge_commit(gh: &Octocrab, prs: &[Pr]) -> Option { + let mut oldest: Option<(DateTime, Option)> = None; + for pr in prs { + let complete_pr = match gh.pulls(ORGANISATION, REPOSITORY).get(pr.number).await { + Ok(x) if x.merged_at.is_some() => x, + _ => continue, + }; + oldest = match oldest { + Some(ref old_date) if old_date.0 < complete_pr.merged_at.unwrap() => oldest, + // None or older + _ => Some((complete_pr.merged_at.unwrap(), complete_pr.merge_commit_sha)), + } + } + oldest.map(|(_, pr)| pr).flatten() +} diff --git a/util/generator/src/main.rs b/util/generator/src/main.rs new file mode 100644 index 0000000..15f29e5 --- /dev/null +++ b/util/generator/src/main.rs @@ -0,0 +1,223 @@ +//! This utilitary generates a barebone report based on a given date and timespan (weekly, monthly). +//! Its goal is to help with things such as fetching merged PRs from github, generating milestone tables, +//! fetching bug/issue status, and so on. + +use clap::{Parser, ValueEnum}; +use error::Error; +use git2::{Oid, Repository}; +use indicatif::MultiProgress; +use octocrab::OctocrabBuilder; +use progress::{FetchMethod, ProgressBarExt, Steps}; +use serde::Serialize; +use std::path::PathBuf; +use testcase::TestCases; +use tinytemplate::TinyTemplate; +use std::collections::HashSet; + +use chrono::{Days, Months, NaiveDate}; + +use github::{ + milestone::{self, MStone}, + pr::{self, find_oldest_pr_merge_commit, Pr}, + contrib::{self, Contrib}, + issues::{self, get_TODO, get_closed, get_in_progress} +}; + +use task::Task; + +mod naming { + pub const ORGANISATION: &str = "rust-gcc"; + pub const REPOSITORY: &str = "gccrs"; +} + +mod error; +mod github; +mod progress; +mod repository; +mod testcase; +mod task; + +// FIXME: There should be two templates: one for weekly reports, one for monthly reports, as monthly reports include tests etc +static TEMPLATE: &str = include_str!("templates/report.org.template"); + +#[derive(Serialize)] +struct Context { + // TODO: Figure out how to unnest this; doing it just by creating another structure does not work. + // Probably needs two template: One for titleblock and one for the template, which include a title block + // so have another static TITLE_BLOCK_TEMPLATE: &str = "#+title: {kind} report for..." etc + kind: Kind, + from: NaiveDate, + to: NaiveDate, + author: String, + date: NaiveDate, + merged_prs: String, + contributors: String, + task_status: String, + test_cases: String, + bugs: String, + milestones: String, +} + +#[derive(ValueEnum, Clone, Copy, Serialize)] +enum Kind { + // TODO: Unit test to make sure this keeps being formatted as "Weekly" and "Monthly" in rendered reports + Weekly, + Monthly, +} + +#[derive(Parser)] +struct Cli { + #[arg(short, long, help = "Skip tests and do not report deltas")] + pub skip_tests: bool, + #[arg( + short, + long, + help = "Path to a local repository to avoid cloning the project" + )] + pub local_repo: Option, + #[arg( + short, + long, + help = "Additional arguments to pass to the configure script" + )] + pub configure: Option, + #[arg(short, long)] + pub kind: Kind, + #[arg(short, long)] + pub date: NaiveDate, + #[arg(short, long)] + pub author: String, +} + +fn get_from_date(kind: &Kind, date: &NaiveDate) -> NaiveDate { + match kind { + Kind::Weekly => date.checked_sub_days(Days::new(7)).unwrap(), + Kind::Monthly => date.checked_sub_months(Months::new(1)).unwrap(), + } +} + +#[tokio::main] +async fn main() -> Result<(), Error> { + let args = Cli::parse(); + let gh = OctocrabBuilder::new().build()?; + let from_date = get_from_date(&args.kind, &args.date); + + let multi = MultiProgress::new(); + let bar = progress::default_progress_bar(); + multi.add(bar.clone()); + + bar.set_step(progress::Steps::RetrievePrs); + let merged_prs = pr::fetch_merged(&gh, &from_date, &args.date) + .await? + // FIXME: Would it be better to have a trait extension for octo::PullRequest here? + // and `impl ReportFormatter` on it? + // yes + .into_iter() + .map(Pr::from) + .collect::>(); + + let old_commit_sha = find_oldest_pr_merge_commit(&gh, &merged_prs).await; + + let ctb = pr::fetch_merged(&gh, &from_date, &args.date) + .await? + // FIXME: Would it be better to have a trait extension for octo::PullRequest here? + // and `impl ReportFormatter` on it? + // yes + .into_iter() + .map(Contrib::from) + .collect::>(); + + + let test_cases = if let (Some(old_commit_sha), false) = (old_commit_sha, args.skip_tests) { + + let repository = if let Some(ref path) = args.local_repo { + bar.set_step(Steps::FetchRepository(FetchMethod::Local)); + Repository::open(path).map_err(Error::Repository)? + } else { + bar.set_step(Steps::FetchRepository(FetchMethod::Remote)); + repository::clone(&gh, &multi).await.map_err(Error::Clone)? + }; + + let previous_commit = repository + .find_commit( + Oid::from_str(&old_commit_sha).expect("We found this SHA in the repository"), + ) + // TODO: Cleanup + .map_err(|_| Error::RepoNotUpToDate("Be sur that your repo is up do date"))? + .parent_id(0) + .unwrap(); + + let results = TestCases::collect( + &repository, + &previous_commit.to_string(), + "master", /* TODO: Change this value ? Do we need to generate older reports ? */ + &args.configure.unwrap_or_default(), + ) + .await + .map_err(Error::Test)?; + + if args.local_repo.is_none() { + bar.set_step(Steps::Cleaning); + std::fs::remove_dir_all( + repository + .path() + .parent() + .expect(".git parent should always exist"), + ) + .map_err(Error::Workspace)?; + } + + results.to_string() + } else { + println!("Tests are skipped ? {}", args.skip_tests); + String::new() + }; + + + bar.set_step(Steps::RetrieveMilestones); + let milestones = milestone::fetch_all(&gh) + .await? + .into_iter() + .map(MStone::from) + .collect::>(); + + let nb_todo = get_TODO(&gh, false).await?; + let in_prog = get_in_progress(&gh, false).await?; + let closed = get_closed(&gh, false).await?; + + let task_status = Task{nb_todo, in_prog, closed}.to_string(); + + let nb_todo = get_TODO(&gh, true).await?; + let in_prog = get_in_progress(&gh, true).await?; + let closed = get_closed(&gh, true).await?; + + let bugs = Task{nb_todo, in_prog, closed}.to_string(); + + + let ctx = Context { + kind: args.kind, + from: from_date, + to: args.date, + author: args.author, + date: args.date, + contributors: ctb.iter().fold(String::new(), |acc, ct| format!("{acc}\n{ct}")), + task_status, + test_cases, + bugs, + milestones: milestones.iter().fold(String::new(), |acc, milestone| { + format!("{acc}\n{milestone}") + }), + merged_prs: merged_prs + .iter() + .fold(String::new(), |acc, pr| format!("{acc}\n{pr}")), + }; + + let mut renderer = TinyTemplate::new(); + renderer.add_template("report", TEMPLATE)?; + + let rendered = renderer.render("report", &ctx)?; + + println!("{rendered}"); + + Ok(()) +} diff --git a/util/generator/src/progress.rs b/util/generator/src/progress.rs new file mode 100644 index 0000000..91f73f5 --- /dev/null +++ b/util/generator/src/progress.rs @@ -0,0 +1,74 @@ +use std::borrow::Cow; + +use indicatif::{ProgressBar, ProgressStyle}; + +#[derive(Copy, Clone)] +pub enum FetchMethod { + Local, + Remote, +} + +#[derive(Copy, Clone)] +pub enum Steps { + RetrievePrs, + FetchRepository(FetchMethod), + PreviousTests, + CurrentTests, + Cleaning, + RetrieveMilestones, + CollectResults, + _LAST, +} + +impl From for Cow<'static, str> { + fn from(value: Steps) -> Self { + match value { + Steps::RetrievePrs => Cow::Borrowed("Retrieving merged PRs"), + Steps::FetchRepository(FetchMethod::Local) => Cow::Borrowed("Locating repository"), + Steps::FetchRepository(FetchMethod::Remote) => Cow::Borrowed("Cloning repository"), + Steps::PreviousTests => Cow::Borrowed("Running previous tests"), + Steps::CurrentTests => Cow::Borrowed("Running current tests"), + Steps::Cleaning => Cow::Borrowed("Cleaning up"), + Steps::RetrieveMilestones => Cow::Borrowed("Retrieving milestones"), + Steps::CollectResults => Cow::Borrowed("Collect results"), + Steps::_LAST => unreachable!(), + } + } +} + +impl From for u64 { + fn from(value: Steps) -> Self { + match value { + Steps::RetrievePrs => 1, + Steps::FetchRepository(_) => 2, + Steps::PreviousTests => 3, + Steps::CurrentTests => 4, + Steps::Cleaning => 5, + Steps::RetrieveMilestones => 6, + Steps::CollectResults => 7, + Steps::_LAST => 8, + } + } +} + +pub fn default_progress_bar() -> ProgressBar { + let bar = ProgressBar::new(Steps::RetrieveMilestones.into()); + bar.set_style( + ProgressStyle::with_template( + "[{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {msg}", + ) + .unwrap(), + ); + bar +} + +pub trait ProgressBarExt { + fn set_step(&self, step: Steps); +} + +impl ProgressBarExt for ProgressBar { + fn set_step(&self, step: Steps) { + self.set_message(step); + self.set_position(step.into()); + } +} diff --git a/util/generator/src/repository.rs b/util/generator/src/repository.rs new file mode 100644 index 0000000..cead67e --- /dev/null +++ b/util/generator/src/repository.rs @@ -0,0 +1,122 @@ +//! A module providing utility functions to interact with git repositories +use crate::naming::{ORGANISATION, REPOSITORY}; +use crate::progress::{default_progress_bar, FetchMethod, ProgressBarExt, Steps}; +use git2::build::RepoBuilder; +use git2::{Error, FetchOptions, RemoteCallbacks, Repository, RepositoryInitMode}; +use indicatif::{MultiProgress, ProgressBar}; +use octocrab::Octocrab; +use std::fmt; +use tokio::task::{self, JoinError}; + +use rand::distributions::Alphanumeric; +use rand::{thread_rng, Rng}; +use std::fs::create_dir; +use std::io::Result as IOResult; +use std::path::PathBuf; + +/// Creates a new directory in temporary ressources folder. +fn rand_dir() -> IOResult { + let mut length = 5; + loop { + let tmp_path = std::env::temp_dir().join( + thread_rng() + .sample_iter(&Alphanumeric) + .take(length) + .map(char::from) + .collect::(), + ); + + if !tmp_path.exists() { + break create_dir(tmp_path.clone()).map(|_| tmp_path); + } else { + length += 1; + } + } +} + +/// Set of error that might arise during a clone operation. +#[derive(Debug)] +pub enum CloneError { + /// Github API provided no clone URL. + MissingCloneUrl, + /// Met a git2 error during the actual clone action. + Download(Error), + /// Error during workspace/directory setup. + Local(std::io::Error), + /// Thread related error. + Thread(JoinError), + /// Met an octocrab error whilst retrieving repository data. + Octocrab(octocrab::Error), +} + +impl fmt::Display for CloneError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Error happened while cloning repository") + } +} + +impl std::error::Error for CloneError {} + +/// Clone gccrs repository to the systems's temp directory. +/// +/// # Arguments +/// +/// * `gh` - Reference to an octocrab instance. +pub async fn clone(gh: &Octocrab, multi: &MultiProgress) -> Result { + use CloneError::{Download, Local, MissingCloneUrl, Octocrab, Thread}; + let gh_repository = gh + .repos(ORGANISATION, REPOSITORY) + .get() + .await + .map_err(Octocrab)?; + + let clone_url = gh_repository.clone_url.ok_or(MissingCloneUrl)?; + + let workspace = rand_dir().map_err(Local)?; + + let bar = default_progress_bar(); + multi.add(bar.clone()); + + let clone_destination = workspace.clone(); + let res = task::spawn_blocking(move || { + let mut callbacks = RemoteCallbacks::new(); + callbacks.transfer_progress(|p| { + bar.set_length(p.total_objects().try_into().unwrap_or_default()); + bar.set_position(p.indexed_objects().try_into().unwrap_or_default()); + bar.set_message("Downloading"); + true + }); + let mut fo = FetchOptions::new(); + fo.remote_callbacks(callbacks); + + let mut builder = RepoBuilder::new(); + builder.fetch_options(fo); + builder + .clone(clone_url.as_str(), &clone_destination) + .map_err(Download) + }) + .await + .map_err(Thread)?; + res +} + +/// Checkout a given repository to a given reference. +/// +/// The reference can be either a commit, a branch name or a tag. +/// +/// # Arguments +/// +/// `repo` - The repository to checkout. +/// `refname` - The name of the reference to checkout to. +pub fn checkout(repo: &Repository, refname: &str) -> Result<(), Error> { + let (object, reference) = repo.revparse_ext(refname)?; + + repo.checkout_tree(&object, None)?; + + match reference { + // branch or tag + Some(gref) => repo.set_head(gref.name().unwrap()), + // commit + None => repo.set_head_detached(object.id()), + } +} diff --git a/util/generator/src/task.rs b/util/generator/src/task.rs new file mode 100644 index 0000000..b8ca249 --- /dev/null +++ b/util/generator/src/task.rs @@ -0,0 +1,53 @@ +use std::fmt; + +pub struct Task +{ + pub nb_todo:u64, + pub in_prog:u64, + pub closed:u64, +} + +impl fmt::Display for Task{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + const W_0: usize = 12; + const W_1: usize = 10; + const W_2: usize = 10; + const W_3: usize = 5; + const SEP: &str = "-"; + + writeln!( + f, + "|{:W_0$}+{SEP:->W_1$}+{SEP:->W_2$}+{SEP:->W_3$}|")?; + writeln!( + f, + "|{:>W_0$}|{:>W_1$}|{:>W_2$}|{:>W_3$}|", + "TODO", + format!("-"), + format!("{}", self.nb_todo), + format!("-"), + )?; + + writeln!( + f, + "|{:>W_0$}|{:>W_1$}|{:>W_2$}|{:>W_3$}|", + "In Progress", + format!("-"), + format!("{}", self.in_prog), + format!("-"), + )?; + + writeln!( + f, + "|{:>W_0$}|{:>W_1$}|{:>W_2$}|{:>W_3$}|", + "Completed", + format!("-"), + format!("{}", self.closed), + format!("-"), + ) + + } +} + diff --git a/util/generator/src/templates/#report.org.template# b/util/generator/src/templates/#report.org.template# new file mode 100644 index 0000000..d7f6877 --- /dev/null +++ b/util/generator/src/templates/#report.org.template# @@ -0,0 +1,35 @@ +#+author: {author} +#+title: {kind} report for {from} to {to} +#+date: {date} + +** Overview + +Thanks again to [[https://opensrcsec.com/][Open Source Security, inc]] and [[https://www.embecosm.com/][Embecosm]] for their ongoing support for this project. + +** Completed Activities +{merged_prs} + +*** Contributors this week +{contributors} + +*** Overall Task Status +{task_status} + +*** Test Cases +{test_cases} + +*** Bugs +{bugs} + +*** Milestones Progress +{milestones} + +*** Risks + +| Risk | Impact (1-3) | Likelihood (0-10) | Risk (I * L) | Mitigation | +|--------------------------------+--------------+-------------------+--------------+------------------------------------------------| +| Missing GCC 13 upstream window | 2 | 3 | 6 | Merge in GCC 14 and be proactive about reviews | + +** Planned Activities + +** Detailed changelog diff --git a/util/generator/src/templates/report.org.template b/util/generator/src/templates/report.org.template new file mode 100644 index 0000000..8268f64 --- /dev/null +++ b/util/generator/src/templates/report.org.template @@ -0,0 +1,35 @@ +#+title: {kind} report for {from} to {to} +#+author: {author} +#+date: {date} + +** Overview + +Thanks again to [[https://opensrcsec.com/][Open Source Security, inc]] and [[https://www.embecosm.com/][Embecosm]] for their ongoing support for this project. + +** Completed Activities +{merged_prs} + +*** Contributors this week +{contributors} + +*** Overall Task Status +{task_status} + +*** Test Cases +{test_cases} + +*** Bugs +{bugs} + +*** Milestones Progress +{milestones} + +*** Risks + +| Risk | Impact (1-3) | Likelihood (0-10) | Risk (I * L) | Mitigation | +|--------------------------------+--------------+-------------------+--------------+------------------------------------------------| +| Missing GCC 13 upstream window | 2 | 3 | 6 | Merge in GCC 14 and be proactive about reviews | + +** Planned Activities + +** Detailed changelog diff --git a/util/generator/src/testcase.rs b/util/generator/src/testcase.rs new file mode 100644 index 0000000..31c57ec --- /dev/null +++ b/util/generator/src/testcase.rs @@ -0,0 +1,280 @@ +//! Functional testsuite report collection module. +use crate::repository; +use git2::Repository; +use std::{ + fmt, fs, io, + path::Path, + process::{Command, Stdio}, + str::FromStr, +}; + +/// An enum representing the different error case during reporting phase. +#[derive(Debug)] +pub enum ReportError { + /// A git2 error happened during commit checkout. + CheckoutError(git2::Error), + /// An error happened during workspace operations. + LocalError(io::Error), + /// An error happened during configuration stage. + Configure(io::Error), + /// An error happened during build stage. + Make(io::Error), + MakeProcces, + /// An error happened during check stage. + Check(io::Error), + /// Cannot convert program output to utf-8. + CollectionError(std::str::Utf8Error), +} + + +impl fmt::Display for ReportError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use ReportError::*; + match self { + CheckoutError(why) => write!(f, "Error whilst checking out: {why}"), + LocalError(why) => write!(f, "Local error: {why}"), + Configure(why) => write!(f, "Error whilst running configure script: {why}"), + Make(why) => write!(f, "Error whilst building compiler: {why}"), + MakeProcces => write!(f, "Error whilst building compiler"), + Check(why) => write!(f, "Error whilst running testsuite: {why}"), + CollectionError(why) => write!(f, "Error whilst collecting testsuite output: {why}"), + } + } +} + +impl std::error::Error for ReportError {} + +/// A number of passed of failed tests with a custom display implementation. +#[derive(Debug, Default)] +struct TestCount(i64); + +impl fmt::Display for TestCount { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.0 == 0 { + write!(f, "-") + } else { + write!(f, "{}", self.0) + } + } +} + +#[derive(Debug, Default)] +struct TestReport { + /// Number of failed tests + failed: TestCount, + /// Number of passing tests + passing: TestCount, + /// Number of failing tests expected to fail + xfail: TestCount, + /// Number of passing tests expected to pass + xpass: TestCount, +} + +/// Structure representing the evolution of tests over a time period. +#[derive(Debug)] +pub struct TestCases { + /// Old test results. + previous: TestReport, + /// New test results. + current: TestReport, +} + +/// Gather test results from the check-rust script +/// +/// Build the project located at the given path and launch it's testsuite +/// then collect the test results. +/// +/// * `repo_location` - The local repository location. +/// * `additional_args` - Additional arguments for the configure script. +fn gather_test_results( + repo_location: &Path, + additional_args: &str, +) -> Result { + let build_dir = repo_location.to_path_buf().join("build_report"); + // We do not want to mess with existing build + if build_dir.exists() { + panic!("A build directory already exists, please delete it.") + } + fs::create_dir(&build_dir).map_err(ReportError::LocalError)?; + let mut configure_args = vec![ + "--disable-multilib", + "--disable-bootstrap", + "--enable-languages=rust", + ]; + + configure_args.push(additional_args); + + Command::new("../configure") + .args(configure_args) + .stdout(Stdio::null()) + .current_dir(&build_dir) + .status() + .map_err(ReportError::Configure)?; + + let mut w_arg = vec!["-c", "env | grep HARDEN"]; + + Command::new("bash") + .args(w_arg) + .current_dir(&build_dir) + .status() + .map_err(ReportError::Configure)?; + + + // TODO: We either want to use a computed value or leave this bit to the + // user by providing an interface for additional make arguments rather than + // hardcoding the job amount. + let make_args = vec!["-j8"]; + + let output = Command::new("make") + .args(make_args) + .stdout(Stdio::null()) + .current_dir(&build_dir) + .status() + .map_err(ReportError::Make)?; + + dbg!(&output); + + if ! output.success() + { + return Err(ReportError::MakeProcces); + } + + let output = Command::new("make") + .arg("check-rust") + .current_dir(&build_dir) + .output() + .map_err(ReportError::Check)?; + + dbg!(&output); + + let s: Vec<&str> = std::str::from_utf8(&output.stdout) + .map_err(ReportError::CollectionError)? + .lines() + .filter(|e| e.starts_with('#')) + .collect(); + + dbg!(&s); + + let xfail = s + .iter() + .find(|s| s.contains("failures")) + .and_then(|s| s.split_whitespace().last()) + .and_then(|s| i64::from_str(s).ok()) + .map(TestCount) + .unwrap_or_default(); + + dbg!(&xfail); + + let passing = s + .iter() + .find(|s| s.contains("passes")) + .and_then(|s| s.split_whitespace().last()) + .and_then(|s| i64::from_str(s).ok()) + .map(TestCount) + .unwrap_or_default(); + + dbg!(&passing); + + let result = TestReport { + xfail, + passing, + ..Default::default() + }; + + fs::remove_dir_all(build_dir).map_err(ReportError::LocalError)?; + + Ok(result) +} + +impl TestCases { + /// Collect the test reports. + /// + /// Build a project and collect the test reports for two different versions. + /// + /// # Arguments + /// + /// * `repo` - Git2 repository handle. + /// * `previous` - Reference to the previous version. + /// * `current` - Reference to the current version. + /// * `configure_args` - Additional arguments to pass to the configure script. + pub async fn collect( + repo: &Repository, + previous: &str, + current: &str, + configure_args: &str, + ) -> Result { + use ReportError::CheckoutError; + let workspace = repo + .path() + .parent() + .expect(".git parent should always exist").to_path_buf(); + repository::checkout(repo, previous).map_err(CheckoutError)?; + + let workspace_current = workspace.clone(); + let configure_args = configure_args.to_owned(); + + let configure_args_current = configure_args.to_owned(); + + let previous = tokio::task::spawn_blocking( move || gather_test_results(&workspace, &configure_args)).await.unwrap()?; + + repository::checkout(repo, current).map_err(CheckoutError)?; + + + let current = tokio::task::spawn_blocking( move || gather_test_results(&workspace_current, &configure_args_current)).await.unwrap()?; + + + Ok(TestCases { previous, current }) + } +} + +impl fmt::Display for TestCases { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + const W_0: usize = 12; + const W_1: usize = 10; + const W_2: usize = 10; + const W_3: usize = 5; + const SEP: &str = "-"; + + writeln!( + f, + "|{:W_0$}+{SEP:->W_1$}+{SEP:->W_2$}+{SEP:->W_3$}|")?; + writeln!( + f, + "|{:>W_0$}|{:>W_1$}|{:>W_2$}|{:>W_3$}|", + "Passing", + format!("{}", self.previous.passing), + format!("{}", self.current.passing), + format!("{}", TestCount(self.current.passing.0 - self.previous.passing.0)), + )?; + + writeln!( + f, + "|{:>W_0$}|{:>W_1$}|{:>W_2$}|{:>W_3$}|", + "Failed", + format!("{}", self.previous.failed), + format!("{}", self.current.failed), + format!("{}", TestCount(self.current.failed.0 - self.previous.failed.0)), + )?; + + writeln!( + f, + "|{:>W_0$}|{:>W_1$}|{:>W_2$}|{:>W_3$}|", + "XFAIL", + format!("{}", self.previous.xfail), + format!("{}", self.current.xfail), + format!("{}", TestCount(self.current.xfail.0 - self.previous.xfail.0)), + )?; + + writeln!( + f, + "|{:>W_0$}|{:>W_1$}|{:>W_2$}|{:>W_3$}|", + "XPASS", + format!("{}", self.previous.xpass), + format!("{}", self.current.xpass), + format!("{}", TestCount(self.current.xpass.0 - self.previous.xpass.0)), + ) + } +} diff --git a/util/generator/weekly.sh b/util/generator/weekly.sh new file mode 100755 index 0000000..84215bf --- /dev/null +++ b/util/generator/weekly.sh @@ -0,0 +1,17 @@ +#!/bin/sh +DATE=$(date -I) +AUTHOR="Philip Herron, Pierre-Emmanuel Patry, Arthur Cohen" + +if [ ! -z $1 ]; then + PATH_TO_SRC="-l $1" +fi + + +if [ -f "Cargo.toml" ]; then + + CMD="cargo run -- " +else + CMD="./generator" +fi + +$CMD -k weekly -d "$DATE" -a "$AUTHOR" $PATH_TO_SRC