diff --git a/Cargo.lock b/Cargo.lock index dd50e46..0a8d630 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,7 +34,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.82", + "syn", ] [[package]] @@ -50,13 +50,13 @@ dependencies = [ [[package]] name = "actix_derive" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c7db3d5a9718568e4cf4a537cfd7070e6e6ff7481510d0237fb529ac850f6d3" +checksum = "b6ac1e58cded18cb28ddc17143c4dea5345b3ad575e14f32f66e4054a56eb271" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] @@ -104,9 +104,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" [[package]] name = "android-tzdata" @@ -125,9 +125,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -140,43 +140,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" [[package]] name = "arc-swap" @@ -186,9 +186,9 @@ checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -204,9 +204,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "assert2" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "844ca3172d927ddd9d01f63b6c80f4ebd3e01c3f787c204626635450dfe3edba" +checksum = "d31fea2b6e18dfe892863c3a0a68f9e005b0195565f3d55b8612946ebca789cc" dependencies = [ "assert2-macros", "diff", @@ -216,25 +216,25 @@ dependencies = [ [[package]] name = "assert2-macros" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ec0e42bd0fe1c8d72c7bde53ac8686764cea0fd86f412b92fcad20fea08b489" +checksum = "3c1ac052c642f6d94e4be0b33028b346b7ab809ea5432b584eb8859f12f7ad2c" dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn", ] [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] @@ -245,9 +245,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" @@ -322,34 +322,35 @@ dependencies = [ [[package]] name = "bon" -version = "2.0.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3b71187ef9d11cfa48c023d574a00ec5e4850dcb145ef51619d99cc119486cb" +checksum = "97493a391b4b18ee918675fb8663e53646fd09321c58b46afa04e8ce2499c869" dependencies = [ "bon-macros", + "rustversion", ] [[package]] name = "bon-macros" -version = "2.0.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f8407447d440da7b3de982f286d15e30e7646bef4ebca994eebebaa1690fd9c" +checksum = "2a2af3eac944c12cdf4423eab70d310da0a8e5851a18ffb192c0a5e3f7ae1663" dependencies = [ "darling", "ident_case", "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] name = "bstr" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" dependencies = [ "memchr", - "regex-automata 0.4.7", + "regex-automata 0.4.9", "serde", ] @@ -367,9 +368,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "bytesize" @@ -394,9 +395,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.14" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d2eb3cd3d1bf4529e31c215ee6f93ec5a3d536d9f578f93d9d33ee19562932" +checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" dependencies = [ "shlex", ] @@ -407,6 +408,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.38" @@ -427,15 +434,15 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eebd66744a15ded14960ab4ccdbfb51ad3b81f51f3f04a80adac98c985396c9" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", "stacker", ] [[package]] name = "clap" -version = "4.5.16" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed6719fffa43d0d87e5fd8caeab59be1554fb028cd30edc88fc4369b17971019" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" dependencies = [ "clap_builder", "clap_derive", @@ -443,9 +450,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.15" +version = "4.5.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "216aec2b177652e3846684cbfe25c9964d18ec45234f0f5da5157b207ed1aab6" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" dependencies = [ "anstream", "anstyle", @@ -455,21 +462,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.13" +version = "4.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501d359d5f3dcaf6ecdeee48833ae73ec6e42723a1e52419c79abf9507eec0a0" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" [[package]] name = "clru" @@ -506,9 +513,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "compact_str" @@ -548,9 +555,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -635,7 +642,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.82", + "syn", ] [[package]] @@ -646,18 +653,18 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.82", + "syn", ] [[package]] name = "dashmap" -version = "6.0.1" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", "crossbeam-utils", - "hashbrown", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -696,7 +703,7 @@ checksum = "841ea25b31404c50f2ddc92e028984a42d0fc818c10afee0b1fbda27c995f028" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] @@ -716,7 +723,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", "unicode-xid", ] @@ -769,6 +776,17 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "doc-comment" version = "0.3.3" @@ -811,9 +829,9 @@ checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] @@ -876,15 +894,15 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", @@ -894,9 +912,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide 0.8.0", @@ -908,6 +926,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -949,9 +973,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -964,9 +988,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -974,15 +998,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -991,32 +1015,32 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-timer" @@ -1026,9 +1050,9 @@ checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1124,12 +1148,12 @@ dependencies = [ "ratatui", "regex", "rstest", - "secrecy 0.10.3", + "secrecy", "sendmail", "serde_json", "standardwebhooks", "test-log", - "thiserror", + "thiserror 2.0.3", "time", "tokio", "toml", @@ -1157,12 +1181,12 @@ dependencies = [ "pike", "pretty_assertions", "rand", - "secrecy 0.10.3", + "secrecy", "serde", "serde_json", "take-until", "test-log", - "thiserror", + "thiserror 2.0.3", "time", "toml", "tracing", @@ -1178,7 +1202,7 @@ dependencies = [ "git-next-core", "kxio", "rand", - "secrecy 0.10.3", + "secrecy", "serde", "serde_json", "tokio", @@ -1198,7 +1222,7 @@ dependencies = [ "hmac", "kxio", "rand", - "secrecy 0.10.3", + "secrecy", "serde", "serde_json", "sha2", @@ -1208,15 +1232,12 @@ dependencies = [ [[package]] name = "git-url-parse" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b037f7449dd4a8b711e660301ff1ff28aa00eea09698421fb2d78db51a7b7a72" +checksum = "68d7ff03a34ea818a59cf30c0d7aa55354925484fa30bcc4cb96d784ff07578f" dependencies = [ - "color-eyre", - "regex", - "strum 0.24.1", - "strum_macros 0.24.3", - "tracing", + "strum", + "thiserror 1.0.69", "url", ] @@ -1278,7 +1299,7 @@ dependencies = [ "regex", "signal-hook", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1291,7 +1312,7 @@ dependencies = [ "gix-date", "gix-utils", "itoa", - "thiserror", + "thiserror 1.0.69", "winnow", ] @@ -1306,7 +1327,7 @@ dependencies = [ "gix-object", "gix-worktree-stream", "jiff", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1322,7 +1343,7 @@ dependencies = [ "gix-trace", "kstring", "smallvec", - "thiserror", + "thiserror 1.0.69", "unicode-bom", ] @@ -1332,7 +1353,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10f78312288bd02052be5dbc2ecbc342c9f4eb791986d86c0a5c06b92dc72efa" dependencies = [ - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1341,7 +1362,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c28b58ba04f0c004722344390af9dbc85888fbb84be1981afb934da4114d4cf" dependencies = [ - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1367,7 +1388,7 @@ dependencies = [ "gix-features", "gix-hash", "memmap2", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1386,7 +1407,7 @@ dependencies = [ "memchr", "once_cell", "smallvec", - "thiserror", + "thiserror 1.0.69", "unicode-bom", "winnow", ] @@ -1401,7 +1422,7 @@ dependencies = [ "bstr", "gix-path", "libc", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1418,7 +1439,7 @@ dependencies = [ "gix-sec", "gix-trace", "gix-url", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1430,7 +1451,7 @@ dependencies = [ "bstr", "itoa", "jiff", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1451,7 +1472,7 @@ dependencies = [ "gix-traverse", "gix-worktree", "imara-diff", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1471,7 +1492,7 @@ dependencies = [ "gix-trace", "gix-utils", "gix-worktree", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1487,7 +1508,7 @@ dependencies = [ "gix-path", "gix-ref", "gix-sec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1509,7 +1530,7 @@ dependencies = [ "parking_lot", "prodash", "sha1_smol", - "thiserror", + "thiserror 1.0.69", "walkdir", ] @@ -1531,7 +1552,7 @@ dependencies = [ "gix-trace", "gix-utils", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1564,7 +1585,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "952c3a29f1bc1007cc901abce7479943abfa42016db089de33d0a4fa3c85bfe8" dependencies = [ "faster-hex", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1574,7 +1595,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ef65b256631078ef733bc5530c4e6b1c2e7d5c2830b75d4e9034ab3997d18fe" dependencies = [ "gix-hash", - "hashbrown", + "hashbrown 0.14.5", "parking_lot", ] @@ -1610,13 +1631,13 @@ dependencies = [ "gix-traverse", "gix-utils", "gix-validate", - "hashbrown", + "hashbrown 0.14.5", "itoa", "libc", "memmap2", "rustix", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1627,7 +1648,7 @@ checksum = "5102acdf4acae2644e38dbbd18cdfba9597a218f7d85f810fe5430207e03c2de" dependencies = [ "gix-tempfile", "gix-utils", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1639,7 +1660,7 @@ dependencies = [ "bstr", "gix-actor", "gix-date", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1660,7 +1681,7 @@ dependencies = [ "gix-trace", "gix-worktree", "imara-diff", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1676,7 +1697,7 @@ dependencies = [ "gix-object", "gix-revwalk", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1695,7 +1716,7 @@ dependencies = [ "gix-validate", "itoa", "smallvec", - "thiserror", + "thiserror 1.0.69", "winnow", ] @@ -1717,7 +1738,7 @@ dependencies = [ "gix-quote", "parking_lot", "tempfile", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1737,7 +1758,7 @@ dependencies = [ "memmap2", "parking_lot", "smallvec", - "thiserror", + "thiserror 1.0.69", "uluru", ] @@ -1750,7 +1771,7 @@ dependencies = [ "bstr", "faster-hex", "gix-trace", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1762,7 +1783,7 @@ dependencies = [ "bstr", "faster-hex", "gix-trace", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1775,7 +1796,7 @@ dependencies = [ "gix-trace", "home", "once_cell", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1790,7 +1811,7 @@ dependencies = [ "gix-config-value", "gix-glob", "gix-path", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1803,7 +1824,7 @@ dependencies = [ "gix-config-value", "parking_lot", "rustix", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1820,7 +1841,7 @@ dependencies = [ "gix-transport", "gix-utils", "maybe-async", - "thiserror", + "thiserror 1.0.69", "winnow", ] @@ -1832,7 +1853,7 @@ checksum = "f89f9a1525dcfd9639e282ea939f5ab0d09d93cf2b90c1fc6104f1b9582a8e49" dependencies = [ "bstr", "gix-utils", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1852,7 +1873,7 @@ dependencies = [ "gix-utils", "gix-validate", "memmap2", - "thiserror", + "thiserror 1.0.69", "winnow", ] @@ -1867,7 +1888,7 @@ dependencies = [ "gix-revision", "gix-validate", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1885,7 +1906,7 @@ dependencies = [ "gix-object", "gix-revwalk", "gix-trace", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1900,7 +1921,7 @@ dependencies = [ "gix-hashtable", "gix-object", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1935,7 +1956,7 @@ dependencies = [ "gix-pathspec", "gix-worktree", "portable-atomic", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1950,7 +1971,7 @@ dependencies = [ "gix-pathspec", "gix-refspec", "gix-url", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1991,7 +2012,7 @@ dependencies = [ "gix-sec", "gix-url", "reqwest", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2008,7 +2029,7 @@ dependencies = [ "gix-object", "gix-revwalk", "smallvec", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2020,7 +2041,7 @@ dependencies = [ "bstr", "gix-features", "gix-path", - "thiserror", + "thiserror 1.0.69", "url", ] @@ -2042,7 +2063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e187b263461bc36cea17650141567753bc6207d036cedd1de6e81a52f277ff68" dependencies = [ "bstr", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2081,7 +2102,7 @@ dependencies = [ "gix-path", "gix-worktree", "io-close", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2099,7 +2120,7 @@ dependencies = [ "gix-path", "gix-traverse", "parking_lot", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -2129,9 +2150,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", @@ -2156,6 +2177,17 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + [[package]] name = "headers" version = "0.3.9" @@ -2180,12 +2212,6 @@ dependencies = [ "http 0.2.12", ] -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" @@ -2303,9 +2329,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -2321,9 +2347,9 @@ checksum = "5c3b1f728c459d27b12448862017b96ad4767b1ec2ec5e6434e99f1577f085b8" [[package]] name = "hyper" -version = "0.14.30" +version = "0.14.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" dependencies = [ "bytes", "futures-channel", @@ -2345,14 +2371,14 @@ dependencies = [ [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.6", + "h2 0.4.7", "http 1.1.0", "http-body 1.0.1", "httparse", @@ -2365,13 +2391,13 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-util", "rustls", "rustls-pki-types", @@ -2389,7 +2415,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-util", "native-tls", "tokio", @@ -2399,29 +2425,28 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", "futures-channel", "futures-util", "http 1.1.0", "http-body 1.0.1", - "hyper 1.4.1", + "hyper 1.5.1", "pin-project-lite", "socket2", "tokio", - "tower", "tower-service", "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2440,6 +2465,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -2448,12 +2591,23 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -2463,7 +2617,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc9da1a252bd44cd341657203722352efc9bc0c847d06ea6d2dc1cd1135e0a01" dependencies = [ "ahash", - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -2474,12 +2628,12 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.1", ] [[package]] @@ -2510,12 +2664,16 @@ dependencies = [ [[package]] name = "instability" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b23a0c8dfe501baac4adf6ebbfa6eddf8f0c07f56b058cc1288017e32397846c" +checksum = "b829f37dead9dc39df40c2d3376c179fdfd2ac771f53f55d3c30dc096a3c0c6e" dependencies = [ + "darling", + "indoc", + "pretty_assertions", + "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] @@ -2539,9 +2697,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "is-terminal" @@ -2571,15 +2729,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "540654e97a3f4470a492cd30ff187bc95d89557a903a2bbf112e2fae98104ef2" [[package]] name = "jiff" -version = "0.1.10" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ef8bc400f8312944a9f879db116fed372c4f0859af672eba2a80f79c767dd19" +checksum = "b9d9d414fc817d3e3d62b2598616733f76c4cc74fbac96069674739b881295c8" dependencies = [ "jiff-tzdb-platform", "windows-sys 0.59.0", @@ -2587,24 +2745,24 @@ dependencies = [ [[package]] name = "jiff-tzdb" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05fac328b3df1c0f18a3c2ab6cb7e06e4e549f366017d796e3e66b6d6889abe6" +checksum = "91335e575850c5c4c673b9bd467b0e025f164ca59d0564f69d0c2ee0ffad4653" [[package]] name = "jiff-tzdb-platform" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8da387d5feaf355954c2c122c194d6df9c57d865125a67984bb453db5336940" +checksum = "9835f0060a626fe59f160437bc725491a6af23133ea906500027d1bd2f8f4329" dependencies = [ "jiff-tzdb", ] [[package]] name = "js-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] @@ -2640,22 +2798,18 @@ dependencies = [ [[package]] name = "kxio" -version = "1.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3dd097e810dd8348c82d8f3da1548bcd03dbfa744456dae7194a977e0c50a9" +checksum = "5d58847f89c67f7152c76eaa5257606157e830151966c4e95268acfb9188b65d" dependencies = [ - "async-trait", + "bytes", "derive_more", "http 1.1.0", "path-clean", "reqwest", - "secrecy 0.8.0", - "serde", - "serde-xml-rs", - "serde_json", "tempfile", - "thiserror", - "tracing", + "tokio", + "url", ] [[package]] @@ -2666,9 +2820,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "lettre" -version = "0.11.7" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a62049a808f1c4e2356a2a380bd5f2aca3b011b0b482cf3b914ba1731426969" +checksum = "0161e452348e399deb685ba05e55ee116cae9410f4f51fe42d597361444521d9" dependencies = [ "base64 0.22.1", "chumsky", @@ -2691,9 +2845,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.158" +version = "0.2.164" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" +checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f" [[package]] name = "libdbus-sys" @@ -2712,7 +2866,7 @@ checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ "bitflags 2.6.0", "libc", - "redox_syscall 0.5.3", + "redox_syscall 0.5.7", ] [[package]] @@ -2721,6 +2875,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" + [[package]] name = "lock_api" version = "0.4.12" @@ -2739,11 +2899,11 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lru" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ee39891760e7d94734f6f63fedc29a2e4a152f836120753a72503f09fcf904" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown", + "hashbrown 0.15.1", ] [[package]] @@ -2784,7 +2944,7 @@ checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] @@ -2795,9 +2955,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", ] @@ -2857,9 +3017,9 @@ dependencies = [ [[package]] name = "mockall" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c28b3fb6d753d28c20e826cd46ee611fda1cf3cde03a443a974043247c065a" +checksum = "39a6bfcc6c8c7eed5ee98b9c3e33adc726054389233e201c95dab2d41a3839d2" dependencies = [ "cfg-if", "downcast", @@ -2871,14 +3031,14 @@ dependencies = [ [[package]] name = "mockall_derive" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "341014e7f530314e9a1fdbc7400b244efea7122662c96bfa248c31da5bfb2020" +checksum = "25ca3004c2efe9011bd4e461bd8256445052b9615405b4f7ea43fc8ca5c20898" dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] @@ -3040,15 +3200,15 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "openssl" -version = "0.10.66" +version = "0.10.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -3067,7 +3227,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] @@ -3078,9 +3238,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -3124,7 +3284,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall 0.5.7", "smallvec", "windows-targets 0.52.6", ] @@ -3155,29 +3315,29 @@ checksum = "29f6494096e8bae5b0ed41c5f45d99545125930c9df917a726fefcb7ead7fb04" [[package]] name = "pin-project" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -3187,15 +3347,15 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "portable-atomic" -version = "1.7.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" [[package]] name = "powerfmt" @@ -3240,9 +3400,9 @@ dependencies = [ [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", "yansi", @@ -3259,9 +3419,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "307e3004becf10f5a6e0d59d20f3cd28231b0e0827a96cd3e0ce6d14bc1e4bb3" dependencies = [ "unicode-ident", ] @@ -3280,18 +3440,18 @@ dependencies = [ [[package]] name = "psm" -version = "0.1.21" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5787f7cda34e3033a72192c018bc5883100330f362ef279a8cbccfce8bb4e874" +checksum = "200b9ff220857e53e184257720a14553b2f4aa02577d2ed9842d45d4b9654810" dependencies = [ "cc", ] [[package]] name = "quinn" -version = "0.11.3" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b22d8e7369034b9a7132bc2008cac12f2013c8132b45e0554e6e20e2617f2156" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" dependencies = [ "bytes", "pin-project-lite", @@ -3300,39 +3460,43 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror", + "thiserror 2.0.3", "tokio", "tracing", ] [[package]] name = "quinn-proto" -version = "0.11.6" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba92fb39ec7ad06ca2582c0ca834dfeadcaf06ddfc8e635c80aa7e1c05315fdd" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" dependencies = [ "bytes", + "getrandom 0.2.15", "rand", "ring", "rustc-hash", "rustls", + "rustls-pki-types", "slab", - "thiserror", + "thiserror 2.0.3", "tinyvec", "tracing", + "web-time", ] [[package]] name = "quinn-udp" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" +checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" dependencies = [ + "cfg_aliases", "libc", "once_cell", "socket2", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3395,7 +3559,7 @@ dependencies = [ "itertools", "lru", "paste", - "strum 0.26.3", + "strum", "unicode-segmentation", "unicode-truncate", "unicode-width 0.2.0", @@ -3409,9 +3573,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] @@ -3435,19 +3599,19 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "regex" -version = "1.10.6" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", ] [[package]] @@ -3461,13 +3625,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", ] [[package]] @@ -3478,9 +3642,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "relative-path" @@ -3490,9 +3654,9 @@ checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] name = "reqwest" -version = "0.12.7" +version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" +checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ "base64 0.22.1", "bytes", @@ -3500,11 +3664,11 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.6", + "h2 0.4.7", "http 1.1.0", "http-body 1.0.1", "http-body-util", - "hyper 1.4.1", + "hyper 1.5.1", "hyper-rustls", "hyper-tls", "hyper-util", @@ -3578,7 +3742,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.82", + "syn", "unicode-ident", ] @@ -3617,9 +3781,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -3630,9 +3794,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "7f1a745511c54ba6d4465e8d5dfbd81b45791756de28d4981af70d6dca128f1e" dependencies = [ "once_cell", "ring", @@ -3644,25 +3808,27 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +dependencies = [ + "web-time", +] [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -3671,9 +3837,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" [[package]] name = "ryu" @@ -3692,11 +3858,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3711,15 +3877,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "secrecy" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" -dependencies = [ - "zeroize", -] - [[package]] name = "secrecy" version = "0.10.3" @@ -3744,9 +3901,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -3766,41 +3923,29 @@ checksum = "b534d6dc60c5df66cda0abd5ebaff07e208722bd0188211a03dd5a21812b9e4a" [[package]] name = "serde" -version = "1.0.209" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] -[[package]] -name = "serde-xml-rs" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" -dependencies = [ - "log", - "serde", - "thiserror", - "xml-rs", -] - [[package]] name = "serde_derive" -version = "1.0.209" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] name = "serde_json" -version = "1.0.127" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -3810,9 +3955,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -3940,16 +4085,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] -name = "stacker" -version = "0.1.16" +name = "stable_deref_trait" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a5daa25ea337c85ed954c0496e3bdd2c7308cc3b24cf7b50d04876654c579f" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stacker" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799c883d55abdb5e98af1a7b3f23b9b6de8ecada0ecac058672d7635eb48ca7b" dependencies = [ "cc", "cfg-if", "libc", "psm", - "windows-sys 0.36.1", + "windows-sys 0.59.0", ] [[package]] @@ -3961,7 +4112,7 @@ dependencies = [ "base64 0.21.7", "hmac-sha256", "http 1.1.0", - "thiserror", + "thiserror 2.0.3", "time", ] @@ -3977,32 +4128,13 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" - [[package]] name = "strum" version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ - "strum_macros 0.26.4", -] - -[[package]] -name = "strum_macros" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 1.0.109", + "strum_macros", ] [[package]] @@ -4011,11 +4143,11 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.82", + "syn", ] [[package]] @@ -4026,20 +4158,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83540f837a8afc019423a8edb95b52a8effe46957ee402287f4292fae35be021" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -4048,13 +4169,24 @@ dependencies = [ [[package]] name = "sync_wrapper" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "system-configuration" version = "0.6.1" @@ -4084,9 +4216,9 @@ checksum = "8bdb6fa0dfa67b38c1e66b7041ba9dcf23b99d8121907cd31c807a332f7a0bbb" [[package]] name = "tempfile" -version = "3.12.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -4120,27 +4252,47 @@ checksum = "5999e24eaa32083191ba4e425deb75cdf25efefabe5aaccb7446dd0d4122a3f5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +dependencies = [ + "thiserror-impl 2.0.3", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -4172,6 +4324,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -4189,9 +4351,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -4213,7 +4375,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] @@ -4251,9 +4413,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -4285,9 +4447,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap", "serde", @@ -4296,27 +4458,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - [[package]] name = "tower-service" version = "0.3.3" @@ -4343,7 +4484,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", ] [[package]] @@ -4426,7 +4567,7 @@ dependencies = [ "log", "rand", "sha1", - "thiserror", + "thiserror 1.0.69", "url", "utf-8", ] @@ -4459,18 +4600,9 @@ dependencies = [ [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-bom" @@ -4480,24 +4612,24 @@ checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-truncate" @@ -4507,14 +4639,14 @@ checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" dependencies = [ "itertools", "unicode-segmentation", - "unicode-width 0.1.13", + "unicode-width 0.1.14", ] [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-width" @@ -4524,9 +4656,9 @@ checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "untrusted" @@ -4536,9 +4668,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" dependencies = [ "form_urlencoded", "idna", @@ -4551,6 +4683,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -4605,7 +4749,7 @@ dependencies = [ "futures-util", "headers", "http 0.2.12", - "hyper 0.14.30", + "hyper 0.14.31", "log", "mime", "mime_guess", @@ -4637,9 +4781,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ "cfg-if", "once_cell", @@ -4648,24 +4792,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.82", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.43" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ "cfg-if", "js-sys", @@ -4675,9 +4819,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4685,28 +4829,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.93" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] name = "web-sys" -version = "0.3.70" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ "js-sys", "wasm-bindgen", @@ -4724,9 +4868,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.3" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" dependencies = [ "rustls-pki-types", ] @@ -4811,19 +4955,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -4894,12 +5025,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -4912,12 +5037,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_i686_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -4936,12 +5055,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -4954,12 +5067,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_x86_64_gnu" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -4984,12 +5091,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_msvc" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -5004,9 +5105,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -5021,16 +5122,46 @@ dependencies = [ ] [[package]] -name = "xml-rs" -version = "0.8.21" +name = "write16" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + +[[package]] +name = "yoke" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] [[package]] name = "zerocopy" @@ -5050,7 +5181,28 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.82", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", ] [[package]] @@ -5058,3 +5210,25 @@ name = "zeroize" version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml index 46644a2..e754fcc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,7 @@ async-trait = "0.1" git-url-parse = "0.4" # fs/network -kxio = { version = "1.2" } +kxio = "3.0" # TOML parsing serde = { version = "1.0", features = ["derive"] } diff --git a/crates/cli/src/alerts/mod.rs b/crates/cli/src/alerts/mod.rs index 8e5db22..eaf1194 100644 --- a/crates/cli/src/alerts/mod.rs +++ b/crates/cli/src/alerts/mod.rs @@ -22,7 +22,7 @@ mod tests; pub struct AlertsActor { shout: Option, // config for sending alerts to users history: History, // record of alerts sent recently (e.g. 24 hours) - net: kxio::network::Network, + net: kxio::net::Net, } impl Actor for AlertsActor { diff --git a/crates/cli/src/alerts/webhook.rs b/crates/cli/src/alerts/webhook.rs index 75647e7..8c8f95b 100644 --- a/crates/cli/src/alerts/webhook.rs +++ b/crates/cli/src/alerts/webhook.rs @@ -1,13 +1,12 @@ // use git_next_core::{git::UserNotification, server::OutboundWebhook}; -use kxio::network::{NetRequest, NetUrl, RequestBody, ResponseType}; use secrecy::ExposeSecret as _; use standardwebhooks::Webhook; pub(super) async fn send_webhook( user_notification: &UserNotification, webhook_config: &OutboundWebhook, - net: &kxio::network::Network, + net: &kxio::net::Net, ) { let Ok(webhook) = Webhook::from_bytes(webhook_config.secret().expose_secret().as_bytes().into()) @@ -22,7 +21,7 @@ async fn do_send_webhook( user_notification: &UserNotification, webhook: Webhook, webhook_config: &OutboundWebhook, - net: &kxio::network::Network, + net: &kxio::net::Net, ) { let message_id = format!("msg_{}", ulid::Ulid::new()); let timestamp = time::OffsetDateTime::now_utc(); @@ -35,20 +34,17 @@ async fn do_send_webhook( .sign(&message_id, timestamp, payload.to_string().as_ref()) .expect("signature"); tracing::info!(?signature, ""); - let url = webhook_config.url(); - - let net_url = NetUrl::new(url.to_string()); - let request = NetRequest::post(net_url) - .body(RequestBody::Json(payload)) - .header("webhook-id", &message_id) - .header("webhook-timestamp", ×tamp.to_string()) - .header("webhook-signature", &signature) - .response_type(ResponseType::None) - .build(); - net.post_json::<()>(request).await.map_or_else( - |err| { - tracing::warn!(?err, "sending webhook"); - }, - |_| (), - ); + net.post(webhook_config.url()) + .body(payload.to_string()) + .header("webhook-id", message_id) + .header("webhook-timestamp", timestamp.to_string()) + .header("webhook-signature", signature) + .send() + .await + .map_or_else( + |err| { + tracing::warn!(?err, "sending webhook"); + }, + |_| (), + ); } diff --git a/crates/cli/src/forge/mod.rs b/crates/cli/src/forge/mod.rs index d1cea92..fad74e3 100644 --- a/crates/cli/src/forge/mod.rs +++ b/crates/cli/src/forge/mod.rs @@ -7,13 +7,13 @@ use git_next_forge_forgejo::ForgeJo; #[cfg(feature = "github")] use git_next_forge_github::Github; -use kxio::network::Network; +use kxio::net::Net; #[derive(Clone, Debug)] pub struct Forge; impl Forge { - pub fn create(repo_details: RepoDetails, net: Network) -> Box { + pub fn create(repo_details: RepoDetails, net: Net) -> Box { match repo_details.forge.forge_type() { #[cfg(feature = "forgejo")] git_next_core::ForgeType::ForgeJo => Box::new(ForgeJo::new(repo_details, net)), diff --git a/crates/cli/src/forge/tests.rs b/crates/cli/src/forge/tests.rs index 6d96588..d596dd8 100644 --- a/crates/cli/src/forge/tests.rs +++ b/crates/cli/src/forge/tests.rs @@ -11,18 +11,18 @@ use git_next_core::{ #[cfg(feature = "forgejo")] #[test] fn test_forgejo_name() { - let net = Network::new_mock(); + let net = kxio::net::mock(); let repo_details = given_repo_details(git_next_core::ForgeType::ForgeJo); - let forge = Forge::create(repo_details, net); + let forge = Forge::create(repo_details, net.into()); assert_eq!(forge.name(), "forgejo"); } #[cfg(feature = "github")] #[test] fn test_github_name() { - let net = Network::new_mock(); + let net = kxio::net::mock(); let repo_details = given_repo_details(git_next_core::ForgeType::GitHub); - let forge = Forge::create(repo_details, net); + let forge = Forge::create(repo_details, net.into()); assert_eq!(forge.name(), "github"); } diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs index 6b6cbca..f9e666e 100644 --- a/crates/cli/src/init.rs +++ b/crates/cli/src/init.rs @@ -5,12 +5,14 @@ use kxio::fs::FileSystem; pub fn run(fs: &FileSystem) -> Result<()> { let pathbuf = fs.base().join(".git-next.toml"); if fs - .path_exists(&pathbuf) + .path(&pathbuf) + .exists() .with_context(|| format!("Checking for existing file: {pathbuf:?}"))? { eprintln!("The configuration file already exists at {pathbuf:?} - not overwritting it.",); } else { - fs.file_write(&pathbuf, include_str!("../default.toml")) + fs.file(&pathbuf) + .write(include_str!("../default.toml")) .with_context(|| format!("Writing file: {pathbuf:?}"))?; println!("Created a default configuration file at {pathbuf:?}"); } diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 21a9b41..8826c87 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -21,7 +21,7 @@ use std::path::PathBuf; use clap::Parser; use color_eyre::Result; -use kxio::{fs, network::Network}; +use kxio::{fs, net}; #[derive(Parser, Debug)] #[clap(version = clap::crate_version!(), author = clap::crate_authors!(), about = clap::crate_description!())] @@ -48,7 +48,7 @@ enum Server { fn main() -> Result<()> { let fs = fs::new(PathBuf::default()); - let net = Network::new_real(); + let net = net::new(); let repository_factory = git::repository::factory::real(); let commands = Commands::parse(); diff --git a/crates/cli/src/repo/handlers/check_ci_status.rs b/crates/cli/src/repo/handlers/check_ci_status.rs index 6f6e103..b031502 100644 --- a/crates/cli/src/repo/handlers/check_ci_status.rs +++ b/crates/cli/src/repo/handlers/check_ci_status.rs @@ -1,7 +1,7 @@ // use actix::prelude::*; -use tracing::{debug, Instrument as _}; +use tracing::{debug, warn, Instrument as _}; use crate::{ repo::{ @@ -26,9 +26,13 @@ impl Handler for RepoActor { self.update_tui(RepoUpdate::CheckingCI); // get the status - pass, fail, pending (all others map to fail, e.g. error) async move { - let status = forge.commit_status(&next).await; - debug!("got status: {status:?}"); - do_send(&addr, ReceiveCIStatus::new((next, status)), log.as_ref()); + match forge.commit_status(&next).await { + Ok(status) => { + debug!("got status: {status:?}"); + do_send(&addr, ReceiveCIStatus::new((next, status)), log.as_ref()); + } + Err(err) => warn!(?err, "fetching commit status"), + } } .in_current_span() .into_actor(self) diff --git a/crates/cli/src/repo/handlers/receive_ci_status.rs b/crates/cli/src/repo/handlers/receive_ci_status.rs index 335dffc..3dc1737 100644 --- a/crates/cli/src/repo/handlers/receive_ci_status.rs +++ b/crates/cli/src/repo/handlers/receive_ci_status.rs @@ -70,6 +70,7 @@ impl Handler for RepoActor { .into_actor(self) .wait(ctx); } + Status::Error(_) => todo!(), } } } diff --git a/crates/cli/src/repo/mod.rs b/crates/cli/src/repo/mod.rs index f60ec51..4c39bb2 100644 --- a/crates/cli/src/repo/mod.rs +++ b/crates/cli/src/repo/mod.rs @@ -6,7 +6,7 @@ use crate::{ server::{actor::messages::RepoUpdate, ServerActor}, }; use derive_more::Deref; -use kxio::network::Network; +use kxio::net::Net; use tracing::{info, instrument, warn, Instrument}; use git_next_core::{ @@ -57,7 +57,7 @@ pub struct RepoActor { last_dev_commit: Option, repository_factory: Box, open_repository: Option>, - net: Network, + net: Net, forge: Box, log: Option, notify_user_recipient: Option>, @@ -70,7 +70,7 @@ impl RepoActor { forge: Box, listen_url: ListenUrl, generation: git::Generation, - net: Network, + net: Net, repository_factory: Box, sleep_duration: std::time::Duration, notify_user_recipient: Option>, diff --git a/crates/cli/src/repo/tests/given.rs b/crates/cli/src/repo/tests/given.rs index 5fbab55..2abd585 100644 --- a/crates/cli/src/repo/tests/given.rs +++ b/crates/cli/src/repo/tests/given.rs @@ -1,8 +1,8 @@ -use git_next_core::server::ListenUrl; - // use super::*; +use git_next_core::server::ListenUrl; + pub fn has_all_valid_remote_defaults( open_repository: &mut MockOpenRepositoryLike, repo_details: &RepoDetails, @@ -48,8 +48,8 @@ pub fn a_repo_alias() -> RepoAlias { RepoAlias::new(a_name()) } -pub fn a_network() -> kxio::network::MockNetwork { - kxio::network::MockNetwork::new() +pub fn a_network() -> kxio::net::MockNet { + kxio::net::mock() } pub fn a_listen_url() -> ListenUrl { @@ -152,8 +152,8 @@ pub fn a_commit_sha() -> Sha { Sha::new(a_name()) } -pub fn a_filesystem() -> kxio::fs::FileSystem { - kxio::fs::temp().unwrap_or_else(|e| panic!("{}", e)) +pub fn a_filesystem() -> kxio::fs::TempFileSystem { + kxio::fs::temp().expect("temp fs") } pub fn repo_details(fs: &kxio::fs::FileSystem) -> RepoDetails { @@ -196,7 +196,7 @@ pub fn a_repo_actor( repo_details: RepoDetails, repository_factory: Box, forge: Box, - net: kxio::network::Network, + net: kxio::net::Net, ) -> (RepoActor, ActorLog) { let listen_url = given::a_listen_url(); let generation = Generation::default(); diff --git a/crates/cli/src/repo/tests/handlers/clone_repo.rs b/crates/cli/src/repo/tests/handlers/clone_repo.rs index 94f6aa2..5f89c58 100644 --- a/crates/cli/src/repo/tests/handlers/clone_repo.rs +++ b/crates/cli/src/repo/tests/handlers/clone_repo.rs @@ -59,7 +59,7 @@ async fn should_open() -> TestResult { let _ = opened_ref.write().map(|mut l| l.push(())); Ok(Box::new(open_repository)) }); - fs.dir_create(&repo_details.gitdir)?; + fs.dir(&repo_details.gitdir).create()?; //when let (addr, _log) = when::start_actor(repository_factory, repo_details, given::a_forge()); @@ -94,7 +94,7 @@ async fn when_server_has_no_repo_config_should_send_load_from_repo() -> TestResu let mut repository_factory = MockRepositoryFactory::new(); expect::open_repository(&mut repository_factory, open_repository); - fs.dir_create(&repo_details.gitdir)?; + fs.dir(&repo_details.gitdir).create()?; //when let (addr, log) = when::start_actor(repository_factory, repo_details, given::a_forge()); @@ -123,7 +123,7 @@ async fn when_server_has_repo_config_should_send_register_webhook() -> TestResul let mut repository_factory = MockRepositoryFactory::new(); expect::open_repository(&mut repository_factory, open_repository); - fs.dir_create(&repo_details.gitdir)?; + fs.dir(&repo_details.gitdir).create()?; //when let (addr, log) = when::start_actor(repository_factory, repo_details, given::a_forge()); @@ -156,7 +156,7 @@ async fn opened_repo_with_no_default_push_should_not_proceed() -> TestResult { let mut repository_factory = MockRepositoryFactory::new(); expect::open_repository(&mut repository_factory, open_repository); - fs.dir_create(&repo_details.gitdir)?; + fs.dir(&repo_details.gitdir).create()?; //when let (addr, log) = when::start_actor(repository_factory, repo_details, given::a_forge()); @@ -180,7 +180,7 @@ async fn opened_repo_with_no_default_fetch_should_not_proceed() -> TestResult { .return_once(|| Err(git::fetch::Error::NoFetchRemoteFound)); let mut repository_factory = MockRepositoryFactory::new(); expect::open_repository(&mut repository_factory, open_repository); - fs.dir_create(&repo_details.gitdir)?; + fs.dir(&repo_details.gitdir).create()?; //when let (addr, log) = when::start_actor(repository_factory, repo_details, given::a_forge()); diff --git a/crates/cli/src/repo/tests/when.rs b/crates/cli/src/repo/tests/when.rs index e00341a..83d67a1 100644 --- a/crates/cli/src/repo/tests/when.rs +++ b/crates/cli/src/repo/tests/when.rs @@ -30,7 +30,7 @@ pub fn commit_status(forge: &mut MockForgeLike, commit: Commit, status: Status) commit_status_forge .expect_commit_status() .with(mockall::predicate::eq(commit)) - .return_once(|_| status); + .return_once(|_| Ok(status)); forge .expect_duplicate() .return_once(move || Box::new(commit_status_forge)); diff --git a/crates/cli/src/server/actor/mod.rs b/crates/cli/src/server/actor/mod.rs index b7d0b0e..7ecffff 100644 --- a/crates/cli/src/server/actor/mod.rs +++ b/crates/cli/src/server/actor/mod.rs @@ -20,7 +20,7 @@ use git_next_core::{ ForgeAlias, ForgeConfig, GitDir, RepoAlias, ServerRepoConfig, StoragePathType, }; -use kxio::{fs::FileSystem, network::Network}; +use kxio::{fs::FileSystem, net::Net}; use std::{ collections::BTreeMap, @@ -52,7 +52,7 @@ pub struct ServerActor { generation: Generation, webhook_actor_addr: Option>, fs: FileSystem, - net: Network, + net: Net, alerts: Addr, repository_factory: Box, sleep_duration: std::time::Duration, @@ -71,7 +71,7 @@ impl Actor for ServerActor { impl ServerActor { pub fn new( fs: FileSystem, - net: Network, + net: Net, alerts: Addr, repo: Box, sleep_duration: std::time::Duration, @@ -100,13 +100,14 @@ impl ServerActor { for (forge_name, _forge_config) in app_config.forges() { let forge_dir: PathBuf = (&forge_name).into(); let path = server_dir.join(&forge_dir); - if self.fs.path_exists(&path)? { - if !self.fs.path_is_dir(&path)? { + let path_handle = self.fs.path(&path); + if path_handle.exists()? { + if !path_handle.is_dir()? { return Err(Error::ForgeDirIsNotDirectory { path }); } } else { - tracing::info!(%forge_name, ?path, "creating storage"); - self.fs.dir_create_all(&path)?; + tracing::info!(%forge_name, ?path_handle, "creating storage"); + self.fs.dir(&path).create_all()?; } } @@ -213,7 +214,7 @@ impl ServerActor { let server_storage = app_config.storage().clone(); let dir = server_storage.path(); if !dir.exists() { - if let Err(err) = self.fs.dir_create(dir) { + if let Err(err) = self.fs.dir(dir).create() { error!(?err, ?dir, "Failed to create server storage"); return None; } diff --git a/crates/cli/src/server/actor/tests/given.rs b/crates/cli/src/server/actor/tests/given.rs index 330215b..899633e 100644 --- a/crates/cli/src/server/actor/tests/given.rs +++ b/crates/cli/src/server/actor/tests/given.rs @@ -5,14 +5,14 @@ use actix::prelude::*; use crate::alerts::{AlertsActor, History}; // -pub fn a_filesystem() -> kxio::fs::FileSystem { - kxio::fs::temp().unwrap_or_else(|e| panic!("{}", e)) +pub fn a_filesystem() -> kxio::fs::TempFileSystem { + kxio::fs::temp().expect("temp fs") } -pub fn a_network() -> kxio::network::MockNetwork { - kxio::network::MockNetwork::new() +pub fn a_network() -> kxio::net::MockNet { + kxio::net::mock() } -pub fn an_alerts_actor(net: kxio::network::Network) -> Addr { +pub fn an_alerts_actor(net: kxio::net::Net) -> Addr { AlertsActor::new(None, History::new(Duration::from_millis(1)), net).start() } diff --git a/crates/cli/src/server/actor/tests/receive_app_config.rs b/crates/cli/src/server/actor/tests/receive_app_config.rs index d5770a6..f5fc625 100644 --- a/crates/cli/src/server/actor/tests/receive_app_config.rs +++ b/crates/cli/src/server/actor/tests/receive_app_config.rs @@ -23,7 +23,7 @@ async fn when_webhook_url_has_trailing_slash_should_not_send() { let duration = std::time::Duration::from_millis(1); // sut - let server = ServerActor::new(fs.clone(), net.into(), alerts, repo, duration); + let server = ServerActor::new(fs.as_real(), net.into(), alerts, repo, duration); // collaborators let listen = Listen::new( diff --git a/crates/cli/src/server/mod.rs b/crates/cli/src/server/mod.rs index f4393f1..e4c683a 100644 --- a/crates/cli/src/server/mod.rs +++ b/crates/cli/src/server/mod.rs @@ -19,7 +19,7 @@ pub use actor::ServerActor; use git_next_core::git::RepositoryFactory; use color_eyre::{eyre::Context, Result}; -use kxio::{fs::FileSystem, network::Network}; +use kxio::{fs::FileSystem, net::Net}; use tracing::info; use std::{ @@ -34,12 +34,14 @@ pub fn init(fs: &FileSystem) -> Result<()> { let file_name = "git-next-server.toml"; let pathbuf = PathBuf::from(file_name); if fs - .path_exists(&pathbuf) + .path(&pathbuf) + .exists() .with_context(|| format!("Checking for existing file: {pathbuf:?}"))? { eprintln!("The configuration file already exists at {pathbuf:?} - not overwritting it.",); } else { - fs.file_write(&pathbuf, include_str!("server-default.toml")) + fs.file(&pathbuf) + .write(include_str!("server-default.toml")) .with_context(|| format!("Writing file: {pathbuf:?}"))?; println!("Created a default configuration file at {pathbuf:?}",); } @@ -50,7 +52,7 @@ pub fn init(fs: &FileSystem) -> Result<()> { pub fn start( ui: bool, fs: FileSystem, - net: Network, + net: Net, repo: Box, sleep_duration: std::time::Duration, ) -> Result<()> { diff --git a/crates/cli/src/tests.rs b/crates/cli/src/tests.rs index 6248879..7aa77a3 100644 --- a/crates/cli/src/tests.rs +++ b/crates/cli/src/tests.rs @@ -6,12 +6,12 @@ mod init { fn should_not_update_file_if_it_exists() -> TestResult { let fs = kxio::fs::temp()?; let file = fs.base().join(".git-next.toml"); - fs.file_write(&file, "contents")?; + fs.file(&file).write("contents")?; crate::init::run(&fs)?; assert_eq!( - fs.file_read_to_string(&file)?, + fs.file(&file).reader()?.to_string(), "contents", "The file has been changed" ); @@ -27,10 +27,10 @@ mod init { let file = fs.base().join(".git-next.toml"); - assert!(fs.path_exists(&file)?, "The file has not been created"); + assert!(fs.path(&file).exists()?, "The file has not been created"); assert_eq!( - fs.file_read_to_string(&file)?, + fs.file(&file).reader()?.to_string(), include_str!("../default.toml"), "The file does not match the default template" ); @@ -54,7 +54,7 @@ mod file_watcher { async fn should_not_block_calling_thread() -> TestResult { let fs = kxio::fs::temp()?; let path = fs.base().join("file"); - fs.file_write(&path, "foo")?; + fs.file(&path).write("foo")?; let listener = Listener; let l_addr = listener.start(); diff --git a/crates/core/src/config/server.rs b/crates/core/src/config/server.rs index 3c394e1..fbda868 100644 --- a/crates/core/src/config/server.rs +++ b/crates/core/src/config/server.rs @@ -57,7 +57,7 @@ impl AppConfig { pub fn load(fs: &FileSystem) -> Result { let file = fs.base().join("git-next-server.toml"); info!(?file, ""); - let str = fs.file_read_to_string(&file)?; + let str = fs.file(&file).reader()?.to_string(); Ok(toml::from_str(&str)?) } diff --git a/crates/core/src/config/tests.rs b/crates/core/src/config/tests.rs index 4271521..e67ee07 100644 --- a/crates/core/src/config/tests.rs +++ b/crates/core/src/config/tests.rs @@ -624,10 +624,8 @@ token = "{forge_token}" "# ); println!("{file_contents}"); - fs.file_write( - &fs.base().join("git-next-server.toml"), - file_contents.as_str(), - )?; + fs.file(&fs.base().join("git-next-server.toml")) + .write(file_contents.as_str())?; Ok(()) } } diff --git a/crates/core/src/git/forge/commit.rs b/crates/core/src/git/forge/commit.rs index e335713..cf9c1f9 100644 --- a/crates/core/src/git/forge/commit.rs +++ b/crates/core/src/git/forge/commit.rs @@ -3,4 +3,5 @@ pub enum Status { Pass, Fail, Pending, + Error(String), } diff --git a/crates/core/src/git/forge/trait.rs b/crates/core/src/git/forge/trait.rs index 5c72986..b61b36d 100644 --- a/crates/core/src/git/forge/trait.rs +++ b/crates/core/src/git/forge/trait.rs @@ -32,7 +32,10 @@ pub trait ForgeLike: std::fmt::Debug + Send + Sync { ) -> git::forge::webhook::Result; /// Checks the results of any (e.g. CI) status checks for the commit. - async fn commit_status(&self, commit: &git::Commit) -> git::forge::commit::Status; + async fn commit_status( + &self, + commit: &git::Commit, + ) -> git::forge::webhook::Result; // Lists all the webhooks async fn list_webhooks( diff --git a/crates/core/src/git/forge/webhook.rs b/crates/core/src/git/forge/webhook.rs index 26d3472..8ecbe86 100644 --- a/crates/core/src/git/forge/webhook.rs +++ b/crates/core/src/git/forge/webhook.rs @@ -4,8 +4,16 @@ pub type Result = core::result::Result; #[derive(Debug, thiserror::Error)] pub enum Error { #[error("network")] - Network(#[from] kxio::network::NetworkError), + Network(#[from] kxio::net::Error), + #[error("reqwest")] + Reqwest(#[from] kxio::net::RequestError), + + // #[error("header")] + // Header(#[from] http::header::InvalidHeaderValue), + + // #[error("parse url")] + // UrlParse(#[from] url::ParseError), #[error("failed to register: {0}")] FailedToRegister(String), diff --git a/crates/core/src/git/push.rs b/crates/core/src/git/push.rs index 25be1b4..b5136bc 100644 --- a/crates/core/src/git/push.rs +++ b/crates/core/src/git/push.rs @@ -23,7 +23,7 @@ pub enum Error { Io(#[from] std::io::Error), #[error("network: {0}")] - Network(#[from] kxio::network::NetworkError), + Network(#[from] kxio::net::Error), #[error("fetch: {0}")] Fetch(#[from] git::fetch::Error), diff --git a/crates/core/src/git/repo_details.rs b/crates/core/src/git/repo_details.rs index 9f98cb6..1ae2326 100644 --- a/crates/core/src/git/repo_details.rs +++ b/crates/core/src/git/repo_details.rs @@ -142,7 +142,8 @@ impl RepoDetails { let fs = self.gitdir.as_fs(); // load config file let config_filename = &self.gitdir.join("config"); - let config_file = fs.file_read_to_string(config_filename)?; + let file = fs.file(config_filename); + let config_file = file.reader()?.to_string(); let mut config_lines = config_file .lines() .map(ToOwned::to_owned) @@ -165,7 +166,7 @@ impl RepoDetails { } tracing::debug!(?config_lines, "updated file"); // write config file back out - fs.file_write(config_filename, config_lines.join("\n").as_str())?; + file.write(config_lines.join("\n").as_str())?; Ok(()) } } diff --git a/crates/core/src/git/repository/open/otest.rs b/crates/core/src/git/repository/open/otest.rs index dd4ac19..6fb325f 100644 --- a/crates/core/src/git/repository/open/otest.rs +++ b/crates/core/src/git/repository/open/otest.rs @@ -172,10 +172,12 @@ impl TestOpenRepository { fn write_origin(gitdir: &GitDir, fs: &kxio::fs::FileSystem) { let config_file = fs.base().join(gitdir.to_path_buf()).join(".git/config"); + let file = fs.file(&config_file); #[allow(clippy::expect_used)] - let contents = fs - .file_read_to_string(&config_file) - .expect("read original .git/config"); + let contents = file + .reader() + .expect("read original .git/config") + .to_string(); let updated_contents = format!( r#"{contents} [remote "origin"] @@ -184,7 +186,7 @@ impl TestOpenRepository { "# ); #[allow(clippy::expect_used)] - fs.file_write(&config_file, &updated_contents) + file.write(&updated_contents) .expect("write updated .git/config"); } } diff --git a/crates/core/src/git/repository/open/tests/commit_log.rs b/crates/core/src/git/repository/open/tests/commit_log.rs index f785f61..322c5d6 100644 --- a/crates/core/src/git/repository/open/tests/commit_log.rs +++ b/crates/core/src/git/repository/open/tests/commit_log.rs @@ -1,3 +1,5 @@ +use std::ops::Deref as _; + use crate::CommitCount; // @@ -9,7 +11,7 @@ fn should_return_single_item_in_commit_log_when_not_searching() -> TestResult { let_assert!(Ok(fs) = kxio::fs::temp()); let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal); let forge_details = given::forge_details(); - let test_repository = git::repository::test(fs.clone(), forge_details); + let test_repository = git::repository::test(fs.deref().clone(), forge_details); let_assert!(Ok(open_repository) = test_repository.open(&gitdir)); let repo_config = &given::a_repo_config(); let branches = repo_config.branches(); @@ -29,7 +31,7 @@ fn should_return_capacity_25_in_commit_log_when_searching_for_garbage() -> TestR let forge_details = given::forge_details().with_max_dev_commits(Some(CommitCount::from(25))); let_assert!(Some(max_dev_commits) = forge_details.max_dev_commits()); assert!(**max_dev_commits >= 25); - let test_repository = git::repository::test(fs.clone(), forge_details); + let test_repository = git::repository::test(fs.deref().clone(), forge_details); let_assert!(Ok(open_repository) = test_repository.open(&gitdir)); for _ in [0; 25] { then::create_a_commit_on_branch(&fs, &gitdir, &branch_name)?; @@ -48,7 +50,7 @@ fn should_return_5_in_commit_log_when_searching_for_5th_item() -> TestResult { let forge_details = given::forge_details().with_max_dev_commits(Some(CommitCount::from(10))); let_assert!(Some(max_dev_commits) = forge_details.max_dev_commits()); assert!(**max_dev_commits > 5); - let test_repository = git::repository::test(fs.clone(), forge_details); + let test_repository = git::repository::test(fs.deref().clone(), forge_details); let_assert!( Ok(open_repository) = test_repository.open(&gitdir), "open repository" diff --git a/crates/core/src/git/repository/open/tests/read_file.rs b/crates/core/src/git/repository/open/tests/read_file.rs index 8c7f944..d29274a 100644 --- a/crates/core/src/git/repository/open/tests/read_file.rs +++ b/crates/core/src/git/repository/open/tests/read_file.rs @@ -1,3 +1,5 @@ +use std::ops::Deref as _; + // use super::*; @@ -11,7 +13,7 @@ fn should_return_file() -> TestResult { let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal); let forge_details = given::forge_details(); - let test_repository = git::repository::test(fs.clone(), forge_details); + let test_repository = git::repository::test(fs.deref().clone(), forge_details); let_assert!(Ok(open_repository) = test_repository.open(&gitdir)); then::commit_named_file_to_branch( &file_name, @@ -35,7 +37,7 @@ fn should_error_on_missing_file() -> TestResult { let_assert!(Ok(fs) = kxio::fs::temp()); let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal); let forge_details = given::forge_details(); - let test_repository = git::repository::test(fs.clone(), forge_details); + let test_repository = git::repository::test(fs.deref().clone(), forge_details); let_assert!(Ok(open_repository) = test_repository.open(&gitdir)); let repo_config = &given::a_repo_config(); let branches = repo_config.branches(); diff --git a/crates/core/src/git/repository/tests/factory.rs b/crates/core/src/git/repository/tests/factory.rs index f3266ec..b7b7a63 100644 --- a/crates/core/src/git/repository/tests/factory.rs +++ b/crates/core/src/git/repository/tests/factory.rs @@ -23,7 +23,7 @@ fn open_where_storage_external_auth_matches() -> TestResult { tracing::debug!(?result, "open"); assert!(result.is_ok()); // verify origin in .git/config matches url - let config = fs.file_read_to_string(&fs.base().join("config"))?; + let config = fs.file(&fs.base().join("config")).reader()?.to_string(); tracing::debug!(config=?config.lines().collect::>(), "auth"); assert!(config.lines().any(|line| line.contains(url))); Ok(()) @@ -60,7 +60,7 @@ fn open_where_storage_external_auth_differs_error() -> TestResult { )); // verify origin in .git/config is unchanged - let config = fs.file_read_to_string(&fs.base().join("config"))?; + let config = fs.file(&fs.base().join("config")).reader()?.to_string(); tracing::debug!(config=?config.lines().collect::>(), "auth"); assert!(config.lines().any(|line| line.contains(original_url))); // the original urk Ok(()) @@ -86,7 +86,7 @@ fn open_where_storage_internal_auth_matches() -> TestResult { tracing::debug!(?result, "open"); assert!(result.is_ok()); // verify origin in .git/config matches url - let config = fs.file_read_to_string(&fs.base().join("config"))?; + let config = fs.file(&fs.base().join("config")).reader()?.to_string(); tracing::debug!(config=?config.lines().collect::>(), "auth"); assert!( config.lines().any(|line| line.contains(url)), @@ -121,7 +121,7 @@ fn open_where_storage_internal_auth_differs_update_config() -> TestResult { assert!(result.is_ok()); // verify origin in .git/config is unchanged - let config = fs.file_read_to_string(&fs.base().join("config"))?; + let config = fs.file(&fs.base().join("config")).reader()?.to_string(); tracing::debug!(config=?config.lines().collect::>(), "auth"); assert!( config diff --git a/crates/core/src/git/tests.rs b/crates/core/src/git/tests.rs index 08760a2..1ec296d 100644 --- a/crates/core/src/git/tests.rs +++ b/crates/core/src/git/tests.rs @@ -306,7 +306,7 @@ pub mod given { webhook::Push::new(branch, sha.to_string(), message.to_string()) } - pub fn a_filesystem() -> kxio::fs::FileSystem { + pub fn a_filesystem() -> kxio::fs::TempFileSystem { kxio::fs::temp().unwrap_or_else(|e| panic!("{}", e)) } @@ -337,7 +337,8 @@ pub mod given { let repo = gix::prepare_clone_bare(url, fs.base()).unwrap(); repo.persist(); // load config file - let config_file = fs.file_read_to_string(&path.join("config")).unwrap(); + let file = fs.file(&path.join("config")); + let config_file = file.reader().unwrap().to_string(); // add use are origin url let mut config_lines = config_file.lines().collect::>(); config_lines.push(r#"[remote "origin"]"#); @@ -345,8 +346,7 @@ pub mod given { tracing::info!(?url, %url_line, "writing"); config_lines.push(&url_line); // write config file back out - fs.file_write(&path.join("config"), config_lines.join("\n").as_str()) - .unwrap(); + file.write(config_lines.join("\n").as_str()).unwrap(); } #[allow(clippy::unwrap_used)] @@ -374,7 +374,7 @@ pub mod then { let pathbuf = PathBuf::from(gitdir); let file = fs.base().join(pathbuf).join(file_name); #[allow(clippy::expect_used)] - fs.file_write(&file, contents)?; + fs.file(&file).write(contents)?; // git add ${file} git_add_file(gitdir, &file)?; // git commit -m"Added ${file}" @@ -396,7 +396,7 @@ pub mod then { let word = given::a_name(); let pathbuf = PathBuf::from(gitdir); let file = fs.base().join(pathbuf).join(&word); - fs.file_write(&file, &word)?; + fs.file(&file).write(&word)?; // git add ${file} git_add_file(gitdir, &file)?; // git commit -m"Added ${file}" @@ -420,9 +420,9 @@ pub mod then { let local_branch = gitrefs.join("heads").join(branch_name.to_string().as_str()); let origin_heads = gitrefs.join("remotes").join("origin"); let remote_branch = origin_heads.join(branch_name.to_string().as_str()); - let contents = fs.file_read_to_string(&local_branch)?; - fs.dir_create_all(&origin_heads)?; - fs.file_write(&remote_branch, &contents)?; + let contents = fs.file(&local_branch).reader()?.to_string(); + fs.dir(&origin_heads).create_all()?; + fs.file(&remote_branch).write(&contents)?; Ok(()) } @@ -514,7 +514,7 @@ pub mod then { .join("refs") .join("heads") .join(branch_name.to_string().as_str()); - let sha = fs.file_read_to_string(&main_ref)?; + let sha = fs.file(&main_ref).reader()?.to_string(); Ok(git::commit::Sha::new(sha.trim().to_string())) } } diff --git a/crates/core/src/git/validation/tests.rs b/crates/core/src/git/validation/tests.rs index 12d5fac..4e54851 100644 --- a/crates/core/src/git/validation/tests.rs +++ b/crates/core/src/git/validation/tests.rs @@ -15,6 +15,8 @@ use crate::{ use assert2::let_assert; +use std::ops::Deref as _; + mod repos { use super::*; @@ -208,12 +210,12 @@ mod positions { let fs = given::a_filesystem(); let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal); let forge_details = given::forge_details(); - let mut test_repository = git::repository::test(fs.clone(), forge_details); + let mut test_repository = git::repository::test(fs.deref().clone(), forge_details); let repo_config = given::a_repo_config(); test_repository.on_fetch(OnFetch::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |branches, gitdir, fs| { // /--- 4 next // 0 --- 1 --- 3 main @@ -259,12 +261,12 @@ mod positions { let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs"); let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal); let forge_details = given::forge_details(); - let mut test_repository = git::repository::test(fs.clone(), forge_details); + let mut test_repository = git::repository::test(fs.deref().clone(), forge_details); let repo_config = given::a_repo_config(); test_repository.on_fetch(OnFetch::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |branches, gitdir, fs| { // /--- 4 dev // 0 --- 1 --- 3 main @@ -288,7 +290,7 @@ mod positions { test_repository.on_fetch(OnFetch::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |_branches, _gitdir, _fs| { // don't change anything git::fetch::Result::Ok(()) @@ -297,7 +299,7 @@ mod positions { test_repository.on_push(OnPush::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |_repo_details, branch_name, gitref, force, repo_branches, gitdir, fs| { assert_eq!( branch_name, @@ -346,12 +348,12 @@ mod positions { let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs"); let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal); let forge_details = given::forge_details(); - let mut test_repository = git::repository::test(fs.clone(), forge_details); + let mut test_repository = git::repository::test(fs.deref().clone(), forge_details); let repo_config = given::a_repo_config(); test_repository.on_fetch(OnFetch::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |branches, gitdir, fs| { // /--- 4 dev // 0 --- 1 --- 3 main @@ -375,7 +377,7 @@ mod positions { test_repository.on_fetch(OnFetch::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |_branches, _gitdir, _fs| { // don't change anything git::fetch::Result::Ok(()) @@ -384,7 +386,7 @@ mod positions { test_repository.on_push(OnPush::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |_repo_details, _branch_name, _gitref, _force, _repo_branches, _gitdir, _fs| { git::push::Result::Err(git::push::Error::Lock) }, @@ -420,12 +422,12 @@ mod positions { let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs"); let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal); let forge_details = given::forge_details(); - let mut test_repository = git::repository::test(fs.clone(), forge_details); + let mut test_repository = git::repository::test(fs.deref().clone(), forge_details); let repo_config = given::a_repo_config(); test_repository.on_fetch(OnFetch::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |branches, gitdir, fs| { // /--- 3 next // 0 --- 1 main & dev @@ -446,7 +448,7 @@ mod positions { test_repository.on_fetch(OnFetch::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |_branches, _gitdir, _fs| { // don't change anything git::fetch::Result::Ok(()) @@ -455,7 +457,7 @@ mod positions { test_repository.on_push(OnPush::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |_repo_details, branch_name, gitref, force, repo_branches, gitdir, fs| { assert_eq!( branch_name, @@ -506,12 +508,12 @@ mod positions { let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs"); let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal); let forge_details = given::forge_details(); - let mut test_repository = git::repository::test(fs.clone(), forge_details); + let mut test_repository = git::repository::test(fs.deref().clone(), forge_details); let repo_config = given::a_repo_config(); test_repository.on_fetch(OnFetch::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |branches, gitdir, fs| { // /--- 3 next // 0 --- 1 main @@ -533,7 +535,7 @@ mod positions { test_repository.on_fetch(OnFetch::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |_branches, _gitdir, _fs| { // don't change anything git::fetch::Result::Ok(()) @@ -542,7 +544,7 @@ mod positions { test_repository.on_push(OnPush::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |_repo_details, branch_name, gitref, force, repo_branches, gitdir, fs| { assert_eq!( branch_name, @@ -604,12 +606,12 @@ mod positions { let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs"); let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal); let forge_details = given::forge_details(); - let mut test_repository = git::repository::test(fs.clone(), forge_details); + let mut test_repository = git::repository::test(fs.deref().clone(), forge_details); let repo_config = given::a_repo_config(); test_repository.on_fetch(OnFetch::new( repo_config.branches().clone(), gitdir.clone(), - fs.clone(), + fs.deref().clone(), |branches, gitdir, fs| { // 0 --- 1 main // \--- 2 next diff --git a/crates/forge-forgejo/src/lib.rs b/crates/forge-forgejo/src/lib.rs index b6a5b08..3828976 100644 --- a/crates/forge-forgejo/src/lib.rs +++ b/crates/forge-forgejo/src/lib.rs @@ -13,17 +13,16 @@ use git_next_core::{ ForgeNotification, RegisteredWebhook, WebhookAuth, WebhookId, }; -use kxio::network::{self, Network}; -use tracing::warn; +use kxio::net::Net; #[derive(Clone, Debug)] pub struct ForgeJo { repo_details: git::RepoDetails, - net: Network, + net: Net, } impl ForgeJo { #[must_use] - pub const fn new(repo_details: git::RepoDetails, net: Network) -> Self { + pub const fn new(repo_details: git::RepoDetails, net: Net) -> Self { Self { repo_details, net } } } @@ -52,45 +51,28 @@ impl git::ForgeLike for ForgeJo { webhook::parse_body(body) } - async fn commit_status(&self, commit: &git::Commit) -> Status { + async fn commit_status(&self, commit: &git::Commit) -> git::forge::webhook::Result { let repo_details = &self.repo_details; let hostname = &repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; let api_token = &repo_details.forge.token(); use secrecy::ExposeSecret; let token = api_token.expose_secret(); - let url = network::NetUrl::new(format!( + let url = format!( "https://{hostname}/api/v1/repos/{repo_path}/commits/{commit}/status?token={token}" - )); - - let request = network::NetRequest::new( - network::RequestMethod::Get, - url, - network::NetRequestHeaders::new(), - network::RequestBody::None, - network::ResponseType::Json, - None, - network::NetRequestLogging::None, ); - let result = self.net.get::(request).await; - match result { - Ok(response) => match response.response_body() { - Some(status) => match status.state { - ForgejoState::Success => Status::Pass, - ForgejoState::Pending | ForgejoState::Blank => Status::Pending, - ForgejoState::Failure | ForgejoState::Error => Status::Fail, - }, - None => { - #[cfg(not(tarpaulin_include))] - unreachable!(); // response.response_body() is always Some when - // request responseType::Json - } - }, - Err(e) => { - warn!(?e, "Failed to get commit status"); - Status::Pending // assume issue is transient and allow retry - } - } + + let Ok(response) = self.net.get(url).send().await else { + return Ok(Status::Pending); + }; + let combined_status = response.json::().await.unwrap_or_default(); + eprintln!("combined_status: {:?}", combined_status); + let status = match combined_status.state { + ForgejoState::Success => Status::Pass, + ForgejoState::Pending | ForgejoState::Blank => Status::Pending, + ForgejoState::Failure | ForgejoState::Error => Status::Fail, + }; + Ok(status) } async fn list_webhooks( @@ -112,16 +94,17 @@ impl git::ForgeLike for ForgeJo { } } -#[derive(Debug, serde::Deserialize)] +#[derive(Debug, Default, serde::Deserialize)] struct CombinedStatus { pub state: ForgejoState, } -#[derive(Debug, serde::Deserialize)] +#[derive(Debug, Default, serde::Deserialize)] enum ForgejoState { #[serde(rename = "success")] Success, #[serde(rename = "pending")] + #[default] Pending, #[serde(rename = "failure")] Failure, diff --git a/crates/forge-forgejo/src/tests.rs b/crates/forge-forgejo/src/tests.rs index 46f852a..5ae9638 100644 --- a/crates/forge-forgejo/src/tests.rs +++ b/crates/forge-forgejo/src/tests.rs @@ -1,14 +1,16 @@ // +#![allow(clippy::expect_used)] // used with mock net + use crate::ForgeJo; use git_next_core::{ git::{self, forge::commit::Status, ForgeLike as _}, - server::ListenUrl, + server::{ListenUrl, RepoListenUrl}, BranchName, ForgeAlias, ForgeConfig, ForgeNotification, ForgeType, GitDir, Hostname, RepoAlias, RepoBranches, RepoPath, ServerRepoConfig, StoragePathType, WebhookAuth, WebhookId, }; use assert2::let_assert; -use kxio::network::{self, MockNetwork, StatusCode}; +use kxio::net::{MockNet, StatusCode}; use secrecy::ExposeSecret; use serde::Serialize; use serde_json::json; @@ -116,77 +118,105 @@ mod forgejo { let fs = given::a_filesystem(); let repo_details = given::repo_details(&fs); let commit = given::a_commit(); - let mut net = given::a_network(); - given::a_commit_state("success", &mut net, &repo_details, &commit); + let net = given::a_network(); + given::a_commit_state("success", &net, &repo_details, &commit); let forge = given::a_forgejo_forge(&repo_details, net); - assert_eq!(forge.commit_status(&commit).await, Status::Pass); + assert_eq!( + forge.commit_status(&commit).await.expect("status"), + Status::Pass + ); } #[tokio::test] async fn should_return_pending_for_pending() { let fs = given::a_filesystem(); let repo_details = given::repo_details(&fs); let commit = given::a_commit(); - let mut net = given::a_network(); - given::a_commit_state("pending", &mut net, &repo_details, &commit); + let net = given::a_network(); + given::a_commit_state("pending", &net, &repo_details, &commit); let forge = given::a_forgejo_forge(&repo_details, net); - assert_eq!(forge.commit_status(&commit).await, Status::Pending); + assert_eq!( + forge.commit_status(&commit).await.expect("status"), + Status::Pending + ); } #[tokio::test] async fn should_return_fail_for_failure() { let fs = given::a_filesystem(); let repo_details = given::repo_details(&fs); let commit = given::a_commit(); - let mut net = given::a_network(); - given::a_commit_state("failure", &mut net, &repo_details, &commit); + let net = given::a_network(); + given::a_commit_state("failure", &net, &repo_details, &commit); let forge = given::a_forgejo_forge(&repo_details, net); - assert_eq!(forge.commit_status(&commit).await, Status::Fail); + assert_eq!( + forge.commit_status(&commit).await.expect("status"), + Status::Fail + ); } #[tokio::test] async fn should_return_fail_for_error() { let fs = given::a_filesystem(); let repo_details = given::repo_details(&fs); let commit = given::a_commit(); - let mut net = given::a_network(); - given::a_commit_state("error", &mut net, &repo_details, &commit); + let net = given::a_network(); + given::a_commit_state("error", &net, &repo_details, &commit); let forge = given::a_forgejo_forge(&repo_details, net); - assert_eq!(forge.commit_status(&commit).await, Status::Fail); + assert_eq!( + forge.commit_status(&commit).await.expect("status"), + Status::Fail + ); } #[tokio::test] async fn should_return_pending_for_blank() { let fs = given::a_filesystem(); let repo_details = given::repo_details(&fs); let commit = given::a_commit(); - let mut net = given::a_network(); - given::a_commit_state("", &mut net, &repo_details, &commit); + let net = given::a_network(); + given::a_commit_state("", &net, &repo_details, &commit); let forge = given::a_forgejo_forge(&repo_details, net); - assert_eq!(forge.commit_status(&commit).await, Status::Pending); + assert_eq!( + forge.commit_status(&commit).await.expect("status"), + Status::Pending + ); } #[tokio::test] async fn should_return_pending_for_no_statuses() { let fs = given::a_filesystem(); let repo_details = given::repo_details(&fs); let commit = given::a_commit(); - let mut net = given::a_network(); - net.add_get_response( - &given::a_commit_status_url(&repo_details, &commit), - StatusCode::OK, - "", - ); + let net = given::a_network(); + net.on() + .get(given::a_commit_status_url(&repo_details, &commit)) + .respond(StatusCode::OK) + .body( + json!({ + "state": "" // blank => Pending + }) + .to_string(), + ) + .expect("mock"); let forge = given::a_forgejo_forge(&repo_details, net); - assert_eq!(forge.commit_status(&commit).await, Status::Pending); + assert_eq!( + forge.commit_status(&commit).await.expect("status"), + Status::Pending + ); } #[tokio::test] async fn should_return_pending_for_network_error() { let fs = given::a_filesystem(); let repo_details = given::repo_details(&fs); let commit = given::a_commit(); - let mut net = given::a_network(); - net.add_get_error( - &given::a_commit_status_url(&repo_details, &commit), - "boom today", + let mock_net = given::a_network(); + mock_net + .on() + .get(given::a_commit_status_url(&repo_details, &commit)) + .respond(StatusCode::INTERNAL_SERVER_ERROR) + .body("book today") + .expect("mock"); + let forge = given::a_forgejo_forge(&repo_details, mock_net); + assert_eq!( + forge.commit_status(&commit).await.expect("status"), + Status::Pending ); - let forge = given::a_forgejo_forge(&repo_details, net); - assert_eq!(forge.commit_status(&commit).await, Status::Pending); } } @@ -246,13 +276,15 @@ mod forgejo { let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; let token = repo_details.forge.token().expose_secret(); - let mut net = given::a_network(); + let net = given::a_network(); - net.add_get_error( - format!("https://{hostname}/api/v1/repos/{repo_path}/hooks?page=1&token={token}") - .as_str(), - "error_message", - ); + net.on() + .get(format!( + "https://{hostname}/api/v1/repos/{repo_path}/hooks?page=1&token={token}" + )) + .respond(StatusCode::INTERNAL_SERVER_ERROR) + .body("error_message") + .expect("mock"); let forge = given::a_forgejo_forge(&repo_details, net); @@ -271,16 +303,15 @@ mod forgejo { let repo_path = &repo_details.repo_path; let token = repo_details.forge.token().expose_secret(); let webhook_id = given::a_webhook_id(); - let mut net = given::a_network(); + let net = given::a_network(); - net.add_delete_response( - format!( + net.on() + .delete(format!( "https://{hostname}/api/v1/repos/{repo_path}/hooks/{webhook_id}?token={token}" - ) - .as_str(), - StatusCode::OK, - "", - ); + )) + .respond(StatusCode::OK) + .body("") + .expect("mock"); let forge = given::a_forgejo_forge(&repo_details, net); @@ -295,15 +326,15 @@ mod forgejo { let repo_path = &repo_details.repo_path; let token = repo_details.forge.token().expose_secret(); let webhook_id = given::a_webhook_id(); - let mut net = given::a_network(); + let net = given::a_network(); - net.add_delete_error( - format!( + net.on() + .delete(format!( "https://{hostname}/api/v1/repos/{repo_path}/hooks/{webhook_id}?token={token}" - ) - .as_str(), - "error", - ); + )) + .respond(StatusCode::INTERNAL_SERVER_ERROR) + .body("error") + .expect("mock"); let forge = given::a_forgejo_forge(&repo_details, net); @@ -343,11 +374,13 @@ mod forgejo { with::get_webhooks_by_page(1, &[], &mut args); // register the webhook will succeed let webhook_id = given::a_forgejo_webhook_id(); - net.add_post_response( - format!("https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}").as_str(), - StatusCode::OK, - json!({"id": webhook_id, "config":{}}).to_string().as_str(), - ); + net.on() + .post(format!( + "https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}" + )) + .respond(StatusCode::OK) + .body(json!({"id": webhook_id, "config":{}}).to_string()) + .expect("mock"); let forge = given::a_forgejo_forge(&repo_details, net); @@ -415,11 +448,13 @@ mod forgejo { with::unregister_webhook(&hooks[1], &mut args); // register the webhook will succeed let webhook_id = given::a_forgejo_webhook_id(); - net.add_post_response( - format!("https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}").as_str(), - StatusCode::OK, - json!({"id": webhook_id, "config":{}}).to_string().as_str(), - ); + net.on() + .post(format!( + "https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}" + )) + .respond(StatusCode::OK) + .body(json!({"id": webhook_id, "config":{}}).to_string()) + .expect("mock"); let forge = given::a_forgejo_forge(&repo_details, net); @@ -454,17 +489,19 @@ mod forgejo { // there are no existing matching webhooks with::get_webhooks_by_page(1, &[], &mut args); // register the webhook will return empty response - net.add_post_response( - format!("https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}").as_str(), - StatusCode::OK, - json!({}).to_string().as_str(), // empty response - ); + net.on() + .post(format!( + "https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}" + )) + .respond(StatusCode::OK) + .body(json!({}).to_string()) // empty response) + .expect("mock"); let forge = given::a_forgejo_forge(&repo_details, net); let_assert!(Err(err) = forge.register_webhook(&repo_listen_url).await); assert!( - matches!(err, git::forge::webhook::Error::FailedToRegister(_)), + matches!(err, git::forge::webhook::Error::NetworkResponseEmpty), "{err:?}" ); } @@ -493,10 +530,13 @@ mod forgejo { // there are no existing matching webhooks with::get_webhooks_by_page(1, &[], &mut args); // register the webhook will return empty response - net.add_post_error( - format!("https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}").as_str(), - "error", - ); + net.on() + .post(format!( + "https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}" + )) + .respond(StatusCode::INTERNAL_SERVER_ERROR) + .body("error") + .expect("mock"); let forge = given::a_forgejo_forge(&repo_details, net); @@ -508,7 +548,6 @@ mod forgejo { } } mod with { - use git_next_core::server::RepoListenUrl; use super::*; @@ -520,31 +559,31 @@ mod forgejo { let hostname = args.hostname; let repo_path = args.repo_path; let token = args.token; - args.net.add_get_response( - format!( + args.net + .on() + .get(format!( "https://{hostname}/api/v1/repos/{repo_path}/hooks?page={page}&token={token}" - ) - .as_str(), - StatusCode::OK, - json!(response).to_string().as_str(), - ); + )) + .respond(StatusCode::OK) + .body(json!(response).to_string()) + .expect("mock"); } pub fn unregister_webhook(hook1: &ReturnedWebhook, args: &mut WebhookArgs) { let webhook_id = hook1.id; let hostname = args.hostname; let repo_path = args.repo_path; let token = args.token; - args.net.add_delete_response( - format!( + args.net + .on() + .delete(format!( "https://{hostname}/api/v1/repos/{repo_path}/hooks/{webhook_id}?token={token}" - ) - .as_str(), - StatusCode::OK, - "", - ); + )) + .respond(StatusCode::OK) + .body("") + .expect("mock"); } pub struct WebhookArgs<'a> { - pub net: &'a mut network::MockNetwork, + pub net: &'a MockNet, pub hostname: &'a Hostname, pub repo_path: &'a RepoPath, pub token: &'a str, @@ -573,21 +612,21 @@ mod forgejo { use git::RepoDetails; use git_next_core::server::RepoListenUrl; + use kxio::net::{MockNet, StatusCode}; use super::*; pub fn a_commit_state( state: impl AsRef, - net: &mut MockNetwork, + net: &MockNet, repo_details: &git::RepoDetails, commit: &git::Commit, ) { - let response = json!({"state":state.as_ref()}); - net.add_get_response( - a_commit_status_url(repo_details, commit).as_str(), - StatusCode::OK, - response.to_string().as_str(), - ); + net.on() + .get(a_commit_status_url(repo_details, commit)) + .respond(StatusCode::OK) + .body((json!({"state":state.as_ref()})).to_string()) + .expect("mock"); } pub fn a_commit_status_url( @@ -644,9 +683,10 @@ mod forgejo { pub fn a_forgejo_forge( repo_details: &git::RepoDetails, - net: impl Into, + net: impl Into, ) -> ForgeJo { - ForgeJo::new(repo_details.clone(), net.into()) + let net: kxio::net::Net = net.into(); + ForgeJo::new(repo_details.clone(), net) } pub fn a_forgejo_webhook_id() -> i64 { @@ -674,8 +714,8 @@ mod forgejo { RepoAlias::new(a_name()) } - pub fn a_network() -> kxio::network::MockNetwork { - kxio::network::MockNetwork::new() + pub fn a_network() -> kxio::net::MockNet { + kxio::net::mock() } pub fn a_name() -> String { @@ -758,8 +798,8 @@ mod forgejo { git::commit::Sha::new(a_name()) } - pub fn a_filesystem() -> kxio::fs::FileSystem { - kxio::fs::temp().unwrap_or_else(|e| panic!("{}", e)) + pub fn a_filesystem() -> kxio::fs::TempFileSystem { + kxio::fs::temp().expect("temp fs") } pub fn repo_details(fs: &kxio::fs::FileSystem) -> git::RepoDetails { diff --git a/crates/forge-forgejo/src/webhook/list.rs b/crates/forge-forgejo/src/webhook/list.rs index 1282fd0..734109f 100644 --- a/crates/forge-forgejo/src/webhook/list.rs +++ b/crates/forge-forgejo/src/webhook/list.rs @@ -1,14 +1,13 @@ // use git_next_core::{git, server::RepoListenUrl, WebhookId}; - -use kxio::network; +use kxio::net::Net; use crate::webhook::Hook; pub async fn list( repo_details: &git::RepoDetails, repo_listen_url: &RepoListenUrl, - net: &network::Network, + net: &Net, ) -> git::forge::webhook::Result> { let mut ids: Vec = vec![]; let hostname = &repo_details.forge.hostname(); @@ -17,22 +16,15 @@ pub async fn list( loop { use secrecy::ExposeSecret; let token = &repo_details.forge.token().expose_secret(); - let url = - format!("https://{hostname}/api/v1/repos/{repo_path}/hooks?page={page}&token={token}"); - let net_url = network::NetUrl::new(url); - let request = network::NetRequest::new( - network::RequestMethod::Get, - net_url, - network::NetRequestHeaders::new(), - network::RequestBody::None, - network::ResponseType::Json, - None, - network::NetRequestLogging::None, - ); - let result = net.get::>(request).await; - match result { + match net + .get(format!( + "https://{hostname}/api/v1/repos/{repo_path}/hooks?page={page}&token={token}" + )) + .send() + .await + { Ok(response) => { - if let Some(list) = response.response_body() { + if let Ok(list) = response.json::>().await { if list.is_empty() { return Ok(ids); } diff --git a/crates/forge-forgejo/src/webhook/register.rs b/crates/forge-forgejo/src/webhook/register.rs index c2160dd..b2feb7c 100644 --- a/crates/forge-forgejo/src/webhook/register.rs +++ b/crates/forge-forgejo/src/webhook/register.rs @@ -1,8 +1,9 @@ // use git_next_core::{git, server::RepoListenUrl, RegisteredWebhook, WebhookAuth, WebhookId}; -use kxio::network; +use kxio::net::Net; use secrecy::ExposeSecret as _; +use serde_json::json; use tracing::{info, instrument, warn}; use crate::webhook; @@ -12,7 +13,7 @@ use crate::webhook::Hook; pub async fn register( repo_details: &git::RepoDetails, repo_listen_url: &RepoListenUrl, - net: &network::Network, + net: &Net, ) -> git::forge::webhook::Result { let Some(repo_config) = repo_details.repo_config.clone() else { return Err(git::forge::webhook::Error::NoRepoConfig); @@ -27,35 +28,27 @@ pub async fn register( let hostname = &repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; let token = repo_details.forge.token().expose_secret(); - let url = network::NetUrl::new(format!( - "https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}" - )); - let headers = network::NetRequestHeaders::new().with("Content-Type", "application/json"); + let url = format!("https://{hostname}/api/v1/repos/{repo_path}/hooks?token={token}"); let authorisation = WebhookAuth::generate(); - let body = network::json!({ - "active": true, - "authorization_header": authorisation.header_value(), - "branch_filter": format!("{{{},{},{}}}", repo_config.branches().main(), repo_config.branches().next(), repo_config.branches().dev()), - "config": { - "content_type": "json", - "url": repo_listen_url.to_string(), - }, - "events": [ "push" ], - "type": "forgejo" - }); - let request = network::NetRequest::new( - network::RequestMethod::Post, - url, - headers, - network::RequestBody::Json(body), - network::ResponseType::Json, - None, - network::NetRequestLogging::None, - ); - let result = net.post_json::(request).await; - match result { + match net + .post(url) + .header("Content-Type", "application/json") + .body(json!({ + "active": true, + "authorization_header": authorisation.header_value(), + "branch_filter": format!("{{{},{},{}}}", repo_config.branches().main(), repo_config.branches().next(), repo_config.branches().dev()), + "config": { + "content_type": "json", + "url": repo_listen_url.to_string(), + }, + "events": [ "push" ], + "type": "forgejo" + }).to_string()) + .send() + .await + { Ok(response) => { - let Some(hook) = response.response_body() else { + let Ok(hook) = response.json::().await else { #[cfg(not(tarpaulin_include))] // request response is Json so response_body never returns None return Err(git::forge::webhook::Error::NetworkResponseEmpty); @@ -71,4 +64,5 @@ pub async fn register( Err(git::forge::webhook::Error::FailedToRegister(e.to_string())) } } + // Ok(()) } diff --git a/crates/forge-forgejo/src/webhook/unregister.rs b/crates/forge-forgejo/src/webhook/unregister.rs index c07a5f6..f50dbb2 100644 --- a/crates/forge-forgejo/src/webhook/unregister.rs +++ b/crates/forge-forgejo/src/webhook/unregister.rs @@ -1,30 +1,24 @@ // use git_next_core::{git, WebhookId}; -use kxio::network; +use kxio::net::Net; use secrecy::ExposeSecret as _; pub async fn unregister( webhook_id: &WebhookId, repo_details: &git::RepoDetails, - net: &network::Network, + net: &Net, ) -> git::forge::webhook::Result<()> { let hostname = &repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; let token = repo_details.forge.token().expose_secret(); - let url = network::NetUrl::new(format!( - "https://{hostname}/api/v1/repos/{repo_path}/hooks/{webhook_id}?token={token}" - )); - let request = network::NetRequest::new( - network::RequestMethod::Delete, - url, - network::NetRequestHeaders::new(), - network::RequestBody::None, - network::ResponseType::None, - None, - network::NetRequestLogging::None, - ); - match net.delete(request).await { + match net + .delete(format!( + "https://{hostname}/api/v1/repos/{repo_path}/hooks/{webhook_id}?token={token}" + )) + .send() + .await + { Err(e) => { tracing::warn!("Failed to unregister webhook"); Err(git::forge::webhook::Error::FailedToUnregister( diff --git a/crates/forge-github/src/commit.rs b/crates/forge-github/src/commit.rs index bee1db6..c286493 100644 --- a/crates/forge-github/src/commit.rs +++ b/crates/forge-github/src/commit.rs @@ -2,53 +2,46 @@ use crate::{self as github, GithubState}; use git_next_core::git::{self, forge::commit::Status}; use github::GithubStatus; -use kxio::network; /// Checks the results of any (e.g. CI) status checks for the commit. /// /// GitHub: -pub async fn status(github: &github::Github, commit: &git::Commit) -> git::forge::commit::Status { +pub async fn status( + github: &github::Github, + commit: &git::Commit, +) -> git::forge::webhook::Result { let repo_details = &github.repo_details; let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; - let url = network::NetUrl::new(format!( - "https://api.{hostname}/repos/{repo_path}/commits/{commit}/statuses" - )); - let headers = github::webhook::headers(repo_details.forge.token()); - let request = network::NetRequest::new( - network::RequestMethod::Get, - url, - headers, - network::RequestBody::None, - network::ResponseType::Json, - None, - network::NetRequestLogging::None, - ); - let result = github.net.get::>(request).await; - match result { - Ok(response) => response - .response_body() - .and_then(|statuses| { - statuses - .into_iter() - .map(|status| match status.state { - GithubState::Success => Status::Pass, - GithubState::Pending | GithubState::Blank => Status::Pending, - GithubState::Failure | GithubState::Error => Status::Fail, - }) - .reduce(|l, r| match (l, r) { - (Status::Pass, Status::Pass) => Status::Pass, - (_, Status::Fail) | (Status::Fail, _) => Status::Fail, - (_, Status::Pending) | (Status::Pending, _) => Status::Pending, - }) - }) - .unwrap_or_else(|| { - tracing::warn!("No status checks configured for 'next' branch",); - Status::Pass - }), - Err(e) => { - tracing::warn!(?e, "Failed to get commit status"); - Status::Pending // assume issue is transient and allow retry - } - } + let url = format!("https://api.{hostname}/repos/{repo_path}/commits/{commit}/statuses"); + let Ok(response) = github + .net + .get(url) + .headers(github::webhook::headers(repo_details.forge.token())) + .body("") + .send() + .await + else { + return Ok(Status::Pending); + }; + let statuses = response.json::>().await?; + let result = statuses + .into_iter() + .map(|status| match status.state { + GithubState::Success => Status::Pass, + GithubState::Pending | GithubState::Blank => Status::Pending, + GithubState::Failure | GithubState::Error => Status::Fail, + }) + .reduce(|l, r| match (l, r) { + (Status::Pass, Status::Pass) => Status::Pass, + (_, Status::Fail) | (Status::Fail, _) => Status::Fail, + (_, Status::Pending) | (Status::Pending, _) => Status::Pending, + (Status::Error(e1), Status::Error(e2)) => Status::Error(format!("{e1} / {e2}")), + (_, Status::Error(err)) | (Status::Error(err), _) => Status::Error(err), + }) + .unwrap_or_else(|| { + tracing::warn!("No status checks configured for 'next' branch",); + Status::Pass + }); + Ok(result) } diff --git a/crates/forge-github/src/lib.rs b/crates/forge-github/src/lib.rs index 5bb410d..14a6783 100644 --- a/crates/forge-github/src/lib.rs +++ b/crates/forge-github/src/lib.rs @@ -7,8 +7,7 @@ mod webhook; use crate as github; use git_next_core::{ - self as core, - git::{self, forge::commit::Status}, + self as core, git, server::{self, RepoListenUrl}, ForgeNotification, RegisteredWebhook, WebhookAuth, WebhookId, }; @@ -18,7 +17,7 @@ use derive_more::Constructor; #[derive(Clone, Debug, Constructor)] pub struct Github { repo_details: git::RepoDetails, - net: kxio::network::Network, + net: kxio::net::Net, } #[async_trait::async_trait] impl git::ForgeLike for Github { @@ -52,7 +51,10 @@ impl git::ForgeLike for Github { github::webhook::parse_body(body) } - async fn commit_status(&self, commit: &git::Commit) -> Status { + async fn commit_status( + &self, + commit: &git::Commit, + ) -> git::forge::webhook::Result { github::commit::status(self, commit).await } diff --git a/crates/forge-github/src/tests/mod.rs b/crates/forge-github/src/tests/mod.rs index 99cf0d4..28a611f 100644 --- a/crates/forge-github/src/tests/mod.rs +++ b/crates/forge-github/src/tests/mod.rs @@ -1,4 +1,6 @@ // +#![allow(clippy::expect_used)] + use crate::{Github, GithubState, GithubStatus}; use git_next_core::{ git::{self, forge::commit::Status, ForgeLike}, @@ -9,7 +11,7 @@ use git_next_core::{ }; use assert2::let_assert; -use kxio::network::{self, MockNetwork, StatusCode}; +use kxio::net::{MockNet, StatusCode}; use rand::RngCore; use serde::Serialize; use serde_json::json; @@ -99,10 +101,10 @@ mod github { let (states, expected) = $value; let repo_details = given::repo_details(); let commit = given::a_commit(); - let mut net = given::a_network(); - given::commit_states(&states, &mut net, &repo_details, &commit); + let net = given::a_network(); + given::commit_states(&states, &net, &repo_details, &commit); let forge = given::a_github_forge(&repo_details, net); - assert_eq!(forge.commit_status(&commit).await, expected); + assert_eq!(forge.commit_status(&commit).await.expect("status"), expected); } )* } @@ -125,29 +127,37 @@ mod github { ); #[tokio::test] - async fn should_return_pending_for_no_statuses() { + async fn should_return_pass_for_no_statuses() { let repo_details = given::repo_details(); let commit = given::a_commit(); - let mut net = given::a_network(); - net.add_get_response( - &given::a_commit_status_url(&repo_details, &commit), - StatusCode::OK, - "", - ); + let net = given::a_network(); + net.on() + .get(given::a_commit_status_url(&repo_details, &commit)) + .respond(StatusCode::OK) + .body(json!([]).to_string()) + .expect("mock"); let forge = given::a_github_forge(&repo_details, net); - assert_eq!(forge.commit_status(&commit).await, Status::Pending); + assert_eq!( + forge.commit_status(&commit).await.expect("status"), + Status::Pass // no CI checks configured + ); } + #[tokio::test] async fn should_return_pending_for_network_error() { let repo_details = given::repo_details(); let commit = given::a_commit(); - let mut net = given::a_network(); - net.add_get_error( - &given::a_commit_status_url(&repo_details, &commit), - "boom today", - ); + let net = given::a_network(); + net.on() + .get(given::a_commit_status_url(&repo_details, &commit)) + .respond(StatusCode::INTERNAL_SERVER_ERROR) + .body("boom today") + .expect("mock"); let forge = given::a_github_forge(&repo_details, net); - assert_eq!(forge.commit_status(&commit).await, Status::Pending); + assert_eq!( + forge.commit_status(&commit).await.expect("status"), + Status::Pending + ); } } @@ -164,9 +174,9 @@ mod github { let hook_id_1 = given::a_github_webhook_id(); let hook_id_2 = given::a_github_webhook_id(); let hook_id_3 = given::a_github_webhook_id(); - let mut net = given::a_network(); - let mut args = with::WebhookArgs { - net: &mut net, + let net = given::a_network(); + let args = with::WebhookArgs { + net: &net, hostname, repo_path, }; @@ -178,10 +188,10 @@ mod github { with::ReturnedWebhook::new(hook_id_2, &repo_listen_url), with::ReturnedWebhook::new(hook_id_3, &given::any_webhook_url()), ], - &mut args, + &args, ); // page 2 with no items - stops pagination - with::get_webhooks_by_page(2, &[], &mut args); + with::get_webhooks_by_page(2, &[], &args); let forge = given::a_github_forge(&repo_details, net); @@ -201,11 +211,14 @@ mod github { let repo_listen_url = given::a_repo_listen_url(&repo_details); let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; - let mut net = given::a_network(); - net.add_get_error( - format!("https://api.{hostname}/repos/{repo_path}/hooks?page=1").as_str(), - "error_message", - ); + let net = given::a_network(); + net.on() + .get(format!( + "https://api.{hostname}/repos/{repo_path}/hooks?page=1" + )) + .respond(StatusCode::INTERNAL_SERVER_ERROR) + .body("error_message") + .expect("mock"); let forge = given::a_github_forge(&repo_details, net); @@ -222,12 +235,14 @@ mod github { let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; let webhook_id = given::a_webhook_id(); - let mut net = given::a_network(); - net.add_delete_response( - format!("https://api.{hostname}/repos/{repo_path}/hooks/{webhook_id}").as_str(), - StatusCode::OK, - "", - ); + let net = given::a_network(); + net.on() + .delete(format!( + "https://api.{hostname}/repos/{repo_path}/hooks/{webhook_id}" + )) + .respond(StatusCode::OK) + .body("") + .expect("mock"); let forge = given::a_github_forge(&repo_details, net); @@ -242,16 +257,19 @@ mod github { ); let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; - let mut net = given::a_network(); + let net = given::a_network(); // unregister the webhook will return empty response - net.add_delete_error( - format!("https://api.{hostname}/repos/{repo_path}/hooks").as_str(), - "error", - ); + let webhook_id = given::a_webhook_id(); + net.on() + .delete(format!( + "https://api.{hostname}/repos/{repo_path}/hooks/{webhook_id}" + )) + .respond(StatusCode::INTERNAL_SERVER_ERROR) + .mock() + .expect("mock"); let forge = given::a_github_forge(&repo_details, net); - let webhook_id = given::a_webhook_id(); let_assert!(Err(err) = forge.unregister_webhook(&webhook_id).await); assert!( matches!(err, git::forge::webhook::Error::FailedToRegister(_)), @@ -274,23 +292,24 @@ mod github { let repo_listen_url = given::a_repo_listen_url(&repo_details); let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; - let mut net = given::a_network(); - let mut args = with::WebhookArgs { - net: &mut net, + let net = given::a_network(); + let args = with::WebhookArgs { + net: &net, hostname, repo_path, }; // there are no existing matching webhooks - with::get_webhooks_by_page(1, &[], &mut args); + with::get_webhooks_by_page(1, &[], &args); // register the webhook will succeed let webhook_id = given::a_github_webhook_id(); - net.add_post_response( - format!("https://api.{hostname}/repos/{repo_path}/hooks").as_str(), - StatusCode::OK, - json!({"id": webhook_id, "config":{"url": repo_listen_url.to_string()}}) - .to_string() - .as_str(), - ); + net.on() + .post(format!("https://api.{hostname}/repos/{repo_path}/hooks")) + .respond(StatusCode::OK) + .body( + json!({"id": webhook_id, "config":{"url": repo_listen_url.to_string()}}) + .to_string(), + ) + .expect("mock"); let forge = given::a_github_forge(&repo_details, net); @@ -329,9 +348,9 @@ mod github { let repo_listen_url = given::a_repo_listen_url(&repo_details); let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; - let mut net = given::a_network(); - let mut args = with::WebhookArgs { - net: &mut net, + let net = given::a_network(); + let args = with::WebhookArgs { + net: &net, hostname, repo_path, }; @@ -341,20 +360,21 @@ mod github { with::ReturnedWebhook::new(given::a_github_webhook_id(), &given::any_webhook_url()); let hooks = [hook_1, hook_2, hook_3]; // there are three existing webhooks, two are matching webhooks - with::get_webhooks_by_page(1, &hooks, &mut args); - with::get_webhooks_by_page(2, &[], &mut args); + with::get_webhooks_by_page(1, &hooks, &args); + with::get_webhooks_by_page(2, &[], &args); // should unregister 1 and 2, but not 3 - with::unregister_webhook(&hooks[0], &mut args); - with::unregister_webhook(&hooks[1], &mut args); + with::unregister_webhook(&hooks[0], &args); + with::unregister_webhook(&hooks[1], &args); // register the webhook will succeed let webhook_id = given::a_github_webhook_id(); - net.add_post_response( - format!("https://api.{hostname}/repos/{repo_path}/hooks").as_str(), - StatusCode::OK, - json!({"id": webhook_id, "config":{"url": repo_listen_url.to_string()}}) - .to_string() - .as_str(), - ); + net.on() + .post(format!("https://api.{hostname}/repos/{repo_path}/hooks")) + .respond(StatusCode::OK) + .body( + json!({"id": webhook_id, "config":{"url": repo_listen_url.to_string()}}) + .to_string(), + ) + .expect("mock"); let forge = given::a_github_forge(&repo_details, net); @@ -375,26 +395,26 @@ mod github { let repo_listen_url = given::a_repo_listen_url(&repo_details); let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; - let mut net = given::a_network(); - let mut args = with::WebhookArgs { - net: &mut net, + let net = given::a_network(); + let args = with::WebhookArgs { + net: &net, hostname, repo_path, }; // there are no existing matching webhooks - with::get_webhooks_by_page(1, &[], &mut args); + with::get_webhooks_by_page(1, &[], &args); // register the webhook will return empty response - net.add_post_response( - format!("https://api.{hostname}/repos/{repo_path}/hooks").as_str(), - StatusCode::OK, - json!({}).to_string().as_str(), // empty response - ); + net.on() + .post(format!("https://api.{hostname}/repos/{repo_path}/hooks")) + .respond(StatusCode::OK) + .body(json!({}).to_string()) + .expect("mock"); let forge = given::a_github_forge(&repo_details, net); let_assert!(Err(err) = forge.register_webhook(&repo_listen_url).await); assert!( - matches!(err, git::forge::webhook::Error::FailedToRegister(_)), + matches!(err, git::forge::webhook::Error::NetworkResponseEmpty), "{err:?}" ); } @@ -409,19 +429,20 @@ mod github { let repo_listen_url = given::a_repo_listen_url(&repo_details); let hostname = repo_details.forge.hostname(); let repo_path = &repo_details.repo_path; - let mut net = given::a_network(); - let mut args = with::WebhookArgs { - net: &mut net, + let net = given::a_network(); + let args = with::WebhookArgs { + net: &net, hostname, repo_path, }; // there are no existing matching webhooks - with::get_webhooks_by_page(1, &[], &mut args); + with::get_webhooks_by_page(1, &[], &args); // register the webhook will return empty response - net.add_post_error( - format!("https://api.{hostname}/repos/{repo_path}/hooks").as_str(), - "error", - ); + net.on() + .post(format!("https://api.{hostname}/repos/{repo_path}/hooks")) + .respond(StatusCode::INTERNAL_SERVER_ERROR) + .body("error") + .expect("mock"); let forge = given::a_github_forge(&repo_details, net); @@ -438,32 +459,34 @@ mod github { use super::*; - pub fn get_webhooks_by_page( - page: u8, - response: &[ReturnedWebhook], - args: &mut WebhookArgs, - ) { + pub fn get_webhooks_by_page(page: u8, response: &[ReturnedWebhook], args: &WebhookArgs) { let hostname = args.hostname; let repo_path = args.repo_path; - args.net.add_get_response( - format!("https://api.{hostname}/repos/{repo_path}/hooks?page={page}").as_str(), - StatusCode::OK, - json!(response).to_string().as_str(), - ); + args.net + .on() + .get(format!( + "https://api.{hostname}/repos/{repo_path}/hooks?page={page}" + )) + .respond(StatusCode::OK) + .body(json!(response).to_string()) + .expect("mock"); } - pub fn unregister_webhook(hook1: &ReturnedWebhook, args: &mut WebhookArgs) { + pub fn unregister_webhook(hook1: &ReturnedWebhook, args: &WebhookArgs) { let webhook_id = hook1.id; let hostname = args.hostname; let repo_path = args.repo_path; - args.net.add_delete_response( - format!("https://api.{hostname}/repos/{repo_path}/hooks/{webhook_id}").as_str(), - StatusCode::OK, - "", - ); + args.net + .on() + .delete(format!( + "https://api.{hostname}/repos/{repo_path}/hooks/{webhook_id}" + )) + .respond(StatusCode::OK) + .body("") + .expect("mock"); } pub struct WebhookArgs<'a> { - pub net: &'a mut network::MockNetwork, + pub net: &'a kxio::net::MockNet, pub hostname: &'a Hostname, pub repo_path: &'a RepoPath, } @@ -497,21 +520,23 @@ mod github { pub fn commit_states( states: &[GithubState], - net: &mut MockNetwork, + net: &MockNet, repo_details: &git::RepoDetails, commit: &git::Commit, ) { - let response = json!(states - .iter() - .map(|state| GithubStatus { - state: state.to_owned() - }) - .collect::>()); - net.add_get_response( - a_commit_status_url(repo_details, commit).as_str(), - StatusCode::OK, - response.to_string().as_str(), - ); + net.on() + .get(a_commit_status_url(repo_details, commit)) + .respond(StatusCode::OK) + .body( + json!(states + .iter() + .map(|state| GithubStatus { + state: state.to_owned() + }) + .collect::>()) + .to_string(), + ) + .expect("mock"); } pub fn a_commit_status_url( @@ -578,10 +603,11 @@ mod github { pub fn a_github_forge( repo_details: &git::RepoDetails, - net: impl Into, + net: impl Into, ) -> Github { Github::new(repo_details.clone(), net.into()) } + pub fn repo_details() -> git::RepoDetails { git::RepoDetails::new( git::Generation::default(), @@ -614,8 +640,8 @@ mod github { pub fn a_repo_alias() -> RepoAlias { RepoAlias::new(a_name()) } - pub fn a_network() -> kxio::network::MockNetwork { - kxio::network::MockNetwork::new() + pub fn a_network() -> kxio::net::MockNet { + kxio::net::mock() } pub fn a_repo_listen_url(repo_details: &RepoDetails) -> RepoListenUrl { diff --git a/crates/forge-github/src/webhook/list.rs b/crates/forge-github/src/webhook/list.rs index 1aaf039..d9843e6 100644 --- a/crates/forge-github/src/webhook/list.rs +++ b/crates/forge-github/src/webhook/list.rs @@ -2,8 +2,6 @@ use crate as github; use git_next_core::{git, server::RepoListenUrl, WebhookId}; -use kxio::network; - // https://docs.github.com/en/rest/repos/webhooks?apiVersion=2022-11-28#list-repository-webhooks pub async fn list( github: &github::Github, @@ -15,40 +13,36 @@ pub async fn list( let net = &github.net; let mut page = 1; loop { - let request = network::NetRequest::new( - network::RequestMethod::Get, - network::NetUrl::new(format!( + let result = net + .get(format!( "https://api.{hostname}/repos/{}/hooks?page={page}", repo_details.repo_path, - )), - github::webhook::headers(repo_details.forge.token()), - network::RequestBody::None, - network::ResponseType::Json, - None, - network::NetRequestLogging::None, - ); - let result = net.get::>(request).await; + )) + .headers(github::webhook::headers(repo_details.forge.token())) + .send() + .await; match result { - Ok(response) => { - let Some(list) = response.response_body() else { - #[cfg(not(tarpaulin_include))] - // request response is Json so response_body never returns None + Ok(response) => match response.json::>().await { + Err(err) => { + tracing::warn!(?err, "failed"); return Err(git::forge::webhook::Error::NetworkResponseEmpty); - }; - if list.is_empty() { - return Ok(ids); } - for hook in list { - if hook - .url() - .as_ref() - .starts_with(&repo_listen_url.to_string()) - { - ids.push(hook.id()); + Ok(list) => { + if list.is_empty() { + return Ok(ids); } + for hook in list { + if hook + .url() + .as_ref() + .starts_with(&repo_listen_url.to_string()) + { + ids.push(hook.id()); + } + } + page += 1; } - page += 1; - } + }, Err(e) => { return Err(git::forge::webhook::Error::Network(e)); } diff --git a/crates/forge-github/src/webhook/mod.rs b/crates/forge-github/src/webhook/mod.rs index d9d5d0f..fd9ebfb 100644 --- a/crates/forge-github/src/webhook/mod.rs +++ b/crates/forge-github/src/webhook/mod.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + // use git_next_core::{git, webhook, ApiToken, BranchName}; @@ -16,19 +18,24 @@ pub use unregister::unregister; #[cfg(test)] pub use authorisation::sign_body; -pub fn headers(token: &ApiToken) -> kxio::network::NetRequestHeaders { +pub fn headers(token: &ApiToken) -> HashMap { use secrecy::ExposeSecret; - kxio::network::NetRequestHeaders::default() - .with("Accept", "application/vnd.github+json") - .with( - "User-Agent", - format!("git-next/server/{}", clap::crate_version!()).as_str(), - ) - .with( - "Authorization", - format!("Bearer {}", token.expose_secret()).as_str(), - ) - .with("X-GitHub-Api-Version", "2022-11-28") + + HashMap::from([ + ( + "Accept".to_string(), + "application/vnd.github+json".to_string(), + ), + ( + "User-Agent".to_string(), + format!("git-next/server/{}", clap::crate_version!()), + ), + ( + "Authorization".to_string(), + format!("Bearer {}", token.expose_secret()), + ), + ("X-GitHub-Api-Version".to_string(), "2022-11-28".to_string()), + ]) } #[derive(Debug, serde::Deserialize)] diff --git a/crates/forge-github/src/webhook/register.rs b/crates/forge-github/src/webhook/register.rs index 056a951..0fbba9a 100644 --- a/crates/forge-github/src/webhook/register.rs +++ b/crates/forge-github/src/webhook/register.rs @@ -1,8 +1,7 @@ // use crate::{self as github, webhook}; use git_next_core::{git, server::RepoListenUrl, RegisteredWebhook, WebhookAuth, WebhookId}; - -use kxio::network; +use serde_json::json; // https://docs.github.com/en/rest/repos/webhooks?apiVersion=2022-11-28#create-a-repository-webhook pub async fn register( @@ -23,45 +22,48 @@ pub async fn register( let net = &github.net; let hostname = repo_details.forge.hostname(); let authorisation = WebhookAuth::generate(); - let request = network::NetRequest::new( - network::RequestMethod::Post, - network::NetUrl::new(format!( + match net + .post(format!( "https://api.{hostname}/repos/{}/hooks", repo_details.repo_path - )), - github::webhook::headers(repo_details.forge.token()), - network::RequestBody::Json(network::json!({ - "name": "web", - "active": true, - "events": ["push"], - "config": { - "url": repo_listen_url.to_string(), - "content_type": "json", - "secret": authorisation.to_string(), - "insecure_ssl": "0", - } - })), - network::ResponseType::Json, - None, - network::NetRequestLogging::None, - ); - let result = net.post_json::(request).await; - match result { - Ok(response) => { - let Some(hook) = response.response_body() else { - #[cfg(not(tarpaulin_include))] - // request response is Json so response_body never returns None - return Err(git::forge::webhook::Error::NetworkResponseEmpty); - }; - tracing::info!(webhook_id = %hook.id, "Webhook registered"); - Ok(RegisteredWebhook::new( - WebhookId::new(format!("{}", hook.id)), - authorisation, - )) - } + )) + .headers(github::webhook::headers(repo_details.forge.token())) + .body( + json!({ + "name": "web", + "active": true, + "events": ["push"], + "config": { + "url": repo_listen_url.to_string(), + "content_type": "json", + "secret": authorisation.to_string(), + "insecure_ssl": "0", + } + }) + .to_string(), + ) + .send() + .await + { Err(e) => { tracing::warn!("Failed to register webhook"); Err(git::forge::webhook::Error::FailedToRegister(e.to_string())) } + Ok(response) => { + match response.json::().await { + Err(_) => { + #[cfg(not(tarpaulin_include))] + // request response is Json so response_body never returns None + return Err(git::forge::webhook::Error::NetworkResponseEmpty); + } + Ok(hook) => { + tracing::info!(webhook_id = %hook.id, "Webhook registered"); + Ok(RegisteredWebhook::new( + WebhookId::new(format!("{}", hook.id)), + authorisation, + )) + } + } + } } } diff --git a/crates/forge-github/src/webhook/unregister.rs b/crates/forge-github/src/webhook/unregister.rs index d1ec177..55f1861 100644 --- a/crates/forge-github/src/webhook/unregister.rs +++ b/crates/forge-github/src/webhook/unregister.rs @@ -2,8 +2,6 @@ use crate as github; use git_next_core::{git, WebhookId}; -use kxio::network; - // https://docs.github.com/en/rest/repos/webhooks?apiVersion=2022-11-28#delete-a-repository-webhook pub async fn unregister( github: &github::Github, @@ -12,20 +10,13 @@ pub async fn unregister( let net = &github.net; let repo_details = &github.repo_details; let hostname = repo_details.forge.hostname(); - let request = network::NetRequest::new( - network::RequestMethod::Delete, - network::NetUrl::new(format!( - "https://api.{hostname}/repos/{}/hooks/{}", - repo_details.repo_path, webhook_id - )), - github::webhook::headers(repo_details.forge.token()), - network::RequestBody::None, - network::ResponseType::None, - None, - network::NetRequestLogging::None, - ); - net.delete(request) - .await - .map_err(|e| git::forge::webhook::Error::FailedToRegister(e.to_string())) - .map(|_| ()) + net.delete(format!( + "https://api.{hostname}/repos/{}/hooks/{}", + repo_details.repo_path, webhook_id + )) + .headers(github::webhook::headers(repo_details.forge.token())) + .send() + .await + .map_err(|e| git::forge::webhook::Error::FailedToRegister(e.to_string())) + .map(|_| ()) }