Commit & metadata caching
Diff
Cargo.lock | 535 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
Cargo.toml | 4 +++-
src/git.rs | 188 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
src/main.rs | 11 +++++------
templates/index.html | 2 +-
src/methods/index.rs | 10 ++++++----
src/methods/repo.rs | 13 +++++++------
7 files changed, 671 insertions(+), 92 deletions(-)
@@ -12,6 +12,12 @@
]
[[package]]
name = "arc-swap"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5d78ce20460b82d3fa150275ed9d55e21064fc7951177baacf86a145c4a4b1f"
[[package]]
name = "askama"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -57,6 +63,34 @@
"serde",
"syn",
"toml",
]
[[package]]
name = "async-io"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5e18f61464ae81cde0a23e713ae8fd299580c54d697a35820cfd0625b8b0e07"
dependencies = [
"concurrent-queue",
"futures-lite",
"libc",
"log",
"once_cell",
"parking",
"polling",
"slab",
"socket2",
"waker-fn",
"winapi",
]
[[package]]
name = "async-lock"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6"
dependencies = [
"event-listener",
]
[[package]]
@@ -137,12 +171,61 @@
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bumpalo"
version = "3.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
[[package]]
name = "bytecount"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c"
[[package]]
name = "bytes"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
[[package]]
name = "cache-padded"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
[[package]]
name = "camino"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412"
dependencies = [
"serde",
]
[[package]]
name = "cargo-platform"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27"
dependencies = [
"serde",
]
[[package]]
name = "cargo_metadata"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
dependencies = [
"camino",
"cargo-platform",
"semver",
"serde",
"serde_json",
]
[[package]]
name = "cc"
@@ -152,6 +235,12 @@
dependencies = [
"jobserver",
]
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
@@ -182,6 +271,85 @@
checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5"
dependencies = [
"os_str_bytes",
]
[[package]]
name = "concurrent-queue"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
dependencies = [
"cache-padded",
]
[[package]]
name = "crossbeam-channel"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-utils 0.8.10",
]
[[package]]
name = "crossbeam-epoch"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace"
dependencies = [
"autocfg",
"cfg-if 0.1.10",
"crossbeam-utils 0.7.2",
"lazy_static",
"maybe-uninit",
"memoffset",
"scopeguard",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
dependencies = [
"autocfg",
"cfg-if 0.1.10",
"lazy_static",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
dependencies = [
"cfg-if 1.0.0",
"once_cell",
]
[[package]]
name = "error-chain"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
dependencies = [
"version_check",
]
[[package]]
name = "event-listener"
version = "2.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71"
[[package]]
name = "fastrand"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
dependencies = [
"instant",
]
[[package]]
@@ -247,6 +415,21 @@
version = "0.3.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b"
[[package]]
name = "futures-lite"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"memchr",
"parking",
"pin-project-lite",
"waker-fn",
]
[[package]]
name = "futures-macro"
@@ -295,9 +478,9 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"libc",
"wasi",
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
@@ -314,6 +497,12 @@
"openssl-sys",
"url",
]
[[package]]
name = "glob"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
name = "hashbrown"
@@ -329,6 +518,12 @@
dependencies = [
"libc",
]
[[package]]
name = "hex"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "http"
@@ -427,6 +622,15 @@
]
[[package]]
name = "instant"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "itoa"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -439,6 +643,15 @@
checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
dependencies = [
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27"
dependencies = [
"wasm-bindgen",
]
[[package]]
@@ -508,8 +721,17 @@
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "mach"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa"
dependencies = [
"cfg-if",
"libc",
]
[[package]]
@@ -523,12 +745,27 @@
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
[[package]]
name = "maybe-uninit"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memoffset"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
dependencies = [
"autocfg",
]
[[package]]
name = "mime"
@@ -560,8 +797,33 @@
dependencies = [
"libc",
"log",
"wasi",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys",
]
[[package]]
name = "moka"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21b3caf8ff6db712c7f7fe018e7fb6d2ddbaf428b74f94a48fe075ef09a6b8a1"
dependencies = [
"async-io",
"async-lock",
"crossbeam-channel",
"crossbeam-epoch",
"crossbeam-utils 0.8.10",
"futures-util",
"num_cpus",
"once_cell",
"parking_lot",
"quanta",
"scheduled-thread-pool",
"skeptic",
"smallvec",
"tagptr",
"thiserror",
"triomphe",
"uuid",
]
[[package]]
@@ -634,13 +896,10 @@
checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa"
[[package]]
name = "owning_ref"
version = "0.4.1"
name = "parking"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ff55baddef9e4ad00f88b6c743a2a8062d4c6ade126c2a528644b8e444d52ce"
dependencies = [
"stable_deref_trait",
]
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
[[package]]
name = "parking_lot"
@@ -658,7 +917,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"libc",
"redox_syscall",
"smallvec",
@@ -714,6 +973,19 @@
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]]
name = "polling"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259"
dependencies = [
"cfg-if 1.0.0",
"libc",
"log",
"wepoll-ffi",
"winapi",
]
[[package]]
name = "proc-macro2"
@@ -722,6 +994,33 @@
checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7"
dependencies = [
"unicode-ident",
]
[[package]]
name = "pulldown-cmark"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6"
dependencies = [
"bitflags",
"memchr",
"unicase",
]
[[package]]
name = "quanta"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bafd74c340a0a7e79415981ede3460df16b530fd071541901a57416eea950b17"
dependencies = [
"crossbeam-utils 0.8.10",
"libc",
"mach",
"once_cell",
"raw-cpuid",
"wasi 0.10.2+wasi-snapshot-preview1",
"web-sys",
"winapi",
]
[[package]]
@@ -731,6 +1030,15 @@
checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804"
dependencies = [
"proc-macro2",
]
[[package]]
name = "raw-cpuid"
version = "10.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "738bc47119e3eeccc7e94c4a506901aea5e7b4944ecd0829cbebf4af04ceda12"
dependencies = [
"bitflags",
]
[[package]]
@@ -740,19 +1048,30 @@
checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42"
dependencies = [
"bitflags",
]
[[package]]
name = "remove_dir_all"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
dependencies = [
"winapi",
]
[[package]]
name = "rgit"
version = "0.1.0"
dependencies = [
"arc-swap",
"askama",
"axum",
"clap",
"futures",
"git2",
"hex",
"humantime",
"owning_ref",
"moka",
"path-clean",
"serde",
"time",
@@ -772,10 +1091,37 @@
checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "scheduled-thread-pool"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf"
dependencies = [
"parking_lot",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1"
dependencies = [
"serde",
]
[[package]]
name = "serde"
@@ -839,6 +1185,21 @@
]
[[package]]
name = "skeptic"
version = "0.13.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8"
dependencies = [
"bytecount",
"cargo_metadata",
"error-chain",
"glob",
"pulldown-cmark",
"tempfile",
"walkdir",
]
[[package]]
name = "slab"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -859,12 +1220,6 @@
"libc",
"winapi",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
[[package]]
name = "strsim"
@@ -888,6 +1243,26 @@
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8"
[[package]]
name = "tagptr"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417"
[[package]]
name = "tempfile"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
dependencies = [
"cfg-if 1.0.0",
"fastrand",
"libc",
"redox_syscall",
"remove_dir_all",
"winapi",
]
[[package]]
name = "termcolor"
@@ -903,6 +1278,26 @@
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb"
[[package]]
name = "thiserror"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
@@ -1031,7 +1426,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160"
dependencies = [
"cfg-if",
"cfg-if 1.0.0",
"log",
"pin-project-lite",
"tracing-attributes",
@@ -1085,6 +1480,12 @@
]
[[package]]
name = "triomphe"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eda0abf5a9b5ad4a5ac1393956ae03fb57033749d3983e2cac9afbfd5ae04ec2"
[[package]]
name = "try-lock"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1158,6 +1559,23 @@
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "waker-fn"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]]
name = "walkdir"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
dependencies = [
"same-file",
"winapi",
"winapi-util",
]
[[package]]
name = "want"
@@ -1168,12 +1586,91 @@
"log",
"try-lock",
]
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
[[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.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994"
dependencies = [
"cfg-if 1.0.0",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a"
dependencies = [
"bumpalo",
"lazy_static",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be"
[[package]]
name = "web-sys"
version = "0.3.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "wepoll-ffi"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb"
dependencies = [
"cc",
]
[[package]]
name = "winapi"
@@ -7,13 +7,15 @@
[dependencies]
askama = "0.11"
arc-swap = "1.5"
axum = "0.5"
clap = { version = "3.2", features = ["cargo"] }
futures = "0.3"
git2 = "0.14"
hex = "0.4"
humantime = "2.1"
moka = { version = "0.9", features = ["future"] }
path-clean = "0.1"
owning_ref = "0.4"
serde = { version = "1.0", features = ["derive"] }
time = "0.3"
tokio = { version = "1.19", features = ["full"] }
@@ -1,98 +1,176 @@
use std::{borrow::Cow, collections::BTreeMap, fmt::Display, path::Path, time::Duration};
use std::{
borrow::Cow,
collections::BTreeMap,
path::{Path, PathBuf},
sync::Arc,
time::Duration,
};
use arc_swap::ArcSwapOption;
use git2::{Oid, Repository, Signature};
use owning_ref::OwningHandle;
use time::OffsetDateTime;
pub type RepositoryMetadataList = BTreeMap<Option<String>, Vec<RepositoryMetadata>>;
#[derive(Clone)]
pub struct Git {
commits: moka::future::Cache<String, Arc<Commit>>,
repository_metadata: Arc<ArcSwapOption<RepositoryMetadataList>>,
}
impl Default for Git {
fn default() -> Self {
Self {
commits: moka::future::Cache::new(100),
repository_metadata: Arc::new(ArcSwapOption::default()),
}
}
}
impl Git {
pub async fn get_commit<'a>(&'a self, repo: PathBuf, commit: &str) -> Arc<Commit> {
let commit = Oid::from_str(commit).unwrap();
self.commits
.get_with(commit.to_string(), async {
tokio::task::spawn_blocking(move || {
let repo = Repository::open_bare(repo).unwrap();
let commit = repo.find_commit(commit).unwrap();
Arc::new(Commit::from(commit))
})
.await
.unwrap()
})
.await
}
pub async fn get_latest_commit<'a>(&'a self, repo: PathBuf) -> Commit {
tokio::task::spawn_blocking(move || {
let repo = Repository::open_bare(repo).unwrap();
let head = repo.head().unwrap();
let commit = head.peel_to_commit().unwrap();
Commit::from(commit)
})
.await
.unwrap()
}
pub async fn fetch_repository_metadata(&self) -> Arc<RepositoryMetadataList> {
if let Some(metadata) = self.repository_metadata.load().as_ref() {
return Arc::clone(&metadata);
}
let start = Path::new("../test-git").canonicalize().unwrap();
let repos = tokio::task::spawn_blocking(move || {
let mut repos: RepositoryMetadataList = RepositoryMetadataList::new();
fetch_repository_metadata_impl(&start, &start, &mut repos);
repos
})
.await
.unwrap();
let repos = Arc::new(repos);
self.repository_metadata.store(Some(repos.clone()));
repos
}
}
#[derive(Debug)]
pub struct RepositoryMetadata {
pub name: String,
pub description: Option<Cow<'static, str>>,
pub owner: Option<String>,
pub last_modified: Duration,
}
pub struct CommitUser {
name: String,
email: String,
time: String,
}
pub struct CommitUser<'a>(Signature<'a>);
impl From<Signature<'_>> for CommitUser {
fn from(v: Signature<'_>) -> Self {
CommitUser {
name: v.name().unwrap().to_string(),
email: v.email().unwrap().to_string(),
time: OffsetDateTime::from_unix_timestamp(v.when().seconds())
.unwrap()
.to_string(),
}
}
}
impl CommitUser<'_> {
impl CommitUser {
pub fn name(&self) -> &str {
self.0.name().unwrap()
&self.name
}
pub fn email(&self) -> &str {
self.0.email().unwrap()
&self.email
}
pub fn time(&self) -> String {
OffsetDateTime::from_unix_timestamp(self.0.when().seconds())
.unwrap()
.to_string()
pub fn time(&self) -> &str {
&self.time
}
}
pub struct Commit {
author: CommitUser,
committer: CommitUser,
oid: String,
tree: String,
parents: Vec<String>,
summary: String,
body: String,
}
pub struct Commit(OwningHandle<Box<Repository>, Box<git2::Commit<'static>>>);
impl From<git2::Commit<'_>> for Commit {
fn from(commit: git2::Commit<'_>) -> Self {
Commit {
author: commit.author().into(),
committer: commit.committer().into(),
oid: commit.id().to_string(),
tree: commit.tree_id().to_string(),
parents: commit.parent_ids().map(|v| v.to_string()).collect(),
summary: commit.summary().unwrap().to_string(),
body: commit.body().map(ToString::to_string).unwrap_or_default(),
}
}
}
impl Commit {
pub fn author(&self) -> CommitUser<'_> {
CommitUser(self.0.author())
pub fn author(&self) -> &CommitUser {
&self.author
}
pub fn committer(&self) -> CommitUser<'_> {
CommitUser(self.0.committer())
pub fn committer(&self) -> &CommitUser {
&self.committer
}
pub fn oid(&self) -> impl Display {
self.0.id()
pub fn oid(&self) -> &str {
&self.oid
}
pub fn tree(&self) -> impl Display {
self.0.tree_id()
pub fn tree(&self) -> &str {
&self.tree
}
pub fn parents(&self) -> impl Iterator<Item = impl Display + '_> {
self.0.parent_ids()
pub fn parents(&self) -> impl Iterator<Item = &str> {
self.parents.iter().map(String::as_str)
}
pub fn summary(&self) -> &str {
self.0.summary().unwrap()
&self.summary
}
pub fn body(&self) -> &str {
self.0.message().unwrap()
&self.body
}
}
pub fn get_commit(path: &Path, commit: &str) -> Commit {
let repo = Repository::open_bare(path).unwrap();
let commit = OwningHandle::new_with_fn(Box::new(repo), |v| {
Box::new(unsafe { (*v).find_commit(Oid::from_str(commit).unwrap()).unwrap() })
});
Commit(commit)
}
pub fn get_latest_commit(path: &Path) -> Commit {
let repo = Repository::open_bare(path).unwrap();
let commit = OwningHandle::new_with_fn(Box::new(repo), |v| {
let head = unsafe { (*v).head().unwrap() };
Box::new(head.peel_to_commit().unwrap())
});
Commit(commit)
}
pub fn fetch_repository_metadata() -> RepositoryMetadataList {
let start = Path::new("../test-git").canonicalize().unwrap();
let mut repos: RepositoryMetadataList = RepositoryMetadataList::new();
fetch_repository_metadata_impl(&start, &start, &mut repos);
repos
}
fn fetch_repository_metadata_impl(
@@ -1,14 +1,12 @@
#![deny(clippy::pedantic)]
use axum::{
body::Body, handler::Handler, http::HeaderValue, response::Response, routing::get, Router,
body::Body, handler::Handler, http::HeaderValue, response::Response, routing::get, Extension,
Router,
};
use tower_layer::layer_fn;
use crate::{
git::{fetch_repository_metadata, get_latest_commit},
layers::logger::LoggingMiddleware,
};
use crate::{git::Git, layers::logger::LoggingMiddleware};
mod git;
mod layers;
@@ -30,7 +28,8 @@
get(static_css(include_bytes!("../statics/style.css"))),
)
.fallback(methods::repo::service.into_service())
.layer(layer_fn(LoggingMiddleware));
.layer(layer_fn(LoggingMiddleware))
.layer(Extension(Git::default()));
axum::Server::bind(&"127.0.0.1:3333".parse().unwrap())
.serve(app.into_make_service_with_connect_info::<std::net::SocketAddr>())
@@ -14,7 +14,7 @@
</thead>
<tbody>
{% for (path, repositories) in repositories %}
{% for (path, repositories) in repositories.iter() %}
{% if let Some(path) = path %}
<tr><td class="repo-section" colspan="4">{{ path }}</td></tr>
{% endif %}
@@ -1,19 +1,21 @@
use askama::Template;
use axum::response::Html;
use axum::Extension;
use std::sync::Arc;
use crate::{fetch_repository_metadata, git::RepositoryMetadataList};
use crate::{git::RepositoryMetadataList, Git};
#[allow(clippy::unused_async)]
pub async fn handle() -> Html<String> {
pub async fn handle(Extension(git): Extension<Git>) -> Html<String> {
#[derive(Template)]
#[template(path = "index.html")]
pub struct View {
pub repositories: RepositoryMetadataList,
pub repositories: Arc<RepositoryMetadataList>,
}
Html(
View {
repositories: fetch_repository_metadata(),
repositories: git.fetch_repository_metadata().await,
}
.render()
.unwrap(),
@@ -1,11 +1,12 @@
use std::{
ops::Deref,
path::{Path, PathBuf},
sync::Arc,
};
use askama::Template;
use axum::extract::Query;
use axum::{
extract::Query,
handler::Handler,
http::Request,
response::{Html, IntoResponse, Response},
@@ -15,8 +16,7 @@
use serde::Deserialize;
use tower::{util::BoxCloneService, Service};
use crate::git::get_commit;
use crate::{get_latest_commit, git::Commit, layers::UnwrapInfallible};
use crate::{git::Commit, layers::UnwrapInfallible, Git};
#[derive(Clone)]
pub struct Repository(pub PathBuf);
@@ -130,22 +130,23 @@
pub async fn handle_commit(
Extension(repo): Extension<Repository>,
Extension(RepositoryPath(repository_path)): Extension<RepositoryPath>,
Extension(git): Extension<Git>,
Query(query): Query<CommitQuery>,
) -> Html<String> {
#[derive(Template)]
#[template(path = "repo/commit.html")]
pub struct View {
pub repo: Repository,
pub commit: Commit,
pub commit: Arc<Commit>,
}
Html(
View {
repo,
commit: if let Some(commit) = query.id {
get_commit(&repository_path, &commit)
git.get_commit(repository_path, &commit).await
} else {
get_latest_commit(&repository_path)
Arc::new(git.get_latest_commit(repository_path).await)
},
}
.render()