diff --git a/Cargo.lock b/Cargo.lock index 752796b37..20ed1d0cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,15 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "addr2line" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" +dependencies = [ + "gimli", +] + [[package]] name = "adler2" version = "2.0.1" @@ -443,6 +452,15 @@ dependencies = [ "webpki-roots 0.26.11", ] +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "atomic-polyfill" version = "1.0.3" @@ -495,7 +513,7 @@ checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core", "axum-macros", - "base64", + "base64 0.22.1", "bytes", "form_urlencoded", "futures-util", @@ -577,6 +595,48 @@ dependencies = [ "syn 2.0.118", ] +[[package]] +name = "axum-tws" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bf5c1e7d60af9632c55c23bbfa208d0fe08aa59fcda87216c9119e30a9d6d4" +dependencies = [ + "axum-core", + "base64 0.22.1", + "bytes", + "futures-util", + "http", + "hyper", + "hyper-util", + "sha1_smol", + "tokio", + "tokio-websockets", +] + +[[package]] +name = "backtrace" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-link", +] + +[[package]] +name = "backtrace-ext" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "537beee3be4a18fb023b570f80e3ae28003db9167a751266b259926e25539d50" +dependencies = [ + "backtrace", +] + [[package]] name = "base-x" version = "0.2.11" @@ -617,6 +677,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "base64ct" version = "1.8.3" @@ -675,6 +741,9 @@ name = "bitflags" version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +dependencies = [ + "serde_core", +] [[package]] name = "bitpacking" @@ -785,10 +854,10 @@ dependencies = [ name = "bobbin-codesearch" version = "0.0.1" dependencies = [ - "base64", + "base64 0.22.1", "http", "jacquard-common", - "reqwest 0.13.1", + "reqwest 0.13.5", "serde", "serde_json", "thiserror 2.0.18", @@ -862,7 +931,7 @@ dependencies = [ "jacquard-common", "knot-capability", "parking_lot", - "reqwest 0.13.1", + "reqwest 0.13.5", "serde", "serde_ipld_dagcbor", "serde_json", @@ -883,7 +952,7 @@ dependencies = [ "futures", "http", "jacquard-common", - "reqwest 0.13.1", + "reqwest 0.13.5", "scc", "thiserror 2.0.18", "tokio", @@ -934,7 +1003,7 @@ dependencies = [ "getrandom 0.4.3", "http", "jacquard-common", - "reqwest 0.13.1", + "reqwest 0.13.5", "rustls", "rustls-native-certs", "thiserror 2.0.18", @@ -998,7 +1067,7 @@ dependencies = [ "futures", "http", "jacquard-common", - "reqwest 0.13.1", + "reqwest 0.13.5", "serde", "serde_json", "thiserror 2.0.18", @@ -1025,7 +1094,7 @@ name = "bobbin-xrpc" version = "0.0.1" dependencies = [ "axum", - "base64", + "base64 0.22.1", "bobbin-codesearch", "bobbin-edge-index", "bobbin-ingest", @@ -1044,7 +1113,7 @@ dependencies = [ "jacquard-identity", "lexicons", "quick_cache", - "reqwest 0.13.1", + "reqwest 0.13.5", "scc", "serde", "serde_json", @@ -1153,6 +1222,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + [[package]] name = "bytes" version = "1.12.0" @@ -1168,6 +1243,12 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49e78e506b9d7633710dab98996f22f95f3d0f488e8f1aa162830556ed9fc14d" +[[package]] +name = "byteview" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d74937895e761d5984206f82ca8ff7725d0fd8021921011921894b41ab1b9f7" + [[package]] name = "cast" version = "0.3.0" @@ -1211,7 +1292,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca1e5eda1b0f8476181bed1bfc9232a91d62ff0b9f1bc0e48afff3cbcb5b0b5c" dependencies = [ "antlr4rust", - "base64", + "base64 0.22.1", "chrono", "lazy_static", "nom", @@ -1429,6 +1510,12 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "compare" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea0095f6103c2a8b44acd6fd15960c801dafebf02e21940360833e0673f48ba7" + [[package]] name = "compression-codecs" version = "0.4.38" @@ -1512,7 +1599,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ "aes-gcm 0.10.3", - "base64", + "base64 0.22.1", "percent-encoding", "rand 0.8.6", "subtle", @@ -1580,6 +1667,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + [[package]] name = "crc32fast" version = "1.5.0" @@ -1656,6 +1758,25 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03e8bd762f7479489c70ed6c768ddca99d7296857de437a68dcb2a94365b3fae" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-skiplist" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df29de440c58ca2cc6e587ec3d22347551a32435fbde9d2bff64e78a9ffa151b" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -2125,6 +2246,12 @@ dependencies = [ "syn 2.0.118", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "downcast-rs" version = "2.0.2" @@ -2222,6 +2349,9 @@ name = "either" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" +dependencies = [ + "serde", +] [[package]] name = "elliptic-curve" @@ -2336,6 +2466,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "etcetera" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de48cc4d1c1d97a20fd819def54b890cadde72ed3ad0c614822a0a433361be96" +dependencies = [ + "cfg-if", "windows-sys 0.61.2", ] @@ -2459,6 +2599,23 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +[[package]] +name = "fjall" +version = "3.1.8" +source = "git+https://github.com/90-008/fjall.git?rev=85a8ad9b3d327c39263cc547fa9944e7535e802f#85a8ad9b3d327c39263cc547fa9944e7535e802f" +dependencies = [ + "byteorder-lite", + "byteview", + "dashmap", + "flume", + "log", + "lsm-tree", + "lz4_flex", + "tempfile", + "xxhash-rust", + "zstd", +] + [[package]] name = "flate2" version = "1.1.9" @@ -2481,6 +2638,17 @@ dependencies = [ "serde", ] +[[package]] +name = "flume" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + [[package]] name = "fnv" version = "1.0.7" @@ -2605,6 +2773,17 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + [[package]] name = "futures-io" version = "0.3.32" @@ -2793,6 +2972,12 @@ dependencies = [ "polyval 0.7.1", ] +[[package]] +name = "gimli" +version = "0.32.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" + [[package]] name = "gitmirror" version = "0.0.1" @@ -2804,7 +2989,13 @@ dependencies = [ "confique", "deadpool-redis", "futures", + "gitmirror-db", + "gitmirror-git", + "gitmirror-ingest", + "gitmirror-sync", + "gitmirror-types", "gitmirror-xrpc", + "hydrant", "jacquard-axum", "jacquard-common", "jacquard-identity", @@ -2812,7 +3003,7 @@ dependencies = [ "opentelemetry-appender-tracing", "opentelemetry-otlp", "opentelemetry_sdk", - "reqwest 0.13.1", + "reqwest 0.13.5", "rustls", "socket2", "thiserror 2.0.18", @@ -2822,6 +3013,17 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "gitmirror-db" +version = "0.0.1" +dependencies = [ + "jacquard-common", + "sqlx", + "thiserror 2.0.18", + "tokio", + "tracing", +] + [[package]] name = "gitmirror-git" version = "0.0.1" @@ -2837,6 +3039,54 @@ dependencies = [ [[package]] name = "gitmirror-ingest" version = "0.0.1" +dependencies = [ + "bobbin-runtime", + "gitmirror-db", + "hydrant", + "jacquard-common", + "lexicons", + "serde_json", + "thiserror 2.0.18", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "gitmirror-sync" +version = "0.0.1" +dependencies = [ + "bobbin-runtime", + "gitmirror-db", + "gitmirror-git", + "gitmirror-types", + "gix", + "gix-hash", + "gix-negotiate", + "gix-object", + "gix-pack", + "gix-protocol", + "gix-transport", + "jacquard-common", + "jacquard-identity", + "reqwest 0.13.5", + "scc", + "sqlx", + "tempfile", + "thiserror 2.0.18", + "tokio", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "gitmirror-types" +version = "0.0.1" +dependencies = [ + "bobbin-knot-proxy", + "jacquard-common", +] [[package]] name = "gitmirror-xrpc" @@ -2863,7 +3113,7 @@ dependencies = [ "metrics", "metrics-exporter-prometheus", "quick_cache", - "reqwest 0.13.1", + "reqwest 0.13.5", "rustc-hash", "serde_json", "sha2 0.11.0", @@ -3289,7 +3539,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19753d40da53d0ec41604750eeb969097a90fb2d7f7992730d904541c04e2c19" dependencies = [ "bstr", - "hashbrown 0.17.1", + "hashbrown 0.15.5", ] [[package]] @@ -3506,11 +3756,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51dea3acb390707ab868f1f9584f18449eb95d869deffae96768e47d303595ee" dependencies = [ "bstr", + "gix-credentials", "gix-date", "gix-features", "gix-hash", + "gix-lock", + "gix-negotiate", + "gix-object", "gix-ref", + "gix-refspec", + "gix-revwalk", "gix-shallow", + "gix-trace", "gix-transport", "gix-utils", "maybe-async", @@ -3720,16 +3977,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd0e34995b1aab0fa8dff2af8db726a0bfad3e119c89302604463264046e7ff" dependencies = [ "async-trait", + "base64 0.22.1", "bstr", "futures-io", "futures-lite", "gix-command", + "gix-credentials", "gix-features", "gix-packetline", "gix-quote", "gix-sec", "gix-url", "pin-project-lite", + "reqwest 0.13.5", "thiserror 2.0.18", ] @@ -4110,6 +4370,30 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e712f64ec3850b98572bffac52e2c6f282b29fe6c5fa6d42334b30be438d95c1" +[[package]] +name = "hickory-net" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c480823ed7c2c5d0f09c41020cb6b7c28029ce60ec42dc942158dcf22f8e0a4d" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "futures-channel", + "futures-io", + "futures-util", + "hickory-proto 0.26.3", + "idna", + "ipnet", + "jni 0.22.4", + "rand 0.10.1", + "thiserror 2.0.18", + "tinyvec", + "tokio", + "tracing", + "url", +] + [[package]] name = "hickory-proto" version = "0.24.4" @@ -4134,6 +4418,26 @@ dependencies = [ "url", ] +[[package]] +name = "hickory-proto" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b92608f679a6fa515dd1d15c1ff89443026e391200a2c840c7afcba482893d" +dependencies = [ + "data-encoding", + "idna", + "ipnet", + "jni 0.22.4", + "once_cell", + "prefix-trie", + "rand 0.10.1", + "ring", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "url", +] + [[package]] name = "hickory-resolver" version = "0.24.4" @@ -4142,7 +4446,7 @@ checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" dependencies = [ "cfg-if", "futures-util", - "hickory-proto", + "hickory-proto 0.24.4", "ipconfig", "lru-cache", "once_cell", @@ -4155,6 +4459,32 @@ dependencies = [ "tracing", ] +[[package]] +name = "hickory-resolver" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f3da5255c95d5a716857d54b5b8f4e8d67c3484d3beaaaae2ce25063b3ba981" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-net", + "hickory-proto 0.26.3", + "ipconfig", + "ipnet", + "jni 0.22.4", + "moka", + "ndk-context", + "once_cell", + "parking_lot", + "rand 0.10.1", + "resolv-conf", + "smallvec", + "system-configuration", + "thiserror 2.0.18", + "tokio", + "tracing", +] + [[package]] name = "hkdf" version = "0.12.4" @@ -4268,6 +4598,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eaec953f16e5bcf6b8a3cb3aa959b17e5577dbd2693e94554c462c08be22624b" +[[package]] +name = "humantime" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15cdd26707701c53297e2fa6afb323d55fbc1d0810c3aec078ae3ef0424c3c15" + [[package]] name = "hybrid-array" version = "0.4.12" @@ -4281,14 +4617,70 @@ dependencies = [ ] [[package]] -name = "hyper" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +name = "hydrant" +version = "0.1.0" +source = "git+https://tangled.org/ptr.pet/hydrant?rev=ccc1b1a3#ccc1b1a37006ce0b0559d81f7f5c1a6b88b20129" dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", + "ahash", + "arc-swap", + "axum", + "axum-tws", + "bytes", + "chrono", + "cid", + "data-encoding", + "fjall", + "fluent-uri", + "futures", + "glob", + "hex", + "hickory-resolver 0.26.3", + "http", + "humantime", + "hyper", + "ipnet", + "iroh-car", + "jacquard-api", + "jacquard-common", + "jacquard-derive", + "jacquard-repo", + "lsm-tree", + "miette", + "multibase", + "nohash-hasher", + "parking_lot", + "rand 0.10.1", + "reqwest 0.12.28", + "rmp-serde", + "rustls", + "scc", + "serde", + "serde_bytes", + "serde_html_form", + "serde_ipld_dagcbor", + "serde_json", + "sha2 0.10.9", + "smol_str", + "socket2", + "thiserror 2.0.18", + "tokio", + "tokio-util", + "tokio-websockets", + "tower-http 0.6.11", + "tracing", + "tracing-subscriber", + "url", +] + +[[package]] +name = "hyper" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", "futures-core", "h2", "http", @@ -4312,6 +4704,7 @@ dependencies = [ "hyper", "hyper-util", "rustls", + "rustls-native-certs", "tokio", "tokio-rustls", "tower-service", @@ -4324,7 +4717,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-util", @@ -4519,6 +4912,15 @@ dependencies = [ "rand_core 0.10.1", ] +[[package]] +name = "interval-heap" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11274e5e8e89b8607cfedc2910b6626e998779b48a019151c7604d0adcb86ac6" +dependencies = [ + "compare", +] + [[package]] name = "inventory" version = "0.3.24" @@ -4567,6 +4969,9 @@ name = "ipnet" version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" +dependencies = [ + "serde", +] [[package]] name = "iroh-car" @@ -4584,6 +4989,12 @@ dependencies = [ "unsigned-varint 0.7.2", ] +[[package]] +name = "is_ci" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -4662,7 +5073,7 @@ source = "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba637 dependencies = [ "axum", "axum-extra", - "base64", + "base64 0.22.1", "bytes", "chrono", "jacquard", @@ -4686,7 +5097,7 @@ name = "jacquard-common" version = "0.12.1" source = "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba6377e0433c391d34f3#bb32de36f1cc2727954fba6377e0433c391d34f3" dependencies = [ - "base64", + "base64 0.22.1", "bon", "bytes", "chrono", @@ -4729,6 +5140,7 @@ dependencies = [ "tokio", "tokio-tungstenite-wasm", "tokio-util", + "tracing", "trait-variant", "unicode-segmentation", ] @@ -4799,7 +5211,7 @@ name = "jacquard-oauth" version = "0.12.1" source = "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba6377e0433c391d34f3#bb32de36f1cc2727954fba6377e0433c391d34f3" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "chrono", "dashmap", @@ -4913,6 +5325,36 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.18", + "walkdir", + "windows-link", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.118", +] + [[package]] name = "jni-sys" version = "0.3.1" @@ -5051,7 +5493,7 @@ name = "knot-atproto" version = "2.0.0" dependencies = [ "base32", - "base64", + "base64 0.22.1", "bs58", "bytes", "cid", @@ -5143,7 +5585,7 @@ dependencies = [ name = "knot-config" version = "2.0.0" dependencies = [ - "base64", + "base64 0.22.1", "confique", "knot-messages", "knot-runtime", @@ -5160,7 +5602,7 @@ dependencies = [ "arc-swap", "async-trait", "axum", - "base64", + "base64 0.22.1", "bytes", "futures", "governor", @@ -5211,7 +5653,7 @@ dependencies = [ name = "knot-git" version = "2.0.0" dependencies = [ - "base64", + "base64 0.22.1", "flate2", "gix", "gix-archive", @@ -5358,7 +5800,7 @@ dependencies = [ name = "knot-migrate" version = "2.0.0" dependencies = [ - "base64", + "base64 0.22.1", "chrono", "knot-cob", "knot-cobs", @@ -5504,11 +5946,11 @@ dependencies = [ "bytes", "futures", "getrandom 0.4.3", - "hickory-resolver", + "hickory-resolver 0.24.4", "http", "k256", "knot-types", - "reqwest 0.13.1", + "reqwest 0.13.5", "serde", "thiserror 2.0.18", "tokio", @@ -5520,7 +5962,7 @@ name = "knot-secrets" version = "2.0.0" dependencies = [ "aes-gcm 0.11.0-rc.4", - "base64", + "base64 0.22.1", "hkdf 0.13.0", "k256", "knot-resource", @@ -5540,7 +5982,7 @@ version = "2.0.0" dependencies = [ "anyhow", "axum", - "base64", + "base64 0.22.1", "clap", "confique", "http", @@ -5563,7 +6005,7 @@ dependencies = [ "knot-ssh", "knot-types", "knot-xrpc", - "reqwest 0.13.1", + "reqwest 0.13.5", "rustix", "serde_json", "tempfile", @@ -5583,7 +6025,7 @@ name = "knot-sim" version = "2.0.0" dependencies = [ "axum", - "base64", + "base64 0.22.1", "bytes", "futures", "h3", @@ -5697,7 +6139,7 @@ name = "knot-xrpc" version = "2.0.0" dependencies = [ "axum", - "base64", + "base64 0.22.1", "bytes", "chrono", "cid", @@ -5916,11 +6358,36 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "lsm-tree" +version = "3.1.8" +source = "git+https://github.com/90-008/lsm-tree.git#ffa6e5edea9dd199b4fe5286a2ad20fc5df63001" +dependencies = [ + "byteorder-lite", + "byteview", + "crossbeam-skiplist", + "enum_dispatch", + "interval-heap", + "log", + "lz4_flex", + "quick_cache", + "rustc-hash", + "self_cell", + "sfa", + "tempfile", + "varint-rs", + "xxhash-rust", + "zstd", +] + [[package]] name = "lz4_flex" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ef0d4ed8669f8f8826eb00dc878084aa8f253506c4fd5e8f58f5bce72ddb97e" +dependencies = [ + "twox-hash", +] [[package]] name = "mac" @@ -6004,6 +6471,16 @@ dependencies = [ "syn 2.0.118", ] +[[package]] +name = "md-5" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" +dependencies = [ + "cfg-if", + "digest 0.11.3", +] + [[package]] name = "md5" version = "0.8.0" @@ -6059,7 +6536,7 @@ version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1db0d8f1fc9e62caebd0319e11eaec5822b0186c171568f0480b46a0137f9108" dependencies = [ - "base64", + "base64 0.22.1", "evmap", "indexmap", "metrics", @@ -6091,9 +6568,17 @@ version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" dependencies = [ + "backtrace", + "backtrace-ext", "cfg-if", "miette-derive", - "unicode-width", + "owo-colors", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "terminal_size", + "textwrap", + "unicode-width 0.1.14", ] [[package]] @@ -6278,6 +6763,12 @@ dependencies = [ "web-time", ] +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -6297,6 +6788,12 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + [[package]] name = "nom" version = "7.1.3" @@ -6331,7 +6828,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -6405,6 +6902,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.37.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe" +dependencies = [ + "memchr", +] + [[package]] name = "oid-registry" version = "0.7.1" @@ -6428,6 +6934,10 @@ name = "once_cell" version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +dependencies = [ + "critical-section", + "portable-atomic", +] [[package]] name = "once_cell_polyfill" @@ -6494,7 +7004,7 @@ dependencies = [ "bytes", "http", "opentelemetry", - "reqwest 0.13.1", + "reqwest 0.13.5", ] [[package]] @@ -6510,7 +7020,7 @@ dependencies = [ "opentelemetry-proto", "opentelemetry_sdk", "prost", - "reqwest 0.13.1", + "reqwest 0.13.5", "thiserror 2.0.18", ] @@ -6568,6 +7078,12 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "owo-colors" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c45bb4a6ae1280ec0803b1ef9d3455eb50f01efbbe1447ab020f1d54fba9d8" + [[package]] name = "oxilangtag" version = "0.1.6" @@ -6732,7 +7248,7 @@ version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ - "base64", + "base64 0.22.1", "serde_core", ] @@ -7041,6 +7557,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "prefix-trie" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf6e3177f0684016a5c209b00882e15f8bdd3f3bb48f0491df10cd102d0c6e7" +dependencies = [ + "either", + "ipnet", + "num-traits", +] + [[package]] name = "prettyplease" version = "0.2.37" @@ -7224,7 +7751,7 @@ version = "0.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01b80ea363c31af2de2b92e3c07ed1156628f7838c4afb4df75ee78a37fedbd1" dependencies = [ - "base64", + "base64 0.22.1", "prost", "prost-reflect-derive", "prost-types", @@ -7359,7 +7886,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -7641,7 +8168,7 @@ version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "encoding_rs", "futures-core", @@ -7660,6 +8187,7 @@ dependencies = [ "pin-project-lite", "quinn", "rustls", + "rustls-native-certs", "rustls-pki-types", "serde", "serde_json", @@ -7674,19 +8202,20 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams", + "wasm-streams 0.4.2", "web-sys", "webpki-roots 1.0.8", ] [[package]] name = "reqwest" -version = "0.13.1" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e9018c9d814e5f30cc16a0f03271aeab3571e609612d9fe78c1aa8d11c2f62" +checksum = "16a1cfa75cc186dd73d5818e510e042e40927bccc9c236b061cea97e1eb08029" dependencies = [ - "base64", + "base64 0.23.1", "bytes", + "encoding_rs", "futures-channel", "futures-core", "futures-util", @@ -7699,6 +8228,7 @@ dependencies = [ "hyper-util", "js-sys", "log", + "mime", "percent-encoding", "pin-project-lite", "quinn", @@ -7718,7 +8248,7 @@ dependencies = [ "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams", + "wasm-streams 0.5.0", "web-sys", ] @@ -7762,6 +8292,23 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rmp" +version = "0.8.15" +source = "git+https://github.com/90-008/msgpack-rust.git?rev=19c54a922301d06310a816c3a6a097aeb73ea3ae#19c54a922301d06310a816c3a6a097aeb73ea3ae" +dependencies = [ + "num-traits", +] + +[[package]] +name = "rmp-serde" +version = "1.3.1" +source = "git+https://github.com/90-008/msgpack-rust.git?rev=19c54a922301d06310a816c3a6a097aeb73ea3ae#19c54a922301d06310a816c3a6a097aeb73ea3ae" +dependencies = [ + "rmp", + "serde", +] + [[package]] name = "rsa" version = "0.9.10" @@ -7932,6 +8479,12 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "rustc-demangle" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" + [[package]] name = "rustc-hash" version = "2.1.2" @@ -7966,7 +8519,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -7995,7 +8548,7 @@ dependencies = [ "async-trait", "async-web-client", "aws-lc-rs", - "base64", + "base64 0.22.1", "blocking", "chrono", "futures", @@ -8050,7 +8603,7 @@ checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" dependencies = [ "core-foundation 0.10.1", "core-foundation-sys", - "jni", + "jni 0.21.1", "log", "once_cell", "rustls", @@ -8060,7 +8613,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -8233,6 +8786,12 @@ dependencies = [ "libc", ] +[[package]] +name = "self_cell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab42ca02749e120097e328d91d415325bdf43b1c72c4c8badf37375fe40a813" + [[package]] name = "semver" version = "1.0.28" @@ -8304,6 +8863,7 @@ dependencies = [ "form_urlencoded", "indexmap", "itoa", + "ryu", "serde_core", ] @@ -8394,7 +8954,7 @@ version = "3.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76a5c54c7310e7b8b9577c286d7e399ddd876c3e12b3ed917a8aabc4b96e9e8c" dependencies = [ - "base64", + "base64 0.22.1", "bs58", "chrono", "hex", @@ -8439,6 +8999,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sfa" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1296838937cab56cd6c4eeeb8718ec777383700c33f060e2869867bd01d1175" +dependencies = [ + "byteorder-lite", + "log", + "xxhash-rust", +] + [[package]] name = "sha1" version = "0.10.6" @@ -8471,6 +9042,12 @@ dependencies = [ "sha1 0.10.6", ] +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + [[package]] name = "sha2" version = "0.10.9" @@ -8529,7 +9106,7 @@ name = "shuttle" version = "0.1.0" dependencies = [ "anyhow", - "base64", + "base64 0.22.1", "libc", "nix", "once_cell", @@ -8592,6 +9169,22 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "simd_cesu8" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11031e251abf8611c80f460e19dbdeb54a66db918e49c65a7065b46ac7aec520" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "1.0.3" @@ -8624,6 +9217,9 @@ name = "smallvec" version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +dependencies = [ + "serde", +] [[package]] name = "smol_str" @@ -8701,6 +9297,183 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "sqlx" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "378620ccc25c62c89d8be1c819e76a88d59bdcc3304733330788948e619bfd71" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b44e85bf579a8eeb4ceaa77a3a523baf2bf0e9bac7e40f405d537b5d2d5ccb" +dependencies = [ + "base64 0.22.1", + "bytes", + "cfg-if", + "chrono", + "crc", + "crossbeam-queue", + "either", + "event-listener", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashbrown 0.16.1", + "hashlink", + "indexmap", + "log", + "memchr", + "percent-encoding", + "rustls", + "serde", + "serde_json", + "sha2 0.10.9", + "smallvec", + "thiserror 2.0.18", + "tokio", + "tokio-stream", + "tracing", + "url", + "webpki-roots 1.0.8", +] + +[[package]] +name = "sqlx-macros" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2b84f2bc39a5705ef27ec785a11c934a41bbd4a24941e257927cddc26b60bf" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 2.0.118", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb8d96de5fdc85a5c4ec813432b523ec637e80ba98f046555f75f7908ddac7c3" +dependencies = [ + "cfg-if", + "dotenvy", + "either", + "heck", + "hex", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2 0.10.9", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 2.0.118", + "thiserror 2.0.18", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90b8020fe17c5f2c245bfa2505d7ef59c5604839527c740266ad2214acebea27" +dependencies = [ + "bitflags 2.13.0", + "byteorder", + "bytes", + "chrono", + "crc", + "digest 0.11.3", + "dotenvy", + "either", + "futures-core", + "futures-util", + "generic-array 0.14.9", + "log", + "percent-encoding", + "serde", + "sha1 0.11.0", + "sha2 0.11.0", + "sqlx-core", + "thiserror 2.0.18", + "tracing", +] + +[[package]] +name = "sqlx-postgres" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87a2bdd6e83f6b3ea525ca9fee568030508b58355a43d0b2c1674d5f79dcd65e" +dependencies = [ + "atoi", + "base64 0.22.1", + "bitflags 2.13.0", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "hkdf 0.13.0", + "hmac 0.13.0", + "itoa", + "log", + "md-5", + "memchr", + "rand 0.10.1", + "serde", + "serde_json", + "sha2 0.11.0", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror 2.0.18", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488e99c397a62007e4229aec669a179816339afc6d2620ca6fa420dbee2e982c" +dependencies = [ + "atoi", + "chrono", + "flume", + "form_urlencoded", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "thiserror 2.0.18", + "tracing", + "url", +] + [[package]] name = "ssh-cipher" version = "0.3.0-rc.9" @@ -8799,6 +9572,17 @@ dependencies = [ "quote", ] +[[package]] +name = "stringprep" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" +dependencies = [ + "unicode-bidi", + "unicode-normalization", + "unicode-properties", +] + [[package]] name = "strsim" version = "0.11.1" @@ -8811,6 +9595,27 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "supports-color" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" +dependencies = [ + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e396b6523b11ccb83120b115a0b7366de372751aa6edf19844dfb13a6af97e91" + +[[package]] +name = "supports-unicode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" + [[package]] name = "syn" version = "2.0.118" @@ -8900,7 +9705,7 @@ checksum = "edde6a10743fff00a4e1a8c9ef020bf5f3cbad301b7d2d39f2b07f123c4eac07" dependencies = [ "aho-corasick", "arc-swap", - "base64", + "base64 0.22.1", "bitpacking", "bon", "byteorder", @@ -9061,7 +9866,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -9082,7 +9887,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" dependencies = [ "rustix", - "windows-sys 0.61.2", + "windows-sys 0.59.0", +] + +[[package]] +name = "textwrap" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" +dependencies = [ + "unicode-linebreak", + "unicode-width 0.2.2", ] [[package]] @@ -9239,6 +10054,7 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", "signal-hook-registry", "socket2", @@ -9356,6 +10172,29 @@ dependencies = [ "vsock", ] +[[package]] +name = "tokio-websockets" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52efb639344a7c6adb8e62c6f3d2c19c001ff1b79a5041ba1c6ed42e19c6aa5" +dependencies = [ + "aws-lc-rs", + "base64 0.22.1", + "bytes", + "futures-core", + "futures-sink", + "http", + "httparse", + "rand 0.10.1", + "rustls-native-certs", + "rustls-pki-types", + "sha1_smol", + "simdutf8", + "tokio", + "tokio-rustls", + "tokio-util", +] + [[package]] name = "toml" version = "0.9.12+spec-1.1.0" @@ -9583,7 +10422,7 @@ version = "0.0.1" dependencies = [ "anyhow", "axum", - "base64", + "base64 0.22.1", "bobbin-runtime", "bs58", "clap", @@ -9592,7 +10431,7 @@ dependencies = [ "jacquard-common", "jacquard-identity", "k256", - "reqwest 0.13.1", + "reqwest 0.13.5", "serde", "serde_json", "tangled-axum", @@ -9662,6 +10501,12 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "twox-hash" +version = "2.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5283634e518fe9e82c7b20520bb4bc209009fd16c82077c802f8111ecbb0117a" + [[package]] name = "typed-arena" version = "2.0.2" @@ -9725,6 +10570,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" +[[package]] +name = "unicode-bidi" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" + [[package]] name = "unicode-bom" version = "2.0.3" @@ -9737,6 +10588,12 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + [[package]] name = "unicode-normalization" version = "0.1.25" @@ -9746,6 +10603,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-properties" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" + [[package]] name = "unicode-segmentation" version = "1.13.3" @@ -9758,6 +10621,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -9875,6 +10744,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[package]] +name = "varint-rs" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa6c38708f6257f1ec2ca7e5a11f9bbf58a27d7060078b6b333624968183d96" + [[package]] name = "vcpkg" version = "0.2.15" @@ -10008,6 +10883,19 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasm-streams" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" version = "0.3.102" @@ -10067,6 +10955,12 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "whoami" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626c4bac6755d76ffc12cb01b2eac751db1996b9e0041de9aa02c8c211ddc82c" + [[package]] name = "widestring" version = "1.2.1" @@ -10095,7 +10989,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -10243,15 +11137,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.5", -] - [[package]] name = "windows-sys" version = "0.61.2" @@ -10285,30 +11170,13 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 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-targets" -version = "0.53.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.1", - "windows_aarch64_msvc 0.53.1", - "windows_i686_gnu 0.53.1", - "windows_i686_gnullvm 0.53.1", - "windows_i686_msvc 0.53.1", - "windows_x86_64_gnu 0.53.1", - "windows_x86_64_gnullvm 0.53.1", - "windows_x86_64_msvc 0.53.1", -] - [[package]] name = "windows-threading" version = "0.2.1" @@ -10330,12 +11198,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" - [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -10348,12 +11210,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" - [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -10366,24 +11222,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" - [[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_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" - [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -10396,12 +11240,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" - [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -10414,12 +11252,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" - [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -10432,12 +11264,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" - [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -10450,12 +11276,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" - [[package]] name = "winnow" version = "0.7.15" @@ -10475,7 +11295,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08db1edfb05d9b3c1542e521aea074442088292f00b5f28e435c714a98f85031" dependencies = [ "assert-json-diff", - "base64", + "base64 0.22.1", "deadpool 0.12.3", "futures", "http", diff --git a/Cargo.toml b/Cargo.toml index 8add59d9e..7ad589508 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -82,10 +82,16 @@ knot-maintenance = { path = "knot2/crates/knot-maintenance" } knot-sim = { path = "knot2/crates/knot-sim" } knot-edge = { path = "knot2/crates/knot-edge" } +gitmirror-db = { path = "gitmirror/crates/gitmirror-db" } gitmirror-git = { path = "gitmirror/crates/gitmirror-git" } gitmirror-ingest = { path = "gitmirror/crates/gitmirror-ingest" } +gitmirror-sync = { path = "gitmirror/crates/gitmirror-sync" } +gitmirror-types = { path = "gitmirror/crates/gitmirror-types" } gitmirror-xrpc = { path = "gitmirror/crates/gitmirror-xrpc" } +hydrant = { git = "https://tangled.org/ptr.pet/hydrant", rev = "ccc1b1a3", default-features = false, features = ["indexer_stream"] } +sqlx = { version = "0.9", default-features = false, features = ["runtime-tokio", "tls-rustls-aws-lc-rs", "postgres", "chrono", "macros", "migrate"] } + jacquard-api = "0.12.1" jacquard-axum = "0.12.1" jacquard-common = "0.12.1" @@ -99,12 +105,14 @@ gix-pack = { version = "0.71", default-features = false, features = ["generate", gix-odb = "0.81" gix-packetline = { version = "0.21", features = ["blocking-io"] } gix-transport = { version = "0.57", default-features = false } +gix-protocol = { version = "0.62", default-features = false, features = ["blocking-client"] } gix-archive = "0.33" gix-hash = { version = "0.25", features = ["sha1", "sha256"] } gix-actor = "0.41" gix-diff = "0.64" gix-features = "0.48" gix-merge = "0.17" +gix-negotiate = "0.32" gix-object = "0.61" gix-ref = "0.64" # `AsyncWriteExt` for the raw writer `gix-transport` hands back from `RequestWriter::into_parts()`. diff --git a/flake.nix b/flake.nix index ad594a679..d20631c52 100644 --- a/flake.nix +++ b/flake.nix @@ -465,6 +465,7 @@ ]; shellHook = '' export CC=${pkgs.stdenv.cc}/bin/cc + export SQLX_OFFLINE=true export NODE_PATH=${tailwindcss-plugins}''${NODE_PATH:+:$NODE_PATH} ( cd "$(git rev-parse --show-toplevel 2>/dev/null || pwd)" diff --git a/gitmirror/README.md b/gitmirror/README.md index dab7304d9..15331a3fb 100644 --- a/gitmirror/README.md +++ b/gitmirror/README.md @@ -2,3 +2,30 @@ gitmirror is alternative name of Knotmirror v2. It is designed to be run under the AppView as git syncing service. It currently speaks XRPC, but because it's internal sync service like tap or hydrant, this API interface can change later. + +## Database + +`gitmirror-ingest` mirrors `org.tangled.git.refs` records into postgres. `gitmirror-db` owns the +schema; `gitmirror-sync` owns the `state` / `error_msg` / `retry_*` columns it leaves alone. + +The two run inside `gitmirror serve`, next to the XRPC server. Ingest +writes a changed record and puts the row back to `pending`; `gitmirror-sync`'s `BackfillWorker` +scans for rows that are behind, fetches, and writes the outcome back. Nothing claims a row in the +database: dedup is an in-memory set, the way hydrant does it, so a crash leaves work eligible +rather than stuck in a state no reaper clears. + +Queries are compile-time checked by `sqlx::query!`, and the build has no database, so +`gitmirror/crates/gitmirror-db/.sqlx/` is committed and `SQLX_OFFLINE=true` is set in the +Containerfile and in `nix/pkgs/gitmirror.nix`. It lives inside the crate rather than at the +workspace root because crate2nix builds each crate in isolation. After changing any query: + + cargo check -p gitmirror-db --all-targets # with the two env vars below + SQLX_OFFLINE_DIR=$PWD/gitmirror/crates/gitmirror-db/.sqlx + DATABASE_URL=postgres://tnglr:tnglr@localhost:5432/gitmirror + +Then verify the cache is complete with `DATABASE_URL` unset: + + SQLX_OFFLINE=true cargo check -p gitmirror --all-targets + +Embedded hydrant is configured through hydrant's own `HYDRANT_*` environment schema; the +collection filter is not among them, since ingest pins it to `org.tangled.git.refs` itself. diff --git a/gitmirror/crates/gitmirror-db/.sqlx/query-27286d65426e3f215744767b774bede293bb1e45b7a6a1aec0af40a729cf89d0.json b/gitmirror/crates/gitmirror-db/.sqlx/query-27286d65426e3f215744767b774bede293bb1e45b7a6a1aec0af40a729cf89d0.json new file mode 100644 index 000000000..934db02e2 --- /dev/null +++ b/gitmirror/crates/gitmirror-db/.sqlx/query-27286d65426e3f215744767b774bede293bb1e45b7a6a1aec0af40a729cf89d0.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "insert into hydrant_cursor (id, last_event_id)\n values (0, $1)\n on conflict (id) do update set last_event_id = excluded.last_event_id", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8" + ] + }, + "nullable": [] + }, + "hash": "27286d65426e3f215744767b774bede293bb1e45b7a6a1aec0af40a729cf89d0" +} diff --git a/gitmirror/crates/gitmirror-db/.sqlx/query-27487b1b800decd26cb5a1500711c474657fa4a1f7899135a690b98cc59a6f97.json b/gitmirror/crates/gitmirror-db/.sqlx/query-27487b1b800decd26cb5a1500711c474657fa4a1f7899135a690b98cc59a6f97.json new file mode 100644 index 000000000..3067de0bc --- /dev/null +++ b/gitmirror/crates/gitmirror-db/.sqlx/query-27487b1b800decd26cb5a1500711c474657fa4a1f7899135a690b98cc59a6f97.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "insert into repos (did, refs_cid, default_branch, refs, deleted_at)\n values ($1, $2, $3, $4, null)\n on conflict (did) do update set\n refs_cid = excluded.refs_cid,\n default_branch = excluded.default_branch,\n refs = excluded.refs,\n deleted_at = null,\n state = 'pending',\n error_msg = null,\n retry_count = 0,\n retry_after_us = null,\n updated_at = now()\n where repos.refs_cid is distinct from excluded.refs_cid\n or repos.deleted_at is not null", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text", + "Text", + "Bytea" + ] + }, + "nullable": [] + }, + "hash": "27487b1b800decd26cb5a1500711c474657fa4a1f7899135a690b98cc59a6f97" +} diff --git a/gitmirror/crates/gitmirror-db/.sqlx/query-a11215321a6b36170dfaaa245329a37363881e690b4100d586b52787bf63c1ec.json b/gitmirror/crates/gitmirror-db/.sqlx/query-a11215321a6b36170dfaaa245329a37363881e690b4100d586b52787bf63c1ec.json new file mode 100644 index 000000000..4150576dd --- /dev/null +++ b/gitmirror/crates/gitmirror-db/.sqlx/query-a11215321a6b36170dfaaa245329a37363881e690b4100d586b52787bf63c1ec.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "update repos\n set state = 'active', error_msg = null, retry_count = 0, retry_after_us = null,\n updated_at = now()\n where did = $1 and refs_cid = $2 and deleted_at is null", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text" + ] + }, + "nullable": [] + }, + "hash": "a11215321a6b36170dfaaa245329a37363881e690b4100d586b52787bf63c1ec" +} diff --git a/gitmirror/crates/gitmirror-db/.sqlx/query-ab795867f17041560dff32d76690dac22678ede2b8949cd557b6ce704d79b0b7.json b/gitmirror/crates/gitmirror-db/.sqlx/query-ab795867f17041560dff32d76690dac22678ede2b8949cd557b6ce704d79b0b7.json new file mode 100644 index 000000000..daa6559a2 --- /dev/null +++ b/gitmirror/crates/gitmirror-db/.sqlx/query-ab795867f17041560dff32d76690dac22678ede2b8949cd557b6ce704d79b0b7.json @@ -0,0 +1,26 @@ +{ + "db_name": "PostgreSQL", + "query": "select last_event_id from hydrant_cursor where id = 0", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "last_event_id", + "type_info": "Int8", + "origin": { + "Table": { + "table": "hydrant_cursor", + "name": "last_event_id" + } + } + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false + ] + }, + "hash": "ab795867f17041560dff32d76690dac22678ede2b8949cd557b6ce704d79b0b7" +} diff --git a/gitmirror/crates/gitmirror-db/.sqlx/query-b36c6631c70015f445c255ca16d81fad68f90fa21d062351661d2ab5d9c91e8e.json b/gitmirror/crates/gitmirror-db/.sqlx/query-b36c6631c70015f445c255ca16d81fad68f90fa21d062351661d2ab5d9c91e8e.json new file mode 100644 index 000000000..af85be842 --- /dev/null +++ b/gitmirror/crates/gitmirror-db/.sqlx/query-b36c6631c70015f445c255ca16d81fad68f90fa21d062351661d2ab5d9c91e8e.json @@ -0,0 +1,77 @@ +{ + "db_name": "PostgreSQL", + "query": "select did, refs_cid, default_branch, refs, retry_count\n from repos\n where deleted_at is null\n and state <> 'active'\n and (retry_after_us is null or retry_after_us <= $1)\n order by retry_after_us nulls first, updated_at\n limit $2", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "did", + "type_info": "Text", + "origin": { + "Table": { + "table": "repos", + "name": "did" + } + } + }, + { + "ordinal": 1, + "name": "refs_cid", + "type_info": "Text", + "origin": { + "Table": { + "table": "repos", + "name": "refs_cid" + } + } + }, + { + "ordinal": 2, + "name": "default_branch", + "type_info": "Text", + "origin": { + "Table": { + "table": "repos", + "name": "default_branch" + } + } + }, + { + "ordinal": 3, + "name": "refs", + "type_info": "Bytea", + "origin": { + "Table": { + "table": "repos", + "name": "refs" + } + } + }, + { + "ordinal": 4, + "name": "retry_count", + "type_info": "Int4", + "origin": { + "Table": { + "table": "repos", + "name": "retry_count" + } + } + } + ], + "parameters": { + "Left": [ + "Int8", + "Int8" + ] + }, + "nullable": [ + false, + false, + false, + false, + false + ] + }, + "hash": "b36c6631c70015f445c255ca16d81fad68f90fa21d062351661d2ab5d9c91e8e" +} diff --git a/gitmirror/crates/gitmirror-db/.sqlx/query-bebe7c55b9010d9e1f1aa5daef9e291b13885004da7d0c98201c98e98e805649.json b/gitmirror/crates/gitmirror-db/.sqlx/query-bebe7c55b9010d9e1f1aa5daef9e291b13885004da7d0c98201c98e98e805649.json new file mode 100644 index 000000000..99ea12c38 --- /dev/null +++ b/gitmirror/crates/gitmirror-db/.sqlx/query-bebe7c55b9010d9e1f1aa5daef9e291b13885004da7d0c98201c98e98e805649.json @@ -0,0 +1,14 @@ +{ + "db_name": "PostgreSQL", + "query": "update repos set deleted_at = now(), updated_at = now()\n where did = $1 and deleted_at is null", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text" + ] + }, + "nullable": [] + }, + "hash": "bebe7c55b9010d9e1f1aa5daef9e291b13885004da7d0c98201c98e98e805649" +} diff --git a/gitmirror/crates/gitmirror-db/.sqlx/query-cb4b72b818a1f2922826955d4ec7948bd99a40d342d5687dd8c1c8dd137a2508.json b/gitmirror/crates/gitmirror-db/.sqlx/query-cb4b72b818a1f2922826955d4ec7948bd99a40d342d5687dd8c1c8dd137a2508.json new file mode 100644 index 000000000..2edb39e77 --- /dev/null +++ b/gitmirror/crates/gitmirror-db/.sqlx/query-cb4b72b818a1f2922826955d4ec7948bd99a40d342d5687dd8c1c8dd137a2508.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "update repos set retry_after_us = $3, updated_at = now()\n where did = $1 and refs_cid = $2 and deleted_at is null", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "cb4b72b818a1f2922826955d4ec7948bd99a40d342d5687dd8c1c8dd137a2508" +} diff --git a/gitmirror/crates/gitmirror-db/.sqlx/query-d8a554b5420520d584b5b759a04c8b31d1a9c159842af5aa0a76f7a89713057c.json b/gitmirror/crates/gitmirror-db/.sqlx/query-d8a554b5420520d584b5b759a04c8b31d1a9c159842af5aa0a76f7a89713057c.json new file mode 100644 index 000000000..00f9ad70f --- /dev/null +++ b/gitmirror/crates/gitmirror-db/.sqlx/query-d8a554b5420520d584b5b759a04c8b31d1a9c159842af5aa0a76f7a89713057c.json @@ -0,0 +1,17 @@ +{ + "db_name": "PostgreSQL", + "query": "update repos\n set state = 'error', error_msg = $3, retry_count = retry_count + 1,\n retry_after_us = $4, updated_at = now()\n where did = $1 and refs_cid = $2 and deleted_at is null", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Text", + "Text", + "Text", + "Int8" + ] + }, + "nullable": [] + }, + "hash": "d8a554b5420520d584b5b759a04c8b31d1a9c159842af5aa0a76f7a89713057c" +} diff --git a/gitmirror/crates/gitmirror-db/Cargo.toml b/gitmirror/crates/gitmirror-db/Cargo.toml new file mode 100644 index 000000000..c61da04aa --- /dev/null +++ b/gitmirror/crates/gitmirror-db/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "gitmirror-db" +version.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true + +[dependencies] +jacquard-common = { workspace = true } +sqlx = { workspace = true } +thiserror = { workspace = true } +tracing = { workspace = true } + +[dev-dependencies] +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } + +[lints] +workspace = true diff --git a/gitmirror/crates/gitmirror-db/migrations/20260916000000_initial.sql b/gitmirror/crates/gitmirror-db/migrations/20260916000000_initial.sql new file mode 100644 index 000000000..32d729294 --- /dev/null +++ b/gitmirror/crates/gitmirror-db/migrations/20260916000000_initial.sql @@ -0,0 +1,29 @@ +create table if not exists hydrant_cursor ( + id smallint primary key check (id = 0), + last_event_id bigint not null +); + +create table if not exists repos ( + -- at:///org.tangled.git.refs/self + did text primary key, + refs_cid text not null, + default_branch text not null, + refs bytea not null, + + -- git sync state + state text not null default 'pending', + error_msg text, + retry_count integer not null default 0, + retry_after_us bigint, + + created_at timestamptz not null default now(), + updated_at timestamptz not null default now(), + -- set when the record is deleted or the account goes inactive + deleted_at timestamptz +); + +create index if not exists idx_repos_updated_at on repos (updated_at desc); + +create index if not exists idx_repos_sync_queue + on repos (retry_after_us nulls first, updated_at) + where deleted_at is null and state <> 'active'; diff --git a/gitmirror/crates/gitmirror-db/src/lib.rs b/gitmirror/crates/gitmirror-db/src/lib.rs new file mode 100644 index 000000000..f5743ecd9 --- /dev/null +++ b/gitmirror/crates/gitmirror-db/src/lib.rs @@ -0,0 +1,269 @@ +use std::borrow::Cow; + +use jacquard_common::deps::bytes::Bytes; +use jacquard_common::deps::smol_str::SmolStr; +use jacquard_common::types::did::Did; +use sqlx::postgres::PgPoolOptions; +use std::time::Duration; +use thiserror::Error; +use tracing::{debug, warn}; + +#[derive(Debug, Error)] +pub enum DbError { + #[error("query failed: {0}")] + Query(String), + #[error("row not found")] + NotFound, + #[error("constraint violation: {0}")] + Constraint(String), + #[error("connection failed: {0}")] + Connection(String), + #[error("migration failed: {0}")] + Migrate(String), + #[error("{0}")] + Other(String), +} + +impl From for DbError { + fn from(e: sqlx::Error) -> Self { + match e { + sqlx::Error::RowNotFound => Self::NotFound, + sqlx::Error::Database(db_err) => { + let msg = db_err.message().to_owned(); + if db_err.is_unique_violation() || db_err.is_foreign_key_violation() { + Self::Constraint(msg) + } else { + Self::Query(msg) + } + } + sqlx::Error::PoolTimedOut => Self::Connection("pool timed out".to_owned()), + sqlx::Error::Io(e) => Self::Connection(e.to_string()), + other => Self::Other(other.to_string()), + } + } +} + +impl From for DbError { + fn from(e: sqlx::migrate::MigrateError) -> Self { + Self::Migrate(e.to_string()) + } +} + +#[derive(Clone)] +pub struct Db(sqlx::PgPool); + +/// The body of one `org.tangled.git.refs` record. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct GitRefs { + pub default_branch: SmolStr, + /// Git refs in `git show-ref` format. + pub refs: Bytes, +} + +#[derive(Debug)] +pub struct RefsUpsert<'a> { + pub did: &'a Did, + pub refs_cid: &'a str, + pub refs: &'a GitRefs, +} + +#[derive(Debug)] +pub struct RepoRow { + pub did: Did, + pub refs_cid: String, + pub refs: GitRefs, + pub retry_count: i32, +} + +impl Db { + pub async fn connect(url: &str, max_connections: u32) -> Result { + let pool = PgPoolOptions::new() + .max_connections(max_connections) + .acquire_timeout(Duration::from_secs(10)) + .idle_timeout(Duration::from_secs(300)) + .max_lifetime(Duration::from_secs(1800)) + .connect(url) + .await?; + Ok(Self(pool)) + } + + pub fn from_pool(pool: sqlx::PgPool) -> Self { + Self(pool) + } + + pub fn pool(&self) -> &sqlx::PgPool { + &self.0 + } + + pub async fn migrate(&self) -> Result<(), DbError> { + sqlx::migrate!("./migrations").run(&self.0).await?; + Ok(()) + } + + pub async fn cursor(&self) -> Result, DbError> { + let row = sqlx::query!("select last_event_id from hydrant_cursor where id = 0") + .fetch_optional(&self.0) + .await?; + Ok(row.map(|r| r.last_event_id as u64)) + } + + /// Checkpoint on its own, for stretches of events that touched no row. + pub async fn set_cursor(&self, cursor: u64) -> Result<(), DbError> { + sqlx::query!( + "insert into hydrant_cursor (id, last_event_id) + values (0, $1) + on conflict (id) do update set last_event_id = excluded.last_event_id", + i64::try_from(cursor).unwrap_or(i64::MAX), + ) + .execute(&self.0) + .await?; + Ok(()) + } + + /// Stores the record, returning whether the row actually changed. + pub async fn upsert_refs(&self, r: RefsUpsert<'_>) -> Result { + let done = sqlx::query!( + "insert into repos (did, refs_cid, default_branch, refs, deleted_at) + values ($1, $2, $3, $4, null) + on conflict (did) do update set + refs_cid = excluded.refs_cid, + default_branch = excluded.default_branch, + refs = excluded.refs, + deleted_at = null, + state = 'pending', + error_msg = null, + retry_count = 0, + retry_after_us = null, + updated_at = now() + where repos.refs_cid is distinct from excluded.refs_cid + or repos.deleted_at is not null", + r.did.as_str(), + r.refs_cid, + r.refs.default_branch.as_str(), + &r.refs.refs[..], + ) + .execute(&self.0) + .await?; + Ok(done.rows_affected() > 0) + } + + pub async fn mark_deleted(&self, did: &Did) -> Result<(), DbError> { + sqlx::query!( + "update repos set deleted_at = now(), updated_at = now() + where did = $1 and deleted_at is null", + did.as_str(), + ) + .execute(&self.0) + .await?; + Ok(()) + } + + /// Repos due for a git resync, longest-waiting first. + pub async fn pending_repos(&self, now_us: i64, limit: i64) -> Result, DbError> { + let rows = sqlx::query!( + "select did, refs_cid, default_branch, refs, retry_count + from repos + where deleted_at is null + and state <> 'active' + and (retry_after_us is null or retry_after_us <= $1) + order by retry_after_us nulls first, updated_at + limit $2", + now_us, + limit, + ) + .fetch_all(&self.0) + .await?; + Ok(rows + .into_iter() + .filter_map(|r| { + let did = Did::new_owned(&r.did) + .inspect_err(|e| warn!(did = %r.did, error = %e, "unparseable did in repos")) + .ok()?; + Some(RepoRow { + did, + refs_cid: r.refs_cid, + refs: GitRefs { + default_branch: r.default_branch.into(), + refs: Bytes::from(r.refs), + }, + retry_count: r.retry_count, + }) + }) + .collect()) + } + + pub async fn mark_synced(&self, did: &Did, refs_cid: &str) -> Result<(), DbError> { + let done = sqlx::query!( + "update repos + set state = 'active', error_msg = null, retry_count = 0, retry_after_us = null, + updated_at = now() + where did = $1 and refs_cid = $2 and deleted_at is null", + did.as_str(), + refs_cid, + ) + .execute(&self.0) + .await?; + if done.rows_affected() > 0 { + debug!(%did, refs_cid, "synced"); + } else { + debug!(%did, refs_cid, "refs changed mid-sync, dropped the stale success"); + } + Ok(()) + } + + pub async fn mark_deferred( + &self, + did: &Did, + refs_cid: &str, + retry_after_us: i64, + ) -> Result<(), DbError> { + let done = sqlx::query!( + "update repos set retry_after_us = $3, updated_at = now() + where did = $1 and refs_cid = $2 and deleted_at is null", + did.as_str(), + refs_cid, + retry_after_us, + ) + .execute(&self.0) + .await?; + if done.rows_affected() > 0 { + debug!(%did, refs_cid, retry_after_us, "knot busy, deferred"); + } else { + debug!(%did, refs_cid, "refs changed mid-sync, dropped the stale defer"); + } + Ok(()) + } + + pub async fn mark_sync_failed( + &self, + did: &Did, + refs_cid: &str, + error: &str, + retry_after_us: i64, + ) -> Result<(), DbError> { + // postgres `text` rejects NUL + let error = if error.contains('\0') { + Cow::Owned(error.replace('\0', "")) + } else { + Cow::Borrowed(error) + }; + let done = sqlx::query!( + "update repos + set state = 'error', error_msg = $3, retry_count = retry_count + 1, + retry_after_us = $4, updated_at = now() + where did = $1 and refs_cid = $2 and deleted_at is null", + did.as_str(), + refs_cid, + &*error, + retry_after_us, + ) + .execute(&self.0) + .await?; + if done.rows_affected() > 0 { + warn!(%did, refs_cid, retry_after_us, error = %error, "sync failed, backing off"); + } else { + debug!(%did, refs_cid, "refs changed mid-sync, dropped the stale failure"); + } + Ok(()) + } +} diff --git a/gitmirror/crates/gitmirror-ingest/Cargo.toml b/gitmirror/crates/gitmirror-ingest/Cargo.toml index 6c1caf617..f674ba0e0 100644 --- a/gitmirror/crates/gitmirror-ingest/Cargo.toml +++ b/gitmirror/crates/gitmirror-ingest/Cargo.toml @@ -6,6 +6,17 @@ license.workspace = true rust-version.workspace = true [dependencies] +bobbin-runtime = { workspace = true } +gitmirror-db = { workspace = true } +lexicons = { workspace = true } + +hydrant = { workspace = true } +jacquard-common = { workspace = true } +serde_json = { workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true } +tokio-util = { workspace = true } +tracing = { workspace = true } [lints] workspace = true diff --git a/gitmirror/crates/gitmirror-ingest/src/lib.rs b/gitmirror/crates/gitmirror-ingest/src/lib.rs index 8b1378917..6795ee45f 100644 --- a/gitmirror/crates/gitmirror-ingest/src/lib.rs +++ b/gitmirror/crates/gitmirror-ingest/src/lib.rs @@ -1 +1,225 @@ +//! Mirror `org.tangled.git.refs` records into postgres. +//! +//! Runs hydrant in-process rather than talking to one over a websocket the way `bobbin-ingest` +//! does, so there is no session/reconnect machinery here: hydrant owns the firehose, and this +//! crate only drains the ordered event stream it hands back. +//! +//! Fetching the git objects those refs point at is `gitmirror-sync`'s job; this crate never +//! touches the `state` / `error_msg` / `retry_*` columns. +use std::sync::Arc; +use std::time::Duration; + +use bobbin_runtime::Clock; +use gitmirror_db::{Db, DbError, GitRefs, RefsUpsert}; +use hydrant::FilterMode; +use hydrant::control::{EventStream, Hydrant}; +use hydrant::deps::futures::StreamExt as _; +use jacquard_common::types::collection::Collection as _; +use lexicons::org_tangled::git::refs::{Refs, RefsRecord}; +use thiserror::Error; +use tokio_util::sync::CancellationToken; +use tracing::{debug, info, warn}; + +const REFS_COLLECTION: &str = RefsRecord::NSID; +const REFS_RKEY: &str = "self"; + +pub const DEFAULT_CHECKPOINT_INTERVAL: Duration = Duration::from_secs(10); + +const RESUBSCRIBE_DELAY: Duration = Duration::from_secs(1); + +#[derive(Debug, Error)] +pub enum IngestError { + #[error("database: {0}")] + Db(#[from] DbError), + #[error("hydrant: {0}")] + Hydrant(String), +} + +pub struct IngestConfig { + pub hydrant: hydrant::config::Config, + /// How often a stretch of events that touched no row still advances the stored cursor. + pub checkpoint_interval: Duration, +} + +impl IngestConfig { + pub fn new(hydrant: hydrant::config::Config) -> Self { + Self { + hydrant, + checkpoint_interval: DEFAULT_CHECKPOINT_INTERVAL, + } + } +} + +pub struct IngestRuntime { + pub db: Db, + pub clock: Arc, + pub cancel: CancellationToken, +} + +pub async fn run(config: IngestConfig, rt: IngestRuntime) -> Result<(), IngestError> { + let IngestConfig { + hydrant: hydrant_config, + checkpoint_interval, + } = config; + + let hydrant = Hydrant::new(hydrant_config) + .await + .map_err(|e| IngestError::Hydrant(format!("open hydrant: {e}")))?; + + hydrant + .filter + .set_mode(FilterMode::Filter) + .set_signals([REFS_COLLECTION]) + .set_collections([REFS_COLLECTION]) + .apply() + .await + .map_err(|e| IngestError::Hydrant(format!("apply filter: {e}")))?; + + let driver = hydrant + .run() + .map_err(|e| IngestError::Hydrant(format!("start hydrant: {e}")))?; + + tokio::select! { + r = driver => r.map_err(|e| IngestError::Hydrant(e.to_string())), + r = consume_forever(&hydrant, &rt, checkpoint_interval) => r, + () = rt.cancel.cancelled() => { + info!("gitmirror-ingest stopped after shutdown signal"); + Ok(()) + } + } +} + +async fn consume_forever( + hydrant: &Hydrant, + rt: &IngestRuntime, + checkpoint_interval: Duration, +) -> Result<(), IngestError> { + loop { + let last = rt.db.cursor().await?; + let resume = last.map_or(0, |c| c + 1); + info!(resume, last, "subscribing to hydrant event stream"); + + consume(hydrant.subscribe(Some(resume)), rt, checkpoint_interval).await?; + + if rt.cancel.is_cancelled() { + return Ok(()); + } + rt.clock.sleep(RESUBSCRIBE_DELAY).await; + } +} + +async fn consume( + mut stream: EventStream, + rt: &IngestRuntime, + checkpoint_interval: Duration, +) -> Result<(), IngestError> { + let mut unflushed: Option = None; + let mut next_flush = rt.clock.now_instant() + checkpoint_interval; + + loop { + tokio::select! { + biased; + () = rt.cancel.cancelled() => { + flush(rt, &mut unflushed).await?; + return Ok(()); + } + () = rt.clock.sleep_until(next_flush) => { + flush(rt, &mut unflushed).await?; + next_flush = rt.clock.now_instant() + checkpoint_interval; + } + item = stream.next() => { + let Some(item) = item else { + flush(rt, &mut unflushed).await?; + warn!("hydrant event stream ended"); + return Ok(()); + }; + let event = match item { + Ok(event) => event, + Err(e) => { + flush(rt, &mut unflushed).await?; + warn!(error = %e, "hydrant event stream closed"); + return Ok(()); + } + }; + let cursor = event.id; + handle(event, rt).await?; + unflushed = Some(cursor); + } + } + } +} + +async fn flush(rt: &IngestRuntime, unflushed: &mut Option) -> Result<(), IngestError> { + if let Some(cursor) = unflushed.take() { + rt.db.set_cursor(cursor).await?; + debug!(cursor, "checkpointed hydrant cursor"); + } + Ok(()) +} + +async fn handle(event: hydrant::control::Event, rt: &IngestRuntime) -> Result<(), IngestError> { + let cursor = event.id; + + if let Some(record) = event.record { + if record.collection.as_ref() != REFS_COLLECTION || record.rkey.as_ref() != REFS_RKEY { + return Ok(()); + } + let did = &record.did; + match record.action.as_ref() { + "create" | "update" => { + let Some(raw) = record.record.as_ref() else { + warn!(%did, cursor, "refs create/update with no body, skipping"); + return Ok(()); + }; + let Some(cid) = record.cid.as_ref() else { + warn!(%did, cursor, "refs create/update with no cid, skipping"); + return Ok(()); + }; + let refs: Refs = match serde_json::from_str(raw.get()) { + Ok(refs) => refs, + Err(e) => { + warn!(%did, cursor, error = %e, "undecodable refs record, skipping"); + return Ok(()); + } + }; + let git_refs = GitRefs { + default_branch: (&*refs.default_branch).into(), + refs: refs.refs, + }; + let changed = rt + .db + .upsert_refs(RefsUpsert { + did, + refs_cid: &cid.to_string(), + refs: &git_refs, + }) + .await?; + if changed { + debug!(%did, cursor, "stored refs"); + } else { + debug!(%did, cursor, "refs unchanged, skipped write"); + } + Ok(()) + } + "delete" => { + rt.db.mark_deleted(did).await?; + info!(%did, cursor, "refs record deleted, tombstoned row"); + Ok(()) + } + other => { + debug!(%did, cursor, action = other, "ignoring unknown record action"); + Ok(()) + } + } + } else if let Some(account) = event.account + && !account.active + { + let did = &account.did; + rt.db.mark_deleted(did).await?; + info!(%did, cursor, "account inactive, tombstoned row"); + Ok(()) + } else { + Ok(()) + } +} diff --git a/gitmirror/crates/gitmirror-sync/Cargo.toml b/gitmirror/crates/gitmirror-sync/Cargo.toml new file mode 100644 index 000000000..0e4e05172 --- /dev/null +++ b/gitmirror/crates/gitmirror-sync/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "gitmirror-sync" +version.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true + +[dependencies] +bobbin-runtime = { workspace = true } +gitmirror-db = { workspace = true } +gitmirror-git = { workspace = true } +gitmirror-types = { workspace = true } + +gix = { workspace = true } +gix-hash = { workspace = true } +gix-negotiate = { workspace = true } +gix-object = { workspace = true } +gix-pack = { workspace = true } +gix-protocol = { workspace = true } +gix-transport = { workspace = true, features = ["http-client-reqwest-rust-tls"] } +jacquard-common = { workspace = true } +jacquard-identity = { workspace = true } +reqwest = { workspace = true } +scc = { workspace = true } +thiserror = { workspace = true } +tokio = { workspace = true } +tokio-util = { workspace = true } +tracing = { workspace = true } +url = { workspace = true } + +[dev-dependencies] +sqlx = { workspace = true } +tempfile = { workspace = true } + +[lints] +workspace = true diff --git a/gitmirror/crates/gitmirror-sync/src/admission.rs b/gitmirror/crates/gitmirror-sync/src/admission.rs new file mode 100644 index 000000000..6595e6785 --- /dev/null +++ b/gitmirror/crates/gitmirror-sync/src/admission.rs @@ -0,0 +1,35 @@ +#![allow(dead_code)] + +use std::sync::Arc; + +use tokio::sync::{OwnedSemaphorePermit, Semaphore}; +use url::Url; + +#[derive(Clone)] +pub(crate) struct BackfillAdmission { + gates: Arc>>, + per_knot_limit: usize, +} + +impl BackfillAdmission { + pub(crate) fn new(global_limit: usize, per_knot_limit: usize) -> Self { + // leave room for another knot whenever the global limit allows it + let fair_limit = global_limit.saturating_sub(1).max(1); + Self { + gates: Arc::new(scc::HashMap::new()), + per_knot_limit: per_knot_limit.min(fair_limit).max(1), + } + } + + pub(crate) async fn try_acquire(&self, knot: &Url) -> Option { + let limit = self.per_knot_limit; + let gate = self + .gates + .entry_async(knot.clone()) + .await + .or_insert_with(|| Arc::new(Semaphore::new(limit))) + .get() + .clone(); + gate.try_acquire_owned().ok() + } +} diff --git a/gitmirror/crates/gitmirror-sync/src/lib.rs b/gitmirror/crates/gitmirror-sync/src/lib.rs new file mode 100644 index 000000000..25e72c3e8 --- /dev/null +++ b/gitmirror/crates/gitmirror-sync/src/lib.rs @@ -0,0 +1,231 @@ +//! sync git repository objects (packfile) + +use std::sync::Arc; +use std::time::Duration; + +use bobbin_runtime::Clock; + +use crate::admission::BackfillAdmission; +use gitmirror_db::{Db, DbError}; +use gitmirror_git::layout::Layout; +use gitmirror_types::KnotPolicy; +use jacquard_common::types::did::Did; +use thiserror::Error; +use tokio::sync::{Notify, Semaphore}; +use tokio_util::sync::CancellationToken; +use tracing::{error, info, Instrument as _}; + +mod admission; +mod task; + +/// The identity resolver, same concrete type the XRPC side uses. +pub type Directory = jacquard_identity::JacquardResolver; + +#[derive(Debug, Error)] +pub enum SyncError { + #[error("database: {0}")] + Db(#[from] DbError), +} + +/// Rows pulled per queue scan. Not a config knob: it only bounds one pass's memory, and the +/// semaphore is what actually limits work in flight. +const BATCH_SIZE: i64 = 64; + +/// Ceiling on the exponential retry backoff. +const MAX_BACKOFF_SECS: i64 = 60 * 60; + +/// How long a repo is parked when the knot was busy rather than broken. Short, because this is +/// not a backoff: it only has to be long enough to get the row out of the scan window. +const DEFER_HOLD_US: i64 = 5 * 1_000_000; + +pub const DEFAULT_CONCURRENCY: usize = 8; +pub const DEFAULT_PER_KNOT_CONCURRENCY: usize = 4; +pub const DEFAULT_POLL_INTERVAL: Duration = Duration::from_secs(5); + +pub struct SyncConfig { + pub concurrency: usize, + pub per_knot_concurrency: usize, + pub poll_interval: Duration, +} + +impl Default for SyncConfig { + fn default() -> Self { + Self { + concurrency: DEFAULT_CONCURRENCY, + per_knot_concurrency: DEFAULT_PER_KNOT_CONCURRENCY, + poll_interval: DEFAULT_POLL_INTERVAL, + } + } +} + +pub struct SyncRuntime { + pub db: Db, + pub clock: Arc, + pub cancel: CancellationToken, + pub http: reqwest::Client, + pub directory: Arc, + pub layout: Layout, + pub knot_policy: KnotPolicy, +} + +// NOTE: see hydrant/src/backfill/worker.rs as reference + +pub struct BackfillWorker { + rt: SyncRuntime, + poll_interval: Duration, + semaphore: Arc, + admission: BackfillAdmission, + in_flight: Arc>, + /// Woken by a finishing task so a pass that hit the concurrency limit picks up the next repo + /// immediately instead of waiting out `poll_interval`. + drained: Arc, +} + +impl BackfillWorker { + pub fn new(rt: SyncRuntime, config: SyncConfig) -> Self { + Self { + rt, + poll_interval: config.poll_interval, + semaphore: Arc::new(Semaphore::new(config.concurrency)), + admission: BackfillAdmission::new(config.concurrency, config.per_knot_concurrency), + in_flight: Arc::new(scc::HashSet::new()), + drained: Arc::new(Notify::new()), + } + } +} + +struct InFlightGuard { + did: Did, + set: Arc>, +} + +impl Drop for InFlightGuard { + fn drop(&mut self) { + let _ = self.set.remove_sync(&self.did); + } +} + +/// The clock reading `retry_after_us` is written from and compared against. +fn now_us(clock: &dyn Clock) -> i64 { + i64::try_from(clock.now_unix_micros().raw()).unwrap_or(i64::MAX) +} + +/// 2^n seconds in micros, capped. +fn backoff_us(retry_count: i32) -> i64 { + let shift = retry_count.clamp(0, 62) as u32; + // cap before scaling; the shift alone would overflow the multiply + (1i64 << shift).min(MAX_BACKOFF_SECS) * 1_000_000 +} + +impl BackfillWorker { + pub async fn run(self) -> Result<(), SyncError> { + info!("backfill worker started"); + + loop { + if self.rt.cancel.is_cancelled() { + break; + } + + let mut spawned = 0; + for row in self + .rt + .db + .pending_repos(now_us(&*self.rt.clock), BATCH_SIZE) + .await? + { + if self.in_flight.contains_sync(&row.did) { + continue; + } + + let permit = match self.semaphore.clone().try_acquire_owned() { + Ok(p) => p, + Err(_) => break, + }; + + // only mark as in flight if we can acquire a permit + if self.in_flight.insert_sync(row.did.clone()).is_err() { + // a task is already running, weh + // so we don't need this one anymore... + break; + } + + let guard = InFlightGuard { + did: row.did.clone(), + set: self.in_flight.clone(), + }; + + let db = self.rt.db.clone(); + let clock = self.rt.clock.clone(); + let http = self.rt.http.clone(); + let directory = self.rt.directory.clone(); + let layout = self.rt.layout.clone(); + let knot_policy = self.rt.knot_policy; + let admission = self.admission.clone(); + let drained = self.drained.clone(); + + let span = tracing::info_span!("backfill", did = %row.did); + tokio::spawn( + async move { + let _guard = guard; + let res = task::did_task( + &http, + &directory, + &layout, + knot_policy, + &row, + &admission, + permit, + ) + .await; + + let write = match &res { + Ok(task::TaskDisposition::Finished) => { + db.mark_synced(&row.did, &row.refs_cid).await + } + Ok(task::TaskDisposition::Deferred) => { + db.mark_deferred( + &row.did, + &row.refs_cid, + now_us(&*clock) + DEFER_HOLD_US, + ) + .await + } + Err(e) => { + db.mark_sync_failed( + &row.did, + &row.refs_cid, + &e.to_string(), + now_us(&*clock) + backoff_us(row.retry_count), + ) + .await + } + }; + + if let Err(e) = write { + error!(error = %e, "recording sync outcome failed"); + } + + // wake worker to pick up more (in case we were sleeping at limit) + drained.notify_one(); + } + .instrument(span), + ); + + spawned += 1; + } + + if spawned == 0 { + // wait for a task to finish, or for a `retry_after` to come due + tokio::select! { + () = self.rt.cancel.cancelled() => break, + () = self.drained.notified() => {} + () = self.rt.clock.sleep(self.poll_interval) => {} + } + } + // loop immediately since we might have more tasks + } + + info!("backfill worker stopped"); + Ok(()) + } +} diff --git a/gitmirror/crates/gitmirror-sync/src/task.rs b/gitmirror/crates/gitmirror-sync/src/task.rs new file mode 100644 index 000000000..10e46df4b --- /dev/null +++ b/gitmirror/crates/gitmirror-sync/src/task.rs @@ -0,0 +1,323 @@ +use std::path::Path; +use std::sync::atomic::AtomicBool; + +use gitmirror_db::RepoRow; +use gitmirror_git::layout::Layout; +use gitmirror_types::jacquard_ext::DidDocumentExt as _; +use gitmirror_types::{KnotHost, KnotPolicy}; +use gix::refs::transaction::{Change, LogChange, PreviousValue, RefEdit, RefLog}; +use gix::refs::{FullName, Target}; +use gix_hash::ObjectId; +use jacquard_common::types::did::Did; +use jacquard_identity::resolver::IdentityResolver as _; +use thiserror::Error; +use tracing::debug; + +use crate::admission::BackfillAdmission; +use crate::Directory; + +const AGENT: &str = concat!("gitmirror/", env!("CARGO_PKG_VERSION")); + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum TaskDisposition { + Finished, + Deferred, +} + +#[derive(Debug, Error)] +pub enum BackfillError { + #[error("resolve {0}: {1}")] + Resolve(Did, String), + #[error("{0} declares no knot service")] + NoKnotEndpoint(Did), + #[error("{0} declares an unusable knot endpoint: {1}")] + UnsafeKnotEndpoint(Did, &'static str), + #[error("malformed refs record: {0}")] + MalformedRefs(String), + #[error("git: {0}")] + Git(#[from] BackfillGitError), + #[error("fetch task panicked")] + Panicked, +} + +#[derive(Debug, Error)] +pub enum BackfillGitError { + #[error("init repo: {0}")] + Init(#[from] gix::init::Error), + #[error("connect host: {0}")] + Connect(#[from] gix_transport::client::blocking_io::connect::Error), + #[error("handshake host: {0}")] + Handshake(#[from] gix_protocol::handshake::Error), + #[error("fetch repo: {0}")] + Fetch(#[from] gix_protocol::fetch::Error), + #[error("edit references: {0}")] + RefsEdit(#[from] gix::reference::edit::Error), +} + +/// syncs git repository +pub async fn did_task( + _http: &reqwest::Client, + directory: &Directory, + layout: &Layout, + policy: KnotPolicy, + repo: &RepoRow, + admission: &BackfillAdmission, + _permit: tokio::sync::OwnedSemaphorePermit, +) -> Result { + // git-fetch is usually done in three steps: + // 1. handshake (host capability check) + // 2. advertisement (ls-refs) + // 3. git-upload-pack + // + // The handshake result will be cached per-host, and we already know the refs list (in db). + // So we can go straight to git-upload-pack call. + + let knot = knot_host(directory, &repo.did, policy).await?; + let knot = knot.url(); + + let Some(_knot_permit) = admission.try_acquire(knot).await else { + return Ok(TaskDisposition::Deferred); + }; + + // TODO: add sha256 support. + let refs = parse_refs(&repo.refs.refs, gix_hash::Kind::Sha1)?; + let head = FullName::try_from(format!("refs/heads/{}", repo.refs.default_branch)) + .map_err(|e| BackfillError::MalformedRefs(e.to_string()))?; + + let url = format!("{knot}{}", repo.did.as_str()); + let path = layout.repo_path(&repo.did); + tokio::task::spawn_blocking(move || fetch_into(&url, &path, &refs, head)) + .await + .map_err(|_| BackfillError::Panicked)??; + + Ok(TaskDisposition::Finished) +} + +/// The repo's own knot, from its DID document. Re-resolved every task: a repo can migrate. +async fn knot_host( + directory: &Directory, + did: &Did, + policy: KnotPolicy, +) -> Result { + let document = directory + .resolve_did_doc_owned(did) + .await + .map_err(|e| BackfillError::Resolve(did.clone(), e.to_string()))?; + + let endpoint = document + .knot_endpoint() + // TODO(post-1.0): remove legacy `#atproto_pds` fallback + .or_else(|| document.pds_endpoint()) + .ok_or_else(|| BackfillError::NoKnotEndpoint(did.clone()))?; + + let host = policy + .safe_knot_host(endpoint.as_ref()) + .map_err(|_reason| { + BackfillError::UnsafeKnotEndpoint(did.clone(), "is invalid knot service endpoint") + })?; + + Ok(host) +} + +// TODO: move this to gitmirror-db & gitmirror-ingest maybe, so we can verify on ingest +fn parse_refs( + blob: &[u8], + kind: gix_hash::Kind, +) -> Result, BackfillError> { + let malformed = |e: &dyn std::fmt::Display| BackfillError::MalformedRefs(e.to_string()); + gix::refs::packed::Iter::new(blob, kind) + .map_err(|e| malformed(&e))? + .map(|entry| { + let entry = entry.map_err(|e| malformed(&e))?; + Ok((entry.target(), entry.name.to_owned())) + }) + .collect() +} + +fn fetch_into( + url: &str, + path: &Path, + refs: &[(ObjectId, FullName)], + head: FullName, +) -> Result<(), BackfillGitError> { + let repo = if path.join("HEAD").exists() { + gix::open(path).map_err(gix::init::Error::Open) + } else { + gix::init_bare(path) + }?; + + let mut transport = gix_transport::client::blocking_io::connect::connect( + url, + gix_transport::client::blocking_io::connect::Options { + version: gix_transport::Protocol::V2, + ssh: Default::default(), + trace: false, + }, + )?; + + let mut progress = gix::progress::Discard; + let should_interrupt = AtomicBool::new(false); + + // TODO: cache per knot. We ignore `handshake.refs` which will be None for v2 protocol anyhow + let mut handshake = gix_protocol::handshake( + &mut transport, + gix_transport::Service::UploadPack, + // no auth + |_| Ok(None), + Default::default(), + &mut progress, + )?; + + let pack_dir = repo.path().join("objects").join("pack"); + let odb = repo.objects.clone(); + + let cache = repo.commit_graph_if_enabled().ok().flatten(); + let mut negotiate = StoredRefs { + repo: &repo, + wants: refs, + negotiator: gix_negotiate::Algorithm::Consecutive.into_negotiator(), + graph: repo.revision_graph(cache.as_ref()), + }; + + gix_protocol::fetch( + &mut negotiate, + |pack, progress, should_interrupt| { + gix_pack::Bundle::write_to_directory( + pack, + Some(&pack_dir), + progress, + should_interrupt, + Some(odb.clone()), + Default::default(), + ) + .map(|_| true) + }, + &mut progress, + &should_interrupt, + gix_protocol::fetch::Context { + handshake: &mut handshake, + transport: &mut transport, + user_agent: ("agent", Some(AGENT.into())), + trace_packetlines: false, + }, + gix_protocol::fetch::Options { + shallow_file: path.join("shallow"), + shallow: &gix_protocol::fetch::Shallow::NoChange, + tags: gix_protocol::fetch::Tags::None, + reject_shallow_remote: true, + }, + )?; + + let ref_edit = |name: FullName, new: Target| RefEdit { + change: Change::Update { + log: LogChange { + mode: RefLog::AndReference, + force_create_reflog: false, + message: "gitmirror: sync".into(), + }, + expected: PreviousValue::Any, + new, + }, + name, + deref: false, + }; + let edits = refs + .iter() + .map(|(oid, name)| ref_edit(name.clone(), Target::Object(*oid))) + .chain([ref_edit("HEAD".try_into().expect("valid ref name"), Target::Symbolic(head))]); + repo.edit_references(edits)?; + + debug!(refs = refs.len(), "fetched and updated refs"); + Ok(()) +} + +struct StoredRefs<'a, 'cache> { + repo: &'a gix::Repository, + wants: &'a [(ObjectId, FullName)], + negotiator: Box, + graph: gix_negotiate::Graph<'a, 'cache>, +} + +impl gix_protocol::fetch::Negotiate for StoredRefs<'_, '_> { + fn mark_complete_and_common_ref( + &mut self, + ) -> Result { + use gix::refs::file::ReferenceExt as _; + use gix_object::Exists as _; + use gix_protocol::fetch::negotiate::Action; + + let (repo, wants) = (self.repo, self.wants); + if wants.is_empty() { + return Ok(Action::NoChange); + } + + let known: Vec = wants + .iter() + .map(|(oid, _)| repo.objects.exists(oid)) + .collect(); + if known.iter().all(|k| *k) { + return Ok(Action::SkipToRefUpdate); + } + + for (oid, _) in wants.iter().zip(&known).filter_map(|(w, k)| k.then_some(w)) { + // TODO(boltless): load known commit to find max commit_time (used for cutoff_date) + self.negotiator.known_common(*oid, &mut self.graph)?; + } + + // TODO(boltless): walk parents back like + // [`gix_protocol::fetch::negotiate::mark_recent_complete_commits`] does. + let store = &repo.refs; + let packed = store.cached_packed_buffer()?; + let mut tips = Vec::new(); + for local_ref in store.iter()?.all()? { + let mut local_ref = local_ref?; + let id = local_ref.peel_to_id_packed( + store, + &repo.objects, + packed.as_ref().map(|b| &***b), + )?; + tips.push(id); + } + for tip in tips { + self.negotiator.add_tip(tip, &mut self.graph)?; + } + + Ok(Action::MustNegotiate { + remote_ref_target_known: known, + }) + } + + fn add_wants( + &mut self, + arguments: &mut gix_protocol::fetch::Arguments, + remote_ref_target_known: &[bool], + ) -> bool { + let mut has_want = false; + for (oid, _) in self + .wants + .iter() + .zip(remote_ref_target_known) + .filter_map(|(want, known)| (!known).then_some(want)) + { + arguments.want(oid); + has_want = true; + } + has_want + } + + fn one_round( + &mut self, + state: &mut gix_protocol::fetch::negotiate::one_round::State, + arguments: &mut gix_protocol::fetch::Arguments, + previous_response: Option<&gix_protocol::fetch::Response>, + ) -> Result<(gix_protocol::fetch::negotiate::Round, bool), gix_protocol::fetch::negotiate::Error> + { + gix_protocol::fetch::negotiate::one_round( + &mut *self.negotiator, + &mut self.graph, + state, + arguments, + previous_response, + ) + } +} diff --git a/gitmirror/crates/gitmirror-types/Cargo.toml b/gitmirror/crates/gitmirror-types/Cargo.toml new file mode 100644 index 000000000..63fe541fe --- /dev/null +++ b/gitmirror/crates/gitmirror-types/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "gitmirror-types" +version.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true + +[dependencies] +jacquard-common = { workspace = true } +bobbin-knot-proxy = { workspace = true } + +[lints] +workspace = true diff --git a/gitmirror/crates/gitmirror-types/src/jacquard_ext.rs b/gitmirror/crates/gitmirror-types/src/jacquard_ext.rs new file mode 100644 index 000000000..c0b8b7f7c --- /dev/null +++ b/gitmirror/crates/gitmirror-types/src/jacquard_ext.rs @@ -0,0 +1,29 @@ +use jacquard_common::Bos; +use jacquard_common::deps::fluent_uri::Uri; +use jacquard_common::types::did_doc::DidDocument; +use jacquard_common::types::string::AtprotoStr; +use jacquard_common::types::value::Data; + +const KNOT_SERVICE_TYPE: &str = "TangledKnot"; + +pub trait DidDocumentExt { + /// The `tangled_knot` service endpoint, if the document declares one. + fn knot_endpoint(&self) -> Option>; +} + +impl + AsRef + Clone> DidDocumentExt for DidDocument { + fn knot_endpoint(&self) -> Option> { + self.service.as_ref().and_then(|services| { + services.iter().find_map(|service| { + if service.r#type.as_ref() != KNOT_SERVICE_TYPE { + return None; + } + match &service.service_endpoint { + Some(Data::String(AtprotoStr::Uri(uri))) => Uri::parse(uri.as_ref()).ok(), + Some(Data::String(AtprotoStr::String(raw))) => Uri::parse(raw.as_ref()).ok(), + _ => None, + } + }) + }) + } +} diff --git a/gitmirror/crates/gitmirror-types/src/lib.rs b/gitmirror/crates/gitmirror-types/src/lib.rs new file mode 100644 index 000000000..a94cd7c6c --- /dev/null +++ b/gitmirror/crates/gitmirror-types/src/lib.rs @@ -0,0 +1,22 @@ +pub mod jacquard_ext; + +pub use bobbin_knot_proxy::KnotHost; + +#[derive(Debug, Clone, Copy)] +pub struct KnotPolicy { + pub allow_private: bool, + pub require_https: bool, +} + +impl KnotPolicy { + pub fn safe_knot_host(&self, endpoint: &str) -> Result { + let host = KnotHost::parse(endpoint).map_err(|_| "is not a usable base URL")?; + if self.require_https && host.url().scheme() != "https" { + return Err("is not https"); + } + if !self.allow_private && host.private_literal_reason().is_some() { + return Err("is a private address"); + } + Ok(host) + } +} diff --git a/gitmirror/crates/gitmirror/Cargo.toml b/gitmirror/crates/gitmirror/Cargo.toml index 81db28942..fe16aa5ec 100644 --- a/gitmirror/crates/gitmirror/Cargo.toml +++ b/gitmirror/crates/gitmirror/Cargo.toml @@ -11,6 +11,11 @@ path = "src/main.rs" [dependencies] bobbin-runtime = { workspace = true } +gitmirror-db = { workspace = true } +gitmirror-git = { workspace = true } +gitmirror-ingest = { workspace = true } +gitmirror-sync = { workspace = true } +gitmirror-types = { workspace = true } gitmirror-xrpc = { workspace = true } anyhow = { workspace = true } @@ -19,6 +24,7 @@ axum = { workspace = true } clap = { workspace = true } confique = { workspace = true } futures = { workspace = true } +hydrant = { workspace = true } jacquard-axum = { workspace = true } jacquard-common = { workspace = true } jacquard-identity = { workspace = true } diff --git a/gitmirror/crates/gitmirror/src/config.rs b/gitmirror/crates/gitmirror/src/config.rs index 7b822794b..e8ed53b8f 100644 --- a/gitmirror/crates/gitmirror/src/config.rs +++ b/gitmirror/crates/gitmirror/src/config.rs @@ -24,6 +24,13 @@ pub struct MirrorConfig { pub knot: KnotConfig, #[config(nested)] pub log: LogConfig, + + #[config(nested)] + pub database: DatabaseConfig, + #[config(nested)] + pub ingest: IngestConfig, + #[config(nested)] + pub sync: SyncConfig, } #[derive(Debug, Config)] @@ -44,6 +51,10 @@ pub struct ServerConfig { default = ["127.0.0.1:9091"] )] pub metrics_binds: Vec, + + /// Seconds to let the remaining task drain after the server or ingest stops before aborting it. + #[config(env = "GITMIRROR_SHUTDOWN_GRACE_SECS", default = 30)] + pub shutdown_grace_secs: u64, } // TODO: share codes with bobbin @@ -132,6 +143,39 @@ pub struct LogConfig { pub service_name: String, } +#[derive(Debug, Config)] +pub struct DatabaseConfig { + /// Postgres connection string, e.g. `postgres://user:pass@host/gitmirror`. + #[config(env = "GITMIRROR_DATABASE_URL")] + pub url: String, + + #[config(env = "GITMIRROR_DATABASE_MAX_CONNECTIONS", default = 16)] + pub max_connections: u32, +} + +#[derive(Debug, Config)] +pub struct IngestConfig { + /// Seconds between cursor checkpoints for stretches of events that touched no row. + #[config(env = "GITMIRROR_CHECKPOINT_INTERVAL_SECS", default = 10)] + pub checkpoint_interval_secs: u64, +} + +#[derive(Debug, Config)] +pub struct SyncConfig { + /// How many repositories may be fetched at once. + #[config(env = "GITMIRROR_SYNC_CONCURRENCY", default = 8)] + pub concurrency: usize, + + /// How many of those may target the same knot, so one slow host cannot take every slot. + #[config(env = "GITMIRROR_SYNC_PER_KNOT_CONCURRENCY", default = 4)] + pub per_knot_concurrency: usize, + + /// Seconds the sync worker waits before rescanning the queue when it found nothing to do. + /// Also the resolution at which a repo's `retry_after` comes due. + #[config(env = "GITMIRROR_SYNC_POLL_INTERVAL_SECS", default = 5)] + pub poll_interval_secs: u64, +} + pub fn load(path: Option<&PathBuf>) -> anyhow::Result { let mut builder = MirrorConfig::builder().env(); if let Some(p) = path { diff --git a/gitmirror/crates/gitmirror/src/main.rs b/gitmirror/crates/gitmirror/src/main.rs index 122c032a5..00b7d2b15 100644 --- a/gitmirror/crates/gitmirror/src/main.rs +++ b/gitmirror/crates/gitmirror/src/main.rs @@ -1,7 +1,7 @@ use std::{net::SocketAddr, path::PathBuf, process::ExitCode, sync::Arc, time::Duration}; use anyhow::{Context as _, anyhow}; -use bobbin_runtime::{ReqwestHttp, SystemClock}; +use bobbin_runtime::{Clock, ReqwestHttp, SystemClock}; use clap::{Parser, Subcommand}; use jacquard_axum::service_auth::ServiceAuthConfig; use jacquard_common::deps::fluent_uri::Uri; @@ -9,7 +9,10 @@ use jacquard_identity::{JacquardResolver, resolver::PlcSource}; use opentelemetry_appender_tracing::layer::{OpenTelemetryTracingBridge, TracingSpanAttributes}; use opentelemetry_otlp::{LogExporter, Protocol, WithExportConfig as _}; use opentelemetry_sdk::{Resource, logs::SdkLoggerProvider}; -use tokio::signal::unix::{SignalKind, signal}; +use tokio::{ + signal::unix::{SignalKind, signal}, + task::JoinSet, +}; use tokio_util::sync::CancellationToken; use tracing::level_filters::LevelFilter; use tracing_subscriber::{ @@ -19,6 +22,9 @@ use tracing_subscriber::{ mod config; use config::MirrorConfig; +use gitmirror_git::layout::Layout; +use gitmirror_ingest::{IngestRuntime, run as run_ingest}; +use gitmirror_sync::{BackfillWorker, Directory, SyncRuntime}; use gitmirror_xrpc::{AppState, KnotPolicy, router}; #[derive(Parser)] @@ -39,6 +45,12 @@ enum Command { /// Print a fully-commented TOML template to stdout. Use this to seed /// `config.toml` for a fresh deploy. ConfigTemplate, + #[command(flatten)] + Configured(ConfiguredCommand), +} + +#[derive(Subcommand)] +enum ConfiguredCommand { /// Load and validate the configuration without starting the server. Validate, /// Run the XRPC server. @@ -51,10 +63,13 @@ async fn main() -> ExitCode { let cli = Cli::parse(); - if let Command::ConfigTemplate = cli.command { - print!("{}", config::template()); - return ExitCode::SUCCESS; - } + let command = match cli.command { + Command::ConfigTemplate => { + print!("{}", config::template()); + return ExitCode::SUCCESS; + } + Command::Configured(command) => command, + }; let cfg = match config::load(cli.config.as_ref()) { Ok(c) => c, @@ -64,6 +79,7 @@ async fn main() -> ExitCode { } }; + // TODO: embed inside serve(). let logs = match init_tracing(&cfg) { Ok(logs) => logs, Err(e) => { @@ -72,20 +88,18 @@ async fn main() -> ExitCode { } }; - let code = match cli.command { - Command::Validate => { + let code = match command { + ConfiguredCommand::Validate => { println!("configuration is valid"); ExitCode::SUCCESS } - Command::Serve => match serve(cfg).await { + ConfiguredCommand::Serve => match serve(cfg).await { Ok(()) => ExitCode::SUCCESS, Err(e) => { tracing::error!(error = ?e, "fatal"); ExitCode::FAILURE } }, - // Handled before the config is loaded. - Command::ConfigTemplate => ExitCode::SUCCESS, }; if let Some(provider) = logs @@ -150,17 +164,35 @@ fn init_tracing(cfg: &MirrorConfig) -> Result, String> Ok(provider) } -async fn serve(cfg: MirrorConfig) -> anyhow::Result<()> { - let http = reqwest::Client::builder() +fn http_client() -> reqwest::Result { + reqwest::Client::builder() .connect_timeout(Duration::from_secs(10)) .timeout(Duration::from_mins(5)) - .build()?; - let directory = Arc::new( + .build() +} + +fn directory(http: &reqwest::Client, plc_url: &str) -> anyhow::Result> { + Ok(Arc::new( JacquardResolver::new(ReqwestHttp::new(http.clone()), Default::default()) - .with_plc_source(plc_source(&cfg.identity.plc_url)?), - ); - let service_auth = - ServiceAuthConfig::new(cfg.service_auth.did.clone(), directory).disable_replay_protection(); + .with_plc_source(plc_source(plc_url)?), + )) +} + +async fn serve(cfg: MirrorConfig) -> anyhow::Result<()> { + let db = gitmirror_db::Db::connect(&cfg.database.url, cfg.database.max_connections) + .await + .context("connect to postgres")?; + db.migrate().await.context("run migrations")?; + std::fs::create_dir_all(&cfg.repo.scan_path) + .with_context(|| format!("create {}", cfg.repo.scan_path.display()))?; + + let hydrant_cfg = hydrant::config::Config::from_env() + .map_err(|e| anyhow!("load hydrant configuration: {e}"))?; + + let http = http_client()?; + let directory = directory(&http, &cfg.identity.plc_url)?; + let service_auth = ServiceAuthConfig::new(cfg.service_auth.did.clone(), directory.clone()) + .disable_replay_protection(); let redis = cfg .redis .url @@ -172,6 +204,46 @@ async fn serve(cfg: MirrorConfig) -> anyhow::Result<()> { }) .transpose()?; + let clock: Arc = Arc::new(SystemClock::new()); + let cancel = CancellationToken::new(); + + let worker = BackfillWorker::new( + SyncRuntime { + db: db.clone(), + clock: clock.clone(), + cancel: cancel.clone(), + directory, + http: http.clone(), + layout: Layout::new(cfg.repo.scan_path.clone()), + knot_policy: gitmirror_types::KnotPolicy { + allow_private: cfg.knot.allow_private, + require_https: cfg.knot.require_https, + }, + }, + gitmirror_sync::SyncConfig { + concurrency: cfg.sync.concurrency, + per_knot_concurrency: cfg.sync.per_knot_concurrency, + poll_interval: Duration::from_secs(cfg.sync.poll_interval_secs), + }, + ); + let ingest_cfg = gitmirror_ingest::IngestConfig { + hydrant: hydrant_cfg, + checkpoint_interval: Duration::from_secs(cfg.ingest.checkpoint_interval_secs), + }; + let ingest_runtime = IngestRuntime { + db, + clock: clock.clone(), + cancel: cancel.clone(), + }; + let mut tasks = JoinSet::new(); + tasks.spawn(async move { + let res = run_ingest(ingest_cfg, ingest_runtime).await; + ("ingest", res.map_err(anyhow::Error::from)) + }); + tasks.spawn(async move { ("sync", worker.run().await.map_err(anyhow::Error::from)) }); + + // TODO: run indexer + let max_blob_bytes = cfg.repo.max_blob_bytes; let max_archive_bytes = cfg.repo.max_archive_bytes; let state = AppState::new( @@ -182,7 +254,7 @@ async fn serve(cfg: MirrorConfig) -> anyhow::Result<()> { allow_private: cfg.knot.allow_private, require_https: cfg.knot.require_https, }, - Arc::new(SystemClock::new()), + clock.clone(), redis, max_blob_bytes, max_archive_bytes, @@ -209,7 +281,33 @@ async fn serve(cfg: MirrorConfig) -> anyhow::Result<()> { .map(|addr| (addr, gitmirror_xrpc::metrics::router())), ); - serve_all(targets).await + let server_cancel = cancel.clone(); + tasks.spawn(async move { ("server", serve_all(targets, server_cancel).await) }); + + let first = tasks.join_next().await.expect("tasks is not empty"); + let was_cancelled = cancel.is_cancelled(); + cancel.cancel(); + + let grace = Duration::from_secs(cfg.server.shutdown_grace_secs); + tracing::info!(grace_secs = grace.as_secs(), "draining tasks"); + tokio::select! { + () = async { while tasks.join_next().await.is_some() {} } => {} + () = clock.sleep(grace) => { + tracing::warn!( + grace_secs = grace.as_secs(), + remaining = tasks.len(), + "tasks did not stop within grace, aborting" + ); + tasks.abort_all(); + } + } + + match first { + Ok((_, Ok(()))) if was_cancelled => Ok(()), + Ok((name, Ok(()))) => Err(anyhow!("{name} exited unexpectedly")), + Ok((name, Err(e))) => Err(e.context(format!("{name} failed"))), + Err(join) => Err(anyhow!("task panicked: {join}")), + } } fn bind_display(binds: &[SocketAddr]) -> String { @@ -220,7 +318,10 @@ fn bind_display(binds: &[SocketAddr]) -> String { .join(",") } -async fn serve_all(targets: Vec<(SocketAddr, axum::Router)>) -> anyhow::Result<()> { +async fn serve_all( + targets: Vec<(SocketAddr, axum::Router)>, + cancel: CancellationToken, +) -> anyhow::Result<()> { let listeners = targets .into_iter() .map(|(addr, app)| { @@ -230,7 +331,6 @@ async fn serve_all(targets: Vec<(SocketAddr, axum::Router)>) -> anyhow::Result<( }) .collect::>>()?; - let cancel = CancellationToken::new(); let trigger = cancel.clone(); let signal_task = tokio::spawn(async move { wait_for_shutdown().await; diff --git a/localinfra/gitmirror.Dockerfile b/localinfra/gitmirror.Dockerfile index f9a392fda..e252d44e6 100644 --- a/localinfra/gitmirror.Dockerfile +++ b/localinfra/gitmirror.Dockerfile @@ -5,6 +5,8 @@ FROM rust:1.96-bookworm AS build WORKDIR /src COPY . . +ENV SQLX_OFFLINE=true + # Cache mounts on the cargo registry + target dir. The binary is copied out within the same # RUN because the target cache mount is unmounted afterwards (a later COPY --from could not # see it). diff --git a/localinfra/postgres-init.sql b/localinfra/postgres-init.sql index bd6c0ed8c..13fa0c63e 100644 --- a/localinfra/postgres-init.sql +++ b/localinfra/postgres-init.sql @@ -1,4 +1,5 @@ CREATE DATABASE plc; CREATE DATABASE mirror; CREATE DATABASE mirror_tap; +CREATE DATABASE gitmirror; CREATE DATABASE tranquil; diff --git a/nix/Cargo.nix b/nix/Cargo.nix index 68bce476e..9375583e2 100644 --- a/nix/Cargo.nix +++ b/nix/Cargo.nix @@ -193,6 +193,16 @@ rec { # File a bug if you depend on any for non-debug work! debug = internal.debugCrate { inherit packageId; }; }; + "gitmirror-db" = rec { + packageId = "gitmirror-db"; + build = internal.buildRustCrateWithFeatures { + packageId = "gitmirror-db"; + }; + + # Debug support which might change between releases. + # File a bug if you depend on any for non-debug work! + debug = internal.debugCrate { inherit packageId; }; + }; "gitmirror-git" = rec { packageId = "gitmirror-git"; build = internal.buildRustCrateWithFeatures { @@ -213,6 +223,16 @@ rec { # File a bug if you depend on any for non-debug work! debug = internal.debugCrate { inherit packageId; }; }; + "gitmirror-sync" = rec { + packageId = "gitmirror-sync"; + build = internal.buildRustCrateWithFeatures { + packageId = "gitmirror-sync"; + }; + + # Debug support which might change between releases. + # File a bug if you depend on any for non-debug work! + debug = internal.debugCrate { inherit packageId; }; + }; "gitmirror-xrpc" = rec { packageId = "gitmirror-xrpc"; build = internal.buildRustCrateWithFeatures { @@ -651,6 +671,36 @@ rec { # inject test dependencies into the build crates = { + "addr2line" = rec { + crateName = "addr2line"; + version = "0.25.1"; + edition = "2018"; + crateBin = []; + sha256 = "0jwb96gv17vdr29hbzi0ha5q6jkpgjyn7rjlg5nis65k41rk0p8v"; + dependencies = [ + { + name = "gimli"; + packageId = "gimli"; + usesDefaultFeatures = false; + features = [ "read" ]; + } + ]; + features = { + "all" = [ "bin" "wasm" ]; + "alloc" = [ "dep:alloc" ]; + "bin" = [ "loader" "rustc-demangle" "cpp_demangle" "fallible-iterator" "smallvec" "dep:clap" ]; + "core" = [ "dep:core" ]; + "cpp_demangle" = [ "dep:cpp_demangle" ]; + "default" = [ "rustc-demangle" "cpp_demangle" "loader" "fallible-iterator" "smallvec" ]; + "fallible-iterator" = [ "dep:fallible-iterator" ]; + "loader" = [ "std" "dep:object" "dep:memmap2" "dep:typed-arena" ]; + "rustc-demangle" = [ "dep:rustc-demangle" ]; + "rustc-dep-of-std" = [ "core" "alloc" "gimli/rustc-dep-of-std" ]; + "smallvec" = [ "dep:smallvec" ]; + "std" = [ "gimli/std" ]; + "wasm" = [ "object/wasm" ]; + }; + }; "adler2" = rec { crateName = "adler2"; version = "2.0.1"; @@ -1972,6 +2022,27 @@ rec { }; resolvedDefaultFeatures = [ "aws-lc-rs" "tls12" ]; }; + "atoi" = rec { + crateName = "atoi"; + version = "2.0.0"; + edition = "2021"; + sha256 = "0a05h42fggmy7h0ajjv6m7z72l924i7igbx13hk9d8pyign9k3gj"; + authors = [ + "Markus Klein" + ]; + dependencies = [ + { + name = "num-traits"; + packageId = "num-traits"; + usesDefaultFeatures = false; + } + ]; + features = { + "default" = [ "std" ]; + "std" = [ "num-traits/std" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; "atomic-polyfill" = rec { crateName = "atomic-polyfill"; version = "1.0.3"; @@ -2481,6 +2552,144 @@ rec { }; resolvedDefaultFeatures = [ "default" ]; }; + "axum-tws" = rec { + crateName = "axum-tws"; + version = "0.6.0"; + edition = "2021"; + sha256 = "1m6nm4q9w4f92rraikczln5f03wd43xbn8swqlr9dbv0glg5rgq8"; + libName = "axum_tws"; + authors = [ + "Rob Wagner " + ]; + dependencies = [ + { + name = "axum-core"; + packageId = "axum-core"; + } + { + name = "base64"; + packageId = "base64"; + } + { + name = "bytes"; + packageId = "bytes"; + } + { + name = "futures-util"; + packageId = "futures-util"; + features = [ "sink" ]; + } + { + name = "http"; + packageId = "http"; + } + { + name = "hyper"; + packageId = "hyper"; + } + { + name = "hyper-util"; + packageId = "hyper-util"; + features = [ "tokio" ]; + } + { + name = "sha1_smol"; + packageId = "sha1_smol"; + } + { + name = "tokio"; + packageId = "tokio"; + usesDefaultFeatures = false; + } + { + name = "tokio-websockets"; + packageId = "tokio-websockets"; + features = [ "server" "sha1_smol" ]; + } + ]; + devDependencies = [ + { + name = "tokio"; + packageId = "tokio"; + features = [ "rt" "macros" ]; + } + ]; + features = { + "http2" = [ "hyper/http2" ]; + }; + resolvedDefaultFeatures = [ "default" ]; + }; + "backtrace" = rec { + crateName = "backtrace"; + version = "0.3.76"; + edition = "2021"; + sha256 = "1mibx75x4jf6wz7qjifynld3hpw3vq6sy3d3c9y5s88sg59ihlxv"; + authors = [ + "The Rust Project Developers" + ]; + dependencies = [ + { + name = "addr2line"; + packageId = "addr2line"; + usesDefaultFeatures = false; + target = { target, features }: (!((target."windows" or false) && ("msvc" == target."env" or null) && (!("uwp" == target."vendor" or null)))); + } + { + name = "cfg-if"; + packageId = "cfg-if"; + } + { + name = "libc"; + packageId = "libc"; + usesDefaultFeatures = false; + target = { target, features }: (!((target."windows" or false) && ("msvc" == target."env" or null) && (!("uwp" == target."vendor" or null)))); + } + { + name = "miniz_oxide"; + packageId = "miniz_oxide"; + usesDefaultFeatures = false; + target = { target, features }: (!((target."windows" or false) && ("msvc" == target."env" or null) && (!("uwp" == target."vendor" or null)))); + } + { + name = "object"; + packageId = "object"; + usesDefaultFeatures = false; + target = { target, features }: (!((target."windows" or false) && ("msvc" == target."env" or null) && (!("uwp" == target."vendor" or null)))); + features = [ "read_core" "elf" "macho" "pe" "xcoff" "unaligned" "archive" ]; + } + { + name = "rustc-demangle"; + packageId = "rustc-demangle"; + } + { + name = "windows-link"; + packageId = "windows-link"; + target = { target, features }: ((target."windows" or false) || ("cygwin" == target."os" or null)); + } + ]; + features = { + "cpp_demangle" = [ "dep:cpp_demangle" ]; + "default" = [ "std" ]; + "ruzstd" = [ "dep:ruzstd" ]; + "serde" = [ "dep:serde" ]; + "serialize-serde" = [ "serde" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; + "backtrace-ext" = rec { + crateName = "backtrace-ext"; + version = "0.2.1"; + edition = "2018"; + sha256 = "0l4xacjnx4jrn9k14xbs2swks018mviq03sp7c1gn62apviywysk"; + libName = "backtrace_ext"; + dependencies = [ + { + name = "backtrace"; + packageId = "backtrace"; + } + ]; + + }; "base-x" = rec { crateName = "base-x"; version = "0.2.11"; @@ -2719,13 +2928,21 @@ rec { authors = [ "The Rust Project Developers" ]; + dependencies = [ + { + name = "serde_core"; + packageId = "serde_core"; + optional = true; + usesDefaultFeatures = false; + } + ]; features = { "arbitrary" = [ "dep:arbitrary" ]; "bytemuck" = [ "dep:bytemuck" ]; "serde" = [ "serde_core" ]; "serde_core" = [ "dep:serde_core" ]; }; - resolvedDefaultFeatures = [ "std" ]; + resolvedDefaultFeatures = [ "serde" "serde_core" "std" ]; }; "bitpacking" = rec { crateName = "bitpacking"; @@ -4466,6 +4683,17 @@ rec { }; resolvedDefaultFeatures = [ "default" "std" ]; }; + "byteorder-lite" = rec { + crateName = "byteorder-lite"; + version = "0.1.0"; + edition = "2021"; + sha256 = "15alafmz4b9az56z6x7glcbcb6a8bfgyd109qc3bvx07zx4fj7wg"; + libName = "byteorder_lite"; + features = { + "default" = [ "std" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; "bytes" = rec { crateName = "bytes"; version = "1.12.0"; @@ -4508,6 +4736,16 @@ rec { }; resolvedDefaultFeatures = [ "default" "std" ]; }; + "byteview" = rec { + crateName = "byteview"; + version = "0.10.2"; + edition = "2021"; + sha256 = "1xxrn4db950qj88i14i1h3yx09bpzyl2ry068acdaqg7jmw96x0d"; + features = { + "serde" = [ "dep:serde" ]; + }; + resolvedDefaultFeatures = [ "default" ]; + }; "cast" = rec { crateName = "cast"; version = "0.3.0"; @@ -5314,6 +5552,17 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "bytes" "default" "futures-core-03" "pin-project-lite" "std" "tokio" "tokio-dep" "tokio-util" ]; }; + "compare" = rec { + crateName = "compare"; + version = "0.0.6"; + edition = "2015"; + sha256 = "19wbyirhcgl3c01r889fy3msy7c01jb1bzfnmi28naiw23v9a07a"; + authors = [ + "Alexis Beingessner " + "Andrew Paseltiner " + ]; + + }; "compression-codecs" = rec { crateName = "compression-codecs"; version = "0.4.38"; @@ -5784,6 +6033,34 @@ rec { } ]; + }; + "crc" = rec { + crateName = "crc"; + version = "3.4.0"; + edition = "2021"; + sha256 = "03dsq5qsv86m35ikg84l80d00wnkjm8q4pjxgac0vaqjrnhs5f2y"; + authors = [ + "Rui Hu " + "Akhil Velagapudi <4@4khil.com>" + ]; + dependencies = [ + { + name = "crc-catalog"; + packageId = "crc-catalog"; + } + ]; + + }; + "crc-catalog" = rec { + crateName = "crc-catalog"; + version = "2.5.0"; + edition = "2018"; + sha256 = "0lq8dl60g457za8la86pak6i7ydxanm2lrpkqh5kyjkbz7m9hxi1"; + libName = "crc_catalog"; + authors = [ + "Akhil Velagapudi " + ]; + }; "crc32fast" = rec { crateName = "crc32fast"; @@ -5993,6 +6270,51 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "default" "std" ]; }; + "crossbeam-queue" = rec { + crateName = "crossbeam-queue"; + version = "0.3.14"; + edition = "2021"; + sha256 = "1bizbcv98anbink3gr3xhnb757d9vj6pcv7df2f4hybl5xvbvs03"; + libName = "crossbeam_queue"; + dependencies = [ + { + name = "crossbeam-utils"; + packageId = "crossbeam-utils"; + usesDefaultFeatures = false; + } + ]; + features = { + "default" = [ "std" ]; + "nightly" = [ "crossbeam-utils/nightly" ]; + "std" = [ "alloc" "crossbeam-utils/std" ]; + }; + resolvedDefaultFeatures = [ "alloc" "default" "std" ]; + }; + "crossbeam-skiplist" = rec { + crateName = "crossbeam-skiplist"; + version = "0.1.3"; + edition = "2021"; + sha256 = "06qmzagqmrv4zwmrvppv6lja6lbm6hi3vv47wp32rjjq1i2dwafz"; + libName = "crossbeam_skiplist"; + dependencies = [ + { + name = "crossbeam-epoch"; + packageId = "crossbeam-epoch"; + usesDefaultFeatures = false; + } + { + name = "crossbeam-utils"; + packageId = "crossbeam-utils"; + usesDefaultFeatures = false; + } + ]; + features = { + "alloc" = [ "crossbeam-epoch/alloc" ]; + "default" = [ "std" ]; + "std" = [ "alloc" "crossbeam-epoch/std" "crossbeam-utils/std" ]; + }; + resolvedDefaultFeatures = [ "alloc" "default" "std" ]; + }; "crossbeam-utils" = rec { crateName = "crossbeam-utils"; version = "0.8.21"; @@ -7529,6 +7851,27 @@ rec { ]; }; + "dotenvy" = rec { + crateName = "dotenvy"; + version = "0.15.7"; + edition = "2018"; + crateBin = []; + sha256 = "16s3n973n5aqym02692i1npb079n5mb0fwql42ikmwn8wnrrbbqs"; + authors = [ + "Noemi Lapresta " + "Craig Hills " + "Mike Piccolo " + "Alice Maz " + "Sean Griffin " + "Adam Sharp " + "Arpad Borsos " + "Allan Zhang " + ]; + features = { + "clap" = [ "dep:clap" ]; + "cli" = [ "clap" ]; + }; + }; "downcast-rs" = rec { crateName = "downcast-rs"; version = "2.0.2"; @@ -7943,12 +8286,21 @@ rec { version = "1.17.0"; edition = "2021"; sha256 = "07dagpwcfdzpkb1n7fxkx0q3nv80rnf81v7gwlz9ljx22mn8yply"; + dependencies = [ + { + name = "serde"; + packageId = "serde"; + optional = true; + usesDefaultFeatures = false; + features = [ "alloc" "derive" ]; + } + ]; features = { "default" = [ "std" ]; "serde" = [ "dep:serde" ]; "use_std" = [ "std" ]; }; - resolvedDefaultFeatures = [ "default" "std" "use_std" ]; + resolvedDefaultFeatures = [ "default" "serde" "std" "use_std" ]; }; "elliptic-curve 0.13.8" = rec { crateName = "elliptic-curve"; @@ -8369,6 +8721,25 @@ rec { }; resolvedDefaultFeatures = [ "default" "std" ]; }; + "etcetera" = rec { + crateName = "etcetera"; + version = "0.11.0"; + edition = "2024"; + sha256 = "15myc4rl62iah8acdl1sxmrdxb8ci55zbphrv07s55qx3i6wqj6y"; + dependencies = [ + { + name = "cfg-if"; + packageId = "cfg-if"; + } + { + name = "windows-sys"; + packageId = "windows-sys 0.61.2"; + target = { target, features }: (target."windows" or false); + features = [ "Win32_Foundation" "Win32_System_Com" "Win32_UI_Shell" ]; + } + ]; + + }; "event-listener" = rec { crateName = "event-listener"; version = "5.4.1"; @@ -8693,6 +9064,74 @@ rec { "serde" = [ "dep:serde" ]; }; }; + "fjall" = rec { + crateName = "fjall"; + version = "3.1.8"; + edition = "2021"; + workspace_member = null; + src = pkgs.fetchgit { + url = "https://github.com/90-008/fjall.git"; + rev = "85a8ad9b3d327c39263cc547fa9944e7535e802f"; + sha256 = "0cn23s3d9vrqz34xs50c2cxb4azr1fqv52fyh349hykfpa0apkzh"; + }; + dependencies = [ + { + name = "byteorder-lite"; + packageId = "byteorder-lite"; + rename = "byteorder"; + } + { + name = "byteview"; + packageId = "byteview"; + } + { + name = "dashmap"; + packageId = "dashmap"; + } + { + name = "flume"; + packageId = "flume"; + usesDefaultFeatures = false; + } + { + name = "log"; + packageId = "log"; + } + { + name = "lsm-tree"; + packageId = "lsm-tree"; + usesDefaultFeatures = false; + } + { + name = "lz4_flex"; + packageId = "lz4_flex"; + optional = true; + } + { + name = "tempfile"; + packageId = "tempfile"; + } + { + name = "xxhash-rust"; + packageId = "xxhash-rust"; + features = [ "xxh3" ]; + } + { + name = "zstd"; + packageId = "zstd"; + optional = true; + usesDefaultFeatures = false; + } + ]; + features = { + "bytes_1" = [ "lsm-tree/bytes_1" ]; + "default" = [ "lz4" ]; + "lz4" = [ "lsm-tree/lz4" "dep:lz4_flex" ]; + "metrics" = [ "lsm-tree/metrics" ]; + "zstd" = [ "lsm-tree/zstd" "dep:zstd" ]; + }; + resolvedDefaultFeatures = [ "default" "lz4" "zstd" ]; + }; "flate2" = rec { crateName = "flate2"; version = "1.1.9"; @@ -8784,6 +9223,44 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "default" "impl-error" "serde" "std" ]; }; + "flume" = rec { + crateName = "flume"; + version = "0.12.0"; + edition = "2018"; + sha256 = "1gnk7gji9r12ig35czj2cq441zf5ijmz0bgnz9gfnxx7dk29n4sy"; + authors = [ + "Joshua Barretto " + ]; + dependencies = [ + { + name = "futures-core"; + packageId = "futures-core"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "futures-sink"; + packageId = "futures-sink"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "spin"; + packageId = "spin 0.9.8"; + rename = "spin1"; + features = [ "mutex" ]; + } + ]; + features = { + "async" = [ "futures-sink" "futures-core" ]; + "default" = [ "async" "select" "eventual-fairness" ]; + "eventual-fairness" = [ "select" "fastrand" ]; + "fastrand" = [ "dep:fastrand" ]; + "futures-core" = [ "dep:futures-core" ]; + "futures-sink" = [ "dep:futures-sink" ]; + }; + resolvedDefaultFeatures = [ "async" "futures-core" "futures-sink" ]; + }; "fnv" = rec { crateName = "fnv"; version = "1.0.7"; @@ -9111,6 +9588,39 @@ rec { }; resolvedDefaultFeatures = [ "default" "std" ]; }; + "futures-intrusive" = rec { + crateName = "futures-intrusive"; + version = "0.5.0"; + edition = "2018"; + sha256 = "0vwm08d1pli6bdaj0i7xhk3476qlx4pll6i0w03gzdnh7lh0r4qx"; + libName = "futures_intrusive"; + authors = [ + "Matthias Einwag " + ]; + dependencies = [ + { + name = "futures-core"; + packageId = "futures-core"; + usesDefaultFeatures = false; + } + { + name = "lock_api"; + packageId = "lock_api"; + } + { + name = "parking_lot"; + packageId = "parking_lot"; + optional = true; + } + ]; + features = { + "alloc" = [ "futures-core/alloc" ]; + "default" = [ "std" ]; + "parking_lot" = [ "dep:parking_lot" ]; + "std" = [ "alloc" "parking_lot" ]; + }; + resolvedDefaultFeatures = [ "alloc" "default" "parking_lot" "std" ]; + }; "futures-io" = rec { crateName = "futures-io"; version = "0.3.32"; @@ -9805,6 +10315,23 @@ rec { "zeroize" = [ "polyval/zeroize" "dep:zeroize" ]; }; }; + "gimli" = rec { + crateName = "gimli"; + version = "0.32.3"; + edition = "2018"; + sha256 = "1iqk5xznimn5bfa8jy4h7pa1dv3c624hzgd2dkz8mpgkiswvjag6"; + features = { + "default" = [ "read-all" "write" ]; + "endian-reader" = [ "read" "dep:stable_deref_trait" ]; + "fallible-iterator" = [ "dep:fallible-iterator" ]; + "read" = [ "read-core" ]; + "read-all" = [ "read" "std" "fallible-iterator" "endian-reader" ]; + "rustc-dep-of-std" = [ "dep:core" "dep:alloc" ]; + "std" = [ "fallible-iterator?/std" "stable_deref_trait?/std" ]; + "write" = [ "dep:indexmap" ]; + }; + resolvedDefaultFeatures = [ "read" "read-core" ]; + }; "gitmirror" = rec { crateName = "gitmirror"; version = "0.0.1"; @@ -9850,10 +10377,32 @@ rec { name = "futures"; packageId = "futures"; } + { + name = "gitmirror-db"; + packageId = "gitmirror-db"; + } + { + name = "gitmirror-git"; + packageId = "gitmirror-git"; + } + { + name = "gitmirror-ingest"; + packageId = "gitmirror-ingest"; + } + { + name = "gitmirror-sync"; + packageId = "gitmirror-sync"; + } { name = "gitmirror-xrpc"; packageId = "gitmirror-xrpc"; } + { + name = "hydrant"; + packageId = "hydrant"; + usesDefaultFeatures = false; + features = [ "indexer_stream" ]; + } { name = "jacquard-axum"; packageId = "jacquard-axum"; @@ -9931,6 +10480,41 @@ rec { } ]; + }; + "gitmirror-db" = rec { + crateName = "gitmirror-db"; + version = "0.0.1"; + edition = "2024"; + src = lib.cleanSourceWith { filter = sourceFilter; src = ../gitmirror/crates/gitmirror-db; }; + libName = "gitmirror_db"; + dependencies = [ + { + name = "jacquard-common"; + packageId = "jacquard-common"; + } + { + name = "sqlx"; + packageId = "sqlx"; + usesDefaultFeatures = false; + features = [ "runtime-tokio" "tls-rustls-aws-lc-rs" "postgres" "chrono" "macros" "migrate" ]; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + } + { + name = "tracing"; + packageId = "tracing"; + } + ]; + devDependencies = [ + { + name = "tokio"; + packageId = "tokio"; + features = [ "macros" "rt-multi-thread" "time" "signal" "io-util" "net" "sync" "macros" "rt-multi-thread" ]; + } + ]; + }; "gitmirror-git" = rec { crateName = "gitmirror-git"; @@ -9973,6 +10557,125 @@ rec { edition = "2024"; src = lib.cleanSourceWith { filter = sourceFilter; src = ../gitmirror/crates/gitmirror-ingest; }; libName = "gitmirror_ingest"; + dependencies = [ + { + name = "bobbin-runtime"; + packageId = "bobbin-runtime"; + } + { + name = "gitmirror-db"; + packageId = "gitmirror-db"; + } + { + name = "hydrant"; + packageId = "hydrant"; + usesDefaultFeatures = false; + features = [ "indexer_stream" ]; + } + { + name = "jacquard-common"; + packageId = "jacquard-common"; + } + { + name = "lexicons"; + packageId = "lexicons"; + } + { + name = "serde_json"; + packageId = "serde_json"; + features = [ "raw_value" ]; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + } + { + name = "tokio"; + packageId = "tokio"; + features = [ "macros" "rt-multi-thread" "time" "signal" "io-util" "net" "sync" ]; + } + { + name = "tokio-util"; + packageId = "tokio-util"; + features = [ "rt" ]; + } + { + name = "tracing"; + packageId = "tracing"; + } + ]; + + }; + "gitmirror-sync" = rec { + crateName = "gitmirror-sync"; + version = "0.0.1"; + edition = "2024"; + src = lib.cleanSourceWith { filter = sourceFilter; src = ../gitmirror/crates/gitmirror-sync; }; + libName = "gitmirror_sync"; + dependencies = [ + { + name = "bobbin-runtime"; + packageId = "bobbin-runtime"; + } + { + name = "gitmirror-db"; + packageId = "gitmirror-db"; + } + { + name = "gitmirror-git"; + packageId = "gitmirror-git"; + } + { + name = "jacquard-common"; + packageId = "jacquard-common"; + } + { + name = "jacquard-identity"; + packageId = "jacquard-identity"; + features = [ "cache" ]; + } + { + name = "reqwest"; + packageId = "reqwest 0.13.1"; + usesDefaultFeatures = false; + features = [ "rustls" "http2" "json" "gzip" "stream" ]; + } + { + name = "scc"; + packageId = "scc"; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + } + { + name = "tokio"; + packageId = "tokio"; + features = [ "macros" "rt-multi-thread" "time" "signal" "io-util" "net" "sync" ]; + } + { + name = "tokio-util"; + packageId = "tokio-util"; + features = [ "rt" ]; + } + { + name = "tracing"; + packageId = "tracing"; + } + { + name = "url"; + packageId = "url"; + features = [ "serde" ]; + } + ]; + devDependencies = [ + { + name = "sqlx"; + packageId = "sqlx"; + usesDefaultFeatures = false; + features = [ "runtime-tokio" "tls-rustls-aws-lc-rs" "postgres" "chrono" "macros" "migrate" ]; + } + ]; }; "gitmirror-xrpc" = rec { @@ -14347,7 +15050,7 @@ rec { "serde" = [ "dep:serde" ]; "std" = [ "alloc" ]; }; - resolvedDefaultFeatures = [ "alloc" ]; + resolvedDefaultFeatures = [ "alloc" "default" "std" ]; }; "hex-literal" = rec { crateName = "hex-literal"; @@ -14360,7 +15063,137 @@ rec { ]; }; - "hickory-proto" = rec { + "hickory-net" = rec { + crateName = "hickory-net"; + version = "0.26.3"; + edition = "2021"; + sha256 = "0k8aiqpz5p2q46adqhpcc372k062nyv0q0j1kkqd1if2swz85064"; + libName = "hickory_net"; + authors = [ + "The contributors to Hickory DNS" + ]; + dependencies = [ + { + name = "async-trait"; + packageId = "async-trait"; + } + { + name = "cfg-if"; + packageId = "cfg-if"; + } + { + name = "data-encoding"; + packageId = "data-encoding"; + usesDefaultFeatures = false; + features = [ "alloc" ]; + } + { + name = "futures-channel"; + packageId = "futures-channel"; + usesDefaultFeatures = false; + features = [ "alloc" "std" ]; + } + { + name = "futures-io"; + packageId = "futures-io"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "futures-util"; + packageId = "futures-util"; + usesDefaultFeatures = false; + features = [ "alloc" "async-await-macro" "std" ]; + } + { + name = "hickory-proto"; + packageId = "hickory-proto 0.26.3"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "idna"; + packageId = "idna"; + usesDefaultFeatures = false; + features = [ "alloc" "compiled_data" ]; + } + { + name = "ipnet"; + packageId = "ipnet"; + usesDefaultFeatures = false; + } + { + name = "jni"; + packageId = "jni 0.22.4"; + target = { target, features }: ("android" == target."os" or null); + } + { + name = "rand"; + packageId = "rand 0.10.1"; + usesDefaultFeatures = false; + features = [ "alloc" "std_rng" ]; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + usesDefaultFeatures = false; + } + { + name = "tinyvec"; + packageId = "tinyvec"; + features = [ "alloc" ]; + } + { + name = "tokio"; + packageId = "tokio"; + optional = true; + features = [ "io-util" "macros" ]; + } + { + name = "tracing"; + packageId = "tracing"; + usesDefaultFeatures = false; + } + { + name = "url"; + packageId = "url"; + usesDefaultFeatures = false; + } + ]; + devDependencies = [ + { + name = "tokio"; + packageId = "tokio"; + features = [ "rt" "time" "macros" "test-util" ]; + } + ]; + features = { + "__dnssec" = [ "dep:bitflags" "dep:rustls-pki-types" "dep:time" "dep:lru-cache" "dep:parking_lot" ]; + "__h3" = [ "dep:h3" "dep:h3-quinn" "dep:http" ]; + "__https" = [ "dep:bytes" "dep:h2" "dep:http" ]; + "__quic" = [ "dep:bytes" "dep:pin-project-lite" "dep:quinn" ]; + "__tls" = [ "dep:bytes" "dep:rustls" "dep:tokio-rustls" "tokio" ]; + "default" = [ "tokio" ]; + "dnssec-aws-lc-rs" = [ "dep:aws-lc-rs" "aws-lc-rs/aws-lc-sys" "aws-lc-rs/ring-io" "hickory-proto/dnssec-aws-lc-rs" "__dnssec" ]; + "dnssec-ring" = [ "dep:ring" "hickory-proto/dnssec-ring" "__dnssec" ]; + "h3-aws-lc-rs" = [ "quic-aws-lc-rs" "__h3" ]; + "h3-ring" = [ "quic-ring" "__h3" ]; + "https-aws-lc-rs" = [ "tls-aws-lc-rs" "__https" ]; + "https-ring" = [ "tls-ring" "__https" ]; + "mdns" = [ "socket2/all" ]; + "quic-aws-lc-rs" = [ "quinn/rustls-aws-lc-rs" "tls-aws-lc-rs" "__quic" ]; + "quic-ring" = [ "quinn/rustls-ring" "tls-ring" "__quic" ]; + "rustls-platform-verifier" = [ "dep:rustls-platform-verifier" ]; + "serde" = [ "dep:serde" "url/serde" ]; + "socket2" = [ "dep:socket2" ]; + "tls-aws-lc-rs" = [ "tokio-rustls/aws-lc-rs" "__tls" ]; + "tls-ring" = [ "tokio-rustls/ring" "__tls" ]; + "tokio" = [ "dep:tokio" "tokio/net" "tokio/rt" "tokio/time" "tokio/rt-multi-thread" ]; + "webpki-roots" = [ "dep:webpki-roots" ]; + }; + resolvedDefaultFeatures = [ "tokio" ]; + }; + "hickory-proto 0.24.4" = rec { crateName = "hickory-proto"; version = "0.24.4"; edition = "2021"; @@ -14491,7 +15324,97 @@ rec { }; resolvedDefaultFeatures = [ "tokio" "tokio-runtime" ]; }; - "hickory-resolver" = rec { + "hickory-proto 0.26.3" = rec { + crateName = "hickory-proto"; + version = "0.26.3"; + edition = "2021"; + sha256 = "0gc9hajcpby7834a400j75p04hwlz0gmrlfibm8zm9kryq42df8j"; + libName = "hickory_proto"; + authors = [ + "The contributors to Hickory DNS" + ]; + dependencies = [ + { + name = "data-encoding"; + packageId = "data-encoding"; + usesDefaultFeatures = false; + features = [ "alloc" ]; + } + { + name = "idna"; + packageId = "idna"; + usesDefaultFeatures = false; + features = [ "alloc" "compiled_data" ]; + } + { + name = "ipnet"; + packageId = "ipnet"; + usesDefaultFeatures = false; + } + { + name = "jni"; + packageId = "jni 0.22.4"; + target = { target, features }: ("android" == target."os" or null); + } + { + name = "once_cell"; + packageId = "once_cell"; + usesDefaultFeatures = false; + features = [ "critical-section" ]; + } + { + name = "prefix-trie"; + packageId = "prefix-trie"; + optional = true; + } + { + name = "rand"; + packageId = "rand 0.10.1"; + usesDefaultFeatures = false; + features = [ "alloc" "std_rng" ]; + } + { + name = "ring"; + packageId = "ring"; + optional = true; + features = [ "std" ]; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + usesDefaultFeatures = false; + } + { + name = "tinyvec"; + packageId = "tinyvec"; + features = [ "alloc" ]; + } + { + name = "tracing"; + packageId = "tracing"; + usesDefaultFeatures = false; + } + { + name = "url"; + packageId = "url"; + usesDefaultFeatures = false; + } + ]; + features = { + "__dnssec" = [ "dep:bitflags" "dep:rustls-pki-types" "dep:time" "std" ]; + "access-control" = [ "std" "dep:prefix-trie" ]; + "default" = [ "std" ]; + "dnssec-aws-lc-rs" = [ "dep:aws-lc-rs" "aws-lc-rs/aws-lc-sys" "aws-lc-rs/ring-io" "__dnssec" ]; + "dnssec-ring" = [ "dep:ring" "__dnssec" ]; + "no-std-rand" = [ "once_cell/critical-section" "dep:critical-section" ]; + "serde" = [ "dep:serde" "std" "url/serde" ]; + "std" = [ "data-encoding/std" "ipnet/std" "rand/std" "rand/thread_rng" "ring?/std" "thiserror/std" "tracing/std" "url/std" ]; + "testing" = [ "std" ]; + "wasm-bindgen" = [ "dep:wasm-bindgen-crate" "dep:js-sys" ]; + }; + resolvedDefaultFeatures = [ "access-control" "std" ]; + }; + "hickory-resolver 0.24.4" = rec { crateName = "hickory-resolver"; version = "0.24.4"; edition = "2021"; @@ -14513,7 +15436,7 @@ rec { } { name = "hickory-proto"; - packageId = "hickory-proto"; + packageId = "hickory-proto 0.24.4"; usesDefaultFeatures = false; } { @@ -14598,6 +15521,154 @@ rec { }; resolvedDefaultFeatures = [ "default" "ipconfig" "resolv-conf" "system-config" "tokio" "tokio-runtime" ]; }; + "hickory-resolver 0.26.3" = rec { + crateName = "hickory-resolver"; + version = "0.26.3"; + edition = "2021"; + sha256 = "10d97cxhc9ffwamamgnkhhs7rmp8yjwbam3xhlbagmcmbhjsag9z"; + libName = "hickory_resolver"; + authors = [ + "The contributors to Hickory DNS" + ]; + dependencies = [ + { + name = "cfg-if"; + packageId = "cfg-if"; + } + { + name = "futures-util"; + packageId = "futures-util"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "hickory-net"; + packageId = "hickory-net"; + usesDefaultFeatures = false; + } + { + name = "hickory-proto"; + packageId = "hickory-proto 0.26.3"; + usesDefaultFeatures = false; + features = [ "std" "access-control" ]; + } + { + name = "ipconfig"; + packageId = "ipconfig"; + optional = true; + target = { target, features }: (target."windows" or false); + } + { + name = "ipnet"; + packageId = "ipnet"; + usesDefaultFeatures = false; + features = [ "serde" ]; + } + { + name = "jni"; + packageId = "jni 0.22.4"; + optional = true; + target = { target, features }: ("android" == target."os" or null); + } + { + name = "moka"; + packageId = "moka"; + features = [ "sync" ]; + } + { + name = "ndk-context"; + packageId = "ndk-context"; + optional = true; + target = { target, features }: ("android" == target."os" or null); + } + { + name = "once_cell"; + packageId = "once_cell"; + usesDefaultFeatures = false; + features = [ "critical-section" ]; + } + { + name = "parking_lot"; + packageId = "parking_lot"; + } + { + name = "rand"; + packageId = "rand 0.10.1"; + usesDefaultFeatures = false; + features = [ "alloc" ]; + } + { + name = "resolv-conf"; + packageId = "resolv-conf"; + optional = true; + features = [ "system" ]; + } + { + name = "smallvec"; + packageId = "smallvec"; + } + { + name = "system-configuration"; + packageId = "system-configuration"; + optional = true; + target = { target, features }: ("apple" == target."vendor" or null); + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + usesDefaultFeatures = false; + } + { + name = "tokio"; + packageId = "tokio"; + optional = true; + } + { + name = "tracing"; + packageId = "tracing"; + usesDefaultFeatures = false; + } + ]; + devDependencies = [ + { + name = "hickory-proto"; + packageId = "hickory-proto 0.26.3"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "tokio"; + packageId = "tokio"; + features = [ "macros" "test-util" ]; + } + ]; + features = { + "__h3" = [ "__quic" ]; + "__https" = [ "__tls" ]; + "__quic" = [ "dep:quinn" "__tls" ]; + "__tls" = [ "dep:rustls" "dep:tokio-rustls" "tokio" ]; + "default" = [ "system-config" "tokio" ]; + "dnssec-aws-lc-rs" = [ "hickory-proto/dnssec-aws-lc-rs" "hickory-net/dnssec-aws-lc-rs" "__dnssec" ]; + "dnssec-ring" = [ "hickory-proto/dnssec-ring" "hickory-net/dnssec-ring" "__dnssec" ]; + "h3-aws-lc-rs" = [ "hickory-net/h3-aws-lc-rs" "__h3" ]; + "h3-ring" = [ "hickory-net/h3-ring" "__h3" ]; + "https-aws-lc-rs" = [ "hickory-net/https-aws-lc-rs" "__https" ]; + "https-ring" = [ "hickory-net/https-ring" "__https" ]; + "metrics" = [ "dep:metrics" ]; + "quic-aws-lc-rs" = [ "hickory-net/quic-aws-lc-rs" "__quic" "quinn/rustls-aws-lc-rs" ]; + "quic-ring" = [ "hickory-net/quic-ring" "__quic" "quinn/rustls-ring" ]; + "recursor" = [ "dep:async-recursion" "dep:lru-cache" ]; + "rustls-platform-verifier" = [ "hickory-net/rustls-platform-verifier" ]; + "serde" = [ "dep:serde" "hickory-proto/serde" ]; + "system-config" = [ "dep:ipconfig" "dep:resolv-conf" "dep:jni" "dep:ndk-context" "dep:system-configuration" ]; + "tls-aws-lc-rs" = [ "hickory-net/tls-aws-lc-rs" "__tls" ]; + "tls-ring" = [ "hickory-net/tls-ring" "__tls" ]; + "tokio" = [ "dep:tokio" "tokio/rt" "hickory-net/tokio" ]; + "toml" = [ "dep:toml" ]; + "webpki-roots" = [ "dep:webpki-roots" "hickory-net/webpki-roots" ]; + }; + resolvedDefaultFeatures = [ "system-config" "tokio" ]; + }; "hkdf 0.12.4" = rec { crateName = "hkdf"; version = "0.12.4"; @@ -14866,6 +15937,14 @@ rec { features = { }; }; + "humantime" = rec { + crateName = "humantime"; + version = "2.4.0"; + edition = "2021"; + sha256 = "059w9i1g0gmfg30axhqh10fvqpym4frsz9iggqlm673h0xkx5k8m"; + features = { + }; + }; "hybrid-array" = rec { crateName = "hybrid-array"; version = "0.4.12"; @@ -14911,6 +15990,245 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "ctutils" "extra-sizes" "subtle" "zeroize" ]; }; + "hydrant" = rec { + crateName = "hydrant"; + version = "0.1.0"; + edition = "2024"; + crateBin = []; + workspace_member = null; + src = pkgs.fetchgit { + url = "https://tangled.org/ptr.pet/hydrant"; + rev = "ccc1b1a37006ce0b0559d81f7f5c1a6b88b20129"; + sha256 = "0gn9lqm2z6kq0qkbv97d07pk0gxafpx00l9xipff1f8sa9vyw55q"; + }; + dependencies = [ + { + name = "ahash"; + packageId = "ahash"; + } + { + name = "arc-swap"; + packageId = "arc-swap"; + } + { + name = "axum"; + packageId = "axum"; + features = [ "macros" ]; + } + { + name = "axum-tws"; + packageId = "axum-tws"; + } + { + name = "bytes"; + packageId = "bytes"; + features = [ "serde" ]; + } + { + name = "chrono"; + packageId = "chrono"; + features = [ "serde" ]; + } + { + name = "cid"; + packageId = "cid"; + } + { + name = "data-encoding"; + packageId = "data-encoding"; + } + { + name = "fjall"; + packageId = "fjall"; + features = [ "lz4" "zstd" ]; + } + { + name = "fluent-uri"; + packageId = "fluent-uri"; + } + { + name = "futures"; + packageId = "futures"; + } + { + name = "glob"; + packageId = "glob"; + } + { + name = "hex"; + packageId = "hex"; + } + { + name = "hickory-resolver"; + packageId = "hickory-resolver 0.26.3"; + usesDefaultFeatures = false; + features = [ "system-config" "tokio" ]; + } + { + name = "http"; + packageId = "http"; + } + { + name = "humantime"; + packageId = "humantime"; + } + { + name = "hyper"; + packageId = "hyper"; + } + { + name = "ipnet"; + packageId = "ipnet"; + } + { + name = "iroh-car"; + packageId = "iroh-car"; + } + { + name = "jacquard-api"; + packageId = "jacquard-api"; + } + { + name = "jacquard-common"; + packageId = "jacquard-common"; + usesDefaultFeatures = false; + features = [ "tracing" "std" "crypto" ]; + } + { + name = "jacquard-derive"; + packageId = "jacquard-derive"; + } + { + name = "jacquard-repo"; + packageId = "jacquard-repo"; + } + { + name = "lsm-tree"; + packageId = "lsm-tree"; + features = [ "lz4" "zstd" ]; + } + { + name = "miette"; + packageId = "miette"; + features = [ "fancy" ]; + } + { + name = "multibase"; + packageId = "multibase"; + } + { + name = "nohash-hasher"; + packageId = "nohash-hasher"; + } + { + name = "parking_lot"; + packageId = "parking_lot"; + } + { + name = "rand"; + packageId = "rand 0.10.1"; + } + { + name = "reqwest"; + packageId = "reqwest 0.12.28"; + usesDefaultFeatures = false; + features = [ "json" "rustls-tls-native-roots" "stream" "gzip" "brotli" "zstd" "http2" ]; + } + { + name = "rmp-serde"; + packageId = "rmp-serde"; + } + { + name = "rustls"; + packageId = "rustls"; + features = [ "aws-lc-rs" ]; + } + { + name = "scc"; + packageId = "scc"; + } + { + name = "serde"; + packageId = "serde"; + features = [ "derive" "rc" ]; + } + { + name = "serde_bytes"; + packageId = "serde_bytes"; + } + { + name = "serde_html_form"; + packageId = "serde_html_form"; + } + { + name = "serde_ipld_dagcbor"; + packageId = "serde_ipld_dagcbor"; + } + { + name = "serde_json"; + packageId = "serde_json"; + } + { + name = "sha2"; + packageId = "sha2 0.10.9"; + } + { + name = "smol_str"; + packageId = "smol_str"; + } + { + name = "socket2"; + packageId = "socket2"; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + } + { + name = "tokio"; + packageId = "tokio"; + features = [ "full" ]; + } + { + name = "tokio-util"; + packageId = "tokio-util"; + features = [ "io" ]; + } + { + name = "tokio-websockets"; + packageId = "tokio-websockets"; + features = [ "client" "server" "rustls-native-roots" "aws_lc_rs" "rand" ]; + } + { + name = "tower-http"; + packageId = "tower-http 0.6.11"; + features = [ "cors" "trace" ]; + } + { + name = "tracing"; + packageId = "tracing"; + } + { + name = "tracing-subscriber"; + packageId = "tracing-subscriber"; + features = [ "env-filter" ]; + } + { + name = "url"; + packageId = "url"; + features = [ "serde" ]; + } + ]; + features = { + "alloc-jemalloc" = [ "dep:tikv-jemallocator" ]; + "alloc-mimalloc" = [ "dep:mimalloc" ]; + "alloc-snmalloc" = [ "dep:snmalloc-rs" ]; + "default" = [ "indexer" "indexer_stream" "alloc-jemalloc" ]; + "indexer_stream" = [ "indexer" ]; + "jetstream" = [ "dep:zstd" ]; + }; + resolvedDefaultFeatures = [ "indexer" "indexer_stream" ]; + }; "hyper" = rec { crateName = "hyper"; version = "1.10.1"; @@ -15043,6 +16361,11 @@ rec { packageId = "rustls"; usesDefaultFeatures = false; } + { + name = "rustls-native-certs"; + packageId = "rustls-native-certs"; + optional = true; + } { name = "tokio"; packageId = "tokio"; @@ -15097,7 +16420,7 @@ rec { "webpki-roots" = [ "dep:webpki-roots" ]; "webpki-tokio" = [ "webpki-roots" ]; }; - resolvedDefaultFeatures = [ "aws-lc-rs" "http1" "http2" "ring" "tls12" "webpki-roots" "webpki-tokio" ]; + resolvedDefaultFeatures = [ "aws-lc-rs" "http1" "http2" "native-tokio" "ring" "rustls-native-certs" "tls12" "webpki-roots" "webpki-tokio" ]; }; "hyper-util" = rec { crateName = "hyper-util"; @@ -15807,6 +17130,25 @@ rec { }; resolvedDefaultFeatures = [ "default" "rand_0_10" "rand_core_0_10" "std" ]; }; + "interval-heap" = rec { + crateName = "interval-heap"; + version = "0.0.5"; + edition = "2015"; + sha256 = "1ikap3f0lkb0qx8r20caniwqg6bfcav10afwzry61f49irg4w9qi"; + libName = "interval_heap"; + authors = [ + "Andrew Paseltiner " + "Sebastian Gesemann " + ]; + dependencies = [ + { + name = "compare"; + packageId = "compare"; + } + ]; + features = { + }; + }; "inventory" = rec { crateName = "inventory"; version = "0.3.24"; @@ -15946,6 +17288,16 @@ rec { authors = [ "Kris Price " ]; + dependencies = [ + { + name = "serde"; + packageId = "serde"; + rename = "serde"; + optional = true; + usesDefaultFeatures = false; + features = [ "derive" ]; + } + ]; features = { "default" = [ "std" ]; "heapless" = [ "dep:heapless" "serde" ]; @@ -15956,7 +17308,7 @@ rec { "ser_as_str" = [ "dep:heapless" ]; "serde" = [ "dep:serde" ]; }; - resolvedDefaultFeatures = [ "default" "std" ]; + resolvedDefaultFeatures = [ "default" "serde" "std" ]; }; "iroh-car" = rec { crateName = "iroh-car"; @@ -16018,6 +17370,17 @@ rec { }; resolvedDefaultFeatures = [ "default" ]; }; + "is_ci" = rec { + crateName = "is_ci"; + version = "1.2.0"; + edition = "2018"; + crateBin = []; + sha256 = "0ifwvxmrsj4r29agfzr71bjq6y1bihkx38fbzafq5vl0jn1wjmbn"; + authors = [ + "Kat Marchán " + ]; + + }; "is_terminal_polyfill" = rec { crateName = "is_terminal_polyfill"; version = "1.70.2"; @@ -16818,6 +18181,11 @@ rec { target = { target, features }: (!("wasm32" == target."arch" or null)); features = [ "io" ]; } + { + name = "tracing"; + packageId = "tracing"; + optional = true; + } { name = "trait-variant"; packageId = "trait-variant"; @@ -16852,7 +18220,7 @@ rec { "websocket" = [ "streaming" "tokio-tungstenite-wasm" "dep:ciborium" "dep:ciborium-io" ]; "zstd" = [ "dep:zstd" ]; }; - resolvedDefaultFeatures = [ "crypto" "crypto-ed25519" "crypto-k256" "crypto-p256" "default" "futures" "miette" "n0-future" "reqwest-client" "reqwest-compression" "service-auth" "std" "streaming" "tokio-tungstenite-wasm" "websocket" ]; + resolvedDefaultFeatures = [ "crypto" "crypto-ed25519" "crypto-k256" "crypto-p256" "default" "futures" "miette" "n0-future" "reqwest-client" "reqwest-compression" "service-auth" "std" "streaming" "tokio-tungstenite-wasm" "tracing" "websocket" ]; }; "jacquard-derive" = rec { crateName = "jacquard-derive"; @@ -17542,7 +18910,7 @@ rec { ]; }; - "jni" = rec { + "jni 0.21.1" = rec { crateName = "jni"; version = "0.21.1"; edition = "2018"; @@ -17594,6 +18962,94 @@ rec { "libloading" = [ "dep:libloading" ]; }; }; + "jni 0.22.4" = rec { + crateName = "jni"; + version = "0.22.4"; + edition = "2024"; + sha256 = "161lza8gz071h22pgyqyx4n91ixd691z2dbb1pq2g97k5i49mzay"; + authors = [ + "jni team" + ]; + dependencies = [ + { + name = "cfg-if"; + packageId = "cfg-if"; + } + { + name = "combine"; + packageId = "combine"; + } + { + name = "jni-macros"; + packageId = "jni-macros"; + } + { + name = "jni-sys"; + packageId = "jni-sys 0.4.1"; + } + { + name = "log"; + packageId = "log"; + } + { + name = "simd_cesu8"; + packageId = "simd_cesu8"; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + } + { + name = "windows-link"; + packageId = "windows-link"; + target = { target, features }: (target."windows" or false); + } + ]; + buildDependencies = [ + { + name = "walkdir"; + packageId = "walkdir"; + } + ]; + features = { + "invocation" = [ "dep:java-locator" "dep:libloading" ]; + }; + resolvedDefaultFeatures = [ "default" ]; + }; + "jni-macros" = rec { + crateName = "jni-macros"; + version = "0.22.4"; + edition = "2024"; + sha256 = "18v02mcn5c7mb2yw6r930xg6ynsn7hwkxv8z2kdhn3qprjn0j0d0"; + procMacro = true; + libName = "jni_macros"; + dependencies = [ + { + name = "proc-macro2"; + packageId = "proc-macro2"; + } + { + name = "quote"; + packageId = "quote"; + } + { + name = "simd_cesu8"; + packageId = "simd_cesu8"; + } + { + name = "syn"; + packageId = "syn 2.0.118"; + features = [ "full" ]; + } + ]; + buildDependencies = [ + { + name = "rustc_version"; + packageId = "rustc_version"; + } + ]; + + }; "jni-sys 0.3.1" = rec { crateName = "jni-sys"; version = "0.3.1"; @@ -19698,7 +21154,7 @@ rec { } { name = "hickory-resolver"; - packageId = "hickory-resolver"; + packageId = "hickory-resolver 0.24.4"; } { name = "http"; @@ -21181,6 +22637,94 @@ rec { ]; }; + "lsm-tree" = rec { + crateName = "lsm-tree"; + version = "3.1.8"; + edition = "2021"; + workspace_member = null; + src = pkgs.fetchgit { + url = "https://github.com/90-008/lsm-tree.git"; + rev = "ffa6e5edea9dd199b4fe5286a2ad20fc5df63001"; + sha256 = "1xkv3j4csa82xpxa6krpjcb1vvbdvih269li0nr31z3hlfskwyli"; + }; + libName = "lsm_tree"; + dependencies = [ + { + name = "byteorder-lite"; + packageId = "byteorder-lite"; + rename = "byteorder"; + } + { + name = "byteview"; + packageId = "byteview"; + } + { + name = "crossbeam-skiplist"; + packageId = "crossbeam-skiplist"; + } + { + name = "enum_dispatch"; + packageId = "enum_dispatch"; + } + { + name = "interval-heap"; + packageId = "interval-heap"; + } + { + name = "log"; + packageId = "log"; + } + { + name = "lz4_flex"; + packageId = "lz4_flex"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "quick_cache"; + packageId = "quick_cache"; + usesDefaultFeatures = false; + } + { + name = "rustc-hash"; + packageId = "rustc-hash"; + } + { + name = "self_cell"; + packageId = "self_cell"; + } + { + name = "sfa"; + packageId = "sfa"; + } + { + name = "tempfile"; + packageId = "tempfile"; + } + { + name = "varint-rs"; + packageId = "varint-rs"; + } + { + name = "xxhash-rust"; + packageId = "xxhash-rust"; + features = [ "xxh3" ]; + } + { + name = "zstd"; + packageId = "zstd"; + optional = true; + usesDefaultFeatures = false; + features = [ "zdict_builder" ]; + } + ]; + features = { + "bytes_1" = [ "dep:bytes" ]; + "lz4" = [ "dep:lz4_flex" ]; + "zstd" = [ "dep:zstd" ]; + }; + resolvedDefaultFeatures = [ "default" "lz4" "zstd" ]; + }; "lz4_flex" = rec { crateName = "lz4_flex"; version = "0.13.1"; @@ -21191,10 +22735,20 @@ rec { "Arthur Silva " "ticki " ]; + dependencies = [ + { + name = "twox-hash"; + packageId = "twox-hash"; + optional = true; + usesDefaultFeatures = false; + features = [ "xxhash32" ]; + } + ]; features = { "default" = [ "std" "safe-encode" "safe-decode" "frame" "checked-decode" ]; "frame" = [ "std" "dep:twox-hash" ]; }; + resolvedDefaultFeatures = [ "checked-decode" "default" "frame" "safe-decode" "safe-encode" "std" ]; }; "mac" = rec { crateName = "mac"; @@ -21410,6 +22964,39 @@ rec { }; resolvedDefaultFeatures = [ "default" ]; }; + "md-5" = rec { + crateName = "md-5"; + version = "0.11.0"; + edition = "2024"; + sha256 = "166yqj8b11pawpys7knnn77cr618cby2iywpp0dq4dh3b4gl9dk9"; + libName = "md5"; + authors = [ + "RustCrypto Developers" + ]; + dependencies = [ + { + name = "cfg-if"; + packageId = "cfg-if"; + } + { + name = "digest"; + packageId = "digest 0.11.3"; + } + ]; + devDependencies = [ + { + name = "digest"; + packageId = "digest 0.11.3"; + features = [ "dev" ]; + } + ]; + features = { + "alloc" = [ "digest/alloc" ]; + "default" = [ "alloc" "oid" ]; + "oid" = [ "digest/oid" ]; + "zeroize" = [ "digest/zeroize" ]; + }; + }; "md5" = rec { crateName = "md5"; version = "0.8.0"; @@ -21711,6 +23298,16 @@ rec { "Kat Marchán " ]; dependencies = [ + { + name = "backtrace"; + packageId = "backtrace"; + optional = true; + } + { + name = "backtrace-ext"; + packageId = "backtrace-ext"; + optional = true; + } { name = "cfg-if"; packageId = "cfg-if"; @@ -21720,9 +23317,41 @@ rec { packageId = "miette-derive"; optional = true; } + { + name = "owo-colors"; + packageId = "owo-colors"; + optional = true; + } + { + name = "supports-color"; + packageId = "supports-color"; + optional = true; + } + { + name = "supports-hyperlinks"; + packageId = "supports-hyperlinks"; + optional = true; + } + { + name = "supports-unicode"; + packageId = "supports-unicode"; + optional = true; + } + { + name = "terminal_size"; + packageId = "terminal_size"; + optional = true; + } + { + name = "textwrap"; + packageId = "textwrap"; + optional = true; + usesDefaultFeatures = false; + features = [ "unicode-linebreak" "unicode-width" ]; + } { name = "unicode-width"; - packageId = "unicode-width"; + packageId = "unicode-width 0.1.14"; } ]; features = { @@ -21735,7 +23364,7 @@ rec { "serde" = [ "dep:serde" ]; "syntect-highlighter" = [ "fancy-no-backtrace" "dep:syntect" ]; }; - resolvedDefaultFeatures = [ "default" "derive" ]; + resolvedDefaultFeatures = [ "default" "derive" "fancy" "fancy-base" "fancy-no-backtrace" ]; }; "miette-derive" = rec { crateName = "miette-derive"; @@ -22287,6 +23916,17 @@ rec { } ]; + }; + "ndk-context" = rec { + crateName = "ndk-context"; + version = "0.1.1"; + edition = "2021"; + sha256 = "12sai3dqsblsvfd1l1zab0z6xsnlha3xsfl7kagdnmj3an3jvc17"; + libName = "ndk_context"; + authors = [ + "The Rust Windowing contributors" + ]; + }; "new_debug_unreachable" = rec { crateName = "new_debug_unreachable"; @@ -22350,6 +23990,20 @@ rec { }; resolvedDefaultFeatures = [ "default" "feature" "fs" "ioctl" "memoffset" "mman" "process" "reboot" "signal" "socket" "term" "user" ]; }; + "nohash-hasher" = rec { + crateName = "nohash-hasher"; + version = "0.2.0"; + edition = "2018"; + sha256 = "0lf4p6k01w4wm7zn4grnihzj8s7zd5qczjmzng7wviwxawih5x9b"; + libName = "nohash_hasher"; + authors = [ + "Parity Technologies " + ]; + features = { + "default" = [ "std" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; "nom" = rec { crateName = "nom"; version = "7.1.3"; @@ -22666,6 +24320,39 @@ rec { ]; }; + "object" = rec { + crateName = "object"; + version = "0.37.3"; + edition = "2018"; + sha256 = "1zikiy9xhk6lfx1dn2gn2pxbnfpmlkn0byd7ib1n720x0cgj0xpz"; + dependencies = [ + { + name = "memchr"; + packageId = "memchr"; + usesDefaultFeatures = false; + } + ]; + features = { + "all" = [ "read" "write" "build" "std" "compression" "wasm" ]; + "alloc" = [ "dep:alloc" ]; + "build" = [ "build_core" "write_std" "elf" ]; + "build_core" = [ "read_core" "write_core" ]; + "compression" = [ "dep:flate2" "dep:ruzstd" "std" ]; + "core" = [ "dep:core" ]; + "default" = [ "read" "compression" ]; + "doc" = [ "read_core" "write_std" "build_core" "std" "compression" "archive" "coff" "elf" "macho" "pe" "wasm" "xcoff" ]; + "pe" = [ "coff" ]; + "read" = [ "read_core" "archive" "coff" "elf" "macho" "pe" "xcoff" "unaligned" ]; + "rustc-dep-of-std" = [ "core" "alloc" "memchr/rustc-dep-of-std" ]; + "std" = [ "memchr/std" ]; + "unstable-all" = [ "all" "unstable" ]; + "wasm" = [ "dep:wasmparser" ]; + "write" = [ "write_std" "coff" "elf" "macho" "pe" "xcoff" ]; + "write_core" = [ "dep:crc32fast" "dep:indexmap" "dep:hashbrown" ]; + "write_std" = [ "write_core" "std" "indexmap?/std" "crc32fast?/std" ]; + }; + resolvedDefaultFeatures = [ "archive" "coff" "elf" "macho" "pe" "read_core" "unaligned" "xcoff" ]; + }; "oid-registry 0.7.1" = rec { crateName = "oid-registry"; version = "0.7.1"; @@ -22716,6 +24403,26 @@ rec { authors = [ "Aleksey Kladov " ]; + dependencies = [ + { + name = "critical-section"; + packageId = "critical-section"; + optional = true; + } + { + name = "portable-atomic"; + packageId = "portable-atomic"; + optional = true; + usesDefaultFeatures = false; + } + ]; + devDependencies = [ + { + name = "critical-section"; + packageId = "critical-section"; + features = [ "std" ]; + } + ]; features = { "alloc" = [ "race" ]; "atomic-polyfill" = [ "critical-section" ]; @@ -22725,7 +24432,7 @@ rec { "portable-atomic" = [ "dep:portable-atomic" ]; "std" = [ "alloc" ]; }; - resolvedDefaultFeatures = [ "alloc" "default" "race" "std" ]; + resolvedDefaultFeatures = [ "alloc" "critical-section" "default" "portable-atomic" "race" "std" ]; }; "once_cell_polyfill" = rec { crateName = "once_cell_polyfill"; @@ -23257,6 +24964,20 @@ rec { ]; }; + "owo-colors" = rec { + crateName = "owo-colors"; + version = "4.4.0"; + edition = "2021"; + sha256 = "1n59zda1s3q2md3i9gpv3vq51ssm6jfyzc8313n804mflss5pi0k"; + libName = "owo_colors"; + authors = [ + "jam1garner <8260240+jam1garner@users.noreply.github.com>" + ]; + features = { + "supports-color" = [ "dep:supports-color" ]; + "supports-colors" = [ "dep:supports-color-2" "supports-color" ]; + }; + }; "oxilangtag" = rec { crateName = "oxilangtag"; version = "0.1.6"; @@ -24832,6 +26553,36 @@ rec { ]; }; + "prefix-trie" = rec { + crateName = "prefix-trie"; + version = "0.8.4"; + edition = "2021"; + sha256 = "1ry6s01d237i3m4z0j5vyg9vvy0m5s4016r0bim03106gwby7xjc"; + libName = "prefix_trie"; + dependencies = [ + { + name = "either"; + packageId = "either"; + } + { + name = "ipnet"; + packageId = "ipnet"; + optional = true; + } + { + name = "num-traits"; + packageId = "num-traits"; + } + ]; + features = { + "cidr" = [ "dep:cidr" ]; + "default" = [ "ipnet" ]; + "ipnet" = [ "dep:ipnet" ]; + "ipnetwork" = [ "dep:ipnetwork" ]; + "serde" = [ "dep:serde" "ipnet/serde" "ipnetwork/serde" "cidr/serde" ]; + }; + resolvedDefaultFeatures = [ "default" "ipnet" ]; + }; "prettyplease" = rec { crateName = "prettyplease"; version = "0.2.37"; @@ -26948,6 +28699,12 @@ rec { target = { target, features }: (!("wasm32" == target."arch" or null)); features = [ "std" "tls12" ]; } + { + name = "rustls-native-certs"; + packageId = "rustls-native-certs"; + optional = true; + target = { target, features }: (!("wasm32" == target."arch" or null)); + } { name = "rustls-pki-types"; packageId = "rustls-pki-types"; @@ -27134,7 +28891,7 @@ rec { "system-proxy" = [ "hyper-util/client-proxy-system" ]; "zstd" = [ "tower-http/decompression-zstd" ]; }; - resolvedDefaultFeatures = [ "__rustls" "__rustls-ring" "__tls" "brotli" "charset" "deflate" "gzip" "h2" "http2" "json" "rustls-tls" "rustls-tls-manual-roots" "rustls-tls-manual-roots-no-provider" "rustls-tls-webpki-roots" "rustls-tls-webpki-roots-no-provider" "stream" "system-proxy" ]; + resolvedDefaultFeatures = [ "__rustls" "__rustls-ring" "__tls" "brotli" "charset" "deflate" "gzip" "h2" "http2" "json" "rustls-tls" "rustls-tls-manual-roots" "rustls-tls-manual-roots-no-provider" "rustls-tls-native-roots" "rustls-tls-native-roots-no-provider" "rustls-tls-webpki-roots" "rustls-tls-webpki-roots-no-provider" "stream" "system-proxy" "zstd" ]; }; "reqwest 0.13.1" = rec { crateName = "reqwest"; @@ -27544,7 +29301,67 @@ rec { "std" = [ "alloc" ]; "wasm32_unknown_unknown_js" = [ "getrandom/js" ]; }; - resolvedDefaultFeatures = [ "alloc" "default" "dev_urandom_fallback" "wasm32_unknown_unknown_js" ]; + resolvedDefaultFeatures = [ "alloc" "default" "dev_urandom_fallback" "std" "wasm32_unknown_unknown_js" ]; + }; + "rmp" = rec { + crateName = "rmp"; + version = "0.8.15"; + edition = "2024"; + workspace_member = null; + src = pkgs.fetchgit { + url = "https://github.com/90-008/msgpack-rust.git"; + rev = "19c54a922301d06310a816c3a6a097aeb73ea3ae"; + sha256 = "01ff1kx4njkslb2wkjp8912x5qchd6pf3c654y16i53n4ini6l6i"; + }; + authors = [ + "Evgeny Safronov " + "Kornel " + ]; + dependencies = [ + { + name = "num-traits"; + packageId = "num-traits"; + usesDefaultFeatures = false; + } + ]; + features = { + "default" = [ "std" ]; + "std" = [ "num-traits/std" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; + "rmp-serde" = rec { + crateName = "rmp-serde"; + version = "1.3.1"; + edition = "2024"; + workspace_member = null; + src = pkgs.fetchgit { + url = "https://github.com/90-008/msgpack-rust.git"; + rev = "19c54a922301d06310a816c3a6a097aeb73ea3ae"; + sha256 = "01ff1kx4njkslb2wkjp8912x5qchd6pf3c654y16i53n4ini6l6i"; + }; + libName = "rmp_serde"; + authors = [ + "Evgeny Safronov " + ]; + dependencies = [ + { + name = "rmp"; + packageId = "rmp"; + } + { + name = "serde"; + packageId = "serde"; + } + ]; + devDependencies = [ + { + name = "serde"; + packageId = "serde"; + features = [ "derive" ]; + } + ]; + }; "rsa 0.10.0-rc.18" = rec { crateName = "rsa"; @@ -28274,6 +30091,20 @@ rec { ]; }; + "rustc-demangle" = rec { + crateName = "rustc-demangle"; + version = "0.1.28"; + edition = "2015"; + sha256 = "1sr083jamg89zcxmchia1pdn584smsy2r32kk9q30a5vm3zmcjxp"; + libName = "rustc_demangle"; + authors = [ + "Alex Crichton " + ]; + features = { + "core" = [ "dep:core" ]; + "rustc-dep-of-std" = [ "core" ]; + }; + }; "rustc-hash" = rec { crateName = "rustc-hash"; version = "2.1.2"; @@ -28706,13 +30537,13 @@ rec { } { name = "jni"; - packageId = "jni"; + packageId = "jni 0.21.1"; optional = true; usesDefaultFeatures = false; } { name = "jni"; - packageId = "jni"; + packageId = "jni 0.21.1"; usesDefaultFeatures = false; target = { target, features }: ("android" == target."os" or null); } @@ -29296,6 +31127,19 @@ rec { }; resolvedDefaultFeatures = [ "OSX_10_13" "default" ]; }; + "self_cell" = rec { + crateName = "self_cell"; + version = "1.3.0"; + edition = "2018"; + sha256 = "04x883z7awzkmn5lqb67n51xynrj2pa9339jgq4j1qa94yh2rd1a"; + authors = [ + "Lukas Bergdoll " + ]; + features = { + "old_rust" = [ "rustversion" ]; + "rustversion" = [ "dep:rustversion" ]; + }; + }; "semver" = rec { crateName = "semver"; version = "1.0.28"; @@ -29354,7 +31198,7 @@ rec { "std" = [ "serde_core/std" ]; "unstable" = [ "serde_core/unstable" ]; }; - resolvedDefaultFeatures = [ "alloc" "default" "derive" "serde_derive" "std" ]; + resolvedDefaultFeatures = [ "alloc" "default" "derive" "rc" "serde_derive" "std" ]; }; "serde-value" = rec { crateName = "serde-value"; @@ -29436,7 +31280,7 @@ rec { features = { "default" = [ "std" "result" ]; }; - resolvedDefaultFeatures = [ "alloc" "default" "result" "std" ]; + resolvedDefaultFeatures = [ "alloc" "default" "rc" "result" "std" ]; }; "serde_derive" = rec { crateName = "serde_derive"; @@ -29493,6 +31337,11 @@ rec { name = "itoa"; packageId = "itoa"; } + { + name = "ryu"; + packageId = "ryu"; + optional = true; + } { name = "serde_core"; packageId = "serde_core"; @@ -29504,7 +31353,7 @@ rec { "default" = [ "ryu" "std" ]; "ryu" = [ "dep:ryu" ]; }; - resolvedDefaultFeatures = [ "std" ]; + resolvedDefaultFeatures = [ "default" "ryu" "std" ]; }; "serde_ipld_dagcbor" = rec { crateName = "serde_ipld_dagcbor"; @@ -29942,6 +31791,29 @@ rec { }; resolvedDefaultFeatures = [ "alloc" ]; }; + "sfa" = rec { + crateName = "sfa"; + version = "1.0.0"; + edition = "2021"; + sha256 = "0x8i3p87p1k95070cgy300vkhxy7irqvivjfdk6mdavwjcw6had1"; + dependencies = [ + { + name = "byteorder-lite"; + packageId = "byteorder-lite"; + rename = "byteorder"; + } + { + name = "log"; + packageId = "log"; + } + { + name = "xxhash-rust"; + packageId = "xxhash-rust"; + features = [ "xxh3" ]; + } + ]; + + }; "sha1 0.10.6" = rec { crateName = "sha1"; version = "0.10.6"; @@ -30054,6 +31926,19 @@ rec { "zeroize" = [ "dep:zeroize" ]; }; }; + "sha1_smol" = rec { + crateName = "sha1_smol"; + version = "1.0.1"; + edition = "2018"; + sha256 = "0pbh2xjfnzgblws3hims0ib5bphv7r5rfdpizyh51vnzvnribymv"; + authors = [ + "Armin Ronacher " + ]; + features = { + "serde" = [ "dep:serde" ]; + "std" = [ "alloc" ]; + }; + }; "sha2 0.10.9" = rec { crateName = "sha2"; version = "0.10.9"; @@ -30422,6 +32307,46 @@ rec { "default" = [ "std" "const-generics" ]; }; }; + "simd_cesu8" = rec { + crateName = "simd_cesu8"; + version = "1.2.0"; + edition = "2021"; + sha256 = "0865mv3nmd35f1dccjcfj7dncjmmvvdij3j61z4131mz38jiw0qi"; + authors = [ + "Sean C. Roach " + ]; + dependencies = [ + { + name = "simdutf8"; + packageId = "simdutf8"; + usesDefaultFeatures = false; + } + ]; + buildDependencies = [ + { + name = "rustc_version"; + packageId = "rustc_version"; + } + ]; + features = { + "default" = [ "std" ]; + "std" = [ "simdutf8/std" ]; + }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; + "simdutf8" = rec { + crateName = "simdutf8"; + version = "0.1.5"; + edition = "2018"; + sha256 = "0vmpf7xaa0dnaikib5jlx6y4dxd3hxqz6l830qb079g7wcsgxag3"; + authors = [ + "Hans Kratz " + ]; + features = { + "default" = [ "std" ]; + }; + resolvedDefaultFeatures = [ "aarch64_neon" "std" ]; + }; "siphasher" = rec { crateName = "siphasher"; version = "1.0.3"; @@ -30499,6 +32424,14 @@ rec { authors = [ "The Servo Project Developers" ]; + dependencies = [ + { + name = "serde"; + packageId = "serde"; + optional = true; + usesDefaultFeatures = false; + } + ]; features = { "arbitrary" = [ "dep:arbitrary" ]; "bincode" = [ "dep:bincode" ]; @@ -30509,7 +32442,7 @@ rec { "serde" = [ "dep:serde" ]; "unty" = [ "dep:unty" ]; }; - resolvedDefaultFeatures = [ "const_generics" "const_new" "write" ]; + resolvedDefaultFeatures = [ "const_generics" "const_new" "serde" "write" ]; }; "smol_str" = rec { crateName = "smol_str"; @@ -30746,267 +32679,1203 @@ rec { "bindgen" = [ "dep:bindgen" ]; }; }; - "ssh-cipher" = rec { - crateName = "ssh-cipher"; - version = "0.3.0-rc.9"; - edition = "2024"; - sha256 = "0dnfvmgirpfywhmyfmqfbgb95mnsbkadj169ks7m5a4nj4hnznqh"; - libName = "ssh_cipher"; + "sqlx" = rec { + crateName = "sqlx"; + version = "0.9.0"; + edition = "2021"; + sha256 = "0wgxkdhqx5480wrk6irhqgf9pmc8dbkikj71iffwhqjwqb6211ip"; authors = [ - "RustCrypto Developers" + "Ryan Leckey " + "Austin Bonander " + "Chloe Ross " + "Daniel Akhterov " ]; dependencies = [ { - name = "aead"; - packageId = "aead 0.6.1"; - optional = true; - usesDefaultFeatures = false; + name = "sqlx-core"; + packageId = "sqlx-core"; + features = [ "migrate" ]; } { - name = "aes"; - packageId = "aes 0.9.1"; + name = "sqlx-macros"; + packageId = "sqlx-macros"; optional = true; - usesDefaultFeatures = false; } { - name = "aes-gcm"; - packageId = "aes-gcm 0.11.0-rc.4"; + name = "sqlx-mysql"; + packageId = "sqlx-mysql"; optional = true; usesDefaultFeatures = false; - features = [ "aes" ]; } { - name = "cbc"; - packageId = "cbc"; + name = "sqlx-postgres"; + packageId = "sqlx-postgres"; optional = true; } { - name = "chacha20"; - packageId = "chacha20"; + name = "sqlx-sqlite"; + packageId = "sqlx-sqlite"; optional = true; + } + ]; + features = { + "_unstable-all-types" = [ "bigdecimal" "rust_decimal" "json" "time" "chrono" "ipnet" "ipnetwork" "mac_address" "uuid" "bit-vec" "bstr" ]; + "_unstable-docs" = [ "all-databases" "_unstable-all-types" "sqlx-sqlite/_unstable-docs" ]; + "all-databases" = [ "mysql" "sqlite" "postgres" "any" ]; + "any" = [ "sqlx-core/any" "sqlx-mysql?/any" "sqlx-postgres?/any" "sqlx-sqlite?/any" ]; + "bigdecimal" = [ "sqlx-core/bigdecimal" "sqlx-macros?/bigdecimal" "sqlx-mysql?/bigdecimal" "sqlx-postgres?/bigdecimal" ]; + "bit-vec" = [ "sqlx-core/bit-vec" "sqlx-macros?/bit-vec" "sqlx-postgres?/bit-vec" ]; + "bstr" = [ "sqlx-core/bstr" ]; + "chrono" = [ "sqlx-core/chrono" "sqlx-macros?/chrono" "sqlx-mysql?/chrono" "sqlx-postgres?/chrono" "sqlx-sqlite?/chrono" ]; + "default" = [ "any" "macros" "migrate" "json" ]; + "derive" = [ "sqlx-macros/derive" ]; + "ipnet" = [ "sqlx-core/ipnet" "sqlx-macros?/ipnet" "sqlx-postgres?/ipnet" ]; + "ipnetwork" = [ "sqlx-core/ipnetwork" "sqlx-macros?/ipnetwork" "sqlx-postgres?/ipnetwork" ]; + "json" = [ "sqlx-core/json" "sqlx-macros?/json" "sqlx-mysql?/json" "sqlx-postgres?/json" "sqlx-sqlite?/json" ]; + "mac_address" = [ "sqlx-core/mac_address" "sqlx-macros?/mac_address" "sqlx-postgres?/mac_address" ]; + "macros" = [ "derive" "sqlx-macros/macros" "sqlx-core/offline" "sqlx-mysql?/offline" "sqlx-postgres?/offline" "sqlx-sqlite?/offline" ]; + "migrate" = [ "sqlx-core/migrate" "sqlx-macros?/migrate" "sqlx-mysql?/migrate" "sqlx-postgres?/migrate" "sqlx-sqlite?/migrate" ]; + "mysql" = [ "sqlx-mysql" "sqlx-macros?/mysql" ]; + "mysql-rsa" = [ "mysql" "sqlx-mysql/rsa" "sqlx-macros?/mysql-rsa" ]; + "postgres" = [ "sqlx-postgres" "sqlx-macros?/postgres" ]; + "regexp" = [ "sqlx-sqlite?/regexp" ]; + "runtime-async-global-executor" = [ "_rt-async-global-executor" "sqlx-core/_rt-async-global-executor" "sqlx-macros?/_rt-async-global-executor" ]; + "runtime-async-std" = [ "_rt-async-std" "sqlx-core/_rt-async-std" "sqlx-macros?/_rt-async-std" ]; + "runtime-smol" = [ "_rt-smol" "sqlx-core/_rt-smol" "sqlx-macros?/_rt-smol" ]; + "runtime-tokio" = [ "_rt-tokio" "sqlx-core/_rt-tokio" "sqlx-macros?/_rt-tokio" ]; + "rust_decimal" = [ "sqlx-core/rust_decimal" "sqlx-macros?/rust_decimal" "sqlx-mysql?/rust_decimal" "sqlx-postgres?/rust_decimal" ]; + "sqlite" = [ "sqlite-bundled" "sqlite-deserialize" "sqlite-load-extension" "sqlite-unlock-notify" ]; + "sqlite-bundled" = [ "_sqlite" "sqlx-sqlite/bundled" "sqlx-macros?/sqlite" ]; + "sqlite-deserialize" = [ "sqlx-sqlite/deserialize" ]; + "sqlite-load-extension" = [ "sqlx-sqlite/load-extension" "sqlx-macros?/sqlite-load-extension" ]; + "sqlite-preupdate-hook" = [ "sqlx-sqlite/preupdate-hook" ]; + "sqlite-unbundled" = [ "_sqlite" "sqlx-sqlite/unbundled" "sqlx-macros?/sqlite-unbundled" ]; + "sqlite-unlock-notify" = [ "sqlx-sqlite/unlock-notify" ]; + "sqlx-macros" = [ "dep:sqlx-macros" ]; + "sqlx-mysql" = [ "dep:sqlx-mysql" ]; + "sqlx-postgres" = [ "dep:sqlx-postgres" ]; + "sqlx-sqlite" = [ "dep:sqlx-sqlite" ]; + "sqlx-toml" = [ "sqlx-core/sqlx-toml" "sqlx-macros?/sqlx-toml" "sqlx-sqlite?/sqlx-toml" ]; + "time" = [ "sqlx-core/time" "sqlx-macros?/time" "sqlx-mysql?/time" "sqlx-postgres?/time" "sqlx-sqlite?/time" ]; + "tls-native-tls" = [ "sqlx-core/_tls-native-tls" "sqlx-macros?/_tls-native-tls" ]; + "tls-rustls" = [ "tls-rustls-ring" ]; + "tls-rustls-aws-lc-rs" = [ "sqlx-core/_tls-rustls-aws-lc-rs" "sqlx-macros?/_tls-rustls-aws-lc-rs" ]; + "tls-rustls-ring" = [ "tls-rustls-ring-webpki" ]; + "tls-rustls-ring-native-roots" = [ "sqlx-core/_tls-rustls-ring-native-roots" "sqlx-macros?/_tls-rustls-ring-native-roots" ]; + "tls-rustls-ring-webpki" = [ "sqlx-core/_tls-rustls-ring-webpki" "sqlx-macros?/_tls-rustls-ring-webpki" ]; + "uuid" = [ "sqlx-core/uuid" "sqlx-macros?/uuid" "sqlx-mysql?/uuid" "sqlx-postgres?/uuid" "sqlx-sqlite?/uuid" ]; + }; + resolvedDefaultFeatures = [ "_rt-tokio" "chrono" "derive" "macros" "migrate" "postgres" "runtime-tokio" "sqlx-macros" "sqlx-postgres" "tls-rustls-aws-lc-rs" ]; + }; + "sqlx-core" = rec { + crateName = "sqlx-core"; + version = "0.9.0"; + edition = "2021"; + sha256 = "1jsw5mfpnlsx807y9ixsx7q2pbrva8x7m9za9kmqx6jppy2lxd05"; + libName = "sqlx_core"; + authors = [ + "Ryan Leckey " + "Austin Bonander " + "Chloe Ross " + "Daniel Akhterov " + ]; + dependencies = [ + { + name = "base64"; + packageId = "base64"; usesDefaultFeatures = false; - features = [ "cipher" "legacy" ]; + features = [ "alloc" ]; } { - name = "cipher"; - packageId = "cipher 0.5.2"; + name = "bytes"; + packageId = "bytes"; } { - name = "ctr"; - packageId = "ctr 0.10.1"; + name = "cfg-if"; + packageId = "cfg-if"; + } + { + name = "chrono"; + packageId = "chrono"; optional = true; usesDefaultFeatures = false; + features = [ "std" "clock" ]; } { - name = "ctutils"; - packageId = "ctutils"; + name = "crc"; + packageId = "crc"; optional = true; + } + { + name = "crossbeam-queue"; + packageId = "crossbeam-queue"; + } + { + name = "either"; + packageId = "either"; + } + { + name = "event-listener"; + packageId = "event-listener"; + } + { + name = "futures-core"; + packageId = "futures-core"; usesDefaultFeatures = false; } { - name = "des"; - packageId = "des"; - optional = true; + name = "futures-intrusive"; + packageId = "futures-intrusive"; + } + { + name = "futures-io"; + packageId = "futures-io"; + } + { + name = "futures-util"; + packageId = "futures-util"; usesDefaultFeatures = false; + features = [ "alloc" "sink" "io" ]; } { - name = "poly1305"; - packageId = "poly1305"; - optional = true; + name = "hashbrown"; + packageId = "hashbrown 0.16.1"; + } + { + name = "hashlink"; + packageId = "hashlink"; + } + { + name = "indexmap"; + packageId = "indexmap"; + } + { + name = "log"; + packageId = "log"; usesDefaultFeatures = false; } { - name = "ssh-encoding"; - packageId = "ssh-encoding"; - rename = "encoding"; + name = "memchr"; + packageId = "memchr"; + usesDefaultFeatures = false; } { - name = "zeroize"; - packageId = "zeroize"; + name = "percent-encoding"; + packageId = "percent-encoding"; + } + { + name = "rustls"; + packageId = "rustls"; optional = true; usesDefaultFeatures = false; + features = [ "std" "tls12" ]; } - ]; - features = { - "aes-cbc" = [ "dep:aes" "dep:cbc" ]; - "aes-ctr" = [ "dep:aes" "dep:ctr" ]; - "aes-gcm" = [ "dep:aead" "dep:aes" "dep:aes-gcm" ]; - "chacha20poly1305" = [ "dep:aead" "dep:chacha20" "dep:poly1305" "dep:ctutils" ]; - "tdes" = [ "dep:des" "dep:cbc" ]; - "zeroize" = [ "dep:zeroize" "aes?/zeroize" "aes-gcm?/zeroize" "chacha20?/zeroize" "des?/zeroize" "poly1305?/zeroize" ]; - }; - resolvedDefaultFeatures = [ "aes-cbc" "aes-ctr" "aes-gcm" "chacha20poly1305" "zeroize" ]; - }; - "ssh-encoding" = rec { - crateName = "ssh-encoding"; - version = "0.3.0-rc.9"; - edition = "2024"; - sha256 = "0sn9z0zqda7n5sknikcj40wsp0m25q26v4wnqjsdb9bdf6m39gvs"; - libName = "ssh_encoding"; - authors = [ - "RustCrypto Developers" - ]; - dependencies = [ { - name = "base64ct"; - packageId = "base64ct"; + name = "serde"; + packageId = "serde"; optional = true; + features = [ "derive" "rc" ]; } { - name = "bytes"; - packageId = "bytes"; + name = "serde_json"; + packageId = "serde_json"; optional = true; - usesDefaultFeatures = false; + features = [ "raw_value" ]; } { - name = "crypto-bigint"; - packageId = "crypto-bigint 0.7.4"; - rename = "bigint"; + name = "sha2"; + packageId = "sha2 0.10.9"; optional = true; usesDefaultFeatures = false; - features = [ "alloc" ]; } { - name = "ctutils"; - packageId = "ctutils"; - optional = true; + name = "smallvec"; + packageId = "smallvec"; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; usesDefaultFeatures = false; + features = [ "std" ]; } { - name = "digest"; - packageId = "digest 0.11.3"; + name = "tokio"; + packageId = "tokio"; optional = true; usesDefaultFeatures = false; + features = [ "time" "net" "sync" "fs" "io-util" "rt" ]; } { - name = "pem-rfc7468"; - packageId = "pem-rfc7468 1.0.0"; + name = "tokio-stream"; + packageId = "tokio-stream"; optional = true; + features = [ "fs" ]; } { - name = "zeroize"; - packageId = "zeroize"; + name = "tracing"; + packageId = "tracing"; + features = [ "log" ]; + } + { + name = "url"; + packageId = "url"; + } + { + name = "webpki-roots"; + packageId = "webpki-roots 1.0.8"; optional = true; - usesDefaultFeatures = false; + } + ]; + devDependencies = [ + { + name = "tokio"; + packageId = "tokio"; + features = [ "rt" ]; } ]; features = { - "alloc" = [ "base64ct?/alloc" "pem-rfc7468?/alloc" "zeroize?/alloc" ]; - "base64" = [ "dep:base64ct" ]; - "bigint" = [ "alloc" "zeroize" "dep:bigint" ]; - "bytes" = [ "alloc" "dep:bytes" ]; - "ctutils" = [ "dep:ctutils" ]; - "derive" = [ "ssh-derive" ]; - "digest" = [ "dep:digest" ]; - "pem" = [ "base64" "dep:pem-rfc7468" ]; - "ssh-derive" = [ "dep:ssh-derive" ]; - "zeroize" = [ "dep:zeroize" ]; + "_rt-async-global-executor" = [ "async-global-executor" "_rt-async-io" "_rt-async-task" ]; + "_rt-async-io" = [ "async-io" "async-fs" ]; + "_rt-async-std" = [ "async-std" "_rt-async-io" ]; + "_rt-async-task" = [ "async-task" ]; + "_rt-smol" = [ "smol" "_rt-async-io" "_rt-async-task" ]; + "_rt-tokio" = [ "tokio" "tokio-stream" ]; + "_tls-native-tls" = [ "native-tls" ]; + "_tls-rustls" = [ "rustls" ]; + "_tls-rustls-aws-lc-rs" = [ "_tls-rustls" "rustls/aws-lc-rs" "webpki-roots" ]; + "_tls-rustls-ring-native-roots" = [ "_tls-rustls" "rustls/ring" "rustls-native-certs" ]; + "_tls-rustls-ring-webpki" = [ "_tls-rustls" "rustls/ring" "webpki-roots" ]; + "_unstable-doc" = [ "sqlx-toml" ]; + "async-fs" = [ "dep:async-fs" ]; + "async-global-executor" = [ "dep:async-global-executor" ]; + "async-io" = [ "dep:async-io" ]; + "async-std" = [ "dep:async-std" ]; + "async-task" = [ "dep:async-task" ]; + "bigdecimal" = [ "dep:bigdecimal" ]; + "bit-vec" = [ "dep:bit-vec" ]; + "bstr" = [ "dep:bstr" ]; + "chrono" = [ "dep:chrono" ]; + "crc" = [ "dep:crc" ]; + "ipnet" = [ "dep:ipnet" ]; + "ipnetwork" = [ "dep:ipnetwork" ]; + "json" = [ "serde" "serde_json" ]; + "mac_address" = [ "dep:mac_address" ]; + "migrate" = [ "sha2" "crc" ]; + "native-tls" = [ "dep:native-tls" ]; + "offline" = [ "serde" "either/serde" ]; + "rust_decimal" = [ "dep:rust_decimal" ]; + "rustls" = [ "dep:rustls" ]; + "rustls-native-certs" = [ "dep:rustls-native-certs" ]; + "serde" = [ "dep:serde" ]; + "serde_json" = [ "dep:serde_json" ]; + "sha2" = [ "dep:sha2" ]; + "smol" = [ "dep:smol" ]; + "sqlx-toml" = [ "serde" "toml/parse" ]; + "time" = [ "dep:time" ]; + "tokio" = [ "dep:tokio" ]; + "tokio-stream" = [ "dep:tokio-stream" ]; + "toml" = [ "dep:toml" ]; + "uuid" = [ "dep:uuid" ]; + "webpki-roots" = [ "dep:webpki-roots" ]; }; - resolvedDefaultFeatures = [ "alloc" "base64" "bigint" "bytes" "ctutils" "digest" "pem" "zeroize" ]; + resolvedDefaultFeatures = [ "_rt-tokio" "_tls-rustls" "_tls-rustls-aws-lc-rs" "any" "chrono" "crc" "default" "json" "migrate" "offline" "rustls" "serde" "serde_json" "sha2" "tokio" "tokio-stream" "webpki-roots" ]; }; - "ssh-key" = rec { - crateName = "ssh-key"; - version = "0.7.0-rc.10"; - edition = "2024"; - sha256 = "0jz7310si1fzh5cd7p63cd886ybzvv7w8574m7j90mm9vvimqws5"; - libName = "ssh_key"; + "sqlx-macros" = rec { + crateName = "sqlx-macros"; + version = "0.9.0"; + edition = "2021"; + sha256 = "1gv0dg1dsz4jazi42jd2sjxl2jlk3jhqbivyy9g7199rpkr88axx"; + procMacro = true; + libName = "sqlx_macros"; authors = [ - "RustCrypto Developers" + "Ryan Leckey " + "Austin Bonander " + "Chloe Ross " + "Daniel Akhterov " ]; dependencies = [ { - name = "argon2"; - packageId = "argon2"; - optional = true; + name = "proc-macro2"; + packageId = "proc-macro2"; usesDefaultFeatures = false; - features = [ "alloc" ]; } { - name = "bcrypt-pbkdf"; - packageId = "bcrypt-pbkdf"; - optional = true; + name = "quote"; + packageId = "quote"; usesDefaultFeatures = false; - features = [ "alloc" ]; } { - name = "ctutils"; - packageId = "ctutils"; + name = "sqlx-core"; + packageId = "sqlx-core"; + features = [ "any" ]; + } + { + name = "sqlx-macros-core"; + packageId = "sqlx-macros-core"; + } + { + name = "syn"; + packageId = "syn 2.0.118"; usesDefaultFeatures = false; + features = [ "parsing" "proc-macro" ]; + } + ]; + features = { + "_rt-async-global-executor" = [ "sqlx-macros-core/_rt-async-global-executor" ]; + "_rt-async-std" = [ "sqlx-macros-core/_rt-async-std" ]; + "_rt-smol" = [ "sqlx-macros-core/_rt-smol" ]; + "_rt-tokio" = [ "sqlx-macros-core/_rt-tokio" ]; + "_tls-native-tls" = [ "sqlx-macros-core/_tls-native-tls" ]; + "_tls-rustls-aws-lc-rs" = [ "sqlx-macros-core/_tls-rustls-aws-lc-rs" ]; + "_tls-rustls-ring-native-roots" = [ "sqlx-macros-core/_tls-rustls-ring-native-roots" ]; + "_tls-rustls-ring-webpki" = [ "sqlx-macros-core/_tls-rustls-ring-webpki" ]; + "bigdecimal" = [ "sqlx-macros-core/bigdecimal" ]; + "bit-vec" = [ "sqlx-macros-core/bit-vec" ]; + "chrono" = [ "sqlx-macros-core/chrono" ]; + "derive" = [ "sqlx-macros-core/derive" ]; + "ipnet" = [ "sqlx-macros-core/ipnet" ]; + "ipnetwork" = [ "sqlx-macros-core/ipnetwork" ]; + "json" = [ "sqlx-macros-core/json" ]; + "mac_address" = [ "sqlx-macros-core/mac_address" ]; + "macros" = [ "sqlx-macros-core/macros" ]; + "migrate" = [ "sqlx-macros-core/migrate" ]; + "mysql" = [ "sqlx-macros-core/mysql" ]; + "mysql-rsa" = [ "sqlx-macros-core/mysql-rsa" ]; + "postgres" = [ "sqlx-macros-core/postgres" ]; + "rust_decimal" = [ "sqlx-macros-core/rust_decimal" ]; + "sqlite" = [ "sqlx-macros-core/sqlite" ]; + "sqlite-load-extension" = [ "sqlx-macros-core/sqlite-load-extension" ]; + "sqlite-unbundled" = [ "sqlx-macros-core/sqlite-unbundled" ]; + "sqlx-toml" = [ "sqlx-macros-core/sqlx-toml" ]; + "time" = [ "sqlx-macros-core/time" ]; + "uuid" = [ "sqlx-macros-core/uuid" ]; + }; + resolvedDefaultFeatures = [ "_rt-tokio" "_tls-rustls-aws-lc-rs" "chrono" "default" "derive" "macros" "migrate" "postgres" ]; + }; + "sqlx-macros-core" = rec { + crateName = "sqlx-macros-core"; + version = "0.9.0"; + edition = "2021"; + sha256 = "1hy7va6r1xvmbxaldw4qpa07wqzc4fsk4d41xk2ab1fwbzg9d3gv"; + libName = "sqlx_macros_core"; + authors = [ + "Ryan Leckey " + "Austin Bonander " + "Chloe Ross " + "Daniel Akhterov " + ]; + dependencies = [ + { + name = "cfg-if"; + packageId = "cfg-if"; } { - name = "ed25519-dalek"; - packageId = "ed25519-dalek 3.0.0-rc.0"; - optional = true; + name = "dotenvy"; + packageId = "dotenvy"; usesDefaultFeatures = false; } + { + name = "either"; + packageId = "either"; + } + { + name = "heck"; + packageId = "heck"; + } { name = "hex"; packageId = "hex"; - optional = true; - usesDefaultFeatures = false; - features = [ "alloc" ]; } { - name = "hmac"; - packageId = "hmac 0.13.0"; - optional = true; + name = "proc-macro2"; + packageId = "proc-macro2"; + usesDefaultFeatures = false; } { - name = "p256"; - packageId = "p256 0.14.0-rc.10"; - optional = true; + name = "quote"; + packageId = "quote"; usesDefaultFeatures = false; - features = [ "ecdsa" ]; } { - name = "p384"; - packageId = "p384 0.14.0-rc.10"; - optional = true; - usesDefaultFeatures = false; - features = [ "ecdsa" ]; + name = "serde"; + packageId = "serde"; + features = [ "derive" ]; } { - name = "p521"; - packageId = "p521"; - optional = true; - usesDefaultFeatures = false; - features = [ "ecdsa" ]; + name = "serde_json"; + packageId = "serde_json"; } { - name = "rand_core"; - packageId = "rand_core 0.10.1"; - optional = true; - usesDefaultFeatures = false; + name = "sha2"; + packageId = "sha2 0.10.9"; } { - name = "rsa"; - packageId = "rsa 0.10.0-rc.18"; - optional = true; - usesDefaultFeatures = false; - features = [ "sha2" ]; + name = "sqlx-core"; + packageId = "sqlx-core"; + features = [ "offline" ]; } { - name = "sec1"; - packageId = "sec1 0.8.1"; + name = "sqlx-mysql"; + packageId = "sqlx-mysql"; optional = true; usesDefaultFeatures = false; - features = [ "point" ]; + features = [ "offline" "migrate" ]; } { - name = "sha1"; - packageId = "sha1 0.11.0"; + name = "sqlx-postgres"; + packageId = "sqlx-postgres"; optional = true; - usesDefaultFeatures = false; - features = [ "oid" ]; + features = [ "offline" "migrate" ]; } { - name = "sha2"; - packageId = "sha2 0.11.0"; - usesDefaultFeatures = false; + name = "sqlx-sqlite"; + packageId = "sqlx-sqlite"; + optional = true; + features = [ "offline" "migrate" ]; } { - name = "signature"; - packageId = "signature 3.0.0"; + name = "syn"; + packageId = "syn 2.0.118"; + usesDefaultFeatures = false; + features = [ "full" "derive" "parsing" "printing" "clone-impls" ]; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + optional = true; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "tokio"; + packageId = "tokio"; + optional = true; + usesDefaultFeatures = false; + features = [ "time" "net" "sync" "fs" "io-util" "rt" ]; + } + { + name = "url"; + packageId = "url"; + } + ]; + features = { + "_rt-async-global-executor" = [ "async-global-executor" "sqlx-core/_rt-async-global-executor" ]; + "_rt-async-std" = [ "async-std" "sqlx-core/_rt-async-std" ]; + "_rt-smol" = [ "smol" "sqlx-core/_rt-smol" ]; + "_rt-tokio" = [ "tokio" "sqlx-core/_rt-tokio" ]; + "_tls-native-tls" = [ "sqlx-core/_tls-native-tls" ]; + "_tls-rustls-aws-lc-rs" = [ "sqlx-core/_tls-rustls-aws-lc-rs" ]; + "_tls-rustls-ring-native-roots" = [ "sqlx-core/_tls-rustls-ring-native-roots" ]; + "_tls-rustls-ring-webpki" = [ "sqlx-core/_tls-rustls-ring-webpki" ]; + "async-global-executor" = [ "dep:async-global-executor" ]; + "async-std" = [ "dep:async-std" ]; + "bigdecimal" = [ "sqlx-core/bigdecimal" "sqlx-mysql?/bigdecimal" "sqlx-postgres?/bigdecimal" ]; + "bit-vec" = [ "sqlx-core/bit-vec" "sqlx-postgres?/bit-vec" ]; + "chrono" = [ "sqlx-core/chrono" "sqlx-mysql?/chrono" "sqlx-postgres?/chrono" "sqlx-sqlite?/chrono" ]; + "ipnet" = [ "sqlx-core/ipnet" "sqlx-postgres?/ipnet" ]; + "ipnetwork" = [ "sqlx-core/ipnetwork" "sqlx-postgres?/ipnetwork" ]; + "json" = [ "sqlx-core/json" "sqlx-mysql?/json" "sqlx-postgres?/json" "sqlx-sqlite?/json" ]; + "mac_address" = [ "sqlx-core/mac_address" "sqlx-postgres?/mac_address" ]; + "macros" = [ "thiserror" ]; + "migrate" = [ "sqlx-core/migrate" ]; + "mysql" = [ "sqlx-mysql" ]; + "mysql-rsa" = [ "mysql" "sqlx-mysql/rsa" ]; + "postgres" = [ "sqlx-postgres" ]; + "rust_decimal" = [ "sqlx-core/rust_decimal" "sqlx-mysql?/rust_decimal" "sqlx-postgres?/rust_decimal" ]; + "smol" = [ "dep:smol" ]; + "sqlite" = [ "_sqlite" "sqlx-sqlite/bundled" ]; + "sqlite-load-extension" = [ "sqlx-sqlite/load-extension" ]; + "sqlite-unbundled" = [ "_sqlite" "sqlx-sqlite/unbundled" ]; + "sqlx-mysql" = [ "dep:sqlx-mysql" ]; + "sqlx-postgres" = [ "dep:sqlx-postgres" ]; + "sqlx-sqlite" = [ "dep:sqlx-sqlite" ]; + "sqlx-toml" = [ "sqlx-core/sqlx-toml" "sqlx-sqlite?/sqlx-toml" ]; + "thiserror" = [ "dep:thiserror" ]; + "time" = [ "sqlx-core/time" "sqlx-mysql?/time" "sqlx-postgres?/time" "sqlx-sqlite?/time" ]; + "tokio" = [ "dep:tokio" ]; + "uuid" = [ "sqlx-core/uuid" "sqlx-mysql?/uuid" "sqlx-postgres?/uuid" "sqlx-sqlite?/uuid" ]; + }; + resolvedDefaultFeatures = [ "_rt-tokio" "_tls-rustls-aws-lc-rs" "chrono" "default" "derive" "macros" "migrate" "postgres" "sqlx-postgres" "thiserror" "tokio" ]; + }; + "sqlx-mysql" = rec { + crateName = "sqlx-mysql"; + version = "0.9.0"; + edition = "2021"; + sha256 = "09zaxfn188mdcq178z2j75461iarxzbha9gsbcj2qpvww47h5f4h"; + libName = "sqlx_mysql"; + authors = [ + "Ryan Leckey " + "Austin Bonander " + "Chloe Ross " + "Daniel Akhterov " + ]; + dependencies = [ + { + name = "bitflags"; + packageId = "bitflags 2.13.0"; + usesDefaultFeatures = false; + } + { + name = "byteorder"; + packageId = "byteorder"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "bytes"; + packageId = "bytes"; + } + { + name = "chrono"; + packageId = "chrono"; + optional = true; + usesDefaultFeatures = false; + features = [ "std" "clock" ]; + } + { + name = "crc"; + packageId = "crc"; + optional = true; + } + { + name = "digest"; + packageId = "digest 0.11.3"; + usesDefaultFeatures = false; + features = [ "alloc" ]; + } + { + name = "dotenvy"; + packageId = "dotenvy"; + usesDefaultFeatures = false; + } + { + name = "either"; + packageId = "either"; + } + { + name = "futures-core"; + packageId = "futures-core"; + usesDefaultFeatures = false; + } + { + name = "futures-util"; + packageId = "futures-util"; + usesDefaultFeatures = false; + features = [ "alloc" "sink" "io" ]; + } + { + name = "generic-array"; + packageId = "generic-array 0.14.9"; + usesDefaultFeatures = false; + } + { + name = "log"; + packageId = "log"; + } + { + name = "percent-encoding"; + packageId = "percent-encoding"; + } + { + name = "serde"; + packageId = "serde"; + optional = true; + } + { + name = "sha1"; + packageId = "sha1 0.11.0"; + usesDefaultFeatures = false; + } + { + name = "sha2"; + packageId = "sha2 0.11.0"; + usesDefaultFeatures = false; + } + { + name = "sqlx-core"; + packageId = "sqlx-core"; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "tracing"; + packageId = "tracing"; + features = [ "log" ]; + } + ]; + features = { + "any" = [ "sqlx-core/any" ]; + "bigdecimal" = [ "dep:bigdecimal" "sqlx-core/bigdecimal" ]; + "chrono" = [ "dep:chrono" "sqlx-core/chrono" ]; + "json" = [ "sqlx-core/json" "serde" ]; + "migrate" = [ "sqlx-core/migrate" "dep:crc" ]; + "offline" = [ "sqlx-core/offline" "serde/derive" "bitflags/serde" ]; + "rsa" = [ "dep:rand" "dep:rsa" ]; + "rust_decimal" = [ "dep:rust_decimal" "rust_decimal/maths" "sqlx-core/rust_decimal" ]; + "serde" = [ "dep:serde" ]; + "time" = [ "dep:time" "sqlx-core/time" ]; + "uuid" = [ "dep:uuid" "sqlx-core/uuid" ]; + }; + resolvedDefaultFeatures = [ "chrono" "migrate" "offline" "serde" ]; + }; + "sqlx-postgres" = rec { + crateName = "sqlx-postgres"; + version = "0.9.0"; + edition = "2021"; + sha256 = "0pnnviwmykb7q6rd0hss6mc8nl1hh1bfx7ya4njkwsrzx3bbv8l7"; + libName = "sqlx_postgres"; + authors = [ + "Ryan Leckey " + "Austin Bonander " + "Chloe Ross " + "Daniel Akhterov " + ]; + dependencies = [ + { + name = "atoi"; + packageId = "atoi"; + } + { + name = "base64"; + packageId = "base64"; + usesDefaultFeatures = false; + features = [ "alloc" ]; + } + { + name = "bitflags"; + packageId = "bitflags 2.13.0"; + usesDefaultFeatures = false; + } + { + name = "byteorder"; + packageId = "byteorder"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "chrono"; + packageId = "chrono"; + optional = true; + usesDefaultFeatures = false; + features = [ "std" "clock" ]; + } + { + name = "crc"; + packageId = "crc"; + optional = true; + } + { + name = "dotenvy"; + packageId = "dotenvy"; + usesDefaultFeatures = false; + } + { + name = "etcetera"; + packageId = "etcetera"; + target = { target, features }: ("windows" == target."os" or null); + } + { + name = "futures-channel"; + packageId = "futures-channel"; + usesDefaultFeatures = false; + features = [ "sink" "alloc" "std" ]; + } + { + name = "futures-core"; + packageId = "futures-core"; + usesDefaultFeatures = false; + } + { + name = "futures-util"; + packageId = "futures-util"; + usesDefaultFeatures = false; + features = [ "alloc" "sink" "io" ]; + } + { + name = "hex"; + packageId = "hex"; + } + { + name = "hkdf"; + packageId = "hkdf 0.13.0"; + } + { + name = "hmac"; + packageId = "hmac 0.13.0"; + usesDefaultFeatures = false; + } + { + name = "itoa"; + packageId = "itoa"; + } + { + name = "log"; + packageId = "log"; + } + { + name = "md-5"; + packageId = "md-5"; + usesDefaultFeatures = false; + } + { + name = "memchr"; + packageId = "memchr"; + usesDefaultFeatures = false; + } + { + name = "rand"; + packageId = "rand 0.10.1"; + usesDefaultFeatures = false; + features = [ "thread_rng" ]; + } + { + name = "serde"; + packageId = "serde"; + optional = true; + features = [ "derive" ]; + } + { + name = "serde_json"; + packageId = "serde_json"; + optional = true; + features = [ "raw_value" ]; + } + { + name = "sha2"; + packageId = "sha2 0.11.0"; + usesDefaultFeatures = false; + } + { + name = "smallvec"; + packageId = "smallvec"; + } + { + name = "sqlx-core"; + packageId = "sqlx-core"; + } + { + name = "stringprep"; + packageId = "stringprep"; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "tracing"; + packageId = "tracing"; + features = [ "log" ]; + } + { + name = "whoami"; + packageId = "whoami"; + usesDefaultFeatures = false; + } + ]; + features = { + "any" = [ "sqlx-core/any" ]; + "bigdecimal" = [ "dep:bigdecimal" "dep:num-bigint" "sqlx-core/bigdecimal" ]; + "bit-vec" = [ "dep:bit-vec" "sqlx-core/bit-vec" ]; + "chrono" = [ "dep:chrono" "sqlx-core/chrono" ]; + "ipnet" = [ "dep:ipnet" "sqlx-core/ipnet" ]; + "ipnetwork" = [ "dep:ipnetwork" "sqlx-core/ipnetwork" ]; + "json" = [ "dep:serde" "dep:serde_json" "sqlx-core/json" ]; + "mac_address" = [ "dep:mac_address" "sqlx-core/mac_address" ]; + "migrate" = [ "sqlx-core/migrate" "dep:crc" ]; + "offline" = [ "json" "sqlx-core/offline" "smallvec/serde" ]; + "rust_decimal" = [ "dep:rust_decimal" "rust_decimal/maths" "sqlx-core/rust_decimal" ]; + "time" = [ "dep:time" "sqlx-core/time" ]; + "uuid" = [ "dep:uuid" "sqlx-core/uuid" ]; + }; + resolvedDefaultFeatures = [ "chrono" "json" "migrate" "offline" ]; + }; + "sqlx-sqlite" = rec { + crateName = "sqlx-sqlite"; + version = "0.9.0"; + edition = "2021"; + sha256 = "0b4q5vpdn854dz5209kdzjd365lq2yd6dv4s4bj0f856jz1rk3j8"; + libName = "sqlx_sqlite"; + authors = [ + "Ryan Leckey " + "Austin Bonander " + "Chloe Ross " + "Daniel Akhterov " + ]; + dependencies = [ + { + name = "atoi"; + packageId = "atoi"; + } + { + name = "chrono"; + packageId = "chrono"; + optional = true; + usesDefaultFeatures = false; + features = [ "std" "clock" ]; + } + { + name = "flume"; + packageId = "flume"; + usesDefaultFeatures = false; + features = [ "async" ]; + } + { + name = "form_urlencoded"; + packageId = "form_urlencoded"; + } + { + name = "futures-channel"; + packageId = "futures-channel"; + usesDefaultFeatures = false; + features = [ "sink" "alloc" "std" ]; + } + { + name = "futures-core"; + packageId = "futures-core"; + usesDefaultFeatures = false; + } + { + name = "futures-executor"; + packageId = "futures-executor"; + } + { + name = "futures-intrusive"; + packageId = "futures-intrusive"; + } + { + name = "futures-util"; + packageId = "futures-util"; + usesDefaultFeatures = false; + features = [ "alloc" "sink" ]; + } + { + name = "libsqlite3-sys"; + packageId = "libsqlite3-sys"; + usesDefaultFeatures = false; + features = [ "pkg-config" "vcpkg" ]; + } + { + name = "log"; + packageId = "log"; + } + { + name = "percent-encoding"; + packageId = "percent-encoding"; + } + { + name = "serde"; + packageId = "serde"; + optional = true; + features = [ "derive" ]; + } + { + name = "sqlx-core"; + packageId = "sqlx-core"; + } + { + name = "thiserror"; + packageId = "thiserror 2.0.18"; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "tracing"; + packageId = "tracing"; + features = [ "log" ]; + } + { + name = "url"; + packageId = "url"; + } + ]; + features = { + "_unstable-all-sqlite-features" = [ "deserialize" "load-extension" "preupdate-hook" "unlock-notify" ]; + "_unstable-all-types" = [ "json" "chrono" "time" "uuid" ]; + "_unstable-docs" = [ "bundled" "any" "_unstable-all-types" "_unstable-all-sqlite-features" ]; + "any" = [ "sqlx-core/any" ]; + "bundled" = [ "libsqlite3-sys/bundled" ]; + "chrono" = [ "dep:chrono" "sqlx-core/chrono" ]; + "json" = [ "sqlx-core/json" "serde" ]; + "migrate" = [ "sqlx-core/migrate" ]; + "offline" = [ "sqlx-core/offline" "serde" ]; + "preupdate-hook" = [ "libsqlite3-sys/preupdate_hook" ]; + "regexp" = [ "dep:regex" ]; + "serde" = [ "dep:serde" ]; + "sqlx-toml" = [ "sqlx-core/sqlx-toml" ]; + "time" = [ "dep:time" "sqlx-core/time" ]; + "unbundled" = [ "libsqlite3-sys/buildtime_bindgen" ]; + "unlock-notify" = [ "libsqlite3-sys/unlock_notify" ]; + "uuid" = [ "dep:uuid" "sqlx-core/uuid" ]; + }; + resolvedDefaultFeatures = [ "chrono" "migrate" "offline" "serde" ]; + }; + "ssh-cipher" = rec { + crateName = "ssh-cipher"; + version = "0.3.0-rc.9"; + edition = "2024"; + sha256 = "0dnfvmgirpfywhmyfmqfbgb95mnsbkadj169ks7m5a4nj4hnznqh"; + libName = "ssh_cipher"; + authors = [ + "RustCrypto Developers" + ]; + dependencies = [ + { + name = "aead"; + packageId = "aead 0.6.1"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "aes"; + packageId = "aes 0.9.1"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "aes-gcm"; + packageId = "aes-gcm 0.11.0-rc.4"; + optional = true; + usesDefaultFeatures = false; + features = [ "aes" ]; + } + { + name = "cbc"; + packageId = "cbc"; + optional = true; + } + { + name = "chacha20"; + packageId = "chacha20"; + optional = true; + usesDefaultFeatures = false; + features = [ "cipher" "legacy" ]; + } + { + name = "cipher"; + packageId = "cipher 0.5.2"; + } + { + name = "ctr"; + packageId = "ctr 0.10.1"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "ctutils"; + packageId = "ctutils"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "des"; + packageId = "des"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "poly1305"; + packageId = "poly1305"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "ssh-encoding"; + packageId = "ssh-encoding"; + rename = "encoding"; + } + { + name = "zeroize"; + packageId = "zeroize"; + optional = true; + usesDefaultFeatures = false; + } + ]; + features = { + "aes-cbc" = [ "dep:aes" "dep:cbc" ]; + "aes-ctr" = [ "dep:aes" "dep:ctr" ]; + "aes-gcm" = [ "dep:aead" "dep:aes" "dep:aes-gcm" ]; + "chacha20poly1305" = [ "dep:aead" "dep:chacha20" "dep:poly1305" "dep:ctutils" ]; + "tdes" = [ "dep:des" "dep:cbc" ]; + "zeroize" = [ "dep:zeroize" "aes?/zeroize" "aes-gcm?/zeroize" "chacha20?/zeroize" "des?/zeroize" "poly1305?/zeroize" ]; + }; + resolvedDefaultFeatures = [ "aes-cbc" "aes-ctr" "aes-gcm" "chacha20poly1305" "zeroize" ]; + }; + "ssh-encoding" = rec { + crateName = "ssh-encoding"; + version = "0.3.0-rc.9"; + edition = "2024"; + sha256 = "0sn9z0zqda7n5sknikcj40wsp0m25q26v4wnqjsdb9bdf6m39gvs"; + libName = "ssh_encoding"; + authors = [ + "RustCrypto Developers" + ]; + dependencies = [ + { + name = "base64ct"; + packageId = "base64ct"; + optional = true; + } + { + name = "bytes"; + packageId = "bytes"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "crypto-bigint"; + packageId = "crypto-bigint 0.7.4"; + rename = "bigint"; + optional = true; + usesDefaultFeatures = false; + features = [ "alloc" ]; + } + { + name = "ctutils"; + packageId = "ctutils"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "digest"; + packageId = "digest 0.11.3"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "pem-rfc7468"; + packageId = "pem-rfc7468 1.0.0"; + optional = true; + } + { + name = "zeroize"; + packageId = "zeroize"; + optional = true; + usesDefaultFeatures = false; + } + ]; + features = { + "alloc" = [ "base64ct?/alloc" "pem-rfc7468?/alloc" "zeroize?/alloc" ]; + "base64" = [ "dep:base64ct" ]; + "bigint" = [ "alloc" "zeroize" "dep:bigint" ]; + "bytes" = [ "alloc" "dep:bytes" ]; + "ctutils" = [ "dep:ctutils" ]; + "derive" = [ "ssh-derive" ]; + "digest" = [ "dep:digest" ]; + "pem" = [ "base64" "dep:pem-rfc7468" ]; + "ssh-derive" = [ "dep:ssh-derive" ]; + "zeroize" = [ "dep:zeroize" ]; + }; + resolvedDefaultFeatures = [ "alloc" "base64" "bigint" "bytes" "ctutils" "digest" "pem" "zeroize" ]; + }; + "ssh-key" = rec { + crateName = "ssh-key"; + version = "0.7.0-rc.10"; + edition = "2024"; + sha256 = "0jz7310si1fzh5cd7p63cd886ybzvv7w8574m7j90mm9vvimqws5"; + libName = "ssh_key"; + authors = [ + "RustCrypto Developers" + ]; + dependencies = [ + { + name = "argon2"; + packageId = "argon2"; + optional = true; + usesDefaultFeatures = false; + features = [ "alloc" ]; + } + { + name = "bcrypt-pbkdf"; + packageId = "bcrypt-pbkdf"; + optional = true; + usesDefaultFeatures = false; + features = [ "alloc" ]; + } + { + name = "ctutils"; + packageId = "ctutils"; + usesDefaultFeatures = false; + } + { + name = "ed25519-dalek"; + packageId = "ed25519-dalek 3.0.0-rc.0"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "hex"; + packageId = "hex"; + optional = true; + usesDefaultFeatures = false; + features = [ "alloc" ]; + } + { + name = "hmac"; + packageId = "hmac 0.13.0"; + optional = true; + } + { + name = "p256"; + packageId = "p256 0.14.0-rc.10"; + optional = true; + usesDefaultFeatures = false; + features = [ "ecdsa" ]; + } + { + name = "p384"; + packageId = "p384 0.14.0-rc.10"; + optional = true; + usesDefaultFeatures = false; + features = [ "ecdsa" ]; + } + { + name = "p521"; + packageId = "p521"; + optional = true; + usesDefaultFeatures = false; + features = [ "ecdsa" ]; + } + { + name = "rand_core"; + packageId = "rand_core 0.10.1"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "rsa"; + packageId = "rsa 0.10.0-rc.18"; + optional = true; + usesDefaultFeatures = false; + features = [ "sha2" ]; + } + { + name = "sec1"; + packageId = "sec1 0.8.1"; + optional = true; + usesDefaultFeatures = false; + features = [ "point" ]; + } + { + name = "sha1"; + packageId = "sha1 0.11.0"; + optional = true; + usesDefaultFeatures = false; + features = [ "oid" ]; + } + { + name = "sha2"; + packageId = "sha2 0.11.0"; + usesDefaultFeatures = false; + } + { + name = "signature"; + packageId = "signature 3.0.0"; usesDefaultFeatures = false; } { @@ -31140,6 +34009,30 @@ rec { } ]; + }; + "stringprep" = rec { + crateName = "stringprep"; + version = "0.1.5"; + edition = "2015"; + sha256 = "1cb3jis4h2b767csk272zw92lc6jzfzvh8d6m1cd86yqjb9z6kbv"; + authors = [ + "Steven Fackler " + ]; + dependencies = [ + { + name = "unicode-bidi"; + packageId = "unicode-bidi"; + } + { + name = "unicode-normalization"; + packageId = "unicode-normalization"; + } + { + name = "unicode-properties"; + packageId = "unicode-properties"; + } + ]; + }; "strsim" = rec { crateName = "strsim"; @@ -31166,6 +34059,45 @@ rec { }; resolvedDefaultFeatures = [ "const-generics" "default" "i128" "std" ]; }; + "supports-color" = rec { + crateName = "supports-color"; + version = "3.0.2"; + edition = "2018"; + sha256 = "1mk7r2j6l7zmqk3pg7av0l6viq413lmk1vz4bjnf9lnq5liwfky6"; + libName = "supports_color"; + authors = [ + "Kat Marchán " + ]; + dependencies = [ + { + name = "is_ci"; + packageId = "is_ci"; + } + ]; + + }; + "supports-hyperlinks" = rec { + crateName = "supports-hyperlinks"; + version = "3.2.0"; + edition = "2021"; + sha256 = "14byz5m3mcfz8jcg3vd639sp5qvd6svs05di40qvik0i7d9bd5p3"; + libName = "supports_hyperlinks"; + authors = [ + "Kat Marchán " + ]; + + }; + "supports-unicode" = rec { + crateName = "supports-unicode"; + version = "3.0.0"; + edition = "2018"; + sha256 = "1qpc344453x3ai4k9iygxnbk6lr2nw5jflj8ns5q3dbcmwq1lh5p"; + libName = "supports_unicode"; + authors = [ + "Kat Marchán " + ]; + + }; "syn 2.0.118" = rec { crateName = "syn"; version = "2.0.118"; @@ -31999,6 +34931,36 @@ rec { ]; }; + "textwrap" = rec { + crateName = "textwrap"; + version = "0.16.2"; + edition = "2021"; + sha256 = "0mrhd8q0dnh5hwbwhiv89c6i41yzmhw4clwa592rrp24b9hlfdf1"; + authors = [ + "Martin Geisler " + ]; + dependencies = [ + { + name = "unicode-linebreak"; + packageId = "unicode-linebreak"; + optional = true; + } + { + name = "unicode-width"; + packageId = "unicode-width 0.2.2"; + optional = true; + } + ]; + features = { + "default" = [ "unicode-linebreak" "unicode-width" "smawk" ]; + "hyphenation" = [ "dep:hyphenation" ]; + "smawk" = [ "dep:smawk" ]; + "terminal_size" = [ "dep:terminal_size" ]; + "unicode-linebreak" = [ "dep:unicode-linebreak" ]; + "unicode-width" = [ "dep:unicode-width" ]; + }; + resolvedDefaultFeatures = [ "unicode-linebreak" "unicode-width" ]; + }; "thiserror 1.0.69" = rec { crateName = "thiserror"; version = "1.0.69"; @@ -32455,6 +35417,11 @@ rec { target = { target, features }: ((target."tokio_unstable" or false) && ("linux" == target."os" or null)); features = [ "os-poll" "os-ext" ]; } + { + name = "parking_lot"; + packageId = "parking_lot"; + optional = true; + } { name = "pin-project-lite"; packageId = "pin-project-lite"; @@ -32523,7 +35490,7 @@ rec { "tracing" = [ "dep:tracing" ]; "windows-sys" = [ "dep:windows-sys" ]; }; - resolvedDefaultFeatures = [ "bytes" "default" "fs" "io-util" "libc" "macros" "mio" "net" "process" "rt" "rt-multi-thread" "signal" "signal-hook-registry" "socket2" "sync" "test-util" "time" "tokio-macros" "windows-sys" ]; + resolvedDefaultFeatures = [ "bytes" "default" "fs" "full" "io-std" "io-util" "libc" "macros" "mio" "net" "parking_lot" "process" "rt" "rt-multi-thread" "signal" "signal-hook-registry" "socket2" "sync" "test-util" "time" "tokio-macros" "windows-sys" ]; }; "tokio-macros" = rec { crateName = "tokio-macros"; @@ -32632,7 +35599,7 @@ rec { "time" = [ "tokio/time" ]; "tokio-util" = [ "dep:tokio-util" ]; }; - resolvedDefaultFeatures = [ "default" "time" ]; + resolvedDefaultFeatures = [ "default" "fs" "time" ]; }; "tokio-tungstenite 0.24.0" = rec { crateName = "tokio-tungstenite"; @@ -32998,6 +35965,132 @@ rec { "tonic09" = [ "dep:tonic09" ]; }; }; + "tokio-websockets" = rec { + crateName = "tokio-websockets"; + version = "0.13.3"; + edition = "2024"; + sha256 = "19bakkhl5vf6l4dh99br3gzh3h0r5hynyb76p2nwd9s4jdiznbnm"; + libName = "tokio_websockets"; + dependencies = [ + { + name = "aws-lc-rs"; + packageId = "aws-lc-rs"; + optional = true; + usesDefaultFeatures = false; + features = [ "aws-lc-sys" ]; + } + { + name = "base64"; + packageId = "base64"; + optional = true; + } + { + name = "bytes"; + packageId = "bytes"; + } + { + name = "futures-core"; + packageId = "futures-core"; + } + { + name = "futures-sink"; + packageId = "futures-sink"; + } + { + name = "http"; + packageId = "http"; + optional = true; + usesDefaultFeatures = false; + features = [ "std" ]; + } + { + name = "httparse"; + packageId = "httparse"; + optional = true; + } + { + name = "rand"; + packageId = "rand 0.10.1"; + optional = true; + usesDefaultFeatures = false; + features = [ "thread_rng" ]; + } + { + name = "rustls-native-certs"; + packageId = "rustls-native-certs"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "rustls-pki-types"; + packageId = "rustls-pki-types"; + optional = true; + } + { + name = "sha1_smol"; + packageId = "sha1_smol"; + optional = true; + } + { + name = "simdutf8"; + packageId = "simdutf8"; + usesDefaultFeatures = false; + features = [ "std" "aarch64_neon" ]; + } + { + name = "tokio"; + packageId = "tokio"; + } + { + name = "tokio-rustls"; + packageId = "tokio-rustls"; + optional = true; + usesDefaultFeatures = false; + } + { + name = "tokio-util"; + packageId = "tokio-util"; + features = [ "codec" "io" ]; + } + ]; + devDependencies = [ + { + name = "rustls-pki-types"; + packageId = "rustls-pki-types"; + } + { + name = "tokio"; + packageId = "tokio"; + usesDefaultFeatures = false; + features = [ "net" "macros" "rt-multi-thread" "time" ]; + } + { + name = "tokio-rustls"; + packageId = "tokio-rustls"; + usesDefaultFeatures = false; + features = [ "aws_lc_rs" ]; + } + ]; + features = { + "aws_lc_rs" = [ "dep:aws-lc-rs" ]; + "client" = [ "dep:base64" "dep:http" "dep:httparse" "tokio/net" "tokio/io-util" ]; + "fastrand" = [ "dep:fastrand" ]; + "getrandom" = [ "dep:getrandom" ]; + "native-tls" = [ "dep:tokio-native-tls" ]; + "nightly" = [ "simdutf8/aarch64_neon_prefetch" ]; + "openssl" = [ "dep:openssl" ]; + "rand" = [ "dep:rand" ]; + "ring" = [ "dep:ring" ]; + "rustls-bring-your-own-connector" = [ "dep:rustls-pki-types" "dep:tokio-rustls" ]; + "rustls-native-roots" = [ "dep:rustls-pki-types" "dep:tokio-rustls" "dep:rustls-native-certs" ]; + "rustls-platform-verifier" = [ "dep:rustls-pki-types" "dep:tokio-rustls" "dep:rustls-platform-verifier" ]; + "rustls-tls12" = [ "tokio-rustls?/tls12" ]; + "rustls-webpki-roots" = [ "dep:rustls-pki-types" "dep:tokio-rustls" "dep:webpki-roots" ]; + "server" = [ "dep:base64" "dep:http" "dep:httparse" "tokio/io-util" ]; + "sha1_smol" = [ "dep:sha1_smol" ]; + }; + resolvedDefaultFeatures = [ "aws_lc_rs" "client" "rand" "rustls-native-roots" "server" "sha1_smol" ]; + }; "toml" = rec { crateName = "toml"; version = "0.9.12+spec-1.1.0"; @@ -33378,7 +36471,7 @@ rec { "uuid" = [ "dep:uuid" ]; "validate-request" = [ "mime" ]; }; - resolvedDefaultFeatures = [ "decompression-br" "decompression-deflate" "decompression-gzip" "default" "follow-redirect" "futures-core" "futures-util" "tokio-util" "tower" "trace" "tracing" ]; + resolvedDefaultFeatures = [ "cors" "decompression-br" "decompression-deflate" "decompression-gzip" "decompression-zstd" "default" "follow-redirect" "futures-core" "futures-util" "tokio-util" "tower" "trace" "tracing" ]; }; "tower-http 0.7.0" = rec { crateName = "tower-http"; @@ -34282,6 +37375,23 @@ rec { }; resolvedDefaultFeatures = [ "__rustls-tls" "data-encoding" "handshake" "http" "httparse" "rustls" "rustls-pki-types" "sha1" ]; }; + "twox-hash" = rec { + crateName = "twox-hash"; + version = "2.1.4"; + edition = "2021"; + sha256 = "0yhin35iw4gq0b47f8682vyhk410pjs0nli0gcnfiscga57670sj"; + libName = "twox_hash"; + authors = [ + "Jake Goulding " + ]; + features = { + "default" = [ "random" "xxhash32" "xxhash64" "xxhash3_64" "xxhash3_128" "std" ]; + "random" = [ "dep:rand" ]; + "serialize" = [ "dep:serde" ]; + "std" = [ "alloc" ]; + }; + resolvedDefaultFeatures = [ "xxhash32" ]; + }; "typed-arena" = rec { crateName = "typed-arena"; version = "2.0.2"; @@ -34418,6 +37528,26 @@ rec { features = { }; }; + "unicode-bidi" = rec { + crateName = "unicode-bidi"; + version = "0.3.18"; + edition = "2018"; + sha256 = "1xcxwbsqa24b8vfchhzyyzgj0l6bn51ib5v8j6krha0m77dva72w"; + libName = "unicode_bidi"; + authors = [ + "The Servo Project Developers" + ]; + features = { + "default" = [ "std" "hardcoded-data" ]; + "flame" = [ "dep:flame" ]; + "flame_it" = [ "flame" "flamer" ]; + "flamer" = [ "dep:flamer" ]; + "serde" = [ "dep:serde" ]; + "smallvec" = [ "dep:smallvec" ]; + "with_serde" = [ "serde" ]; + }; + resolvedDefaultFeatures = [ "default" "hardcoded-data" "std" ]; + }; "unicode-bom" = rec { crateName = "unicode-bom"; version = "2.0.3"; @@ -34439,6 +37569,17 @@ rec { "David Tolnay " ]; + }; + "unicode-linebreak" = rec { + crateName = "unicode-linebreak"; + version = "0.1.5"; + edition = "2021"; + sha256 = "07spj2hh3daajg335m4wdav6nfkl0f6c0q72lc37blr97hych29v"; + libName = "unicode_linebreak"; + authors = [ + "Axel Forsman " + ]; + }; "unicode-normalization" = rec { crateName = "unicode-normalization"; @@ -34460,6 +37601,22 @@ rec { features = { "default" = [ "std" ]; }; + resolvedDefaultFeatures = [ "default" "std" ]; + }; + "unicode-properties" = rec { + crateName = "unicode-properties"; + version = "0.1.4"; + edition = "2021"; + sha256 = "07fpm3sqq7lm9gmgpxa93z31q933h3c3ypfwy4cdh6l42g3miw3x"; + libName = "unicode_properties"; + authors = [ + "Charles Lew " + "Manish Goregaokar " + ]; + features = { + "default" = [ "general-category" "emoji" ]; + }; + resolvedDefaultFeatures = [ "default" "emoji" "general-category" ]; }; "unicode-segmentation" = rec { crateName = "unicode-segmentation"; @@ -34474,7 +37631,7 @@ rec { features = { }; }; - "unicode-width" = rec { + "unicode-width 0.1.14" = rec { crateName = "unicode-width"; version = "0.1.14"; edition = "2021"; @@ -34493,6 +37650,24 @@ rec { }; resolvedDefaultFeatures = [ "cjk" "default" ]; }; + "unicode-width 0.2.2" = rec { + crateName = "unicode-width"; + version = "0.2.2"; + edition = "2021"; + sha256 = "0m7jjzlcccw716dy9423xxh0clys8pfpllc5smvfxrzdf66h9b5l"; + libName = "unicode_width"; + authors = [ + "kwantam " + "Manish Goregaokar " + ]; + features = { + "core" = [ "dep:core" ]; + "default" = [ "cjk" ]; + "rustc-dep-of-std" = [ "std" "core" ]; + "std" = [ "dep:std" ]; + }; + resolvedDefaultFeatures = [ "cjk" "default" ]; + }; "unicode-xid" = rec { crateName = "unicode-xid"; version = "0.2.6"; @@ -34831,6 +38006,20 @@ rec { }; resolvedDefaultFeatures = [ "alloc" "std" ]; }; + "varint-rs" = rec { + crateName = "varint-rs"; + version = "2.2.1"; + edition = "2018"; + sha256 = "15ix31l4jqiknfv7h006swkqmxdvz48mlznaq8g7y9gn123w79mz"; + libName = "varint_rs"; + authors = [ + "Leon Davis " + ]; + features = { + "default" = [ "std" "signed" ]; + }; + resolvedDefaultFeatures = [ "default" "signed" "std" ]; + }; "vcpkg" = rec { crateName = "vcpkg"; version = "0.2.15"; @@ -35763,6 +38952,18 @@ rec { ]; }; + "whoami" = rec { + crateName = "whoami"; + version = "2.1.3"; + edition = "2021"; + sha256 = "0b68vl8w5j02mblis170p6b1knsiqzmb40fb2by6zmsmcyn4nv32"; + features = { + "default" = [ "std" "wasi-wasite" "wasm-web" ]; + "std" = [ "dep:libc" "dep:libredox" "dep:objc2-system-configuration" "libc?/std" "web-sys?/std" ]; + "wasi-wasite" = [ "dep:wasite" ]; + "wasm-web" = [ "dep:web-sys" ]; + }; + }; "widestring" = rec { crateName = "widestring"; version = "1.2.1"; @@ -38101,7 +41302,7 @@ rec { "Win32_Web" = [ "Win32" ]; "Win32_Web_InternetExplorer" = [ "Win32_Web" ]; }; - resolvedDefaultFeatures = [ "Wdk" "Wdk_Foundation" "Wdk_Storage" "Wdk_Storage_FileSystem" "Wdk_System" "Wdk_System_IO" "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_Security" "Win32_Security_Authentication" "Win32_Security_Authentication_Identity" "Win32_Security_Authorization" "Win32_Security_Credentials" "Win32_Security_Cryptography" "Win32_Storage" "Win32_Storage_FileSystem" "Win32_System" "Win32_System_Console" "Win32_System_Diagnostics" "Win32_System_Diagnostics_Debug" "Win32_System_IO" "Win32_System_LibraryLoader" "Win32_System_Memory" "Win32_System_Pipes" "Win32_System_Registry" "Win32_System_SystemInformation" "Win32_System_SystemServices" "Win32_System_Threading" "Win32_System_WindowsProgramming" "default" ]; + resolvedDefaultFeatures = [ "Wdk" "Wdk_Foundation" "Wdk_Storage" "Wdk_Storage_FileSystem" "Wdk_System" "Wdk_System_IO" "Win32" "Win32_Foundation" "Win32_Networking" "Win32_Networking_WinSock" "Win32_Security" "Win32_Security_Authentication" "Win32_Security_Authentication_Identity" "Win32_Security_Authorization" "Win32_Security_Credentials" "Win32_Security_Cryptography" "Win32_Storage" "Win32_Storage_FileSystem" "Win32_System" "Win32_System_Com" "Win32_System_Console" "Win32_System_Diagnostics" "Win32_System_Diagnostics_Debug" "Win32_System_IO" "Win32_System_LibraryLoader" "Win32_System_Memory" "Win32_System_Pipes" "Win32_System_Registry" "Win32_System_SystemInformation" "Win32_System_SystemServices" "Win32_System_Threading" "Win32_System_WindowsProgramming" "Win32_UI" "Win32_UI_Shell" "default" ]; }; "windows-targets 0.42.2" = rec { crateName = "windows-targets"; diff --git a/nix/crate-hashes.json b/nix/crate-hashes.json index 75f05cde0..611431501 100644 --- a/nix/crate-hashes.json +++ b/nix/crate-hashes.json @@ -1,4 +1,8 @@ { + "git+https://github.com/90-008/fjall.git?rev=85a8ad9b3d327c39263cc547fa9944e7535e802f#fjall@3.1.8": "0cn23s3d9vrqz34xs50c2cxb4azr1fqv52fyh349hykfpa0apkzh", + "git+https://github.com/90-008/lsm-tree.git#lsm-tree@3.1.8": "1xkv3j4csa82xpxa6krpjcb1vvbdvih269li0nr31z3hlfskwyli", + "git+https://github.com/90-008/msgpack-rust.git?rev=19c54a922301d06310a816c3a6a097aeb73ea3ae#rmp-serde@1.3.1": "01ff1kx4njkslb2wkjp8912x5qchd6pf3c654y16i53n4ini6l6i", + "git+https://github.com/90-008/msgpack-rust.git?rev=19c54a922301d06310a816c3a6a097aeb73ea3ae#rmp@0.8.15": "01ff1kx4njkslb2wkjp8912x5qchd6pf3c654y16i53n4ini6l6i", "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba6377e0433c391d34f3#0.12.1": "1v8f0k6ncydb6rqpmdkq3aaaljc136xllniap4ksx9qb17rl9bkj", "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba6377e0433c391d34f3#jacquard-api@0.12.1": "1v8f0k6ncydb6rqpmdkq3aaaljc136xllniap4ksx9qb17rl9bkj", "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba6377e0433c391d34f3#jacquard-axum@0.12.1": "1v8f0k6ncydb6rqpmdkq3aaaljc136xllniap4ksx9qb17rl9bkj", @@ -7,5 +11,6 @@ "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba6377e0433c391d34f3#jacquard-identity@0.12.1": "1v8f0k6ncydb6rqpmdkq3aaaljc136xllniap4ksx9qb17rl9bkj", "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba6377e0433c391d34f3#jacquard-lexicon@0.12.1": "1v8f0k6ncydb6rqpmdkq3aaaljc136xllniap4ksx9qb17rl9bkj", "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba6377e0433c391d34f3#jacquard-oauth@0.12.1": "1v8f0k6ncydb6rqpmdkq3aaaljc136xllniap4ksx9qb17rl9bkj", - "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba6377e0433c391d34f3#mini-moka-wasm@0.10.99": "1v8f0k6ncydb6rqpmdkq3aaaljc136xllniap4ksx9qb17rl9bkj" + "git+https://tangled.org/oppi.li/jacquard?rev=bb32de36f1cc2727954fba6377e0433c391d34f3#mini-moka-wasm@0.10.99": "1v8f0k6ncydb6rqpmdkq3aaaljc136xllniap4ksx9qb17rl9bkj", + "git+https://tangled.org/ptr.pet/hydrant?rev=ccc1b1a3#0.1.0": "0gn9lqm2z6kq0qkbv97d07pk0gxafpx00l9xipff1f8sa9vyw55q" } \ No newline at end of file