diff --git a/Cargo.lock b/Cargo.lock index 10270731..5ba95624 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -156,9 +156,9 @@ checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" [[package]] name = "byteorder" @@ -168,9 +168,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "bzip2" @@ -195,9 +195,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.37" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "jobserver", "libc", @@ -283,9 +283,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -351,9 +351,9 @@ dependencies = [ [[package]] name = "csv" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" dependencies = [ "csv-core", "itoa", @@ -393,7 +393,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -436,7 +436,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -468,12 +468,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -510,9 +510,9 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.34" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -542,6 +542,7 @@ dependencies = [ "chrono-english", "csv", "directories", + "git2", "human-time", "humansize", "imagesize", @@ -647,6 +648,21 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "git2" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b903b73e45dc0c6c596f2d37eccece7c1c8bb6e4407b001096387c63d0d93724" +dependencies = [ + "bitflags 2.6.0", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + [[package]] name = "h2" version = "0.3.26" @@ -677,15 +693,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" - -[[package]] -name = "hermit-abi" -version = "0.3.9" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "hmac" @@ -943,7 +953,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -975,12 +985,12 @@ checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" [[package]] name = "indexmap" -version = "2.6.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", ] [[package]] @@ -1009,9 +1019,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jobserver" @@ -1024,10 +1034,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -1057,9 +1068,23 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.162" +version = "0.2.167" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" + +[[package]] +name = "libgit2-sys" +version = "0.17.0+1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10472326a8a6477c3c20a64547b0059e4b0d086869eee31e6d7da728a8eb7224" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] [[package]] name = "libm" @@ -1087,6 +1112,32 @@ dependencies = [ "libc", ] +[[package]] +name = "libssh2-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -1095,9 +1146,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lockfree-object-pool" @@ -1179,11 +1230,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi", "libc", "wasi", "windows-sys 0.52.0", @@ -1285,6 +1335,24 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -1353,7 +1421,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1400,9 +1468,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -1494,7 +1562,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1511,9 +1579,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1590,9 +1658,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.39" +version = "0.38.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" +checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" dependencies = [ "bitflags 2.6.0", "errno", @@ -1615,9 +1683,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.16" +version = "0.23.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee87ff5d9b36712a58574e12e9f0ea80f915a5b0ac518d322b24a465617925e" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" dependencies = [ "log", "once_cell", @@ -1716,29 +1784,29 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -1845,9 +1913,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1896,9 +1964,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -1919,7 +1987,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1945,29 +2013,49 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f49a1853cf82743e3b7950f77e0f4d622ca36cf4317cba00c767838bac8d490" +dependencies = [ + "thiserror-impl 2.0.4", ] [[package]] name = "thiserror-impl" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8381894bb3efe0c4acac3ded651301ceee58a15d47c2e34885ed1908ad667061" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", ] [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "num-conv", @@ -1994,9 +2082,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.41.1" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -2019,9 +2107,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -2072,9 +2160,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-core", @@ -2082,9 +2170,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", ] @@ -2123,9 +2211,9 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[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-segmentation" @@ -2161,27 +2249,27 @@ dependencies = [ [[package]] name = "ureq" -version = "2.10.1" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" dependencies = [ "base64 0.22.1", "flate2", "log", "once_cell", - "rustls 0.23.16", + "rustls 0.23.19", "rustls-pki-types", "serde", "serde_json", "url", - "webpki-roots 0.26.6", + "webpki-roots 0.26.7", ] [[package]] name = "url" -version = "2.5.3" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -2216,6 +2304,12 @@ dependencies = [ "log", ] +[[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.5" @@ -2250,9 +2344,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -2261,36 +2355,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2298,22 +2392,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wavers" @@ -2324,14 +2418,14 @@ dependencies = [ "bytemuck", "num-traits", "paste", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -2345,9 +2439,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.6" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -2553,9 +2647,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -2565,13 +2659,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "synstructure", ] @@ -2593,27 +2687,27 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "synstructure", ] @@ -2634,7 +2728,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -2656,14 +2750,14 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "zip" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494" +checksum = "99d52293fc86ea7cf13971b3bb81eb21683636e7ae24c729cdaf1b7c4157a352" dependencies = [ "aes", "arbitrary", @@ -2681,7 +2775,7 @@ dependencies = [ "pbkdf2", "rand", "sha1", - "thiserror", + "thiserror 2.0.4", "time", "zeroize", "zopfli", diff --git a/Cargo.toml b/Cargo.toml index ee3b877e..ecce201a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ chrono = "0.4" chrono-english = "0.1" csv = "1.0" directories = "5.0" +git2 = "0.19.0" human-time = "0.1.6" humansize = "2.0" imagesize = "0.13" diff --git a/src/ignore/git.rs b/src/ignore/git.rs deleted file mode 100644 index 56522876..00000000 --- a/src/ignore/git.rs +++ /dev/null @@ -1,455 +0,0 @@ -//! Handles .gitignore parsing - -use std::collections::HashMap; -use std::ffi::OsStr; -use std::fs::File; -use std::ops::Add; -use std::ops::Index; -use std::path::{Path, PathBuf}; -use std::sync::LazyLock; -use regex::Captures; -use regex::Error; -use regex::Regex; - -use crate::util::error_exit; - -#[derive(Clone, Debug)] -pub struct GitignoreFilter { - pub regex: Regex, - pub only_dir: bool, - pub negate: bool, -} - -impl GitignoreFilter { - fn new(regex: Regex, only_dir: bool, negate: bool) -> GitignoreFilter { - GitignoreFilter { - regex, - only_dir, - negate, - } - } -} - -pub fn search_upstream_gitignore( - gitignore_map: &mut HashMap>, - dir: &Path, -) { - if let Ok(canonical_path) = crate::util::canonical_path(&dir.to_path_buf()) { - let mut path = PathBuf::from(canonical_path); - - if let Some(root_dir) = path.iter().next() { - parse_global_ignore(gitignore_map, root_dir); - } - - loop { - let parent_found = path.pop(); - - if !parent_found { - return; - } - - update_gitignore_map(gitignore_map, &mut path); - } - } -} - -pub fn update_gitignore_map( - gitignore_map: &mut HashMap>, - path: &Path, -) { - let gitignore_file = path.join(".gitignore"); - if gitignore_file.is_file() { - let regexes = parse_gitignore(&gitignore_file, path); - gitignore_map.insert(path.to_path_buf(), regexes); - } -} - -pub fn get_gitignore_filters( - gitignore_map: &mut HashMap>, - dir: &Path, -) -> Vec { - if let Some(regexes) = gitignore_map.get(&dir.to_path_buf()) { - return regexes.to_vec(); - } - - let mut result = vec![]; - - let mut path = dir.to_path_buf(); - - loop { - let parent_found = path.pop(); - - if !parent_found { - return result; - } - - if let Some(regexes) = gitignore_map.get(&path) { - result = vec![regexes.to_vec(), result].concat(); - } - } -} - -pub fn matches_gitignore_filter( - gitignore_filters: &Option>, - file_name: &str, - is_dir: bool, -) -> bool { - match gitignore_filters { - Some(gitignore_filters) => { - let mut matched = false; - - for gitignore_filter in gitignore_filters { - if gitignore_filter.only_dir && !is_dir { - continue; - } - - let file_name_prepared = convert_file_name_for_matcher(file_name); - let is_match = gitignore_filter.regex.is_match(&file_name_prepared); - - if is_match && gitignore_filter.negate { - return false; - } - - if is_match { - matched = true; - } - } - - matched - } - _ => false, - } -} - -fn convert_file_name_for_matcher(file_name: &str) -> String { - #[cfg(windows)] - { - return String::from(file_name).replace("\\", "/"); - } - - #[cfg(not(windows))] - { - return String::from(file_name); - } -} - -fn parse_gitignore(file_path: &Path, dir_path: &Path) -> Vec { - let mut result = vec![]; - - let git_dir = dir_path.join(".git"); - if git_dir.is_dir() { - let info_dir = git_dir.join("info"); - if info_dir.is_dir() { - let exclude_file = info_dir.join("exclude"); - if exclude_file.exists() { - result.append(&mut parse_file(&exclude_file, dir_path)); - } - } - } - - result.append(&mut convert_gitignore_pattern(".git/", dir_path)); - - result.append(&mut parse_file(file_path, dir_path)); - - result -} - -fn parse_global_ignore( - gitignore_map: &mut HashMap>, - root_dir: &OsStr -) { - let mut regexes: Vec = Vec::new(); - - let home_env_var; - #[cfg(windows)] - { - home_env_var = "USERPROFILE"; - } - #[cfg(not(windows))] - { - home_env_var = "HOME"; - } - - if let Ok(user_profile) = std::env::var(home_env_var) { - let mut global_config_found = false; - if !user_profile.is_empty() { - let user_profile_gitconfig = user_profile + "/.gitconfig"; - if let Ok(file) = File::open(user_profile_gitconfig) { - use std::io::BufRead; - use std::io::BufReader; - let reader = BufReader::new(file); - let excludes_file = reader - .lines() - .filter(|line| match line { - Ok(line) => !line.starts_with(";") && !line.starts_with("#") && line.contains("excludesFile"), - _ => false, - }) - .next(); - if let Some(Ok(excludes_file)) = excludes_file { - let excludes_file: Vec<&str> = excludes_file.split("=").collect(); - if excludes_file.len() == 2 { - let excludes_file = excludes_file[1].trim(); - regexes.append(&mut parse_file(Path::new(excludes_file), Path::new("/"))); - global_config_found = true; - } - } - } - } - - if !global_config_found { - if let Ok(xdg_home) = std::env::var("XDG_CONFIG_HOME") { - if !xdg_home.is_empty() { - let xdg_home_ignore = xdg_home + "/git/ignore"; - regexes.append(&mut parse_file(Path::new(&xdg_home_ignore), Path::new("/"))); - global_config_found = true; - } - } - - if !global_config_found { - if let Ok(home) = std::env::var("HOME") { - if !home.is_empty() { - let home_ignore = home + "/.config/git/ignore"; - regexes.append(&mut parse_file(Path::new(&home_ignore), Path::new("/"))); - } - } - } - } - } - - #[cfg(windows)] - { - gitignore_map.insert(Path::new((root_dir.to_string_lossy() + "\\").as_ref()).to_path_buf(), regexes); - } - - #[cfg(not(windows))] - { - gitignore_map.insert(Path::new(root_dir).to_path_buf(), regexes); - } -} - -fn parse_file(file_path: &Path, dir_path: &Path) -> Vec { - let mut result = vec![]; - - if let Ok(file) = File::open(file_path) { - use std::io::BufRead; - use std::io::BufReader; - let reader = BufReader::new(file); - reader - .lines() - .filter(|line| match line { - Ok(line) => !line.trim().is_empty() && !line.starts_with("#"), - _ => false, - }) - .for_each(|line| { - if let Ok(line) = line { - result.append(&mut convert_gitignore_pattern(&line, dir_path)) - } - }); - } - - result -} - -fn convert_gitignore_pattern(pattern: &str, file_path: &Path) -> Vec { - let mut result = vec![]; - - let mut pattern = String::from(pattern); - - let mut negate = false; - if pattern.starts_with("!") { - pattern = pattern.replace("!", ""); - negate = true; - } - - if pattern.ends_with("/") { - pattern.pop(); - - let regex = convert_gitignore_glob(&pattern, file_path); - if let Ok(regex) = regex { - result.push(GitignoreFilter::new(regex, true, negate)); - } - - pattern = pattern.add("/**"); - } - - let regex = convert_gitignore_glob(&pattern, file_path); - if let Ok(regex) = regex { - result.push(GitignoreFilter::new(regex, false, negate)) - } - - result -} - -static GIT_CONVERT_REPLACE_REGEX: LazyLock = LazyLock::new(|| { - Regex::new("(\\*\\*|\\?|\\.|\\*)").unwrap() -}); - -fn convert_gitignore_glob(glob: &str, file_path: &Path) -> Result { - let mut pattern = GIT_CONVERT_REPLACE_REGEX - .replace_all(&glob, |c: &Captures| { - match c.index(0) { - "**" => ".*", - "." => "\\.", - "*" => "[^/]*", - "?" => "[^/]+", - _ => error_exit(".gitignore", "Error parsing pattern"), - } - .to_string() - }) - .to_string(); - - while pattern.starts_with("/") || pattern.starts_with("\\") { - pattern.remove(0); - } - - #[allow(unused_mut)] - let mut file_path_pattern = file_path - .to_string_lossy() - .to_string() - .replace("\\", "\\\\") - .add("/([^/]+/)*"); - - #[cfg(windows)] - { - file_path_pattern = file_path_pattern.replace("\\", "/").replace("//", "/"); - } - - pattern = file_path_pattern.add(&pattern); - - Regex::new(&pattern) -} - -#[cfg(test)] -mod tests { - use super::*; - - // *nix - - #[test] - #[cfg(not(windows))] - fn test_simple_pattern() { - let file_path = Path::new("/home/user/projects/testprj"); - let glob = "foo"; - - let result = convert_gitignore_pattern(glob, file_path); - - assert_eq!(result.len(), 1); - - let filter = &result[0]; - - assert_eq!( - filter.regex.as_str(), - "/home/user/projects/testprj/([^/]+/)*foo" - ); - assert!(!filter.only_dir); - assert!(!filter.negate); - } - - #[test] - #[cfg(not(windows))] - fn test_dir_pattern() { - let file_path = Path::new("/home/user/projects/testprj"); - let glob = "foo/"; - - let result = convert_gitignore_pattern(glob, file_path); - - assert_eq!(result.len(), 2); - - let filter = &result[0]; - - assert_eq!( - filter.regex.as_str(), - "/home/user/projects/testprj/([^/]+/)*foo" - ); - assert!(filter.only_dir); - assert!(!filter.negate); - - let filter = &result[1]; - - assert_eq!( - filter.regex.as_str(), - "/home/user/projects/testprj/([^/]+/)*foo/.*" - ); - assert!(!filter.only_dir); - assert!(!filter.negate); - } - - #[test] - #[cfg(not(windows))] - fn test_negate_pattern() { - let file_path = Path::new("/home/user/projects/testprj"); - let glob = "!foo"; - - let result = convert_gitignore_pattern(glob, file_path); - - assert_eq!(result.len(), 1); - - let filter = &result[0]; - - assert_eq!( - filter.regex.as_str(), - "/home/user/projects/testprj/([^/]+/)*foo" - ); - assert!(!filter.only_dir); - assert!(filter.negate); - } - - // Windows - - #[test] - #[cfg(windows)] - fn test_simple_pattern() { - let file_path = Path::new("C:\\Projects\\testprj"); - let glob = "foo"; - - let result = convert_gitignore_pattern(glob, file_path); - - assert_eq!(result.len(), 1); - - let filter = &result[0]; - - assert_eq!(filter.regex.as_str(), "C:/Projects/testprj/([^/]+/)*foo"); - assert!(!filter.only_dir); - assert!(!filter.negate); - } - - #[test] - #[cfg(windows)] - fn test_dir_pattern() { - let file_path = Path::new("C:\\Projects\\testprj"); - let glob = "foo/"; - - let result = convert_gitignore_pattern(glob, file_path); - - assert_eq!(result.len(), 2); - - let filter = &result[0]; - - assert_eq!(filter.regex.as_str(), "C:/Projects/testprj/([^/]+/)*foo"); - assert!(filter.only_dir); - assert!(!filter.negate); - - let filter = &result[1]; - - assert_eq!(filter.regex.as_str(), "C:/Projects/testprj/([^/]+/)*foo/.*"); - assert!(!filter.only_dir); - assert!(!filter.negate); - } - - #[test] - #[cfg(windows)] - fn test_negate_pattern() { - let file_path = Path::new("C:\\Projects\\testprj"); - let glob = "!foo"; - - let result = convert_gitignore_pattern(glob, file_path); - - assert_eq!(result.len(), 1); - - let filter = &result[0]; - - assert_eq!(filter.regex.as_str(), "C:/Projects/testprj/([^/]+/)*foo"); - assert!(!filter.only_dir); - assert!(filter.negate); - } -} diff --git a/src/ignore/mod.rs b/src/ignore/mod.rs index e625e2f4..dfc1bc4f 100644 --- a/src/ignore/mod.rs +++ b/src/ignore/mod.rs @@ -1,3 +1,2 @@ pub(crate) mod docker; -pub(crate) mod git; pub(crate) mod hg; diff --git a/src/searcher.rs b/src/searcher.rs index a87f4d46..d20fcbee 100644 --- a/src/searcher.rs +++ b/src/searcher.rs @@ -14,6 +14,7 @@ use std::path::{Path, PathBuf}; use std::rc::Rc; use chrono::{DateTime, Local}; +use git2::Repository; use lscolors::{LsColors, Style}; use mp3_metadata::MP3Metadata; use regex::Regex; @@ -31,10 +32,6 @@ use crate::function::{Variant, VariantType}; use crate::ignore::docker::{ matches_dockerignore_filter, search_upstream_dockerignore, DockerignoreFilter, }; -use crate::ignore::git::{ - get_gitignore_filters, matches_gitignore_filter, search_upstream_gitignore, - update_gitignore_map, GitignoreFilter, -}; use crate::ignore::hg::{matches_hgignore_filter, search_upstream_hgignore, HgignoreFilter}; use crate::mode; use crate::operators::{LogicalOp, Op}; @@ -166,7 +163,6 @@ pub struct Searcher<'a> { raw_output_buffer: Vec>, partitioned_output_buffer: Rc, Vec>>>, output_buffer: TopN, String>, - gitignore_map: HashMap>, hgignore_filters: Vec, dockerignore_filters: Vec, visited_dirs: HashSet, @@ -208,7 +204,6 @@ impl<'a> Searcher<'a> { } else { TopN::new(limit) }, - gitignore_map: HashMap::new(), hgignore_filters: vec![], dockerignore_filters: vec![], visited_dirs: HashSet::new(), @@ -360,10 +355,6 @@ impl<'a> Searcher<'a> { let traversal_mode = root.options.traversal; // Apply filters - if apply_gitignore { - search_upstream_gitignore(&mut self.gitignore_map, root_dir); - } - if apply_hgignore { search_upstream_hgignore(&mut self.hgignore_filters, root_dir); } @@ -392,6 +383,7 @@ impl<'a> Searcher<'a> { 0, search_archives, apply_gitignore, + Repository::discover(&root_dir).ok().as_ref(), apply_hgignore, apply_dockerignore, traversal_mode, @@ -505,6 +497,7 @@ impl<'a> Searcher<'a> { root_depth: u32, search_archives: bool, apply_gitignore: bool, + git_repository: Option<&Repository>, apply_hgignore: bool, apply_dockerignore: bool, traversal_mode: TraversalMode, @@ -542,17 +535,6 @@ impl<'a> Searcher<'a> { let depth = canonical_depth - base_depth + 1; - let mut gitignore_filters = None; - - if apply_gitignore { - let canonical_path = PathBuf::from(canonical_path); - update_gitignore_map(&mut self.gitignore_map, &canonical_path); - gitignore_filters = Some(get_gitignore_filters( - &mut self.gitignore_map, - &canonical_path, - )); - } - // Read the directory and process each entry match fs::read_dir(dir) { Ok(entry_list) => { @@ -575,11 +557,9 @@ impl<'a> Searcher<'a> { // Check the path against the filters let pass_gitignore = !apply_gitignore - || !matches_gitignore_filter( - &gitignore_filters, - canonical_path.to_string_lossy().as_ref(), - path.is_dir(), - ); + || (git_repository.is_some() && + git_repository.unwrap().is_path_ignored(&path) + .unwrap_or(false)); let pass_hgignore = !apply_hgignore || !matches_hgignore_filter( &self.hgignore_filters, @@ -649,6 +629,7 @@ impl<'a> Searcher<'a> { base_depth, search_archives, apply_gitignore, + git_repository, apply_hgignore, apply_dockerignore, traversal_mode, @@ -696,6 +677,7 @@ impl<'a> Searcher<'a> { base_depth, search_archives, apply_gitignore, + git_repository, apply_hgignore, apply_dockerignore, traversal_mode,