From ec0ae6e514a1a1f2456baab6b2170a66fdb867e7 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Wed, 21 Jun 2023 15:14:55 +1000 Subject: [PATCH] feat: Support install directly from git repo Fixed #3 Signed-off-by: Jiahao XU --- Cargo.lock | 1164 ++++++++++++++++++++++++++-- crates/bin/Cargo.toml | 7 +- crates/bin/src/args.rs | 39 +- crates/bin/src/entry.rs | 17 +- crates/bin/src/lib.rs | 2 + crates/binstalk/Cargo.toml | 8 +- crates/binstalk/src/errors.rs | 11 + crates/binstalk/src/helpers.rs | 2 + crates/binstalk/src/helpers/git.rs | 80 ++ crates/binstalk/src/lib.rs | 2 + crates/binstalk/src/ops.rs | 13 +- crates/binstalk/src/ops/resolve.rs | 68 +- e2e-tests/git.sh | 31 + justfile | 8 +- 14 files changed, 1351 insertions(+), 101 deletions(-) create mode 100644 crates/binstalk/src/helpers/git.rs create mode 100644 e2e-tests/git.sh diff --git a/Cargo.lock b/Cargo.lock index 7f82f6eec..a8ef40f12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,6 +28,18 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.0.2" @@ -101,6 +113,18 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "async-compression" version = "0.3.15" @@ -226,6 +250,7 @@ dependencies = [ "compact_str", "detect-targets", "either", + "gix", "home", "itertools", "jobslot", @@ -336,6 +361,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded" + [[package]] name = "block-buffer" version = "0.10.4" @@ -366,6 +397,27 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "bstr" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a246e68bb43f6cd9db24bea052a53e40405417c5fb372e3d1a8a7f770a564ef5" +dependencies = [ + "memchr", + "once_cell", + "regex-automata", + "serde", +] + +[[package]] +name = "btoi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad" +dependencies = [ + "num-traits", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -384,6 +436,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "bytesize" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38fcc2979eff34a4b84e1cf9a1e3da42a7d44b3b690a40cdcb23e3d556cfb2e5" + [[package]] name = "bzip2" version = "0.4.4" @@ -487,7 +545,7 @@ checksum = "c1458a1df40e1e2afebb7ab60ce55c1fa8f431146205aa5f4887e0b111c27636" dependencies = [ "anstream", "anstyle", - "bitflags", + "bitflags 1.3.2", "clap_lex", "strsim", ] @@ -510,6 +568,12 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +[[package]] +name = "clru" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8191fa7302e03607ff0e237d4246cc043ff5b3cb9409d995172ba3bea16b807" + [[package]] name = "cmake" version = "0.1.50" @@ -576,6 +640,73 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" +dependencies = [ + "cfg-if", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -641,6 +772,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + [[package]] name = "either" version = "1.8.1" @@ -814,108 +951,757 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" [[package]] -name = "futures-io" -version = "0.3.28" +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.18", +] + +[[package]] +name = "futures-sink" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[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.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gh-token" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1ff8db6b58b68c39ec14a0922cad141fee0e350324eb01ee45e3898f780d46" +dependencies = [ + "home", + "serde", + "serde_derive", + "serde_yaml", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "gix" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99368b48a2f68c3fdc26e62c6425bdc4baeb4f30a4f24eb2e0904d29a2ba97ab" +dependencies = [ + "gix-actor", + "gix-attributes", + "gix-commitgraph", + "gix-config", + "gix-credentials", + "gix-date", + "gix-diff", + "gix-discover", + "gix-features", + "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-prompt", + "gix-protocol", + "gix-ref", + "gix-refspec", + "gix-revision", + "gix-sec", + "gix-tempfile", + "gix-transport", + "gix-traverse", + "gix-url", + "gix-utils", + "gix-validate", + "gix-worktree", + "log", + "once_cell", + "reqwest", + "signal-hook", + "smallvec", + "thiserror", + "unicode-normalization", +] + +[[package]] +name = "gix-actor" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fe73f9f6be1afbf1bd5be919a9636fa560e2f14d42262a934423ed6760cd838" +dependencies = [ + "bstr", + "btoi", + "gix-date", + "itoa", + "nom", + "thiserror", +] + +[[package]] +name = "gix-attributes" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b79590ac382f80d87e06416f5fcac6fee5d83dcb152a00ed0bdbaa988acc31" +dependencies = [ + "bstr", + "gix-glob", + "gix-path", + "gix-quote", + "kstring", + "log", + "smallvec", + "thiserror", + "unicode-bom", +] + +[[package]] +name = "gix-bitmap" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc02feb20ad313d52a450852f2005c2205d24f851e74d82b7807cbe12c371667" +dependencies = [ + "thiserror", +] + +[[package]] +name = "gix-chunk" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7acf3bc6c4b91e8fb260086daf5e105ea3a6d913f5fd3318137f7e309d6e540" +dependencies = [ + "thiserror", +] + +[[package]] +name = "gix-command" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6141b70cfb21255223e42f3379855037cbbe8673b58dd8318d2f09b516fad1" +dependencies = [ + "bstr", +] + +[[package]] +name = "gix-commitgraph" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8490ae1b3d55c47e6a71d247c082304a2f79f8d0332c1a2f5693d42a2021a09" +dependencies = [ + "bstr", + "gix-chunk", + "gix-features", + "gix-hash", + "memmap2", + "thiserror", +] + +[[package]] +name = "gix-config" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f310120ae1ba8f0ca52fb22876ce9bad5b15c8ffb3eb7302e4b64a3b9f681c" +dependencies = [ + "bstr", + "gix-config-value", + "gix-features", + "gix-glob", + "gix-path", + "gix-ref", + "gix-sec", + "log", + "memchr", + "nom", + "once_cell", + "smallvec", + "thiserror", + "unicode-bom", +] + +[[package]] +name = "gix-config-value" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f216df1c33e6e1555923eff0096858a879e8aaadd35b5d788641e4e8064c892" +dependencies = [ + "bitflags 2.3.2", + "bstr", + "gix-path", + "libc", + "thiserror", +] + +[[package]] +name = "gix-credentials" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f89fea8acd28f5ef8fa5042146f1637afd4d834bc8f13439d8fd1e5aca0d65" +dependencies = [ + "bstr", + "gix-command", + "gix-config-value", + "gix-path", + "gix-prompt", + "gix-sec", + "gix-url", + "thiserror", +] + +[[package]] +name = "gix-date" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc164145670e9130a60a21670d9b6f0f4f8de04e5dd256c51fa5a0340c625902" +dependencies = [ + "bstr", + "itoa", + "thiserror", + "time", +] + +[[package]] +name = "gix-diff" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9029ad0083cc286a4bd2f5b3bf66bb66398abc26f2731a2824cd5edfc41a0e33" +dependencies = [ + "gix-hash", + "gix-object", + "imara-diff", + "thiserror", +] + +[[package]] +name = "gix-discover" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba9c6c0d1f2b2efe65581de73de4305004612d49c83773e783202a7ef204f46" +dependencies = [ + "bstr", + "dunce", + "gix-hash", + "gix-path", + "gix-ref", + "gix-sec", + "thiserror", +] + +[[package]] +name = "gix-features" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8c493409bf6060d408eec9bbdd1b12ea351266b50012e2a522f75dfc7b8314" +dependencies = [ + "bytes", + "bytesize", + "crc32fast", + "crossbeam-channel", + "flate2", + "gix-hash", + "jwalk", + "libc", + "once_cell", + "parking_lot", + "prodash", + "sha1_smol", + "thiserror", + "walkdir", +] + +[[package]] +name = "gix-fs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30da8997008adb87f94e15beb7ee229f8a48e97af585a584bfee4a5a1880aab5" +dependencies = [ + "gix-features", +] + +[[package]] +name = "gix-glob" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0ade1e80ab1f079703d1824e1daf73009096386aa7fd2f0477f6e4ac0a558e" +dependencies = [ + "bitflags 2.3.2", + "bstr", + "gix-features", + "gix-path", +] + +[[package]] +name = "gix-hash" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee181c85d3955f54c4426e6bfaeeada4428692e1a39b8788c2ac7785fc301dd8" +dependencies = [ + "hex", + "thiserror", +] + +[[package]] +name = "gix-hashtable" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd259bd0d96e6153e357a8cdaca76c48e103fd34208b6c0ce77b1ad995834bd2" +dependencies = [ + "gix-hash", + "hashbrown 0.13.2", + "parking_lot", +] + +[[package]] +name = "gix-ignore" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6f7f101a0ccce808dbf7008ba131dede94e20257e7bde7a44cbb2f8c775625" +dependencies = [ + "bstr", + "gix-glob", + "gix-path", + "unicode-bom", +] + +[[package]] +name = "gix-index" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca0380cdab7863e67966eee4aed32856c864c20b077e026b637af6bb3a9281b4" +dependencies = [ + "bitflags 2.3.2", + "bstr", + "btoi", + "filetime", + "gix-bitmap", + "gix-features", + "gix-hash", + "gix-lock", + "gix-object", + "gix-traverse", + "itoa", + "memmap2", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-lock" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ec5d5e6f07316d3553aa7425e3ecd935ec29882556021fe1696297a448af8d2" +dependencies = [ + "gix-tempfile", + "gix-utils", + "thiserror", +] + +[[package]] +name = "gix-mailmap" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4653701922c920e009f1bc4309feaff14882ade017770788f9a150928da3fa6a" +dependencies = [ + "bstr", + "gix-actor", + "thiserror", +] + +[[package]] +name = "gix-negotiate" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "945c3ef1e912e44a5f405fc9e924edf42000566a1b257ed52cb1293300f6f08c" +dependencies = [ + "bitflags 2.3.2", + "gix-commitgraph", + "gix-hash", + "gix-object", + "gix-revision", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-object" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8926c8f51c44dec3e709cb5dbc93deb9e8d4064c43c9efc54c158dcdfe8446c7" +dependencies = [ + "bstr", + "btoi", + "gix-actor", + "gix-features", + "gix-hash", + "gix-validate", + "hex", + "itoa", + "nom", + "smallvec", + "thiserror", +] + +[[package]] +name = "gix-odb" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91d98eaba4f649fed17250651c4ddfaf997c80a30f5ee4b47ac9bc18ffe3eb16" +dependencies = [ + "arc-swap", + "gix-features", + "gix-hash", + "gix-object", + "gix-pack", + "gix-path", + "gix-quote", + "parking_lot", + "tempfile", + "thiserror", +] + +[[package]] +name = "gix-pack" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e9e228f18cd87e7596e687b38619b5e4caebc678644ae6bb3d842598166d72" +dependencies = [ + "clru", + "gix-chunk", + "gix-diff", + "gix-features", + "gix-hash", + "gix-hashtable", + "gix-object", + "gix-path", + "gix-tempfile", + "gix-traverse", + "memmap2", + "parking_lot", + "smallvec", + "thiserror", + "uluru", +] + +[[package]] +name = "gix-packetline" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74414f89a6b72fa1a530ce8e646faf1a05499c3f4a5c15441d17ae8c978578eb" +dependencies = [ + "bstr", + "hex", + "thiserror", +] + +[[package]] +name = "gix-path" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1226f2e50adeb4d76c754c1856c06f13a24cad1624801653fbf09b869e5b808" +dependencies = [ + "bstr", + "home", + "once_cell", + "thiserror", +] + +[[package]] +name = "gix-prompt" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e15fe57fa48572b7d3bf465d6a2a0351cd3c55cba74fd5f0b9c23689f9c1a31e" +dependencies = [ + "gix-command", + "gix-config-value", + "parking_lot", + "rustix", + "thiserror", +] + +[[package]] +name = "gix-protocol" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92a17058b45c461f0847528c5fb6ee6e76115e026979eb2d2202f98ee94f6c24" +dependencies = [ + "bstr", + "btoi", + "gix-credentials", + "gix-features", + "gix-hash", + "gix-transport", + "maybe-async", + "nom", + "thiserror", +] + +[[package]] +name = "gix-quote" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d59489bff95b06dcdabe763b7266d3dc0a628cac1ac1caf65a7ca0a43eeae0" +dependencies = [ + "bstr", + "btoi", + "thiserror", +] + +[[package]] +name = "gix-ref" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +checksum = "ebdd999256f4ce8a5eefa89999879c159c263f3493a951d62aa5ce42c0397e1c" +dependencies = [ + "gix-actor", + "gix-features", + "gix-fs", + "gix-hash", + "gix-lock", + "gix-object", + "gix-path", + "gix-tempfile", + "gix-validate", + "memmap2", + "nom", + "thiserror", +] [[package]] -name = "futures-lite" -version = "1.13.0" +name = "gix-refspec" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +checksum = "72bfd622abc86dd8ad1ec51b9eb77b4f1a766b94e3a1b87cf4a022c5b5570cf4" dependencies = [ - "futures-core", - "pin-project-lite", + "bstr", + "gix-hash", + "gix-revision", + "gix-validate", + "smallvec", + "thiserror", ] [[package]] -name = "futures-macro" -version = "0.3.28" +name = "gix-revision" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +checksum = "5044f56cd7a487ce9b034cbe0252ae0b6b47ff56ca3dabd79bc30214d0932cd7" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.18", + "bstr", + "gix-date", + "gix-hash", + "gix-hashtable", + "gix-object", + "gix-revwalk", + "thiserror", ] [[package]] -name = "futures-sink" -version = "0.3.28" +name = "gix-revwalk" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" +checksum = "bc2623ba8747914f151f5e12b65adac576ab459dbed5f50a36c7a3e9cbf2d3ca" +dependencies = [ + "gix-commitgraph", + "gix-hash", + "gix-hashtable", + "gix-object", + "smallvec", + "thiserror", +] [[package]] -name = "futures-task" -version = "0.3.28" +name = "gix-sec" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" +checksum = "b2b7b38b766eb95dcc5350a9c450030b69892c0902fa35f4a6d0809273bd9dae" +dependencies = [ + "bitflags 2.3.2", + "gix-path", + "libc", + "windows 0.48.0", +] [[package]] -name = "futures-util" -version = "0.3.28" +name = "gix-tempfile" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +checksum = "b3785cb010e9dc5c446dfbf02bc1119fc17d3a48a27c029efcb3a3c32953eb10" dependencies = [ - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", + "gix-fs", + "libc", + "once_cell", + "parking_lot", + "signal-hook", + "signal-hook-registry", + "tempfile", ] [[package]] -name = "fxhash" -version = "0.2.1" +name = "gix-transport" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +checksum = "64a39ffed9a9078ed700605e064b15d7c6ae50aa65e7faa36ca6919e8081df15" dependencies = [ - "byteorder", + "base64 0.21.2", + "bstr", + "gix-command", + "gix-credentials", + "gix-features", + "gix-packetline", + "gix-quote", + "gix-sec", + "gix-url", + "reqwest", + "thiserror", ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "gix-traverse" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "8673546506391a10fdfd4e48c8e0f3ec92355cf1fac787d2e714c7d45e301ede" dependencies = [ - "typenum", - "version_check", + "gix-commitgraph", + "gix-hash", + "gix-hashtable", + "gix-object", + "gix-revwalk", + "smallvec", + "thiserror", ] [[package]] -name = "getrandom" -version = "0.2.10" +name = "gix-url" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "f1663df25ac42047a2547618d2a6979a26f478073f6306997429235d2cd4c863" dependencies = [ - "cfg-if", - "libc", - "wasi", + "bstr", + "gix-features", + "gix-path", + "home", + "thiserror", + "url", ] [[package]] -name = "gh-token" +name = "gix-utils" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1ff8db6b58b68c39ec14a0922cad141fee0e350324eb01ee45e3898f780d46" +checksum = "dbcfcb150c7ef553d76988467d223254045bdcad0dc6724890f32fbe96415da5" dependencies = [ - "home", - "serde", - "serde_derive", - "serde_yaml", + "fastrand", ] [[package]] -name = "gimli" -version = "0.27.3" +name = "gix-validate" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" +checksum = "57ea5845b506c7728b9d89f4227cc369a5fc5a1d5b26c3add0f0d323413a3a60" +dependencies = [ + "bstr", + "thiserror", +] + +[[package]] +name = "gix-worktree" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b32a0e7ed52577bfb050f5350bdee2741d1b08a9ed02a2f2df6effe353896ca" +dependencies = [ + "bstr", + "filetime", + "gix-attributes", + "gix-features", + "gix-fs", + "gix-glob", + "gix-hash", + "gix-ignore", + "gix-index", + "gix-object", + "gix-path", + "io-close", + "thiserror", +] [[package]] name = "guess_host_triple" @@ -954,9 +1740,15 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.6", ] +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" + [[package]] name = "heck" version = "0.4.1" @@ -978,6 +1770,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "home" version = "0.5.5" @@ -1032,6 +1830,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +[[package]] +name = "human_format" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86cce260d758a9aa3d7c4b99d55c815a540f8a37514ba6046ab6be402a157cb0" + [[package]] name = "hyper" version = "0.14.26" @@ -1103,6 +1907,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "imara-diff" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e98c1d0ad70fc91b8b9654b1f33db55e59579d3b3de2bffdced0fdb810570cb8" +dependencies = [ + "ahash 0.8.3", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "1.9.3" @@ -1110,7 +1924,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", - "hashbrown", + "hashbrown 0.12.3", ] [[package]] @@ -1122,6 +1936,16 @@ dependencies = [ "cfg-if", ] +[[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 = "io-lifetimes" version = "1.0.11" @@ -1216,6 +2040,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2735847566356cd2179a2a38264839308f7079fa96e6bd5a42d740460e003c56" +dependencies = [ + "crossbeam", + "rayon", +] + +[[package]] +name = "kstring" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" +dependencies = [ + "static_assertions", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -1327,6 +2170,17 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "maybe-async" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1b8c13cb1f814b634a96b2c725449fe7ed464a7b8781de8688be5ffbd3f305" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "maybe-owned" version = "0.3.4" @@ -1342,6 +2196,24 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "memmap2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + [[package]] name = "miette" version = "5.9.0" @@ -1389,6 +2261,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.6.2" @@ -1442,12 +2320,22 @@ version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "libc", "static_assertions", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "normalize-path" version = "0.2.0" @@ -1462,6 +2350,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.15.0" @@ -1472,6 +2369,15 @@ dependencies = [ "libc", ] +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + [[package]] name = "object" version = "0.30.4" @@ -1493,7 +2399,7 @@ version = "0.10.54" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if", "foreign-types", "libc", @@ -1641,6 +2547,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prodash" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3236ce1618b6da4c7b618e0143c4d5b5dc190f75f81c49f248221382f7e9e9ae" +dependencies = [ + "bytesize", + "human_format", +] + [[package]] name = "quick-error" version = "1.2.3" @@ -1739,13 +2655,35 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rayon" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + [[package]] name = "redox_syscall" version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1754,7 +2692,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1779,6 +2717,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" + [[package]] name = "regex-syntax" version = "0.7.2" @@ -1877,7 +2821,7 @@ version = "0.37.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno 0.3.1", "io-lifetimes", "libc", @@ -1961,6 +2905,15 @@ version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.21" @@ -1992,7 +2945,7 @@ version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -2092,6 +3045,12 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + [[package]] name = "sharded-slab" version = "0.1.4" @@ -2101,6 +3060,16 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "signal-hook" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732768f1176d21d09e076c23a93123d40bba92d50c4058da34d45c8de8e682b9" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -2309,6 +3278,35 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" +dependencies = [ + "itoa", + "libc", + "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" + +[[package]] +name = "time-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" +dependencies = [ + "time-core", +] + [[package]] name = "tinyvec" version = "1.6.0" @@ -2632,12 +3630,27 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "uluru" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794a32261a1f5eb6a4462c81b59cec87b5c27d5deea7dd1ac8fc781c41d226db" +dependencies = [ + "arrayvec", +] + [[package]] name = "unicode-bidi" version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +[[package]] +name = "unicode-bom" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98e90c70c9f0d4d1ee6d0a7d04aa06cb9bbd53d8cfbdd62a0269a7c2eb640552" + [[package]] name = "unicode-ident" version = "1.0.9" @@ -2650,7 +3663,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c5faade31a542b8b35855fff6e8def199853b2da8da256da52f52f1316ee3137" dependencies = [ - "hashbrown", + "hashbrown 0.12.3", "regex", ] @@ -2737,6 +3750,16 @@ dependencies = [ "libc", ] +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -2882,6 +3905,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/crates/bin/Cargo.toml b/crates/bin/Cargo.toml index b4bf65315..aae1f939c 100644 --- a/crates/bin/Cargo.toml +++ b/crates/bin/Cargo.toml @@ -49,7 +49,9 @@ tracing-subscriber = { version = "0.3.17", features = ["fmt", "json", "ansi"], d embed-resource = "2.1.1" [features] -default = ["static", "rustls", "trust-dns", "fancy-no-backtrace", "zstd-thin"] +default = ["static", "rustls", "trust-dns", "fancy-no-backtrace", "zstd-thin", "git"] + +git = ["binstalk/git"] mimalloc = ["dep:mimalloc"] @@ -74,3 +76,6 @@ log_max_level_debug = ["log/max_level_debug", "tracing/max_level_debug", "log_re log_release_max_level_info = ["log/release_max_level_info", "tracing/release_max_level_info"] log_release_max_level_debug = ["log/release_max_level_debug", "tracing/release_max_level_debug"] + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] diff --git a/crates/bin/src/args.rs b/crates/bin/src/args.rs index 814d2705e..f604b1a81 100644 --- a/crates/bin/src/args.rs +++ b/crates/bin/src/args.rs @@ -38,7 +38,7 @@ pub struct Args { /// install. The version syntax is as with the --version option. /// /// When multiple names are provided, the --version option and override option - /// `manifest_path` is unavailable due to ambiguity. + /// `--manifest-path` and `--git` is unavailable due to ambiguity. /// /// If duplicate names are provided, the last one (and their version requirement) /// is kept. @@ -88,9 +88,21 @@ pub struct Args { /// This skips searching crates.io for a manifest and uses the specified path directly, useful /// for debugging and when adding Binstall support. This may be either the path to the folder /// containing a Cargo.toml file, or the Cargo.toml file itself. + /// + /// This option cannot be used with `--git`. #[clap(help_heading = "Overrides", long)] pub manifest_path: Option, + #[cfg(feature = "git")] + /// Override how to fetch Cargo.toml package manifest. + /// + /// This skip searching crates.io and instead clone the repository specified and + /// runs as if `--manifest-path $cloned_repo` is passed to binstall. + /// + /// This option cannot be used with `--manifest-path`. + #[clap(help_heading = "Overrides", long)] + pub git: Option, + /// Override Cargo.toml package manifest bin-dir. #[clap(help_heading = "Overrides", long)] pub bin_dir: Option, @@ -391,13 +403,36 @@ pub fn parse() -> Args { // Ensure no conflict let mut command = Args::command(); + #[cfg(feature = "git")] + if opts.manifest_path.is_some() && opts.git.is_some() { + command + .error( + ErrorKind::ArgumentConflict, + format_args!( + r#"Multiple override options for Cargo.toml fetching. +You cannot use --manifest-path and --git. Do one or the other."# + ), + ) + .exit(); + } + if opts.crate_names.len() > 1 { let option = if opts.version_req.is_some() { "version" } else if opts.manifest_path.is_some() { "manifest-path" } else { - "" + #[cfg(not(feature = "git"))] + { + "" + } + + #[cfg(feature = "git")] + if opts.git.is_some() { + "git" + } else { + "" + } }; if !option.is_empty() { diff --git a/crates/bin/src/entry.rs b/crates/bin/src/entry.rs index 5818ae3cb..3b7b27369 100644 --- a/crates/bin/src/entry.rs +++ b/crates/bin/src/entry.rs @@ -19,7 +19,7 @@ use binstalk::{ ops::{ self, resolve::{CrateName, Resolution, ResolutionFetch, VersionReqExt}, - Resolver, + CargoTomlFetchOverride, Options, Resolver, }, }; use binstalk_manifests::cargo_toml_binstall::PkgOverride; @@ -95,7 +95,7 @@ pub fn install_crates( let gh_api_client = GhApiClient::new(client.clone(), args.github_token); // Create binstall_opts - let binstall_opts = Arc::new(ops::Options { + let binstall_opts = Arc::new(Options { no_symlinks: args.no_symlinks, dry_run: args.dry_run, force: args.force, @@ -104,7 +104,16 @@ pub fn install_crates( no_track: args.no_track, version_req: args.version_req, - manifest_path: args.manifest_path, + #[cfg(feature = "git")] + cargo_toml_fetch_override: match (args.manifest_path, args.git) { + (Some(manifest_path), None) => Some(CargoTomlFetchOverride::Path(manifest_path)), + (None, Some(git_url)) => Some(CargoTomlFetchOverride::Git(git_url)), + (None, None) => None, + _ => unreachable!("manifest_path and git cannot be specified at the same time"), + }, + + #[cfg(not(feature = "git"))] + cargo_toml_fetch_override: args.manifest_path.map(CargoTomlFetchOverride::Path), cli_overrides, desired_targets, @@ -326,7 +335,7 @@ fn do_install_fetches( resolution_fetchs: Vec>, // Take manifests by value to drop the `FileLock`. manifests: Option, - binstall_opts: &ops::Options, + binstall_opts: &Options, dry_run: bool, temp_dir: tempfile::TempDir, no_cleanup: bool, diff --git a/crates/bin/src/lib.rs b/crates/bin/src/lib.rs index 57299fe95..5e19e4d67 100644 --- a/crates/bin/src/lib.rs +++ b/crates/bin/src/lib.rs @@ -1,3 +1,5 @@ +#![cfg_attr(docsrs, feature(doc_auto_cfg))] + pub mod args; pub mod bin_util; pub mod entry; diff --git a/crates/binstalk/Cargo.toml b/crates/binstalk/Cargo.toml index 30e1d0a47..9ad7deae2 100644 --- a/crates/binstalk/Cargo.toml +++ b/crates/binstalk/Cargo.toml @@ -18,6 +18,7 @@ command-group = { version = "2.1.0", features = ["with-tokio"] } compact_str = { version = "0.7.0", features = ["serde"] } detect-targets = { version = "0.1.7", path = "../detect-targets" } either = "1.8.1" +gix = { version = "0.46.0", features = ["blocking-http-transport-reqwest-rust-tls"], optional = true } home = "0.5.5" itertools = "0.10.5" jobslot = { version = "0.2.11", features = ["tokio"] } @@ -43,7 +44,9 @@ xz2 = "0.1.7" windows = { version = "0.48.0", features = ["Win32_Storage_FileSystem", "Win32_Foundation"] } [features] -default = ["static", "rustls"] +default = ["static", "rustls", "git"] + +git = ["dep:gix"] static = ["binstalk-downloader/static"] pkg-config = ["binstalk-downloader/pkg-config"] @@ -57,3 +60,6 @@ trust-dns = ["binstalk-downloader/trust-dns"] zstd-thin = ["binstalk-downloader/zstd-thin"] cross-lang-fat-lto = ["binstalk-downloader/cross-lang-fat-lto"] + +[package.metadata.docs.rs] +rustdoc-args = ["--cfg", "docsrs"] diff --git a/crates/binstalk/src/errors.rs b/crates/binstalk/src/errors.rs index bc637947b..3f22dc120 100644 --- a/crates/binstalk/src/errors.rs +++ b/crates/binstalk/src/errors.rs @@ -323,6 +323,15 @@ pub enum BinstallError { #[diagnostic(severity(error), code(binstall::target_triple_parse_error))] TargetTripleParseError(#[source] Box), + /// Failed to shallow clone git repository + /// + /// - Code: `binstall::git` + /// - Exit: 98 + #[cfg(feature = "git")] + #[error("Failed to shallow clone git repository: {0}")] + #[diagnostic(severity(error), code(binstall::git))] + GitError(#[from] crate::helpers::git::GitError), + /// A wrapped error providing the context of which crate the error is about. #[error(transparent)] #[diagnostic(transparent)] @@ -358,6 +367,8 @@ impl BinstallError { InvalidPkgFmt(..) => 95, GhApiErr(..) => 96, TargetTripleParseError(..) => 97, + #[cfg(feature = "git")] + GitError(_) => 98, CrateContext(context) => context.err.exit_number(), }; diff --git a/crates/binstalk/src/helpers.rs b/crates/binstalk/src/helpers.rs index 23ed00ef2..66b76f34f 100644 --- a/crates/binstalk/src/helpers.rs +++ b/crates/binstalk/src/helpers.rs @@ -1,4 +1,6 @@ pub mod futures_resolver; +#[cfg(feature = "git")] +pub mod git; pub mod jobserver_client; pub mod remote; pub mod signal; diff --git a/crates/binstalk/src/helpers/git.rs b/crates/binstalk/src/helpers/git.rs new file mode 100644 index 000000000..26bd66ad2 --- /dev/null +++ b/crates/binstalk/src/helpers/git.rs @@ -0,0 +1,80 @@ +use std::{num::NonZeroU32, path::Path, str::FromStr, sync::atomic::AtomicBool}; + +use gix::{clone, create, open, progress::Discard, remote, Url}; +use thiserror::Error as ThisError; +use tracing::debug; + +#[derive(Debug, ThisError)] +#[non_exhaustive] +pub enum GitError { + #[error("Failed to prepare for fetch: {0}")] + PrepareFetchError(#[source] Box), + + #[error("Failed to fetch: {0}")] + FetchError(#[source] Box), + + #[error("Failed to checkout: {0}")] + CheckOutError(#[source] Box), +} + +impl From for GitError { + fn from(e: clone::Error) -> Self { + Self::PrepareFetchError(Box::new(e)) + } +} + +impl From for GitError { + fn from(e: clone::fetch::Error) -> Self { + Self::FetchError(Box::new(e)) + } +} + +impl From for GitError { + fn from(e: clone::checkout::main_worktree::Error) -> Self { + Self::CheckOutError(Box::new(e)) + } +} + +#[derive(Clone, Debug)] +pub struct GitUrl(Url); + +impl FromStr for GitUrl { + type Err = gix::url::parse::Error; + + fn from_str(s: &str) -> Result { + Url::try_from(s).map(Self) + } +} + +#[derive(Debug)] +pub struct Repository(gix::Repository); + +impl Repository { + /// WARNING: This is a blocking operation, if you want to use it in + /// async context then you must wrap the call in [`tokio::task::spawn_blocking`]. + pub fn shallow_clone(url: GitUrl, path: &Path) -> Result { + debug!("Shallow cloning {url:?} to {}", path.display()); + + let mut progress = Discard; + + Ok(Self( + clone::PrepareFetch::new( + url.0, + path, + create::Kind::WithWorktree, + create::Options { + destination_must_be_empty: true, + ..Default::default() + }, + open::Options::isolated(), + )? + .with_shallow(remote::fetch::Shallow::DepthAtRemote( + NonZeroU32::new(1).unwrap(), + )) + .fetch_then_checkout(&mut progress, &AtomicBool::new(false))? + .0 + .main_worktree(&mut progress, &AtomicBool::new(false))? + .0, + )) + } +} diff --git a/crates/binstalk/src/lib.rs b/crates/binstalk/src/lib.rs index b4c67f0b2..a32de76f1 100644 --- a/crates/binstalk/src/lib.rs +++ b/crates/binstalk/src/lib.rs @@ -1,3 +1,5 @@ +#![cfg_attr(docsrs, feature(doc_auto_cfg))] + pub mod bins; pub mod drivers; pub mod errors; diff --git a/crates/binstalk/src/ops.rs b/crates/binstalk/src/ops.rs index 58affa677..382d3fc50 100644 --- a/crates/binstalk/src/ops.rs +++ b/crates/binstalk/src/ops.rs @@ -10,7 +10,9 @@ use tokio::{ use crate::{ fetchers::{Data, Fetcher, TargetData}, - helpers::{gh_api_client::GhApiClient, jobserver_client::LazyJobserverClient, remote::Client}, + helpers::{ + self, gh_api_client::GhApiClient, jobserver_client::LazyJobserverClient, remote::Client, + }, manifests::cargo_toml_binstall::PkgOverride, DesiredTargets, }; @@ -19,6 +21,13 @@ pub mod resolve; pub type Resolver = fn(Client, GhApiClient, Arc, Arc) -> Arc; +#[non_exhaustive] +pub enum CargoTomlFetchOverride { + #[cfg(feature = "git")] + Git(helpers::git::GitUrl), + Path(PathBuf), +} + pub struct Options { pub no_symlinks: bool, pub dry_run: bool, @@ -28,7 +37,7 @@ pub struct Options { pub no_track: bool, pub version_req: Option, - pub manifest_path: Option, + pub cargo_toml_fetch_override: Option, pub cli_overrides: PkgOverride, pub desired_targets: DesiredTargets, diff --git a/crates/binstalk/src/ops/resolve.rs b/crates/binstalk/src/ops/resolve.rs index f38246bfa..3e78a163c 100644 --- a/crates/binstalk/src/ops/resolve.rs +++ b/crates/binstalk/src/ops/resolve.rs @@ -13,17 +13,18 @@ use itertools::Itertools; use leon::Template; use maybe_owned::MaybeOwned; use semver::{Version, VersionReq}; -use tokio::task::block_in_place; +use tempfile::TempDir; +use tokio::task::{block_in_place, spawn_blocking}; use tracing::{debug, info, instrument, warn}; -use super::Options; use crate::{ bins, drivers::fetch_crate_cratesio, errors::{BinstallError, VersionParseError}, fetchers::{Data, Fetcher, TargetData}, - helpers::{download::ExtractedFiles, remote::Client, target_triple::TargetTriple}, + helpers::{self, download::ExtractedFiles, remote::Client, target_triple::TargetTriple}, manifests::cargo_toml_binstall::{Meta, PkgMeta, PkgOverride}, + ops::{CargoTomlFetchOverride, Options}, }; mod crate_name; @@ -359,9 +360,23 @@ impl PackageInfo { version_req: &VersionReq, client: Client, ) -> Result, BinstallError> { + use CargoTomlFetchOverride::*; + // Fetch crate via crates.io, git, or use a local manifest path - let manifest = match opts.manifest_path.as_ref() { - Some(manifest_path) => load_manifest_path(manifest_path)?, + let manifest = match opts.cargo_toml_fetch_override.as_ref() { + Some(Path(manifest_path)) => load_manifest_path(manifest_path)?, + #[cfg(feature = "git")] + Some(Git(git_url)) => { + let git_url = git_url.clone(); + + spawn_blocking(move || { + let dir = TempDir::new()?; + helpers::git::Repository::shallow_clone(git_url, dir.as_ref())?; + + load_manifest_path_blocking(dir.as_ref()) + }) + .await?? + } None => { Box::pin(fetch_crate_cratesio( client, @@ -440,24 +455,33 @@ pub fn load_manifest_path>( ) -> Result, BinstallError> { let manifest_path = manifest_path.as_ref(); - block_in_place(|| { - let manifest_path = if manifest_path.is_dir() { - Cow::Owned(manifest_path.join("Cargo.toml")) - } else if manifest_path.is_file() { - Cow::Borrowed(manifest_path) - } else { - return Err(BinstallError::CargoManifestPath); - }; + block_in_place(|| load_manifest_path_blocking(manifest_path)) +} - debug!( - "Reading manifest at local path: {}", - manifest_path.display() - ); +/// Load binstall metadata from the crate `Cargo.toml` at the provided path +/// +/// WARNING: This is a blocking operation. +pub fn load_manifest_path_blocking>( + manifest_path: P, +) -> Result, BinstallError> { + let manifest_path = manifest_path.as_ref(); + + let manifest_path = if manifest_path.is_dir() { + Cow::Owned(manifest_path.join("Cargo.toml")) + } else if manifest_path.is_file() { + Cow::Borrowed(manifest_path) + } else { + return Err(BinstallError::CargoManifestPath); + }; + + debug!( + "Reading manifest at local path: {}", + manifest_path.display() + ); - // Load and parse manifest (this checks file system for binary output names) - let manifest = Manifest::::from_path_with_metadata(manifest_path)?; + // Load and parse manifest (this checks file system for binary output names) + let manifest = Manifest::::from_path_with_metadata(manifest_path)?; - // Return metadata - Ok(manifest) - }) + // Return metadata + Ok(manifest) } diff --git a/e2e-tests/git.sh b/e2e-tests/git.sh new file mode 100644 index 000000000..f1b248bfb --- /dev/null +++ b/e2e-tests/git.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +set -euxo pipefail + +unset CARGO_INSTALL_ROOT + +CARGO_HOME="$(mktemp -d 2>/dev/null || mktemp -d -t 'cargo-home')" +export CARGO_HOME +export PATH="$CARGO_HOME/bin:$PATH" + +GIT="$(mktemp -d 2>/dev/null || mktemp -d -t 'git')" +git init "$GIT" +cp manifests/github-test-Cargo.toml "$GIT/Cargo.toml" +( + cd "$GIT" + git config user.email 'test@example.com' + git config user.name 'test' + git add Cargo.toml + git commit -m "Add Cargo.toml" +) + +# Install binaries using `--git` +"./$1" binstall --force --git "file://$GIT" --no-confirm cargo-binstall + +# Test that the installed binaries can be run +cargo binstall --help >/dev/null + +cargo_binstall_version="$(cargo binstall -V)" +echo "$cargo_binstall_version" + +[ "$cargo_binstall_version" = "cargo-binstall 0.12.0" ] diff --git a/justfile b/justfile index 58a05e6ee..4afb56871 100644 --- a/justfile +++ b/justfile @@ -74,8 +74,8 @@ support-pkg-config := if target == target-host { } else { "" } cargo-features := trim_end_match(if override-features != "" { override-features - } else if (cargo-profile / ci-or-no) == "dev/ci" { "rustls,fancy-with-backtrace,zstd-thin,log_max_level_debug" + (if support-pkg-config != "" { ",pkg-config" } else { "" }) + extra-features - } else if (cargo-profile / ci-or-no) == "release/ci" { "static,rustls,trust-dns,fancy-no-backtrace,zstd-thin,log_release_max_level_debug,cross-lang-fat-lto" + extra-features + } else if (cargo-profile / ci-or-no) == "dev/ci" { "git,rustls,fancy-with-backtrace,zstd-thin,log_max_level_debug" + (if support-pkg-config != "" { ",pkg-config" } else { "" }) + extra-features + } else if (cargo-profile / ci-or-no) == "release/ci" { "git,static,rustls,trust-dns,fancy-no-backtrace,zstd-thin,log_release_max_level_debug,cross-lang-fat-lto" + extra-features } else { extra-features }, ",") @@ -184,6 +184,7 @@ check: print-env {{cargo-bin}} check {{cargo-build-args}} cargo-hack hack check --feature-powerset -p leon {{cargo-check-args}} {{cargo-bin}} check -p binstalk-downloader --no-default-features + {{cargo-bin}} check -p cargo-binstall --no-default-features --features rustls {{cargo-check-args}} cargo-hack hack check -p binstalk-downloader \ --feature-powerset \ --include-features default,json,gh-api-client \ @@ -210,6 +211,7 @@ e2e-test-upgrade: (e2e-test "upgrade") e2e-test-self-upgrade-no-symlink: (e2e-test "self-upgrade-no-symlink") e2e-test-uninstall: (e2e-test "uninstall") e2e-test-no-track: (e2e-test "no-track") +e2e-test-git: (e2e-test "git") # WinTLS (Windows in CI) does not have TLS 1.3 support [windows] @@ -218,7 +220,7 @@ e2e-test-tls: (e2e-test "tls" "1.2") [macos] e2e-test-tls: (e2e-test "tls" "1.2") (e2e-test "tls" "1.3") -e2e-tests: e2e-test-live e2e-test-manifest-path e2e-test-other-repos e2e-test-strategies e2e-test-version-syntax e2e-test-upgrade e2e-test-tls e2e-test-self-upgrade-no-symlink e2e-test-uninstall e2e-test-subcrate e2e-test-no-track +e2e-tests: e2e-test-live e2e-test-manifest-path e2e-test-git e2e-test-other-repos e2e-test-strategies e2e-test-version-syntax e2e-test-upgrade e2e-test-tls e2e-test-self-upgrade-no-symlink e2e-test-uninstall e2e-test-subcrate e2e-test-no-track unit-tests: print-env {{cargo-bin}} test {{cargo-build-args}}