diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 3a98579..14adfec 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -1,2 +1,3 @@ nonnominandus Maximilian Volk +Baptiste (@BapRx) diff --git a/Cargo.lock b/Cargo.lock index e7454eb..fe597e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,13 +4,62 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is-terminal", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" + +[[package]] +name = "anstyle-parse" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "anstyle-wincon" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" +dependencies = [ + "anstyle", + "windows-sys 0.48.0", +] + [[package]] name = "async-channel" version = "1.8.0" @@ -36,9 +85,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bytes" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" [[package]] name = "castaway" @@ -48,9 +97,9 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6" [[package]] name = "cc" -version = "1.0.77" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" dependencies = [ "jobserver", ] @@ -63,46 +112,58 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "4.0.29" +version = "4.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d" +checksum = "34d21f9bf1b425d2968943631ec91202fe5e837264063503708b83013f8fc938" dependencies = [ - "bitflags", + "clap_builder", "clap_derive", + "once_cell", +] + +[[package]] +name = "clap_builder" +version = "4.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914c8c79fb560f238ef6429439a30023c862f7a28e688c58f7203f12b29970bd" +dependencies = [ + "anstream", + "anstyle", + "bitflags", "clap_lex", - "is-terminal", "once_cell", "strsim", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.0.21" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" +checksum = "3f9644cd56d6b87dbe899ef8b053e331c0637664e9e21a33dfcdc36093f5c5c4" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "clap_lex" -version = "0.3.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" -dependencies = [ - "os_str_bytes", -] +checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "comfy-table" -version = "6.1.3" +version = "6.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e621e7e86c46fd8a14c32c6ae3cb95656621b4743a27d0cffedb831d46e7ad21" +checksum = "6e7b787b0dc42e8111badfdbe4c3059158ccb2db8780352fa1b01e8ccf45cc4d" dependencies = [ "crossterm", "strum", @@ -112,32 +173,31 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7bef69dc86e3c610e4e7aed41035e2a7ed12e72dd7530f61327a6579a4390b" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" dependencies = [ "crossbeam-utils", ] [[package]] name = "console" -version = "0.15.2" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c050367d967ced717c04b65d8c619d863ef9292ce0c5760028655a2fb298718c" +checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" dependencies = [ "encode_unicode", "lazy_static", "libc", - "terminal_size", "unicode-width", - "winapi", + "windows-sys 0.42.0", ] [[package]] name = "crossbeam-utils" -version = "0.8.14" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" +checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b" dependencies = [ "cfg-if", ] @@ -184,9 +244,9 @@ dependencies = [ [[package]] name = "curl-sys" -version = "0.4.59+curl-7.86.0" +version = "0.4.61+curl-8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cfce34829f448b08f55b7db6d0009e23e2e86a34e8c2b366269bf5799b4a407" +checksum = "14d05c10f541ae6f3bc5b3d923c20001f47db7d5f0b2bc6ad16490133842db79" dependencies = [ "cc", "libc", @@ -200,22 +260,23 @@ dependencies = [ [[package]] name = "dirs" -version = "4.0.0" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.3.7" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" dependencies = [ "libc", + "option-ext", "redox_users", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -226,22 +287,22 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.31" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ "cfg-if", ] [[package]] name = "errno" -version = "0.2.8" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -262,9 +323,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "fastrand" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" dependencies = [ "instant", ] @@ -292,21 +353,21 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] name = "futures-io" -version = "0.3.25" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" [[package]] name = "futures-lite" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ "fastrand", "futures-core", @@ -319,9 +380,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if", "libc", @@ -330,7 +391,7 @@ dependencies = [ [[package]] name = "git-repo-manager" -version = "0.7.12" +version = "0.7.13" dependencies = [ "clap", "comfy-table", @@ -350,9 +411,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.15.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2994bee4a3a6a51eb90c218523be382fd7ea09b16380b9312e9dbe955ff7c7d1" +checksum = "8b7905cdfe33d31a88bb2e8419ddd054451f5432d1da9eaf2ac7804ee1ea12d5" dependencies = [ "bitflags", "libc", @@ -371,24 +432,21 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.2.6" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] +checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "http" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ "bytes", "fnv", @@ -407,9 +465,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.2" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown", @@ -426,24 +484,25 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.3" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ + "hermit-abi", "libc", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] name = "is-terminal" -version = "0.4.1" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi", "io-lifetimes", "rustix", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] @@ -477,15 +536,15 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" +checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" [[package]] name = "jobserver" -version = "0.1.25" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "068b1ee6743e4d11fb9c6a1e6064b3693a1b600e7f5f5988047d98b3dc9fb90b" +checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2" dependencies = [ "libc", ] @@ -498,15 +557,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.138" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libgit2-sys" -version = "0.14.0+1.5.0" +version = "0.15.1+1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47a00859c70c8a4f7218e6d1cc32875c4b55f6799445b842b0d8ed5e4c3d959b" +checksum = "fb4577bde8cdfc7d6a2a4bcb7b049598597de33ffd337276e9c7db6cd4a2cee7" dependencies = [ "cc", "libc", @@ -528,9 +587,9 @@ dependencies = [ [[package]] name = "libssh2-sys" -version = "0.2.23" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca" +checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" dependencies = [ "cc", "libc", @@ -542,9 +601,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" dependencies = [ "cc", "libc", @@ -554,9 +613,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.3" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f" +checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" [[package]] name = "lock_api" @@ -585,27 +644,27 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mio" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" dependencies = [ "libc", "log", "wasi", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "openssl-probe" @@ -615,20 +674,19 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.24.0+1.1.1s" +version = "111.25.3+1.1.1t" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3498f259dab01178c6228c6b00dcef0ed2a2d5e20d648c017861227773ea4abd" +checksum = "924757a6a226bf60da5f7dd0311a34d2b52283dd82ddeb103208ddc66362f80c" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.79" +version = "0.9.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5454462c0eced1e97f2ec09036abc8da362e66802f66fd20f86854d9d8cbcbc4" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" dependencies = [ - "autocfg", "cc", "libc", "openssl-src", @@ -637,16 +695,16 @@ dependencies = [ ] [[package]] -name = "os_str_bytes" -version = "6.4.1" +name = "option-ext" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "parking" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" [[package]] name = "parking_lot" @@ -660,15 +718,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.5" +version = "0.9.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-sys 0.42.0", + "windows-sys 0.45.0", ] [[package]] @@ -705,7 +763,7 @@ checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] [[package]] @@ -716,62 +774,40 @@ checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] name = "pkg-config" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] name = "polling" -version = "2.5.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "166ca89eb77fd403230b9c156612965a81e094ec6ec3aa13663d4c8b113fa748" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ "autocfg", + "bitflags", "cfg-if", + "concurrent-queue", "libc", "log", - "wepoll-ffi", - "windows-sys 0.42.0", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", + "pin-project-lite", + "windows-sys 0.48.0", ] [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.21" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -835,9 +871,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", @@ -846,9 +882,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" [[package]] name = "remove_dir_all" @@ -861,38 +897,37 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.5" +version = "0.37.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" +checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" dependencies = [ "bitflags", "errno", "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.42.0", + "windows-sys 0.48.0", ] [[package]] name = "rustversion" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" [[package]] name = "ryu" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "schannel" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "windows-sys 0.36.1", + "windows-sys 0.42.0", ] [[package]] @@ -903,29 +938,29 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.150" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +checksum = "71b2f6e1ab5c2b98c05f0f35b236b22e8df7ead6ffbf51d7808da7f8817e7ab6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.150" +version = "1.0.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +checksum = "a2a0814352fd64b58489904a44ea8d90cb1a91dcb6b4f5ebabc32c8318e93cb6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] name = "serde_json" -version = "1.0.89" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -933,10 +968,19 @@ dependencies = [ ] [[package]] -name = "serde_yaml" -version = "0.9.14" +name = "serde_spanned" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d232d893b10de3eb7258ff01974d6ee20663d8e833263c99409d4b13a0209da" +checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9d684e3ec7de3bf5466b32bd75303ac16f0736426e5a4e0d6e489559ce1249c" dependencies = [ "indexmap", "itoa", @@ -947,18 +991,18 @@ dependencies = [ [[package]] name = "shellexpand" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd1c7ddea665294d484c39fd0c0d2b7e35bbfe10035c5fe1854741a57f6880e1" +checksum = "da03fa3b94cc19e3ebfc88c4229c49d8f08cdbd1228870a45f0ffdf84988e14b" dependencies = [ "dirs", ] [[package]] name = "signal-hook" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" dependencies = [ "libc", "signal-hook-registry", @@ -977,18 +1021,18 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ "libc", ] [[package]] name = "slab" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ "autocfg", ] @@ -1012,9 +1056,9 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", @@ -1042,14 +1086,25 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn", + "syn 1.0.109", ] [[package]] name = "syn" -version = "1.0.105" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", @@ -1066,43 +1121,24 @@ dependencies = [ "remove_dir_all", ] -[[package]] -name = "termcolor" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "terminal_size" -version = "0.1.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "thiserror" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -1116,17 +1152,42 @@ dependencies = [ [[package]] name = "tinyvec_macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "toml" -version = "0.5.9" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" dependencies = [ "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "239410c8609e8125456927e6707163a3b1fdb40561e4b803bc041f466ccfdc13" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] @@ -1144,13 +1205,13 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.15", ] [[package]] @@ -1174,15 +1235,15 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.8" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-normalization" @@ -1201,9 +1262,9 @@ checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" [[package]] name = "unsafe-libyaml" -version = "0.2.4" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1e5fa573d8ac5f1a856f8d7be41d390ee973daf97c806b2c1a465e4e1406e68" +checksum = "1865806a559042e51ab5414598446a5871b561d21b6764f2eabb0dd481d880a6" [[package]] name = "url" @@ -1225,18 +1286,18 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - [[package]] name = "waker-fn" version = "1.1.0" @@ -1249,15 +1310,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wepoll-ffi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" -dependencies = [ - "cc", -] - [[package]] name = "winapi" version = "0.3.9" @@ -1274,117 +1326,164 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.36.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" -dependencies = [ - "windows_aarch64_msvc 0.36.1", - "windows_i686_gnu 0.36.1", - "windows_i686_msvc 0.36.1", - "windows_x86_64_gnu 0.36.1", - "windows_x86_64_msvc 0.36.1", -] - [[package]] name = "windows-sys" version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.0", - "windows_i686_gnu 0.42.0", - "windows_i686_msvc 0.42.0", - "windows_x86_64_gnu 0.42.0", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.0", + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] name = "windows_aarch64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" [[package]] name = "windows_aarch64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] name = "windows_i686_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" [[package]] name = "windows_i686_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] name = "windows_i686_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" [[package]] name = "windows_i686_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] name = "windows_x86_64_gnu" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" [[package]] name = "windows_x86_64_gnu" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.0" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] name = "windows_x86_64_msvc" -version = "0.36.1" +version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" [[package]] name = "windows_x86_64_msvc" -version = "0.42.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +dependencies = [ + "memchr", +] diff --git a/Cargo.toml b/Cargo.toml index 0f38095..b23c190 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "git-repo-manager" -version = "0.7.12" +version = "0.7.13" edition = "2021" authors = [ @@ -41,36 +41,36 @@ path = "src/grm/main.rs" [dependencies] [dependencies.toml] -version = "=0.5.9" +version = "=0.7.3" [dependencies.serde] -version = "=1.0.150" +version = "=1.0.162" features = ["derive"] [dependencies.git2] -version = "=0.15.0" +version = "=0.17.1" [dependencies.shellexpand] -version = "=3.0.0" +version = "=3.1.0" [dependencies.clap] -version = "=4.0.29" +version = "=4.2.7" features = ["derive", "cargo"] [dependencies.console] -version = "=0.15.2" +version = "=0.15.5" [dependencies.regex] -version = "=1.7.0" +version = "=1.8.1" [dependencies.comfy-table] -version = "=6.1.3" +version = "=6.1.4" [dependencies.serde_yaml] -version = "=0.9.14" +version = "=0.9.21" [dependencies.serde_json] -version = "=1.0.89" +version = "=1.0.96" [dependencies.isahc] version = "=1.7.2" diff --git a/Justfile b/Justfile index 05140c0..4e906f4 100644 --- a/Justfile +++ b/Justfile @@ -4,35 +4,39 @@ set shell := ["/bin/bash", "-c"] static_target := "x86_64-unknown-linux-musl" +cargo := "cargo +nightly" + check: fmt-check lint test - cargo check + {{cargo}} check clean: - cargo clean + {{cargo}} clean git clean -f -d -X fmt: - cargo fmt + {{cargo}} fmt + git ls-files | grep '\.py$' | xargs isort git ls-files | grep '\.py$' | xargs black git ls-files | grep '\.sh$' | xargs -L 1 shfmt --indent 4 --write fmt-check: - cargo fmt --check + {{cargo}} fmt --check git ls-files | grep '\.py$' | xargs black --check git ls-files | grep '\.sh$' | xargs -L 1 shfmt --indent 4 --diff lint: - cargo clippy --no-deps -- -Dwarnings + {{cargo}} clippy --no-deps -- -Dwarnings + git ls-files | grep '\.py$' | xargs ruff --ignore E501 git ls-files | grep '\.sh$' | xargs -L 1 shellcheck --norc lint-fix: - cargo clippy --no-deps --fix + {{cargo}} clippy --no-deps --fix build-release: - cargo build --release + {{cargo}} build --release build-release-static: - cargo build --release --target {{static_target}} --features=static-build + {{cargo}} build --release --target {{static_target}} --features=static-build pushall: for r in $(git remote) ; do \ @@ -48,27 +52,27 @@ test-binary: env \ GITHUB_API_BASEURL=http://rest:5000/github \ GITLAB_API_BASEURL=http://rest:5000/gitlab \ - cargo build --profile e2e-tests --target {{static_target}} --features=static-build + {{cargo}} build --profile e2e-tests --target {{static_target}} --features=static-build install: - cargo install --path . + {{cargo}} install --path . install-static: - cargo install --target {{static_target}} --features=static-build --path . + {{cargo}} install --target {{static_target}} --features=static-build --path . build: - cargo build + {{cargo}} build build-static: - cargo build --target {{static_target}} --features=static-build + {{cargo}} build --target {{static_target}} --features=static-build test: test-unit test-integration test-e2e test-unit +tests="": - cargo test --lib --bins -- --show-output {{tests}} + {{cargo}} test --lib --bins -- --show-output {{tests}} test-integration: - cargo test --test "*" + {{cargo}} test --test "*" test-e2e +tests=".": test-binary cd ./e2e_tests \ diff --git a/depcheck/update-cargo-dependencies.py b/depcheck/update-cargo-dependencies.py index e69e74d..7b5145f 100755 --- a/depcheck/update-cargo-dependencies.py +++ b/depcheck/update-cargo-dependencies.py @@ -1,9 +1,8 @@ #!/usr/bin/env python3 -import subprocess -import os import json -import sys +import os +import subprocess import semver import tomlkit diff --git a/docs/src/developing.md b/docs/src/developing.md index 33eb147..df32a6f 100644 --- a/docs/src/developing.md +++ b/docs/src/developing.md @@ -34,8 +34,8 @@ You will need the following tools: [here](https://github.com/casey/just#installation) for installation instructions (it's most likely just a simple `cargo install just`). * Docker & docker-compose for the e2e tests -* `black` and `shfmt` for formatting. -* `shellcheck` for shell script linting +* `isort`, `black` and `shfmt` for formatting. +* `ruff` and `shellcheck` for linting. * `mdbook` for the documentation Here are the tools: diff --git a/docs/src/local_configuration.md b/docs/src/local_configuration.md index 6cbcea3..35042ad 100644 --- a/docs/src/local_configuration.md +++ b/docs/src/local_configuration.md @@ -11,7 +11,7 @@ Let's try it out: ## Get the example configuration ```bash -$ curl --proto '=https' --tlsv1.2 -sSfO https://raw.githubusercontent.com/hakoerber/git-repo-manager/master/example.config.toml +curl --proto '=https' --tlsv1.2 -sSfO https://raw.githubusercontent.com/hakoerber/git-repo-manager/master/example.config.toml ``` Then, you're ready to run the first sync. This will clone all configured @@ -30,7 +30,7 @@ $ grm repos sync config --config example.config.toml If you run it again, it will report no changes: -``` +```bash $ grm repos sync config -c example.config.toml [✔] git-repo-manager: OK [✔] dotfiles: OK @@ -43,11 +43,18 @@ write a configuration from scratch. Luckily, GRM has a way to generate a configuration from an existing file tree: ```bash -$ grm repos find local ~/your/project/root > config.toml +grm repos find local ~/your/project/root > config.toml ``` This will detect all repositories and remotes and write them to `config.toml`. +You can exclude repositories from the generated configuration by providing +a regex that will be test against the path of each discovered repository: + +```bash +grm repos find local ~/your/project/root --exclude "^.*/subdir/match-(foo|bar)/.*$" > config.toml +``` + ### Show the state of your projects ```bash @@ -65,7 +72,7 @@ $ grm repos status --config example.config.toml You can also use `status` without `--config` to check the repository you're currently in: -``` +```bash $ cd ~/example-projects/dotfiles $ grm repos status ╭──────────┬──────────┬────────┬──────────┬───────┬─────────╮ @@ -79,5 +86,5 @@ $ grm repos status By default, the repo configuration uses TOML. If you prefer YAML, just give it a YAML file instead (file ending does not matter, `grm` will figure out the -format). For generating a configuration, pass `--format yaml` to `grm repo +format). For generating a configuration, pass `--format yaml` to `grm repo find` which generates a YAML configuration instead of a TOML configuration. diff --git a/docs/src/testing.md b/docs/src/testing.md index c3c2c4c..4dcedad 100644 --- a/docs/src/testing.md +++ b/docs/src/testing.md @@ -49,7 +49,7 @@ Note: You will most likely not need to read this. Each test parameter will exponentially increase the number of tests that will be run. As a general rule, comprehensiveness is more important than test suite runtime (so if in doubt, better to add another parameter to catch every edge -case). But try to keep the total runtime sane. Currently, the whole `just e2e` +case). But try to keep the total runtime sane. Currently, the whole `just test-e2e` target runs ~8'000 tests and takes around 5 minutes on my machine, exlucding binary and docker build time. I'd say that keeping it under 10 minutes is a good idea. diff --git a/e2e_tests/conftest.py b/e2e_tests/conftest.py index 0c23ab6..ef201e1 100644 --- a/e2e_tests/conftest.py +++ b/e2e_tests/conftest.py @@ -1,7 +1,5 @@ import os -from helpers import * - def pytest_configure(config): os.environ["GIT_AUTHOR_NAME"] = "Example user" diff --git a/e2e_tests/docker-rest/flask/app.py b/e2e_tests/docker-rest/flask/app.py index e22c533..3d00e54 100644 --- a/e2e_tests/docker-rest/flask/app.py +++ b/e2e_tests/docker-rest/flask/app.py @@ -3,5 +3,5 @@ from flask import Flask app = Flask(__name__) app.url_map.strict_slashes = False -import github -import gitlab +import github # noqa: E402,F401 +import gitlab # noqa: E402,F401 diff --git a/e2e_tests/docker-rest/flask/github.py b/e2e_tests/docker-rest/flask/github.py index e51df42..6d1659d 100644 --- a/e2e_tests/docker-rest/flask/github.py +++ b/e2e_tests/docker-rest/flask/github.py @@ -1,10 +1,8 @@ import os.path -from app import app - -from flask import Flask, request, abort, jsonify, make_response - import jinja2 +from app import app +from flask import abort, jsonify, make_response, request def check_headers(): @@ -48,7 +46,7 @@ def add_pagination(response, page, last_page): def read_project_files(namespaces=[]): last_page = 4 - page = username = int(request.args.get("page", "1")) + page = int(request.args.get("page", "1")) response_file = f"./github_api_page_{page}.json.j2" if not os.path.exists(response_file): return jsonify([]) diff --git a/e2e_tests/docker-rest/flask/gitlab.py b/e2e_tests/docker-rest/flask/gitlab.py index bbfb26e..605a57d 100644 --- a/e2e_tests/docker-rest/flask/gitlab.py +++ b/e2e_tests/docker-rest/flask/gitlab.py @@ -1,10 +1,8 @@ import os.path -from app import app - -from flask import Flask, request, abort, jsonify, make_response - import jinja2 +from app import app +from flask import abort, jsonify, make_response, request def check_headers(): @@ -48,7 +46,7 @@ def add_pagination(response, page, last_page): def read_project_files(namespaces=[]): last_page = 4 - page = username = int(request.args.get("page", "1")) + page = int(request.args.get("page", "1")) response_file = f"./gitlab_api_page_{page}.json" if not os.path.exists(response_file): return jsonify([]) diff --git a/e2e_tests/helpers.py b/e2e_tests/helpers.py index b9567e6..e54a15f 100644 --- a/e2e_tests/helpers.py +++ b/e2e_tests/helpers.py @@ -1,12 +1,12 @@ #!/usr/bin/env python3 +import hashlib +import inspect import os import os.path +import shutil import subprocess import tempfile -import hashlib -import shutil -import inspect import git @@ -176,7 +176,6 @@ class TempGitRemote: newobj.remoteid = remoteid return newobj, remoteid else: - refresh = False if cachekey not in cls.obj: tmpdir = get_temporary_directory() shell( diff --git a/e2e_tests/test_basic.py b/e2e_tests/test_basic.py index 6ea5172..dcfd95e 100644 --- a/e2e_tests/test_basic.py +++ b/e2e_tests/test_basic.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -from helpers import * +from helpers import grm def test_invalid_command(): diff --git a/e2e_tests/test_repos_find.py b/e2e_tests/test_repos_find.py index 59b0078..588cb31 100644 --- a/e2e_tests/test_repos_find.py +++ b/e2e_tests/test_repos_find.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 +import os +import re import tempfile -import toml import pytest +import toml import yaml - -from helpers import * +from helpers import NonExistentPath, TempGitRepository, grm, shell def test_repos_find_nonexistent(): @@ -40,7 +41,7 @@ def test_repos_find_invalid_format(): ) assert cmd.returncode != 0 assert len(cmd.stdout) == 0 - assert "isn't a valid value" in cmd.stderr + assert "invalid value 'invalidformat'" in cmd.stderr def test_repos_find_non_git_repos(): @@ -63,9 +64,10 @@ def test_repos_find_non_git_repos(): assert len(cmd.stderr) != 0 -@pytest.mark.parametrize("default", [True, False]) +@pytest.mark.parametrize("default_format", [True, False]) @pytest.mark.parametrize("configtype", ["toml", "yaml"]) -def test_repos_find(configtype, default): +@pytest.mark.parametrize("exclude", [None, "^.*/repo2$", "^not_matching$"]) +def test_repos_find(configtype, exclude, default_format): with tempfile.TemporaryDirectory() as tmpdir: shell( f""" @@ -99,13 +101,19 @@ def test_repos_find(configtype, default): ) args = ["repos", "find", "local", tmpdir] - if not default: + if not default_format: args += ["--format", configtype] + if exclude: + args += ["--exclude", exclude] cmd = grm(args) assert cmd.returncode == 0 - assert len(cmd.stderr) == 0 + if exclude == "^.*/repo2$": + assert re.match(r"^.*\[skipped\] .*\/repo2$", cmd.stderr.lower()) + assert "repo2" in cmd.stderr.lower() + else: + assert len(cmd.stderr) == 0 - if default or configtype == "toml": + if default_format or configtype == "toml": output = toml.loads(cmd.stdout) elif configtype == "yaml": output = yaml.safe_load(cmd.stdout) @@ -120,7 +128,7 @@ def test_repos_find(configtype, default): assert set(tree.keys()) == {"root", "repos"} assert tree["root"] == tmpdir assert isinstance(tree["repos"], list) - assert len(tree["repos"]) == 2 + assert len(tree["repos"]) == (1 if exclude == "^.*/repo2$" else 2) repo1 = [r for r in tree["repos"] if r["name"] == "repo1"][0] assert repo1["worktree_setup"] is False @@ -137,30 +145,33 @@ def test_repos_find(configtype, default): assert someremote["type"] == "ssh" assert someremote["url"] == "ssh://example.com/repo2.git" - repo2 = [r for r in tree["repos"] if r["name"] == "repo2"][0] - assert repo2["worktree_setup"] is False - assert isinstance(repo1["remotes"], list) - assert len(repo2["remotes"]) == 1 + if exclude == "^.*/repo2$": + assert [r for r in tree["repos"] if r["name"] == "repo2"] == [] + else: + repo2 = [r for r in tree["repos"] if r["name"] == "repo2"][0] + assert repo2["worktree_setup"] is False + assert isinstance(repo1["remotes"], list) + assert len(repo2["remotes"]) == 1 - origin = [r for r in repo2["remotes"] if r["name"] == "origin"][0] - assert set(origin.keys()) == {"name", "type", "url"} - assert origin["type"] == "https" - assert origin["url"] == "https://example.com/repo2.git" + origin = [r for r in repo2["remotes"] if r["name"] == "origin"][0] + assert set(origin.keys()) == {"name", "type", "url"} + assert origin["type"] == "https" + assert origin["url"] == "https://example.com/repo2.git" -@pytest.mark.parametrize("default", [True, False]) +@pytest.mark.parametrize("default_format", [True, False]) @pytest.mark.parametrize("configtype", ["toml", "yaml"]) -def test_repos_find_in_root(configtype, default): +def test_repos_find_in_root(configtype, default_format): with TempGitRepository() as repo_dir: args = ["repos", "find", "local", repo_dir] - if not default: + if not default_format: args += ["--format", configtype] cmd = grm(args) assert cmd.returncode == 0 assert len(cmd.stderr) == 0 - if default or configtype == "toml": + if default_format or configtype == "toml": output = toml.loads(cmd.stdout) elif configtype == "yaml": output = yaml.safe_load(cmd.stdout) @@ -194,8 +205,8 @@ def test_repos_find_in_root(configtype, default): @pytest.mark.parametrize("configtype", ["toml", "yaml"]) -@pytest.mark.parametrize("default", [True, False]) -def test_repos_find_with_invalid_repo(configtype, default): +@pytest.mark.parametrize("default_format", [True, False]) +def test_repos_find_with_invalid_repo(configtype, default_format): with tempfile.TemporaryDirectory() as tmpdir: shell( f""" @@ -229,13 +240,13 @@ def test_repos_find_with_invalid_repo(configtype, default): ) args = ["repos", "find", "local", tmpdir] - if not default: + if not default_format: args += ["--format", configtype] cmd = grm(args) assert cmd.returncode == 0 assert "broken" in cmd.stderr - if default or configtype == "toml": + if default_format or configtype == "toml": output = toml.loads(cmd.stdout) elif configtype == "yaml": output = yaml.safe_load(cmd.stdout) diff --git a/e2e_tests/test_repos_find_remote.py b/e2e_tests/test_repos_find_remote.py index df395f8..19c9560 100644 --- a/e2e_tests/test_repos_find_remote.py +++ b/e2e_tests/test_repos_find_remote.py @@ -1,14 +1,13 @@ #!/usr/bin/env python3 -import re import os +import re +import tempfile -import toml import pytest +import toml import yaml - -from helpers import * - +from helpers import grm ALTERNATE_DOMAIN = os.environ["ALTERNATE_DOMAIN"] PROVIDERS = ["github", "gitlab"] @@ -44,7 +43,7 @@ def test_repos_find_remote_invalid_provider(use_config): assert cmd.returncode != 0 assert len(cmd.stdout) == 0 if not use_config: - assert re.match(".*isn't a valid value for.*provider", cmd.stderr) + assert re.match(".*invalid value 'thisproviderdoesnotexist' for.*provider", cmd.stderr) @pytest.mark.parametrize("provider", PROVIDERS) @@ -67,7 +66,7 @@ def test_repos_find_remote_invalid_format(provider): ) assert cmd.returncode != 0 assert len(cmd.stdout) == 0 - assert "isn't a valid value" in cmd.stderr + assert "invalid value 'invalidformat'" in cmd.stderr @pytest.mark.parametrize("provider", PROVIDERS) @@ -275,9 +274,9 @@ def test_repos_find_remote_user( if not worktree_default: cfg += f"worktree = {str(worktree).lower()}\n" if force_ssh: - cfg += f"force_ssh = true\n" + cfg += "force_ssh = true\n" if override_remote_name: - cfg += f'remote_name = "otherremote"\n' + cfg += 'remote_name = "otherremote"\n' if use_owner: cfg += """ [filters] @@ -475,7 +474,7 @@ def test_repos_find_remote_group( if not worktree_default: cfg += f"worktree = {str(worktree).lower()}\n" if force_ssh: - cfg += f"force_ssh = true\n" + cfg += "force_ssh = true\n" if use_alternate_endpoint: cfg += f'api_url = "http://{ALTERNATE_DOMAIN}:5000/{provider}"\n' cfg += """ @@ -591,7 +590,7 @@ def test_repos_find_remote_user_and_group( if not worktree_default: cfg += f"worktree = {str(worktree).lower()}\n" if force_ssh: - cfg += f"force_ssh = true\n" + cfg += "force_ssh = true\n" if use_alternate_endpoint: cfg += f'api_url = "http://{ALTERNATE_DOMAIN}:5000/{provider}"\n' cfg += """ @@ -742,7 +741,7 @@ def test_repos_find_remote_owner( if not worktree_default: cfg += f"worktree = {str(worktree).lower()}\n" if force_ssh: - cfg += f"force_ssh = true\n" + cfg += "force_ssh = true\n" if use_alternate_endpoint: cfg += f'api_url = "http://{ALTERNATE_DOMAIN}:5000/{provider}"\n' cfg += """ @@ -873,13 +872,11 @@ def test_repos_find_remote_owner( assert repo["remotes"][0]["name"] == "origin" if force_ssh: assert ( - repo["remotes"][0]["url"] == f"ssh://git@example.com/myuser2/myproject3.git" + repo["remotes"][0]["url"] == "ssh://git@example.com/myuser2/myproject3.git" ) assert repo["remotes"][0]["type"] == "ssh" else: - assert ( - repo["remotes"][0]["url"] == f"https://example.com/myuser2/myproject3.git" - ) + assert repo["remotes"][0]["url"] == "https://example.com/myuser2/myproject3.git" assert repo["remotes"][0]["type"] == "https" group_namespace_1 = [t for t in output["trees"] if t["root"] == "/myroot/mygroup1"][ @@ -923,13 +920,13 @@ def test_repos_find_remote_owner( if force_ssh: assert ( repo["remotes"][0]["url"] - == f"ssh://git@example.com/mygroup1/myproject4.git" + == "ssh://git@example.com/mygroup1/myproject4.git" ) assert repo["remotes"][0]["type"] == "ssh" else: assert ( repo["remotes"][0]["url"] - == f"https://example.com/mygroup1/myproject4.git" + == "https://example.com/mygroup1/myproject4.git" ) assert repo["remotes"][0]["type"] == "https" @@ -948,12 +945,11 @@ def test_repos_find_remote_owner( assert repo["remotes"][0]["name"] == "origin" if force_ssh: assert ( - repo["remotes"][0]["url"] - == f"ssh://git@example.com/mygroup2/myproject5.git" + repo["remotes"][0]["url"] == "ssh://git@example.com/mygroup2/myproject5.git" ) assert repo["remotes"][0]["type"] == "ssh" else: assert ( - repo["remotes"][0]["url"] == f"https://example.com/mygroup2/myproject5.git" + repo["remotes"][0]["url"] == "https://example.com/mygroup2/myproject5.git" ) assert repo["remotes"][0]["type"] == "https" diff --git a/e2e_tests/test_repos_status.py b/e2e_tests/test_repos_status.py index 8787dea..e9a7511 100644 --- a/e2e_tests/test_repos_status.py +++ b/e2e_tests/test_repos_status.py @@ -1,8 +1,6 @@ #!/usr/bin/env python3 -import tempfile - -from helpers import * +from helpers import RepoTree, grm def test_repos_sync_worktree_clone(): diff --git a/e2e_tests/test_repos_sync.py b/e2e_tests/test_repos_sync.py index bba5b7c..8833aee 100644 --- a/e2e_tests/test_repos_sync.py +++ b/e2e_tests/test_repos_sync.py @@ -1,14 +1,21 @@ #!/usr/bin/env python3 -import tempfile +import os import re +import subprocess +import tempfile import textwrap -import pytest -import toml import git - -from helpers import * +import pytest +from helpers import ( + NonExistentPath, + TempGitFileRemote, + TempGitRepository, + checksum_directory, + grm, + shell, +) templates = { "repo_simple": { @@ -291,7 +298,9 @@ def test_repos_sync_unmanaged_repos(configtype): # this removes the prefix (root) from the path (unmanaged_repo) unmanaged_repo_name = os.path.relpath(unmanaged_repo, root) regex = f".*unmanaged.*{unmanaged_repo_name}" - assert any([re.match(regex, l) for l in cmd.stderr.lower().split("\n")]) + assert any( + [re.match(regex, line) for line in cmd.stderr.lower().split("\n")] + ) @pytest.mark.parametrize("configtype", ["toml", "yaml"]) @@ -374,7 +383,7 @@ def test_repos_sync_repo_in_subdirectory(configtype): assert urls[0] == f"file://{remote}" cmd = grm(["repos", "sync", "config", "--config", config.name]) - assert not "found unmanaged repository" in cmd.stderr.lower() + assert "found unmanaged repository" not in cmd.stderr.lower() @pytest.mark.parametrize("configtype", ["toml", "yaml"]) @@ -419,7 +428,7 @@ def test_repos_sync_nested_clone(configtype): cmd = grm(["repos", "sync", "config", "--config", config.name]) print(cmd.stdout) print(cmd.stderr) - assert not "found unmanaged repository" in cmd.stderr.lower() + assert "found unmanaged repository" not in cmd.stderr.lower() @pytest.mark.parametrize("configtype", ["toml", "yaml"]) @@ -720,14 +729,14 @@ def test_repos_sync_invalid_syntax(configtype): with open(config.name, "w") as f: if configtype == "toml": f.write( - f""" + """ [[trees]] root = invalid as there are no quotes ;) """ ) elif configtype == "yaml": f.write( - f""" + """ trees: wrong: indentation: @@ -779,8 +788,6 @@ def test_repos_sync_normal_change_to_worktree(configtype): cmd = grm(["repos", "sync", "config", "--config", config.name]) assert cmd.returncode == 0 - git_dir = os.path.join(target, "test") - with open(config.name, "w") as f: f.write( templates["worktree_repo_with_remote"][configtype].format( @@ -810,8 +817,6 @@ def test_repos_sync_worktree_change_to_normal(configtype): cmd = grm(["repos", "sync", "config", "--config", config.name]) assert cmd.returncode == 0 - git_dir = os.path.join(target, "test") - with open(config.name, "w") as f: f.write( templates["repo_with_remote"][configtype].format( diff --git a/e2e_tests/test_worktree_clean.py b/e2e_tests/test_worktree_clean.py index b64172a..cc1958a 100644 --- a/e2e_tests/test_worktree_clean.py +++ b/e2e_tests/test_worktree_clean.py @@ -1,8 +1,17 @@ #!/usr/bin/env python3 -import pytest +import os -from helpers import * +import pytest +from helpers import ( + NonGitDir, + TempGitRepository, + TempGitRepositoryWorktree, + checksum_directory, + funcname, + grm, + shell, +) def test_worktree_clean(): @@ -153,13 +162,13 @@ def test_worktree_clean_configured_default_branch( with open(os.path.join(base_dir, "grm.toml"), "w") as f: if branch_list_empty: f.write( - f""" + """ persistent_branches = [] """ ) else: f.write( - f""" + """ persistent_branches = [ "mybranch" ] diff --git a/e2e_tests/test_worktree_config_presistent_branch.py b/e2e_tests/test_worktree_config_presistent_branch.py index e7d2923..cae4c57 100644 --- a/e2e_tests/test_worktree_config_presistent_branch.py +++ b/e2e_tests/test_worktree_config_presistent_branch.py @@ -2,7 +2,8 @@ import os.path -from helpers import * +import git +from helpers import TempGitRepositoryWorktree, checksum_directory, funcname, grm, shell def test_worktree_never_clean_persistent_branches(): diff --git a/e2e_tests/test_worktree_conversion.py b/e2e_tests/test_worktree_conversion.py index 7f1448d..b06b32a 100644 --- a/e2e_tests/test_worktree_conversion.py +++ b/e2e_tests/test_worktree_conversion.py @@ -1,8 +1,16 @@ #!/usr/bin/env python3 -import tempfile +import os -from helpers import * +from helpers import ( + EmptyDir, + NonGitDir, + TempGitRepository, + TempGitRepositoryWorktree, + checksum_directory, + funcname, + grm, +) def test_convert(): diff --git a/e2e_tests/test_worktree_fetch.py b/e2e_tests/test_worktree_fetch.py index a30ef7d..232948b 100644 --- a/e2e_tests/test_worktree_fetch.py +++ b/e2e_tests/test_worktree_fetch.py @@ -1,11 +1,17 @@ #!/usr/bin/env python3 -from helpers import * - import re -import pytest import git +import pytest +from helpers import ( + EmptyDir, + TempGitFileRemote, + TempGitRepositoryWorktree, + funcname, + grm, + shell, +) def test_worktree_fetch(): diff --git a/e2e_tests/test_worktree_rebase.py b/e2e_tests/test_worktree_rebase.py index 0c73c79..6f18fe3 100644 --- a/e2e_tests/test_worktree_rebase.py +++ b/e2e_tests/test_worktree_rebase.py @@ -1,11 +1,11 @@ #!/usr/bin/env python3 -from helpers import * - +import os import re -import pytest import git +import pytest +from helpers import TempGitRepositoryWorktree, funcname, grm, shell @pytest.mark.parametrize("pull", [True, False]) diff --git a/e2e_tests/test_worktree_status.py b/e2e_tests/test_worktree_status.py index d54788f..39eccc6 100644 --- a/e2e_tests/test_worktree_status.py +++ b/e2e_tests/test_worktree_status.py @@ -1,10 +1,17 @@ #!/usr/bin/env python3 +import os import re -from helpers import * - import pytest +from helpers import ( + NonGitDir, + TempGitRepository, + TempGitRepositoryWorktree, + funcname, + grm, + shell, +) @pytest.mark.parametrize("has_config", [True, False]) diff --git a/e2e_tests/test_worktrees.py b/e2e_tests/test_worktrees.py index e5b9b48..8f90580 100644 --- a/e2e_tests/test_worktrees.py +++ b/e2e_tests/test_worktrees.py @@ -1,12 +1,18 @@ #!/usr/bin/env python3 -from helpers import * +import datetime +import os.path import git import pytest -import datetime - -import os.path +from helpers import ( + TempGitRepositoryWorktree, + checksum_directory, + funcname, + grm, + shell, + tempfile, +) @pytest.mark.parametrize( @@ -151,18 +157,20 @@ def test_worktree_add( ] ) - cachefn = lambda nr: "_".join( - [ - str(nr), - str(default_remote), - str(local_branch_exists), - str(remote_branch_already_exists), - str(remote_branch_with_prefix_already_exists), - str(remote_count), - str(remotes_differ), - str(worktree_name), - ] - ) + def cachefn(nr): + return "_".join( + [ + str(nr), + str(default_remote), + str(local_branch_exists), + str(remote_branch_already_exists), + str(remote_branch_with_prefix_already_exists), + str(remote_count), + str(remotes_differ), + str(worktree_name), + ] + ) + remote1_cache_key = cachefn(1) remote2_cache_key = cachefn(2) @@ -281,7 +289,7 @@ def test_worktree_add( and remotes_differ ): assert ( - f"branch exists on multiple remotes, but they deviate" + "branch exists on multiple remotes, but they deviate" in cmd.stderr.lower() ) assert len(cmd.stderr.strip().split("\n")) == base + 1 diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..124501d --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "nightly" +targets = ["x86_64-unknown-linux-musl"] diff --git a/src/grm/cmd.rs b/src/grm/cmd.rs index 4b0fd1e..d269610 100644 --- a/src/grm/cmd.rs +++ b/src/grm/cmd.rs @@ -63,6 +63,14 @@ pub struct FindLocalArgs { #[clap(help = "The path to search through")] pub path: String, + #[clap( + short, + long, + help = "Exclude repositories that match the given regex", + name = "REGEX" + )] + pub exclude: Option, + #[clap( value_enum, short, diff --git a/src/grm/main.rs b/src/grm/main.rs index aa522b4..3d02872 100644 --- a/src/grm/main.rs +++ b/src/grm/main.rs @@ -199,7 +199,8 @@ fn main() { } }; - let (found_repos, warnings) = match find_in_tree(&path) { + let (found_repos, warnings) = match find_in_tree(&path, args.exclude.as_deref()) + { Ok((repos, warnings)) => (repos, warnings), Err(error) => { print_error(&error); diff --git a/src/lib.rs b/src/lib.rs index cdfc596..14e4346 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,4 @@ #![feature(io_error_more)] -#![feature(const_option_ext)] #![forbid(unsafe_code)] use std::path::Path; @@ -19,12 +18,22 @@ pub mod worktree; /// The bool in the return value specifies whether there is a repository /// in root itself. #[allow(clippy::type_complexity)] -fn find_repos(root: &Path) -> Result, Vec, bool)>, String> { +fn find_repos( + root: &Path, + exclusion_pattern: Option<&str>, +) -> Result, Vec, bool)>, String> { let mut repos: Vec = Vec::new(); let mut repo_in_root = false; let mut warnings = Vec::new(); + let exlusion_regex: regex::Regex = regex::Regex::new(exclusion_pattern.unwrap_or(r"^$")) + .map_err(|e| format!("invalid regex: {e}"))?; for path in tree::find_repo_paths(root)? { + if exclusion_pattern.is_some() && exlusion_regex.is_match(&path::path_as_string(&path)) { + warnings.push(format!("[skipped] {}", &path::path_as_string(&path))); + continue; + } + let is_worktree = repo::RepoHandle::detect_worktree(&path); if path == root { repo_in_root = true; @@ -63,12 +72,13 @@ fn find_repos(root: &Path) -> Result, Vec, bool) let name = remote.name(); let url = remote.url(); let remote_type = match repo::detect_remote_type(&url) { - Some(t) => t, - None => { + Ok(t) => t, + Err(e) => { warnings.push(format!( - "{}: Could not detect remote type of \"{}\"", + "{}: Could not handle URL {}. Reason: {}", &path::path_as_string(&path), - &url + &url, + e )); continue; } @@ -130,10 +140,14 @@ fn find_repos(root: &Path) -> Result, Vec, bool) Ok(Some((repos, warnings, repo_in_root))) } -pub fn find_in_tree(path: &Path) -> Result<(tree::Tree, Vec), String> { +pub fn find_in_tree( + path: &Path, + exclusion_pattern: Option<&str>, +) -> Result<(tree::Tree, Vec), String> { let mut warnings = Vec::new(); - let (repos, repo_in_root): (Vec, bool) = match find_repos(path)? { + let (repos, repo_in_root): (Vec, bool) = match find_repos(path, exclusion_pattern)? + { Some((vec, mut repo_warnings, repo_in_root)) => { warnings.append(&mut repo_warnings); (vec, repo_in_root) diff --git a/src/provider/github.rs b/src/provider/github.rs index e495237..6b7ec21 100644 --- a/src/provider/github.rs +++ b/src/provider/github.rs @@ -9,8 +9,10 @@ use super::Project; use super::Provider; const ACCEPT_HEADER_JSON: &str = "application/vnd.github.v3+json"; -const GITHUB_API_BASEURL: &str = - option_env!("GITHUB_API_BASEURL").unwrap_or("https://api.github.com"); +const GITHUB_API_BASEURL: &str = match option_env!("GITHUB_API_BASEURL") { + Some(url) => url, + None => "https://api.github.com", +}; #[derive(Deserialize)] pub struct GithubProject { diff --git a/src/provider/gitlab.rs b/src/provider/gitlab.rs index b1a08b8..b149c26 100644 --- a/src/provider/gitlab.rs +++ b/src/provider/gitlab.rs @@ -9,7 +9,10 @@ use super::Project; use super::Provider; const ACCEPT_HEADER_JSON: &str = "application/json"; -const GITLAB_API_BASEURL: &str = option_env!("GITLAB_API_BASEURL").unwrap_or("https://gitlab.com"); +const GITLAB_API_BASEURL: &str = match option_env!("GITLAB_API_BASEURL") { + Some(url) => url, + None => "https://gitlab.com", +}; #[derive(Deserialize)] #[serde(rename_all = "lowercase")] diff --git a/src/repo.rs b/src/repo.rs index 2b3549d..bf22c47 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -406,50 +406,78 @@ mod tests { fn check_ssh_remote() { assert_eq!( detect_remote_type("ssh://git@example.com"), - Some(RemoteType::Ssh) + Ok(RemoteType::Ssh) ); - assert_eq!(detect_remote_type("git@example.git"), Some(RemoteType::Ssh)); + assert_eq!(detect_remote_type("git@example.git"), Ok(RemoteType::Ssh)); } #[test] fn check_https_remote() { assert_eq!( detect_remote_type("https://example.com"), - Some(RemoteType::Https) + Ok(RemoteType::Https) ); assert_eq!( detect_remote_type("https://example.com/test.git"), - Some(RemoteType::Https) + Ok(RemoteType::Https) ); } #[test] fn check_file_remote() { - assert_eq!( - detect_remote_type("file:///somedir"), - Some(RemoteType::File) - ); + assert_eq!(detect_remote_type("file:///somedir"), Ok(RemoteType::File)); } #[test] fn check_invalid_remotes() { - assert_eq!(detect_remote_type("https//example.com"), None); - assert_eq!(detect_remote_type("https:example.com"), None); - assert_eq!(detect_remote_type("ssh//example.com"), None); - assert_eq!(detect_remote_type("ssh:example.com"), None); - assert_eq!(detect_remote_type("git@example.com"), None); + assert_eq!( + detect_remote_type("https//example.com"), + Err(String::from( + "The remote URL starts with an unimplemented protocol" + )) + ); + assert_eq!( + detect_remote_type("https:example.com"), + Err(String::from( + "The remote URL starts with an unimplemented protocol", + )) + ); + assert_eq!( + detect_remote_type("ssh//example.com"), + Err(String::from( + "The remote URL starts with an unimplemented protocol", + )) + ); + assert_eq!( + detect_remote_type("ssh:example.com"), + Err(String::from( + "The remote URL starts with an unimplemented protocol", + )) + ); + assert_eq!( + detect_remote_type("git@example.com"), + Err(String::from( + "The remote URL starts with an unimplemented protocol", + )) + ); } #[test] - #[should_panic] fn check_unsupported_protocol_http() { - detect_remote_type("http://example.com"); + assert_eq!( + detect_remote_type("http://example.com"), + Err(String::from( + "Remotes using HTTP protocol are not supported", + )) + ); } #[test] - #[should_panic] fn check_unsupported_protocol_git() { - detect_remote_type("git://example.com"); + assert_eq!( + detect_remote_type("git://example.com"), + Err(String::from("Remotes using git protocol are not supported")) + ); } #[test] @@ -473,27 +501,31 @@ mod tests { } } -pub fn detect_remote_type(remote_url: &str) -> Option { +pub fn detect_remote_type(remote_url: &str) -> Result { let git_regex = regex::Regex::new(r"^[a-zA-Z]+@.*$").unwrap(); if remote_url.starts_with("ssh://") { - return Some(RemoteType::Ssh); + return Ok(RemoteType::Ssh); } if git_regex.is_match(remote_url) && remote_url.ends_with(".git") { - return Some(RemoteType::Ssh); + return Ok(RemoteType::Ssh); } if remote_url.starts_with("https://") { - return Some(RemoteType::Https); + return Ok(RemoteType::Https); } if remote_url.starts_with("file://") { - return Some(RemoteType::File); + return Ok(RemoteType::File); } if remote_url.starts_with("http://") { - unimplemented!("Remotes using HTTP protocol are not supported"); + return Err(String::from( + "Remotes using HTTP protocol are not supported", + )); } if remote_url.starts_with("git://") { - unimplemented!("Remotes using git protocol are not supported"); + return Err(String::from("Remotes using git protocol are not supported")); } - None + Err(String::from( + "The remote URL starts with an unimplemented protocol", + )) } pub struct RepoHandle(git2::Repository); @@ -1588,7 +1620,7 @@ impl RemoteHandle<'_> { pub fn is_pushable(&self) -> Result { let remote_type = detect_remote_type(self.0.url().expect("Remote name is not valid utf-8")) - .ok_or_else(|| String::from("Could not detect remote type"))?; + .expect("Could not detect remote type"); Ok(matches!(remote_type, RemoteType::Ssh | RemoteType::File)) }