From e30ba5179d94caa9839ee34045e874ff565ac9ab Mon Sep 17 00:00:00 2001 From: Kyle Lacy Date: Mon, 23 Sep 2024 00:11:22 -0700 Subject: [PATCH] Implement `Brioche.gitRef()` for locked git refs (#126) --- Cargo.lock | 1292 ++++++++++++++++++-- crates/brioche-core/Cargo.toml | 1 + crates/brioche-core/src/download.rs | 123 ++ crates/brioche-core/src/project.rs | 95 +- crates/brioche-core/src/project/analyze.rs | 62 +- crates/brioche-core/src/references.rs | 4 +- crates/brioche-core/src/script.rs | 2 +- crates/brioche-core/src/script/bridge.rs | 67 +- crates/brioche-core/tests/script_eval.rs | 101 ++ 9 files changed, 1596 insertions(+), 151 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 855fd58..14e6634 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,6 +127,12 @@ dependencies = [ "backtrace", ] +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + [[package]] name = "arrayref" version = "0.3.7" @@ -846,6 +852,7 @@ dependencies = [ "directories", "divan", "futures", + "gix", "globset", "hex", "human-repr", @@ -968,6 +975,12 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +[[package]] +name = "bytesize" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" + [[package]] name = "bzip2" version = "0.4.4" @@ -1097,6 +1110,12 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" +[[package]] +name = "clru" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd0f76e066e64fdc5631e3bb46381254deab9ef1158292f27c8c57e3bf3fe59" + [[package]] name = "colorchoice" version = "1.0.0" @@ -1394,6 +1413,20 @@ dependencies = [ "parking_lot_core 0.9.9", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.9", +] + [[package]] name = "data-encoding" version = "2.5.0" @@ -1724,6 +1757,15 @@ dependencies = [ "serde", ] +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if 1.0.0", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -1776,11 +1818,17 @@ dependencies = [ "regex", ] +[[package]] +name = "faster-hex" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" + [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "filedescriptor" @@ -1887,133 +1935,989 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] -name = "futures" -version = "0.3.29" +name = "futures" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" + +[[package]] +name = "futures-executor" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.12.3", +] + +[[package]] +name = "futures-io" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" + +[[package]] +name = "futures-macro" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "futures-sink" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" + +[[package]] +name = "futures-task" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" + +[[package]] +name = "futures-util" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "gix" +version = "0.66.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9048b8d1ae2104f045cb37e5c450fc49d5d8af22609386bfc739c11ba88995eb" +dependencies = [ + "gix-actor", + "gix-archive", + "gix-attributes", + "gix-command", + "gix-commitgraph", + "gix-config", + "gix-credentials", + "gix-date", + "gix-diff", + "gix-dir", + "gix-discover", + "gix-features", + "gix-filter", + "gix-fs", + "gix-glob", + "gix-hash", + "gix-hashtable", + "gix-ignore", + "gix-index", + "gix-lock", + "gix-mailmap", + "gix-negotiate", + "gix-object", + "gix-odb", + "gix-pack", + "gix-path", + "gix-pathspec", + "gix-prompt", + "gix-protocol", + "gix-ref", + "gix-refspec", + "gix-revision", + "gix-revwalk", + "gix-sec", + "gix-status", + "gix-submodule", + "gix-tempfile", + "gix-trace", + "gix-transport", + "gix-traverse", + "gix-url", + "gix-utils", + "gix-validate", + "gix-worktree", + "gix-worktree-state", + "gix-worktree-stream", + "once_cell", + "parking_lot 0.12.3", + "regex", + "signal-hook 0.3.17", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-actor" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc19e312cd45c4a66cd003f909163dc2f8e1623e30a0c0c6df3776e89b308665" +dependencies = [ + "bstr 1.8.0", + "gix-date", + "gix-utils", + "itoa", + "thiserror", + "winnow 0.6.18", +] + +[[package]] +name = "gix-archive" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9147c08a55c1398b755539e2cdd63ff690ffe4a2e5e5e0780ee6ef2b49b0a60a" +dependencies = [ + "bstr 1.8.0", + "gix-date", + "gix-object", + "gix-worktree-stream", + "jiff", + "thiserror", +] + +[[package]] +name = "gix-attributes" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebccbf25aa4a973dd352564a9000af69edca90623e8a16dad9cbc03713131311" +dependencies = [ + "bstr 1.8.0", + "gix-glob", + "gix-path", + "gix-quote", + "gix-trace", + "kstring", + "smallvec", + "thiserror", + "unicode-bom", +] + +[[package]] +name = "gix-bitmap" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a371db66cbd4e13f0ed9dc4c0fea712d7276805fccc877f77e96374d317e87ae" +dependencies = [ + "thiserror", +] + +[[package]] +name = "gix-chunk" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45c8751169961ba7640b513c3b24af61aa962c967aaf04116734975cd5af0c52" +dependencies = [ + "thiserror", +] + +[[package]] +name = "gix-command" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff2e692b36bbcf09286c70803006ca3fd56551a311de450be317a0ab8ea92e7" +dependencies = [ + "bstr 1.8.0", + "gix-path", + "gix-trace", + "shell-words", +] + +[[package]] +name = "gix-commitgraph" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "133b06f67f565836ec0c473e2116a60fb74f80b6435e21d88013ac0e3c60fc78" +dependencies = [ + "bstr 1.8.0", + "gix-chunk", + "gix-features", + "gix-hash", + "memmap2", + "thiserror", +] + +[[package]] +name = "gix-config" +version = "0.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78e797487e6ca3552491de1131b4f72202f282fb33f198b1c34406d765b42bb0" +dependencies = [ + "bstr 1.8.0", + "gix-config-value", + "gix-features", + "gix-glob", + "gix-path", + "gix-ref", + "gix-sec", + "memchr", + "once_cell", + "smallvec", + "thiserror", + "unicode-bom", + "winnow 0.6.18", +] + +[[package]] +name = "gix-config-value" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03f76169faa0dec598eac60f83d7fcdd739ec16596eca8fb144c88973dbe6f8c" +dependencies = [ + "bitflags 2.6.0", + "bstr 1.8.0", + "gix-path", + "libc", + "thiserror", +] + +[[package]] +name = "gix-credentials" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ce391d305968782f1ae301c4a3d42c5701df7ff1d8bc03740300f6fd12bce78" +dependencies = [ + "bstr 1.8.0", + "gix-command", + "gix-config-value", + "gix-path", + "gix-prompt", + "gix-sec", + "gix-trace", + "gix-url", + "thiserror", +] + +[[package]] +name = "gix-date" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c84b7af01e68daf7a6bb8bb909c1ff5edb3ce4326f1f43063a5a96d3c3c8a5" +dependencies = [ + "bstr 1.8.0", + "itoa", + "jiff", + "thiserror", +] + +[[package]] +name = "gix-diff" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92c9afd80fff00f8b38b1c1928442feb4cd6d2232a6ed806b6b193151a3d336c" +dependencies = [ + "bstr 1.8.0", + "gix-command", + "gix-filter", + "gix-fs", + "gix-hash", + "gix-object", + "gix-path", + "gix-tempfile", + "gix-trace", + "gix-worktree", + "imara-diff", + "thiserror", +] + +[[package]] +name = "gix-dir" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed3a9076661359a1c5a27c12ad6c3ebe2dd96b8b3c0af6488ab7c128b7bdd98" +dependencies = [ + "bstr 1.8.0", + "gix-discover", + "gix-fs", + "gix-ignore", + "gix-index", + "gix-object", + "gix-path", + "gix-pathspec", + "gix-trace", + "gix-utils", + "gix-worktree", + "thiserror", +] + +[[package]] +name = "gix-discover" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0577366b9567376bc26e815fd74451ebd0e6218814e242f8e5b7072c58d956d2" +dependencies = [ + "bstr 1.8.0", + "dunce", + "gix-fs", + "gix-hash", + "gix-path", + "gix-ref", + "gix-sec", + "thiserror", +] + +[[package]] +name = "gix-features" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac7045ac9fe5f9c727f38799d002a7ed3583cd777e3322a7c4b43e3cf437dc69" +dependencies = [ + "bytes", + "bytesize", + "crc32fast", + "crossbeam-channel", + "flate2", + "gix-hash", + "gix-trace", + "gix-utils", + "libc", + "once_cell", + "parking_lot 0.12.3", + "prodash", + "sha1_smol", + "thiserror", + "walkdir", +] + +[[package]] +name = "gix-filter" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4121790ae140066e5b953becc72e7496278138d19239be2e63b5067b0843119e" +dependencies = [ + "bstr 1.8.0", + "encoding_rs", + "gix-attributes", + "gix-command", + "gix-hash", + "gix-object", + "gix-packetline-blocking", + "gix-path", + "gix-quote", + "gix-trace", + "gix-utils", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-fs" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2bfe6249cfea6d0c0e0990d5226a4cb36f030444ba9e35e0639275db8f98575" +dependencies = [ + "fastrand", + "gix-features", + "gix-utils", +] + +[[package]] +name = "gix-glob" +version = "0.16.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74908b4bbc0a0a40852737e5d7889f676f081e340d5451a16e5b4c50d592f111" +dependencies = [ + "bitflags 2.6.0", + "bstr 1.8.0", + "gix-features", + "gix-path", +] + +[[package]] +name = "gix-hash" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93d7df7366121b5018f947a04d37f034717e113dcf9ccd85c34b58e57a74d5e" +dependencies = [ + "faster-hex", + "thiserror", +] + +[[package]] +name = "gix-hashtable" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ddf80e16f3c19ac06ce415a38b8591993d3f73aede049cb561becb5b3a8e242" +dependencies = [ + "gix-hash", + "hashbrown 0.14.5", + "parking_lot 0.12.3", +] + +[[package]] +name = "gix-ignore" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e447cd96598460f5906a0f6c75e950a39f98c2705fc755ad2f2020c9e937fab7" +dependencies = [ + "bstr 1.8.0", + "gix-glob", + "gix-path", + "gix-trace", + "unicode-bom", +] + +[[package]] +name = "gix-index" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cd4203244444017682176e65fd0180be9298e58ed90bd4a8489a357795ed22d" +dependencies = [ + "bitflags 2.6.0", + "bstr 1.8.0", + "filetime", + "fnv", + "gix-bitmap", + "gix-features", + "gix-fs", + "gix-hash", + "gix-lock", + "gix-object", + "gix-traverse", + "gix-utils", + "gix-validate", + "hashbrown 0.14.5", + "itoa", + "libc", + "memmap2", + "rustix", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-lock" +version = "14.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bc7fe297f1f4614774989c00ec8b1add59571dc9b024b4c00acb7dedd4e19d" +dependencies = [ + "gix-tempfile", + "gix-utils", + "thiserror", +] + +[[package]] +name = "gix-mailmap" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d522c8ec2501e1a5b2b4cb54e83cb5d9a52471c9d23b3a1e8dadaf063752f7" +dependencies = [ + "bstr 1.8.0", + "gix-actor", + "gix-date", + "thiserror", +] + +[[package]] +name = "gix-negotiate" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4063bf329a191a9e24b6f948a17ccf6698c0380297f5e169cee4f1d2ab9475b" +dependencies = [ + "bitflags 2.6.0", + "gix-commitgraph", + "gix-date", + "gix-hash", + "gix-object", + "gix-revwalk", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-object" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f5b801834f1de7640731820c2df6ba88d95480dc4ab166a5882f8ff12b88efa" +dependencies = [ + "bstr 1.8.0", + "gix-actor", + "gix-date", + "gix-features", + "gix-hash", + "gix-utils", + "gix-validate", + "itoa", + "smallvec", + "thiserror", + "winnow 0.6.18", +] + +[[package]] +name = "gix-odb" +version = "0.63.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3158068701c17df54f0ab2adda527f5a6aca38fd5fd80ceb7e3c0a2717ec747" +dependencies = [ + "arc-swap", + "gix-date", + "gix-features", + "gix-fs", + "gix-hash", + "gix-object", + "gix-pack", + "gix-path", + "gix-quote", + "parking_lot 0.12.3", + "tempfile", + "thiserror", +] + +[[package]] +name = "gix-pack" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3223aa342eee21e1e0e403cad8ae9caf9edca55ef84c347738d10681676fd954" +dependencies = [ + "clru", + "gix-chunk", + "gix-features", + "gix-hash", + "gix-hashtable", + "gix-object", + "gix-path", + "gix-tempfile", + "memmap2", + "parking_lot 0.12.3", + "smallvec", + "thiserror", + "uluru", +] + +[[package]] +name = "gix-packetline" +version = "0.17.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c43ef4d5fe2fa222c606731c8bdbf4481413ee4ef46d61340ec39e4df4c5e49" +dependencies = [ + "bstr 1.8.0", + "faster-hex", + "gix-trace", + "thiserror", +] + +[[package]] +name = "gix-packetline-blocking" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9802304baa798dd6f5ff8008a2b6516d54b74a69ca2d3a2b9e2d6c3b5556b40" +dependencies = [ + "bstr 1.8.0", + "faster-hex", + "gix-trace", + "thiserror", +] + +[[package]] +name = "gix-path" +version = "0.10.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebfc4febd088abdcbc9f1246896e57e37b7a34f6909840045a1767c6dafac7af" +dependencies = [ + "bstr 1.8.0", + "gix-trace", + "home", + "once_cell", + "thiserror", +] + +[[package]] +name = "gix-pathspec" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d23bf239532b4414d0e63b8ab3a65481881f7237ed9647bb10c1e3cc54c5ceb" +dependencies = [ + "bitflags 2.6.0", + "bstr 1.8.0", + "gix-attributes", + "gix-config-value", + "gix-glob", + "gix-path", + "thiserror", +] + +[[package]] +name = "gix-prompt" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fde865cdb46b30d8dad1293385d9bcf998d3a39cbf41bee67d0dab026fe6b1" +dependencies = [ + "gix-command", + "gix-config-value", + "parking_lot 0.12.3", + "rustix", + "thiserror", +] + +[[package]] +name = "gix-protocol" +version = "0.45.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc43a1006f01b5efee22a003928c9eb83dde2f52779ded9d4c0732ad93164e3e" +dependencies = [ + "bstr 1.8.0", + "gix-credentials", + "gix-date", + "gix-features", + "gix-hash", + "gix-transport", + "gix-utils", + "maybe-async", + "thiserror", + "winnow 0.6.18", +] + +[[package]] +name = "gix-quote" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbff4f9b9ea3fa7a25a70ee62f545143abef624ac6aa5884344e70c8b0a1d9ff" +dependencies = [ + "bstr 1.8.0", + "gix-utils", + "thiserror", +] + +[[package]] +name = "gix-ref" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae0d8406ebf9aaa91f55a57f053c5a1ad1a39f60fdf0303142b7be7ea44311e5" +dependencies = [ + "gix-actor", + "gix-features", + "gix-fs", + "gix-hash", + "gix-lock", + "gix-object", + "gix-path", + "gix-tempfile", + "gix-utils", + "gix-validate", + "memmap2", + "thiserror", + "winnow 0.6.18", +] + +[[package]] +name = "gix-refspec" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebb005f82341ba67615ffdd9f7742c87787544441c88090878393d0682869ca6" +dependencies = [ + "bstr 1.8.0", + "gix-hash", + "gix-revision", + "gix-validate", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-revision" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4621b219ac0cdb9256883030c3d56a6c64a6deaa829a92da73b9a576825e1e" +dependencies = [ + "bstr 1.8.0", + "gix-date", + "gix-hash", + "gix-hashtable", + "gix-object", + "gix-revwalk", + "gix-trace", + "thiserror", +] + +[[package]] +name = "gix-revwalk" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "b41e72544b93084ee682ef3d5b31b1ba4d8fa27a017482900e5e044d5b1b3984" dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", + "gix-commitgraph", + "gix-date", + "gix-hash", + "gix-hashtable", + "gix-object", + "smallvec", + "thiserror", ] [[package]] -name = "futures-channel" -version = "0.3.29" +name = "gix-sec" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "0fe4d52f30a737bbece5276fab5d3a8b276dc2650df963e293d0673be34e7a5f" dependencies = [ - "futures-core", - "futures-sink", + "bitflags 2.6.0", + "gix-path", + "libc", + "windows-sys 0.52.0", ] [[package]] -name = "futures-core" -version = "0.3.29" +name = "gix-status" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "f70d35ba639f0c16a6e4cca81aa374a05f07b23fa36ee8beb72c100d98b4ffea" +dependencies = [ + "bstr 1.8.0", + "filetime", + "gix-diff", + "gix-dir", + "gix-features", + "gix-filter", + "gix-fs", + "gix-hash", + "gix-index", + "gix-object", + "gix-path", + "gix-pathspec", + "gix-worktree", + "portable-atomic", + "thiserror", +] [[package]] -name = "futures-executor" -version = "0.3.29" +name = "gix-submodule" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "529d0af78cc2f372b3218f15eb1e3d1635a21c8937c12e2dd0b6fc80c2ca874b" dependencies = [ - "futures-core", - "futures-task", - "futures-util", + "bstr 1.8.0", + "gix-config", + "gix-path", + "gix-pathspec", + "gix-refspec", + "gix-url", + "thiserror", ] [[package]] -name = "futures-intrusive" -version = "0.5.0" +name = "gix-tempfile" +version = "14.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +checksum = "046b4927969fa816a150a0cda2e62c80016fe11fb3c3184e4dddf4e542f108aa" dependencies = [ - "futures-core", - "lock_api", + "dashmap 6.1.0", + "gix-fs", + "libc", + "once_cell", "parking_lot 0.12.3", + "signal-hook 0.3.17", + "signal-hook-registry", + "tempfile", ] [[package]] -name = "futures-io" -version = "0.3.29" +name = "gix-trace" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "6cae0e8661c3ff92688ce1c8b8058b3efb312aba9492bbe93661a21705ab431b" [[package]] -name = "futures-macro" -version = "0.3.29" +name = "gix-transport" +version = "0.42.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "421dcccab01b41a15d97b226ad97a8f9262295044e34fbd37b10e493b0a6481f" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", + "base64 0.22.1", + "bstr 1.8.0", + "gix-command", + "gix-credentials", + "gix-features", + "gix-packetline", + "gix-quote", + "gix-sec", + "gix-url", + "reqwest", + "thiserror", ] [[package]] -name = "futures-sink" -version = "0.3.29" +name = "gix-traverse" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "030da39af94e4df35472e9318228f36530989327906f38e27807df305fccb780" +dependencies = [ + "bitflags 2.6.0", + "gix-commitgraph", + "gix-date", + "gix-hash", + "gix-hashtable", + "gix-object", + "gix-revwalk", + "smallvec", + "thiserror", +] [[package]] -name = "futures-task" -version = "0.3.29" +name = "gix-url" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "fd280c5e84fb22e128ed2a053a0daeacb6379469be6a85e3d518a0636e160c89" +dependencies = [ + "bstr 1.8.0", + "gix-features", + "gix-path", + "home", + "thiserror", + "url", +] [[package]] -name = "futures-util" -version = "0.3.29" +name = "gix-utils" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "35192df7fd0fa112263bad8021e2df7167df4cc2a6e6d15892e1e55621d3d4dc" dependencies = [ - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", + "bstr 1.8.0", + "fastrand", + "unicode-normalization", ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "gix-validate" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "81f2badbb64e57b404593ee26b752c26991910fd0d81fe6f9a71c1a8309b6c86" dependencies = [ - "typenum", - "version_check", + "bstr 1.8.0", + "thiserror", ] [[package]] -name = "getrandom" -version = "0.2.11" +name = "gix-worktree" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "c312ad76a3f2ba8e865b360d5cb3aa04660971d16dec6dd0ce717938d903149a" dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi", - "wasm-bindgen", + "bstr 1.8.0", + "gix-attributes", + "gix-features", + "gix-fs", + "gix-glob", + "gix-hash", + "gix-ignore", + "gix-index", + "gix-object", + "gix-path", + "gix-validate", ] [[package]] -name = "gimli" -version = "0.28.1" +name = "gix-worktree-state" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "7b05c4b313fa702c0bacd5068dd3e01671da73b938fade97676859fee286de43" +dependencies = [ + "bstr 1.8.0", + "gix-features", + "gix-filter", + "gix-fs", + "gix-glob", + "gix-hash", + "gix-index", + "gix-object", + "gix-path", + "gix-worktree", + "io-close", + "thiserror", +] + +[[package]] +name = "gix-worktree-stream" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68e81b87c1a3ece22a54b682d6fdc37fbb3977132da972cafe5ec07175fddbca" +dependencies = [ + "gix-attributes", + "gix-features", + "gix-filter", + "gix-fs", + "gix-hash", + "gix-object", + "gix-path", + "gix-traverse", + "parking_lot 0.12.3", + "thiserror", +] [[package]] name = "glob" @@ -2261,6 +3165,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f58b778a5761513caf593693f8951c97a5b610841e754788400f32102eefdff1" +[[package]] +name = "human_format" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3b1f728c459d27b12448862017b96ad4767b1ec2ec5e6434e99f1577f085b8" + [[package]] name = "humantime" version = "2.1.0" @@ -2407,6 +3317,16 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" +[[package]] +name = "imara-diff" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc9da1a252bd44cd341657203722352efc9bc0c847d06ea6d2dc1cd1135e0a01" +dependencies = [ + "ahash", + "hashbrown 0.14.5", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -2441,6 +3361,16 @@ dependencies = [ "web-sys", ] +[[package]] +name = "io-close" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cadcf447f06744f8ce713d2d6239bb5bde2c357a452397a9ed90c625da390bc" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "ipnet" version = "2.9.0" @@ -2492,6 +3422,31 @@ version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +[[package]] +name = "jiff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a45489186a6123c128fdf6016183fcfab7113e1820eb813127e036e287233fb" +dependencies = [ + "jiff-tzdb-platform", + "windows-sys 0.59.0", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91335e575850c5c4c673b9bd467b0e025f164ca59d0564f69d0c2ee0ffad4653" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9835f0060a626fe59f160437bc725491a6af23133ea906500027d1bd2f8f4329" +dependencies = [ + "jiff-tzdb", +] + [[package]] name = "jobserver" version = "0.1.27" @@ -2533,6 +3488,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d129799327c8f80861e467c59b825ba24c277dba6ad0d71a141dc98f9e04ee" +[[package]] +name = "kstring" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" +dependencies = [ + "static_assertions", +] + [[package]] name = "lab" version = "0.11.0" @@ -2573,7 +3537,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if 1.0.0", - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -2686,6 +3650,17 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "maybe-async" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "md-5" version = "0.10.6" @@ -2702,6 +3677,15 @@ version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +[[package]] +name = "memmap2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +dependencies = [ + "libc", +] + [[package]] name = "memmem" version = "0.1.1" @@ -3128,7 +4112,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47777510a49fc554e7fb33101b67b6dc0bca28ea6d6fa852c113241e433a9e89" dependencies = [ - "dashmap", + "dashmap 5.5.3", "dunce", "indexmap 2.2.6", "json-strip-comments", @@ -3408,6 +4392,12 @@ dependencies = [ "nom 7.1.3", ] +[[package]] +name = "portable-atomic" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d30538d42559de6b034bc76fd6dd4c38961b1ee5c6c56e3808c50128fdbc22ce" + [[package]] name = "powerfmt" version = "0.2.0" @@ -3496,6 +4486,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prodash" +version = "28.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744a264d26b88a6a7e37cbad97953fa233b94d585236310bcbc88474b4092d79" +dependencies = [ + "bytesize", + "human_format", +] + [[package]] name = "prost" version = "0.13.1" @@ -3760,9 +4760,11 @@ dependencies = [ "async-compression", "base64 0.22.1", "bytes", + "encoding_rs", "futures-channel", "futures-core", "futures-util", + "h2 0.4.5", "http 1.1.0", "http-body 1.0.0", "http-body-util", @@ -3784,6 +4786,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", + "system-configuration", "tokio", "tokio-rustls", "tokio-util", @@ -4303,6 +5306,12 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + [[package]] name = "sha2" version = "0.9.9" @@ -4336,6 +5345,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "shellexpand" version = "3.1.0" @@ -4876,7 +5891,7 @@ checksum = "83406221c501860fce9c27444f44125eafe9e598b8b81be7563d7036784cd05c" dependencies = [ "ahash", "anyhow", - "dashmap", + "dashmap 5.5.3", "once_cell", "regex", "serde", @@ -5096,7 +6111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d411add563dd86d50b3db6e74e38def06587fa2fd370b430f71226688bfa6ded" dependencies = [ "base64 0.21.7", - "dashmap", + "dashmap 5.5.3", "indexmap 2.2.6", "once_cell", "serde", @@ -5243,6 +6258,27 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tap" version = "1.0.1" @@ -5261,15 +6297,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.8.1" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if 1.0.0", "fastrand", - "redox_syscall 0.4.1", + "once_cell", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -5621,7 +6657,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.28", ] [[package]] @@ -5689,7 +6725,7 @@ dependencies = [ "async-trait", "auto_impl", "bytes", - "dashmap", + "dashmap 5.5.3", "futures", "httparse", "lsp-types", @@ -5858,6 +6894,15 @@ dependencies = [ "web-time", ] +[[package]] +name = "uluru" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c8a2469e56e6e5095c82ccd3afb98dad95f7af7929aab6d8ba8d6e0f73657da" +dependencies = [ + "arrayvec", +] + [[package]] name = "unicode-bidi" version = "0.3.14" @@ -5938,9 +6983,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -6376,7 +7421,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -6396,17 +7450,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -6417,9 +7472,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -6429,9 +7484,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -6441,9 +7496,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -6453,9 +7514,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -6465,9 +7526,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -6477,9 +7538,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -6489,9 +7550,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" @@ -6502,6 +7563,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.52.0" diff --git a/crates/brioche-core/Cargo.toml b/crates/brioche-core/Cargo.toml index 66195d1..c849485 100644 --- a/crates/brioche-core/Cargo.toml +++ b/crates/brioche-core/Cargo.toml @@ -65,6 +65,7 @@ urlencoding = "2.1.3" walkdir = "2.5.0" petgraph = "0.6.5" wax = { version = "0.6.0", default-features = false } +gix = { version = "0.66.0", features = ["blocking-network-client", "blocking-http-transport-reqwest"] } [dev-dependencies] assert_matches = "1.5.0" diff --git a/crates/brioche-core/src/download.rs b/crates/brioche-core/src/download.rs index 5795214..9821294 100644 --- a/crates/brioche-core/src/download.rs +++ b/crates/brioche-core/src/download.rs @@ -80,3 +80,126 @@ pub async fn download( Ok(blob_hash) } + +pub async fn fetch_git_commit_for_ref(repository: &url::Url, ref_: &str) -> anyhow::Result { + let (tx, rx) = tokio::sync::oneshot::channel::>(); + + // gix uses a blocking client, so spawn a separate thread to fetch + std::thread::spawn({ + let repository: gix::Url = repository + .as_str() + .try_into() + .with_context(|| format!("failed to parse git repository URL: {repository}"))?; + move || { + // Connect to the repository by URL + let transport = gix::protocol::transport::connect(repository, Default::default()); + let mut transport = match transport { + Ok(transport) => transport, + Err(error) => { + let _ = tx.send(Err(error.into())); + return; + } + }; + + // Perform a handshake to get the remote's capabilities. + // Authentication is disabled + let empty_auth = |_| Ok(None); + let outcome = gix::protocol::fetch::handshake( + &mut transport, + empty_auth, + vec![], + &mut gix::progress::Discard, + ); + let outcome = match outcome { + Ok(outcome) => outcome, + Err(error) => { + let _ = gix::protocol::indicate_end_of_interaction(&mut transport, false); + let _ = tx.send(Err(error.into())); + return; + } + }; + + let refs = match outcome.refs { + Some(refs) => { + // The handshake will sometimes return the refs directly, + // depending on protocol version. If that happens, we're + // done + refs + } + None => { + // Fetch the refs + let refs = gix::protocol::ls_refs( + &mut transport, + &outcome.capabilities, + |_, _, _| Ok(gix::protocol::ls_refs::Action::Continue), + &mut gix::progress::Discard, + false, + ); + match refs { + Ok(refs) => refs, + Err(error) => { + let _ = + gix::protocol::indicate_end_of_interaction(&mut transport, false); + let _ = tx.send(Err(error.into())); + return; + } + } + } + }; + + // End the interaction with the remote + let _ = gix::protocol::indicate_end_of_interaction(&mut transport, false); + + let _ = tx.send(Ok(refs)); + } + }); + + let remote_refs = rx.await?; + let remote_refs = match remote_refs { + Ok(remote_refs) => remote_refs, + Err(error) => { + anyhow::bail!("{error}"); + } + }; + + // Find the ref that matches the requested ref name + let object_id = remote_refs + .iter() + .find_map(|remote_ref| { + let (name, object) = match remote_ref { + gix::protocol::handshake::Ref::Peeled { + full_ref_name, + object, + .. + } => (full_ref_name, object), + gix::protocol::handshake::Ref::Direct { + full_ref_name, + object, + } => (full_ref_name, object), + gix::protocol::handshake::Ref::Symbolic { + full_ref_name, + object, + .. + } => (full_ref_name, object), + gix::protocol::handshake::Ref::Unborn { .. } => { + return None; + } + }; + + if let Some(tag_name) = name.strip_prefix(b"refs/tags/") { + if tag_name == ref_.as_bytes() { + return Some(object); + } + } else if let Some(head_name) = name.strip_prefix(b"refs/heads/") { + if head_name == ref_.as_bytes() { + return Some(object); + } + } + + None + }) + .with_context(|| format!("git ref '{ref_}' not found in repo {repository}"))?; + + let commit = object_id.to_string(); + Ok(commit) +} diff --git a/crates/brioche-core/src/project.rs b/crates/brioche-core/src/project.rs index 1a59b89..b2dc9d5 100644 --- a/crates/brioche-core/src/project.rs +++ b/crates/brioche-core/src/project.rs @@ -4,13 +4,13 @@ use std::{ sync::Arc, }; -use analyze::{StaticOutput, StaticOutputKind, StaticQuery}; +use analyze::{GitRefOptions, StaticOutput, StaticOutputKind, StaticQuery}; use anyhow::Context as _; use futures::{StreamExt as _, TryStreamExt as _}; use relative_path::{PathExt as _, RelativePath, RelativePathBuf}; use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _}; -use crate::recipe::{Artifact, RecipeHash}; +use crate::recipe::Artifact; use super::{vfs::FileId, Brioche}; @@ -314,7 +314,7 @@ impl Projects { &self, specifier: &super::script::specifier::BriocheModuleSpecifier, static_: &StaticQuery, - ) -> anyhow::Result> { + ) -> anyhow::Result> { let projects = self .inner .read() @@ -450,7 +450,7 @@ impl ProjectsInner { &self, specifier: &super::script::specifier::BriocheModuleSpecifier, static_: &StaticQuery, - ) -> anyhow::Result> { + ) -> anyhow::Result> { let path = match specifier { super::script::specifier::BriocheModuleSpecifier::File { path } => path, _ => { @@ -485,8 +485,7 @@ impl ProjectsInner { let Some(Some(output)) = statics.get(static_) else { return Ok(None); }; - let recipe_hash = static_.output_recipe_hash(output)?; - Ok(Some(recipe_hash)) + Ok(Some(output.clone())) } } @@ -994,7 +993,9 @@ async fn fetch_project_from_registry( }; let recipe_hash = static_.output_recipe_hash(output)?; - statics_recipes.insert(recipe_hash); + if let Some(recipe_hash) = recipe_hash { + statics_recipes.insert(recipe_hash); + } } crate::registry::fetch_recipes_deep(brioche, statics_recipes).await?; @@ -1012,6 +1013,7 @@ async fn fetch_project_from_registry( match static_ { StaticQuery::Include(include) => { + let recipe_hash = recipe_hash.context("no recipe hash for include static")?; let recipe = crate::recipe::get_recipe(brioche, recipe_hash).await?; let artifact: crate::recipe::Artifact = recipe.try_into().map_err(|_| { anyhow::anyhow!("included static recipe is not an artifact") @@ -1031,6 +1033,7 @@ async fn fetch_project_from_registry( .await?; } StaticQuery::Glob { .. } => { + let recipe_hash = recipe_hash.context("no recipe hash for glob static")?; let recipe = crate::recipe::get_recipe(brioche, recipe_hash).await?; let artifact: crate::recipe::Artifact = recipe.try_into().map_err(|_| { anyhow::anyhow!("included static recipe is not an artifact") @@ -1048,7 +1051,7 @@ async fn fetch_project_from_registry( ) .await?; } - StaticQuery::Download { .. } => { + StaticQuery::Download { .. } | StaticQuery::GitRef { .. } => { // No need to do anything while fetching the project } } @@ -1091,27 +1094,37 @@ async fn fetch_project_from_registry( .iter() .map(|(name, hash)| (name.clone(), *hash)) .collect(); - let downloads = project - .statics - .values() - .flatten() - .filter_map(|(static_, output)| { - let url = match static_ { - StaticQuery::Download { url, .. } => url, - _ => return None, - }; - let hash = match output { - Some(StaticOutput::Kind(StaticOutputKind::Download { hash })) => hash, - _ => return None, - }; + let mut downloads = BTreeMap::new(); + let mut git_refs = BTreeMap::new(); + for (static_, output) in project.statics.values().flatten() { + match static_ { + StaticQuery::Include(_) | StaticQuery::Glob { .. } => { + continue; + } + StaticQuery::Download { url } => { + let Some(StaticOutput::Kind(StaticOutputKind::Download { hash })) = output else { + continue; + }; + + downloads.insert(url.clone(), hash.clone()); + } + StaticQuery::GitRef(GitRefOptions { repository, ref_ }) => { + let Some(StaticOutput::Kind(StaticOutputKind::GitRef { commit })) = output else { + continue; + }; + + let repo_refs: &mut BTreeMap<_, _> = + git_refs.entry(repository.clone()).or_default(); + repo_refs.insert(ref_.clone(), commit.clone()); + } + } + } - Some((url.clone(), hash.clone())) - }) - .collect(); let lockfile = Lockfile { dependencies, downloads, + git_refs, }; let lockfile_path = temp_project_path.join("brioche.lock"); let lockfile_contents = @@ -1439,6 +1452,37 @@ async fn resolve_static( hash: download_hash, })) } + StaticQuery::GitRef(GitRefOptions { repository, ref_ }) => { + let current_commit = lockfile.and_then(|lockfile| { + lockfile + .git_refs + .get(repository) + .and_then(|repo_refs| repo_refs.get(ref_)) + }); + + let commit = if let Some(commit) = current_commit { + commit.clone() + } else if lockfile_required { + // Error out if the git ref isn't in the lockfile but where + // updating the lockfile is disabled + anyhow::bail!( + "commit for git repo '{repository}' ref '{ref_}' not found in lockfile" + ); + } else { + // Fetch the current commit hash of the git ref from the repo + crate::download::fetch_git_commit_for_ref(repository, ref_) + .await + .with_context(|| { + format!("failed to fetch ref '{ref_}' from git repo '{repository}'") + })? + }; + + // Update the new lockfile with the commit + let repo_refs = new_lockfile.git_refs.entry(repository.clone()).or_default(); + repo_refs.insert(ref_.clone(), commit.clone()); + + Ok(StaticOutput::Kind(StaticOutputKind::GitRef { commit })) + } } } @@ -1671,4 +1715,7 @@ pub struct Lockfile { #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] pub downloads: BTreeMap, + + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] + pub git_refs: BTreeMap>, } diff --git a/crates/brioche-core/src/project/analyze.rs b/crates/brioche-core/src/project/analyze.rs index 5947579..3ddf817 100644 --- a/crates/brioche-core/src/project/analyze.rs +++ b/crates/brioche-core/src/project/analyze.rs @@ -43,15 +43,16 @@ pub enum StaticQuery { Include(StaticInclude), Glob { patterns: Vec }, Download { url: url::Url }, + GitRef(GitRefOptions), } impl StaticQuery { pub fn output_recipe_hash( &self, output: &StaticOutput, - ) -> anyhow::Result { + ) -> anyhow::Result> { let recipe_hash = match output { - StaticOutput::RecipeHash(hash) => *hash, + StaticOutput::RecipeHash(hash) => Some(*hash), StaticOutput::Kind(StaticOutputKind::Download { hash }) => { let download_url = match self { StaticQuery::Download { url } => url, @@ -61,7 +62,11 @@ impl StaticQuery { url: download_url.clone(), hash: hash.clone(), }); - recipe.hash() + Some(recipe.hash()) + } + StaticOutput::Kind(StaticOutputKind::GitRef { .. }) => { + // git ref statics don't resolve to a recipe + None } }; @@ -69,6 +74,14 @@ impl StaticQuery { } } +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)] +pub struct GitRefOptions { + pub repository: url::Url, + + #[serde(rename = "ref")] + pub ref_: String, +} + #[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)] #[serde(untagged)] pub enum StaticOutput { @@ -80,6 +93,7 @@ pub enum StaticOutput { #[serde(tag = "kind")] pub enum StaticOutputKind { Download { hash: crate::Hash }, + GitRef { commit: String }, } #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)] @@ -556,7 +570,36 @@ where })?; Ok(Some(StaticQuery::Download { url })) + } + "gitRef" => { + // Get the arguments + let args = call_expr.arguments()?.args(); + let args = args + .iter() + .map(|arg| arg_to_json(arg, env)) + .map(|arg| { + arg.with_context(|| { + format!("{location}: invalid arg to Brioche.download") + }) + }) + .collect::>>()?; + + // Ensure there's exactly one argument + let options = match &*args { + [options] => options.clone(), + _ => { + anyhow::bail!( + "{location}: Brioche.gitRef() must take exactly one argument", + ); + } + }; + + // Parse the options + let options = serde_json::from_value(options).with_context(|| { + format!("{location}: invalid options for Brioche.gitRef, expected an object with the keys `repository` and `ref`") + })?; + Ok(Some(StaticQuery::GitRef(options))) } _ => Ok(None), } @@ -764,15 +807,24 @@ fn expression_to_json( } } -fn arg_to_string_literal( +fn arg_to_json( arg: biome_rowan::SyntaxResult, env: &HashMap, -) -> anyhow::Result { +) -> anyhow::Result { let arg = arg?; let arg = arg .as_any_js_expression() .context("spread arguments are not supported")?; let arg = expression_to_json(arg, env)?; + + anyhow::Ok(arg) +} + +fn arg_to_string_literal( + arg: biome_rowan::SyntaxResult, + env: &HashMap, +) -> anyhow::Result { + let arg = arg_to_json(arg, env)?; let arg = arg.as_str().context("expected string argument")?; anyhow::Ok(arg.to_string()) diff --git a/crates/brioche-core/src/references.rs b/crates/brioche-core/src/references.rs index 2f6703c..9d28e88 100644 --- a/crates/brioche-core/src/references.rs +++ b/crates/brioche-core/src/references.rs @@ -101,7 +101,9 @@ pub async fn project_references( .as_ref() .with_context(|| format!("static not loaded for module {module_path}"))?; let static_recipe_hash = static_.output_recipe_hash(output)?; - new_recipes.insert(static_recipe_hash); + if let Some(static_recipe_hash) = static_recipe_hash { + new_recipes.insert(static_recipe_hash); + } } } } diff --git a/crates/brioche-core/src/script.rs b/crates/brioche-core/src/script.rs index 48d76c1..5c5d541 100644 --- a/crates/brioche-core/src/script.rs +++ b/crates/brioche-core/src/script.rs @@ -265,7 +265,7 @@ pub async fn op_brioche_get_static( state: Rc>, #[string] url: String, #[serde] static_: StaticQuery, -) -> Result { +) -> Result { let bridge = { let state = state.try_borrow()?; state diff --git a/crates/brioche-core/src/script/bridge.rs b/crates/brioche-core/src/script/bridge.rs index 677a904..268d270 100644 --- a/crates/brioche-core/src/script/bridge.rs +++ b/crates/brioche-core/src/script/bridge.rs @@ -8,10 +8,10 @@ use crate::{ bake::BakeScope, blob::BlobHash, project::{ - analyze::{StaticInclude, StaticQuery}, + analyze::{GitRefOptions, StaticInclude, StaticOutput, StaticOutputKind, StaticQuery}, ProjectHash, Projects, }, - recipe::{Artifact, Recipe, WithMeta}, + recipe::{Artifact, DownloadRecipe, Recipe, WithMeta}, Brioche, }; @@ -220,9 +220,9 @@ impl RuntimeBridge { static_, result_tx, } => { - let recipe_hash = projects.get_static(&specifier, &static_); - let recipe_hash = match recipe_hash { - Ok(Some(recipe_hash)) => recipe_hash, + let static_output = projects.get_static(&specifier, &static_); + let static_output = match static_output { + Ok(Some(static_output)) => static_output, Ok(None) => { let error = match static_ { StaticQuery::Include(StaticInclude::File { path }) => { @@ -243,6 +243,9 @@ impl RuntimeBridge { StaticQuery::Download { url } => { anyhow::anyhow!("failed to resolve Brioche.download({url:?}) from {specifier}, was the URL passed in as a string literal?") } + StaticQuery::GitRef(GitRefOptions { repository, ref_ }) => { + anyhow::anyhow!("failed to resolve Brioche.gitRef({{ repository: \"{repository}\", ref: {ref_:?} }}) from {specifier}, were the repository and ref values passed in as string literals?") + } }; let _ = result_tx.send(Err(error)); return; @@ -253,8 +256,44 @@ impl RuntimeBridge { } }; - let result = crate::recipe::get_recipe(&brioche, recipe_hash).await; - let _ = result_tx.send(result); + let result = match static_output { + StaticOutput::RecipeHash(recipe_hash) => { + let recipe = + crate::recipe::get_recipe(&brioche, recipe_hash).await; + let recipe = match recipe { + Ok(recipe) => recipe, + Err(error) => { + let _ = result_tx.send(Err(error)); + return; + } + }; + + GetStaticResult::Recipe(recipe) + } + StaticOutput::Kind(StaticOutputKind::Download { hash }) => { + let StaticQuery::Download { url } = static_ else { + let _ = result_tx.send(Err(anyhow::anyhow!("invalid 'download' static output kind for non-download static"))); + return; + }; + + GetStaticResult::Recipe(Recipe::Download(DownloadRecipe { + url, + hash, + })) + } + StaticOutput::Kind(StaticOutputKind::GitRef { commit }) => { + let StaticQuery::GitRef(git_ref) = static_ else { + let _ = result_tx.send(Err(anyhow::anyhow!("invalid 'git_ref' static output kind for non-git ref static"))); + return; + }; + + GetStaticResult::GitRef { + repository: git_ref.repository, + commit, + } + } + }; + let _ = result_tx.send(Ok(result)); } } }); @@ -406,7 +445,7 @@ impl RuntimeBridge { &self, specifier: BriocheModuleSpecifier, static_: StaticQuery, - ) -> anyhow::Result { + ) -> anyhow::Result { let (result_tx, result_rx) = tokio::sync::oneshot::channel(); self.tx.send(RuntimeBridgeMessage::GetStatic { @@ -466,6 +505,16 @@ enum RuntimeBridgeMessage { GetStatic { specifier: BriocheModuleSpecifier, static_: StaticQuery, - result_tx: tokio::sync::oneshot::Sender>, + result_tx: tokio::sync::oneshot::Sender>, + }, +} + +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)] +#[serde(tag = "staticKind", rename_all = "snake_case")] +pub enum GetStaticResult { + Recipe(Recipe), + GitRef { + repository: url::Url, + commit: String, }, } diff --git a/crates/brioche-core/tests/script_eval.rs b/crates/brioche-core/tests/script_eval.rs index 067e712..59ac821 100644 --- a/crates/brioche-core/tests/script_eval.rs +++ b/crates/brioche-core/tests/script_eval.rs @@ -640,3 +640,104 @@ async fn test_eval_brioche_download() -> anyhow::Result<()> { Ok(()) } + +#[tokio::test] +async fn test_eval_brioche_git_ref() -> anyhow::Result<()> { + let (brioche, context) = brioche_test_support::brioche_test().await; + + let mut mock_repo = mockito::Server::new_with_port(1231); + let mock_repo_url = mock_repo.url(); + + // Mock a git "handshake" server response for protocol version 2 + let mock_git_info_refs_response = b"001e# service=git-upload-pack\n0000000eversion 2\n0000"; + let mock_git_info_refs = mock_repo + .mock("GET", "/info/refs?service=git-upload-pack") + .with_header( + "Content-Type", + "application/x-git-upload-pack-advertisement", + ) + .with_header("Cache-Control", "no-cache") + .with_body(mock_git_info_refs_response) + .expect(1) + .create(); + + // Mock a git "ls-refs" response, with one branch named "main" with a + // commit hash of "0123456789abcdef01234567890123456789abcd" + let mock_git_upload_pack_response = + b"003d0123456789abcdef01234567890123456789abcd refs/heads/main\n0000"; + let mock_git_upload_pack = mock_repo + .mock("POST", "/git-upload-pack") + .with_header("Content-Type", "application/x-git-upload-pack-result") + .with_header("Cache-Control", "no-cache") + .with_body(mock_git_upload_pack_response) + .expect(1) + .create(); + + let project_dir = context.mkdir("myproject").await; + context + .write_file( + "myproject/project.bri", + r#" + globalThis.Brioche = { + gitRef: async ({ repository, ref }) => { + return await Deno.core.ops.op_brioche_get_static( + import.meta.url, + { + type: "git_ref", + repository, + ref, + }, + ); + } + } + + export default async () => { + const gitRef = await Brioche.gitRef({ + repository: "", + ref: "main", + }); + return { + briocheSerialize: async () => { + return { + type: "create_file", + content: JSON.stringify(gitRef), + executable: false, + resources: { + type: "directory", + entries: {}, + }, + }; + }, + }; + }; + "# + .replace("", &mock_repo_url), + ) + .await; + + let (projects, project_hash) = + brioche_test_support::load_project(&brioche, &project_dir).await?; + + let resolved = evaluate(&brioche, &projects, project_hash, "default") + .await? + .value; + + let brioche_core::recipe::Recipe::CreateFile { content, .. } = resolved else { + panic!("expected create_file recipe, got {resolved:?}"); + }; + + mock_git_info_refs.assert_async().await; + mock_git_upload_pack.assert_async().await; + + let git_ref: serde_json::Value = serde_json::from_slice(&content)?; + assert_eq!( + git_ref, + serde_json::json!({ + "staticKind": "git_ref", + "repository": format!("{mock_repo_url}/"), + "commit": "0123456789abcdef01234567890123456789abcd", + }), + ); + + Ok(()) +}