From b304de81998ebae035d6092b5394f575f42b6788 Mon Sep 17 00:00:00 2001 From: Alex van de Sandt Date: Wed, 1 Jan 2020 01:45:27 -0500 Subject: [PATCH] Rewrite `which` (#1144) * Detect built-in commands passed as args to `which` This expands the built-in `which` command to detect nushell commands that may have the same name as a binary in the path. * Allow which to interpret multiple arguments Previously, it would discard any argument besides the first. This allows `which` to process multiple arguments. It also makes the output a stream of rows. * Use map to build the output * Add boolean column for builtins * Use macros for entry creation shortcuts * Process command args and use async_stream In order to use `ichwh`, I'll need to use async_stream. But in order to avoid lifetime errors with that, I have to process the command args before using them. I'll admit I don't fully understand what is going on with the `args.process(...)` function, but it works. * Use `ichwh` for path searching This commit transitions from `which` to `ichwh`. The path search is now done asynchronously. * Enable the `--all` flag on `which` * Make `which` respect external commands Escaped commands passed to wich (e.g., `which "^ls"`), are now searched before builtins. * Fix clippy warnings This commit resolves two warnings from clippy, in light of #1142. * Update Cargo.lock to get new `ichwh` version `ichwh@0.2.1` has support for local paths. * Add documentation for command --- Cargo.lock | 425 +++++++++++++++++++++++++++++++---------- Cargo.toml | 2 +- docs/commands/which.md | 72 +++++++ src/commands/which_.rs | 162 +++++++++++----- 4 files changed, 514 insertions(+), 147 deletions(-) create mode 100644 docs/commands/which.md diff --git a/Cargo.lock b/Cargo.lock index 193adb0c86..2023e154db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,9 +35,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9267dff192e68f3399525901e709a48c1d3982c9c072fa32f2127a0cb0babf14" +checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" [[package]] name = "app_dirs" @@ -72,6 +72,42 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" +[[package]] +name = "async-attributes" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efd3d156917d94862e779f356c5acae312b08fd3121e792c857d7928c8088423" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "async-std" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf6039b315300e057d198b9d3ab92ee029e31c759b7f1afae538145e6f18a3e" +dependencies = [ + "async-attributes", + "async-task", + "crossbeam-channel 0.4.0", + "crossbeam-deque", + "crossbeam-utils 0.7.0", + "futures-core", + "futures-io", + "futures-timer 2.0.2", + "kv-log-macro", + "log", + "memchr", + "mio", + "mio-uds", + "num_cpus", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "async-stream" version = "0.1.2" @@ -93,6 +129,15 @@ dependencies = [ "syn", ] +[[package]] +name = "async-task" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d22dc86693d375d2733b536fd8914bea0fa93adf4b1e6bcbd9c7c500cb62d920" +dependencies = [ + "crossbeam-utils 0.7.0", +] + [[package]] name = "atty" version = "0.2.13" @@ -172,7 +217,7 @@ dependencies = [ "num-bigint", "num-integer", "num-traits 0.2.10", - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -182,7 +227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5753e2a71534719bf3f4e57006c3a4f0d2c672a4b676eec84161f763eca87dbf" dependencies = [ "byteorder", - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -222,7 +267,7 @@ dependencies = [ "linked-hash-map 0.5.2", "md5", "rand", - "serde 1.0.103", + "serde 1.0.104", "serde_json", "time", ] @@ -236,7 +281,7 @@ dependencies = [ "lazy_static 1.4.0", "memchr", "regex-automata", - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -293,7 +338,7 @@ dependencies = [ "encoding_rs", "log", "quick-xml", - "serde 1.0.103", + "serde 1.0.104", "zip", ] @@ -321,7 +366,7 @@ checksum = "31850b4a4d6bae316f7a09e691c944c28299298837edc0a03f755618c23cbc01" dependencies = [ "num-integer", "num-traits 0.2.10", - "serde 1.0.103", + "serde 1.0.104", "time", ] @@ -398,7 +443,7 @@ dependencies = [ "lazy_static 1.4.0", "nom 4.2.3", "rust-ini", - "serde 1.0.103", + "serde 1.0.104", "serde-hjson 0.8.2", "serde_json", "toml 0.4.10", @@ -461,6 +506,15 @@ dependencies = [ "crossbeam-utils 0.6.6", ] +[[package]] +name = "crossbeam-channel" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acec9a3b0b3559f15aee4f90746c4e5e293b701c0f7d3925d24e01645267b68c" +dependencies = [ + "crossbeam-utils 0.7.0", +] + [[package]] name = "crossbeam-deque" version = "0.7.2" @@ -487,10 +541,11 @@ dependencies = [ [[package]] name = "crossbeam-queue" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfd6515864a82d2f877b42813d4553292c6659498c9a2aa31bab5a15243c2700" +checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" dependencies = [ + "cfg-if", "crossbeam-utils 0.7.0", ] @@ -623,7 +678,7 @@ dependencies = [ "csv-core", "itoa", "ryu", - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -717,7 +772,7 @@ dependencies = [ "libc", "ord_subset", "rustc-serialize", - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -822,9 +877,9 @@ checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" [[package]] name = "encoding_rs" -version = "0.8.20" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87240518927716f79692c2ed85bfe6e98196d18c6401ec75355760233a7e12e9" +checksum = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28" dependencies = [ "cfg-if", ] @@ -868,7 +923,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beee4bc16478a1b26f2e80ad819a52d24745e292f521a63c16eea5f74b7eb60" dependencies = [ - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -935,12 +990,43 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + [[package]] name = "futures" version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b980f2816d6ee8673b6517b52cb0e808a180efc92e5c19d02cdda79066703ef" +[[package]] +name = "futures" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f16056ecbb57525ff698bb955162d0cd03bee84e6241c27ff75c08d8ca5987" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.1" @@ -948,6 +1034,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcae98ca17d102fd8a3603727b9259fcf7fa4239b603d2142926189bc8999b86" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -972,6 +1059,17 @@ version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b35b6263fb1ef523c3056565fa67b1d16f0a8604ff12b11b08c25f28a734c60a" +[[package]] +name = "futures-executor" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e274736563f686a837a0568b478bdabfeaec2dca794b5649b04e2fe1627c231" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-executor-preview" version = "0.3.0-alpha.19" @@ -983,6 +1081,12 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "futures-io" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e676577d229e70952ab25f3945795ba5b16d63ca794ca9d2c860e5595d20b5ff" + [[package]] name = "futures-io-preview" version = "0.3.0-alpha.19" @@ -1015,6 +1119,12 @@ dependencies = [ "futures-util-preview", ] +[[package]] +name = "futures-sink" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171be33efae63c2d59e6dbba34186fe0d6394fb378069a76dfd80fdcffd43c16" + [[package]] name = "futures-sink-preview" version = "0.3.0-alpha.19" @@ -1037,15 +1147,25 @@ dependencies = [ "pin-utils", ] +[[package]] +name = "futures-timer" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1de7508b218029b0f01662ed8f61b1c964b3ae99d6f25462d0f55a595109df6" + [[package]] name = "futures-util" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0d66274fb76985d3c62c886d1da7ac4c0903a8c9f754e8fe0f35a6a6cc39e76" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-utils", "proc-macro-hack", "proc-macro-nested", @@ -1058,7 +1178,7 @@ version = "0.3.0-alpha.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ce968633c17e5f97936bd2797b6e38fb56cf16a7422319f7ec2e30d3c470e8d" dependencies = [ - "futures", + "futures 0.1.29", "futures-channel-preview", "futures-core-preview", "futures-io-preview", @@ -1081,9 +1201,9 @@ dependencies = [ [[package]] name = "gethostname" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4ab273ca2a31eb6ca40b15837ccf1aa59a43c5db69ac10c542be342fae2e01d" +checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028" dependencies = [ "libc", "winapi 0.3.8", @@ -1182,7 +1302,7 @@ dependencies = [ "lazy_static 1.4.0", "libc", "mach 0.3.2", - "nix 0.16.0", + "nix 0.16.1", "pin-utils", "uom", "winapi 0.3.8", @@ -1280,7 +1400,7 @@ dependencies = [ "hex 0.4.0", "libc", "macaddr", - "nix 0.16.0", + "nix 0.16.1", ] [[package]] @@ -1345,9 +1465,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "307c3c9f937f38e3534b1d6447ecf090cafcc9744e4a6360e8b037b2cf5af120" +checksum = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" dependencies = [ "libc", ] @@ -1384,6 +1504,18 @@ dependencies = [ "quick-error", ] +[[package]] +name = "ichwh" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee706a4af782acda5a05b7641867dd9c93d7f2884f214fbbad009e5752228d1" +dependencies = [ + "async-std", + "cfg-if", + "futures 0.3.1", + "thiserror", +] + [[package]] name = "idna" version = "0.2.0" @@ -1416,7 +1548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" dependencies = [ "autocfg", - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -1430,9 +1562,9 @@ dependencies = [ [[package]] name = "inventory" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4cece20baea71d9f3435e7bbe9adf4765f091c5fe404975f844006964a71299" +checksum = "2bf98296081bd2cb540acc09ef9c97f22b7e487841520350293605db1b2c7a27" dependencies = [ "ctor", "ghost", @@ -1441,9 +1573,9 @@ dependencies = [ [[package]] name = "inventory-impl" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2869bf972e998977b1cb87e60df70341d48e48dca0823f534feb91ea44adaf9" +checksum = "0a8e30575afe28eea36a9a39136b70b2fb6b0dd0a212a5bd1f30a498395c0274" dependencies = [ "proc-macro2", "quote", @@ -1466,7 +1598,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17b77027f12e53ae59a379f7074259d32eb10867e6183388020e922832d9c3fb" dependencies = [ "bytes", - "crossbeam-channel", + "crossbeam-channel 0.3.9", "crossbeam-utils 0.6.6", "curl", "curl-sys", @@ -1537,9 +1669,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c840fdb2167497b0bd0db43d6dfe61e91637fa72f9d061f8bd17ddc44ba6414" +checksum = "367647c532db6f1555d7151e619540ec5f713328235b8c062c6b4f63e84adfe3" dependencies = [ "wasm-bindgen", ] @@ -1554,6 +1686,15 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "kv-log-macro" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c54d9f465d530a752e6ebdc217e081a7a614b48cb200f6f0aee21ba6bc9aabb" +dependencies = [ + "log", +] + [[package]] name = "language-reporting" version = "0.4.0" @@ -1564,7 +1705,7 @@ dependencies = [ "itertools 0.7.11", "log", "render-tree", - "serde 1.0.103", + "serde 1.0.104", "serde_derive", "termcolor", ] @@ -1782,6 +1923,48 @@ dependencies = [ "adler32", ] +[[package]] +name = "mio" +version = "0.6.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f" +dependencies = [ + "cfg-if", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio-uds" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" +dependencies = [ + "iovec", + "libc", + "mio", +] + +[[package]] +name = "miow" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + [[package]] name = "natural" version = "0.3.0" @@ -1797,11 +1980,22 @@ dependencies = [ "bincode", "cfg-if", "log", - "serde 1.0.103", + "serde 1.0.104", "serde_derive", "wasm-bindgen", ] +[[package]] +name = "net2" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" +dependencies = [ + "cfg-if", + "libc", + "winapi 0.3.8", +] + [[package]] name = "nix" version = "0.14.1" @@ -1830,9 +2024,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19a8300bf427d432716764070ff70d5b2b7801c958b9049686e6cbd8b06fad92" +checksum = "dd0eaf8df8bab402257e0a5c17a254e4cc1f72a93588a1ddfb5d356c801aa7cb" dependencies = [ "bitflags", "cc", @@ -1935,7 +2129,7 @@ dependencies = [ "dirs 2.0.2", "dunce", "futures-preview", - "futures-timer", + "futures-timer 1.0.3", "futures-util", "futures_codec", "getset", @@ -1943,6 +2137,7 @@ dependencies = [ "glob", "heim", "hex 0.4.0", + "ichwh", "indexmap", "itertools 0.8.2", "language-reporting", @@ -1986,7 +2181,7 @@ dependencies = [ "roxmltree", "rusqlite", "rustyline", - "serde 1.0.103", + "serde 1.0.104", "serde-hjson 0.9.1", "serde_bytes", "serde_ini", @@ -2008,7 +2203,6 @@ dependencies = [ "umask", "unicode-xid", "url", - "which", ] [[package]] @@ -2016,7 +2210,7 @@ name = "nu-build" version = "0.7.0" dependencies = [ "lazy_static 1.4.0", - "serde 1.0.103", + "serde 1.0.104", "serde_json", "toml 0.5.5", ] @@ -2035,7 +2229,7 @@ dependencies = [ "nu-source", "num-bigint", "num-traits 0.2.10", - "serde 1.0.103", + "serde 1.0.104", "serde_json", "serde_yaml", "subprocess", @@ -2076,7 +2270,7 @@ dependencies = [ "pretty_assertions", "pretty_env_logger", "ptree", - "serde 1.0.103", + "serde 1.0.104", "shellexpand", "termcolor", "unicode-xid", @@ -2093,7 +2287,7 @@ dependencies = [ "nu-source", "nu-value-ext", "num-bigint", - "serde 1.0.103", + "serde 1.0.104", "serde_json", ] @@ -2120,7 +2314,7 @@ dependencies = [ "num-bigint", "num-traits 0.2.10", "query_interface", - "serde 1.0.103", + "serde 1.0.104", "serde_bytes", "serde_json", "serde_yaml", @@ -2140,7 +2334,7 @@ dependencies = [ "nom_locate", "nu-build", "pretty", - "serde 1.0.103", + "serde 1.0.104", "termcolor", ] @@ -2258,7 +2452,7 @@ name = "nu_plugin_ps" version = "0.7.0" dependencies = [ "futures-preview", - "futures-timer", + "futures-timer 1.0.3", "futures-util", "heim", "nu-build", @@ -2347,7 +2541,7 @@ dependencies = [ "autocfg", "num-integer", "num-traits 0.2.10", - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -2548,6 +2742,12 @@ dependencies = [ "ordermap", ] +[[package]] +name = "pin-project-lite" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0af6cbca0e6e3ce8692ee19fb8d734b641899e07b68eb73e9bbbd32f1703991" + [[package]] name = "pin-utils" version = "0.1.0-alpha.4" @@ -2576,7 +2776,7 @@ dependencies = [ "byteorder", "humantime", "line-wrap", - "serde 1.0.103", + "serde 1.0.104", "xml-rs", ] @@ -2693,7 +2893,7 @@ dependencies = [ "directories", "isatty", "petgraph", - "serde 1.0.103", + "serde 1.0.104", "serde-value", "serde_derive", "tint", @@ -2713,9 +2913,9 @@ checksum = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" [[package]] name = "quick-xml" -version = "0.17.1" +version = "0.17.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219717e55033c0c1c2368d6c469baaf10115ffdb54b1e83a8b1e8bfd95cde19" +checksum = "fe1e430bdcf30c9fdc25053b9c459bb1a4672af4617b6c783d7d91dc17c6bbb0" dependencies = [ "encoding_rs", "memchr", @@ -2825,9 +3025,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43739f8831493b276363637423d3622d4bd6394ab6f0a9c4a552e208aeb7fddd" +checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" dependencies = [ "crossbeam-deque", "either", @@ -2836,9 +3036,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8bf17de6f23b05473c437eb958b9c850bfc8af0961fe17b4cc92d5a627b4791" +checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" dependencies = [ "crossbeam-deque", "crossbeam-queue", @@ -2858,9 +3058,9 @@ dependencies = [ [[package]] name = "readkey" -version = "0.1.5" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d98db94bb4f3e926c8d8186547cd9366d958d753aff5801214d93d38214e8f0f" +checksum = "86d401b6d6a1725a59f1b4e813275d289dff3ad09c72b373a10a7a8217ba3146" [[package]] name = "redox_syscall" @@ -3072,9 +3272,9 @@ checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" [[package]] name = "serde" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1217f97ab8e8904b57dd22eb61cde455fa7446a9c1cf43966066da047c1f3702" +checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" dependencies = [ "serde_derive", ] @@ -3112,7 +3312,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a663f873dedc4eac1a559d4c6bc0d0b2c34dc5ac4702e105014b8281489e44f" dependencies = [ "ordered-float", - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -3121,14 +3321,14 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "325a073952621257820e7a3469f55ba4726d8b28657e7e36653d1c36dc2c84ae" dependencies = [ - "serde 1.0.103", + "serde 1.0.104", ] [[package]] name = "serde_derive" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c6faef9a2e64b0064f48570289b4bf8823b7581f1d6157c1b52152306651d0" +checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" dependencies = [ "proc-macro2", "quote", @@ -3142,7 +3342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb236687e2bb073a7521c021949be944641e671b8505a94069ca37b656c81139" dependencies = [ "result", - "serde 1.0.103", + "serde 1.0.104", "void", ] @@ -3155,7 +3355,7 @@ dependencies = [ "indexmap", "itoa", "ryu", - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -3175,7 +3375,7 @@ checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97" dependencies = [ "dtoa", "itoa", - "serde 1.0.103", + "serde 1.0.104", "url", ] @@ -3187,7 +3387,7 @@ checksum = "691b17f19fc1ec9d94ec0b5864859290dff279dbd7b03f017afda54eb36c3c35" dependencies = [ "dtoa", "linked-hash-map 0.5.2", - "serde 1.0.103", + "serde 1.0.104", "yaml-rust", ] @@ -3203,9 +3403,12 @@ dependencies = [ [[package]] name = "shellexpand" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de7a5b5a9142fd278a10e0209b021a1b85849352e6951f4f914735c976737564" +checksum = "3a23aed0018ea07316c7826ade41e551772031cf652805f93ebc922215a44d4a" +dependencies = [ + "dirs 1.0.5", +] [[package]] name = "slab" @@ -3226,9 +3429,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86" +checksum = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4" [[package]] name = "socket2" @@ -3332,7 +3535,7 @@ dependencies = [ "log", "mime", "mime_guess", - "serde 1.0.103", + "serde 1.0.104", "serde_json", "serde_urlencoded", "url", @@ -3379,7 +3582,7 @@ dependencies = [ "onig", "plist", "regex-syntax", - "serde 1.0.103", + "serde 1.0.104", "serde_derive", "serde_json", "walkdir", @@ -3454,6 +3657,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f357d1814b33bc2dc221243f8424104bfe72dbe911d5b71b3816a2dff1c977e" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2e25d25307eb8436894f727aba8f65d07adf02e5b35a13cebed48bd282bfef" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "0.3.6" @@ -3499,7 +3722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5090db468dad16e1a7a54c8c67280c5e4b544f3d3e018f0b913b400261f85926" dependencies = [ "bytes", - "futures", + "futures 0.1.29", "log", ] @@ -3509,7 +3732,7 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" dependencies = [ - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -3518,7 +3741,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01d1404644c8b12b16bfcffa4322403a91a451584daaaa7c28d3152e6cbc98cf" dependencies = [ - "serde 1.0.103", + "serde 1.0.104", ] [[package]] @@ -3551,7 +3774,7 @@ dependencies = [ "erased-serde", "inventory", "lazy_static 1.4.0", - "serde 1.0.103", + "serde 1.0.104", "typetag-impl", ] @@ -3713,9 +3936,9 @@ checksum = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" [[package]] name = "wasm-bindgen" -version = "0.2.55" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ae32af33bacd663a9a28241abecf01f2be64e6a185c6139b04f18b6385c5f2" +checksum = "99de4b68939a880d530aed51289a7c7baee154e3ea8ac234b542c49da7134aaf" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3723,9 +3946,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.55" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1845584bd3593442dc0de6e6d9f84454a59a057722f36f005e44665d6ab19d85" +checksum = "b58e66a093a7b7571cb76409763c495b8741ac4319ac20acc2b798f6766d92ee" dependencies = [ "bumpalo", "lazy_static 1.4.0", @@ -3743,7 +3966,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83420b37346c311b9ed822af41ec2e82839bfe99867ec6c54e2da43b7538771c" dependencies = [ "cfg-if", - "futures", + "futures 0.1.29", "futures-channel-preview", "futures-util-preview", "js-sys", @@ -3754,9 +3977,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.55" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fcc747e6b73c93d22c947a6334644d22cfec5abd8b66238484dc2b0aeb9fe4" +checksum = "a80f89daea7b0a67b11f6e9f911422ed039de9963dce00048a653b63d51194bf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3764,9 +3987,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.55" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dc4b3f2c4078c8c4a5f363b92fcf62604c5913cbd16c6ff5aaf0f74ec03f570" +checksum = "4f9dbc3734ad6cff6b76b75b7df98c06982becd0055f651465a08f769bca5c61" dependencies = [ "proc-macro2", "quote", @@ -3777,15 +4000,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.55" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca0b78d6d3be8589b95d1d49cdc0794728ca734adf36d7c9f07e6459508bb53d" +checksum = "d907984f8506b3554eab48b8efff723e764ddbf76d4cd4a3fe4196bc00c49a70" [[package]] name = "wasm-bindgen-webidl" -version = "0.2.55" +version = "0.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3126356474ceb717c8fb5549ae387c9fbf4872818454f4d87708bee997214bb5" +checksum = "f85a3825a459cf6a929d03bacb54dca37a614d43032ad1343ef2d4822972947d" dependencies = [ "anyhow", "heck", @@ -3799,9 +4022,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.32" +version = "0.3.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98405c0a2e722ed3db341b4c5b70eb9fe0021621f7350bab76df93b09b649bbf" +checksum = "2fb60433d0dc12c803b9b017b3902d80c9451bab78d27bc3210bf2a7b96593f1" dependencies = [ "anyhow", "js-sys", @@ -3819,16 +4042,6 @@ dependencies = [ "nom 4.2.3", ] -[[package]] -name = "which" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5475d47078209a02e60614f7ba5e645ef3ed60f771920ac1906d7c1cc65024c8" -dependencies = [ - "failure", - "libc", -] - [[package]] name = "widestring" version = "0.4.0" @@ -3888,6 +4101,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "x11" version = "2.18.1" diff --git a/Cargo.toml b/Cargo.toml index e7ed9c5e44..af79cada1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,7 +107,7 @@ subprocess = "0.1.18" pretty-hex = "0.1.1" hex = "0.4" tempfile = "3.1.0" -which = "3.1" +ichwh = "0.2" textwrap = {version = "0.11.0", features = ["term_size"]} shellexpand = "1.0.0" pin-utils = "0.1.0-alpha.4" diff --git a/docs/commands/which.md b/docs/commands/which.md new file mode 100644 index 0000000000..667e9db18c --- /dev/null +++ b/docs/commands/which.md @@ -0,0 +1,72 @@ +# which + +Finds a program file. + +Usage: + > which ...args{flags} + +## Parameters + +- ...args: the names of the commands to find the path to +- --all: list all executables + +## Examples + +`which` finds the location of an executable: + +```shell +/home/bob> which python +━━━━━━━━┯━━━━━━━━━━━━━━━━━┯━━━━━━━━━ + arg │ path │ builtin +────────┼─────────────────┼───────── + python │ /usr/bin/python │ No +━━━━━━━━┷━━━━━━━━━━━━━━━━━┷━━━━━━━━━ +/home/bob> which cargo +━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━ + arg │ path │ builtin +───────┼────────────────────────────┼───────── + cargo │ /home/bob/.cargo/bin/cargo │ No +━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━ +``` + +`which` will identify nushell commands: + +```shell +/home/bob> which ls +━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━ + arg │ path │ builtin +─────┼──────────────────────────┼───────── + ls │ nushell built-in command │ Yes +━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━ +/home/bob> which which +━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━ + arg │ path │ builtin +───────┼──────────────────────────┼───────── + which │ nushell built-in command │ Yes +━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━ +``` + +Passing the `all` flag identifies all instances of a command or binary + +```shell +/home/bob> which ls --all +━━━┯━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━ + # │ arg │ path │ builtin +───┼─────┼──────────────────────────┼───────── + 0 │ ls │ nushell built-in command │ Yes + 1 │ ls │ /usr/bin/ls │ No +━━━┷━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━ +``` + +`which` will also identify local binaries + +```shell +/home/bob> touch foo +/home/bob> chmod +x foo +/home/bob> which ./foo +━━━━━━━┯━━━━━━━━━━━━━━━┯━━━━━━━━━ + arg │ path │ builtin +───────┼───────────────┼───────── + ./foo │ /home/bob/foo │ No +━━━━━━━┷━━━━━━━━━━━━━━━┷━━━━━━━━━ +``` diff --git a/src/commands/which_.rs b/src/commands/which_.rs index 7152e1fc38..2e2773bfd3 100644 --- a/src/commands/which_.rs +++ b/src/commands/which_.rs @@ -1,7 +1,9 @@ use crate::commands::WholeStreamCommand; use crate::prelude::*; +use indexmap::map::IndexMap; use nu_errors::ShellError; -use nu_protocol::{Primitive, Signature, SyntaxShape, UntaggedValue, Value}; +use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value}; +use nu_source::Tagged; pub struct Which; @@ -11,11 +13,12 @@ impl WholeStreamCommand for Which { } fn signature(&self) -> Signature { - Signature::build("which").required( - "name", - SyntaxShape::Any, - "the name of the command to find the path to", - ) + Signature::build("which") + .switch("all", "list all executables") + .rest( + SyntaxShape::String, + "the names of the commands to find the path to", + ) } fn usage(&self) -> &str { @@ -27,51 +30,120 @@ impl WholeStreamCommand for Which { args: CommandArgs, registry: &CommandRegistry, ) -> Result { - which(args, registry) + args.process(registry, which)?.run() } } -pub fn which(args: CommandArgs, registry: &CommandRegistry) -> Result { - let args = args.evaluate_once(registry)?; +/// Shortcuts for creating an entry to the output table +fn entry(arg: impl Into, path: Value, builtin: bool, tag: Tag) -> Value { + let mut map = IndexMap::new(); + map.insert( + "arg".to_string(), + UntaggedValue::Primitive(Primitive::String(arg.into())).into_value(tag.clone()), + ); + map.insert("path".to_string(), path); + map.insert( + "builtin".to_string(), + UntaggedValue::Primitive(Primitive::Boolean(builtin)).into_value(tag.clone()), + ); - let mut which_out = VecDeque::new(); - let tag = args.call_info.name_tag.clone(); + UntaggedValue::row(map).into_value(tag) +} - if let Some(v) = &args.call_info.args.positional { - if !v.is_empty() { - match &v[0] { - Value { - value: UntaggedValue::Primitive(Primitive::String(s)), - tag, - } => { - if let Ok(ok) = which::which(&s) { - which_out.push_back( - UntaggedValue::Primitive(Primitive::Path(ok)).into_value(tag.clone()), - ); - } - } - Value { tag, .. } => { - return Err(ShellError::labeled_error( - "Expected a filename to find", - "needs a filename", - tag, - )); +macro_rules! entry_builtin { + ($arg:expr, $tag:expr) => { + entry( + $arg.clone(), + UntaggedValue::Primitive(Primitive::String("nushell built-in command".to_string())) + .into_value($tag.clone()), + true, + $tag, + ) + }; +} + +macro_rules! entry_path { + ($arg:expr, $path:expr, $tag:expr) => { + entry( + $arg.clone(), + UntaggedValue::Primitive(Primitive::Path($path)).into_value($tag.clone()), + false, + $tag, + ) + }; +} + +#[derive(Deserialize, Debug)] +struct WhichArgs { + bin: Tagged, + all: bool, +} + +fn which( + WhichArgs { bin, all }: WhichArgs, + RunnableContext { commands, .. }: RunnableContext, +) -> Result { + let external = bin.starts_with('^'); + let item = if external { + bin.item[1..].to_string() + } else { + bin.item.clone() + }; + + if all { + let stream = async_stream! { + if external { + if let Ok(path) = ichwh::which(&item).await { + yield ReturnSuccess::value(entry_path!(item, path.into(), bin.tag.clone())); } } - } else { - return Err(ShellError::labeled_error( - "Expected a binary to find", - "needs application name", - tag, - )); - } - } else { - return Err(ShellError::labeled_error( - "Expected a binary to find", - "needs application name", - tag, - )); - } - Ok(which_out.to_output_stream()) + let builtin = commands.has(&item); + if builtin { + yield ReturnSuccess::value(entry_builtin!(item, bin.tag.clone())); + } + + if let Ok(paths) = ichwh::which_all(&item).await { + if !builtin && paths.len() == 0 { + yield Err(ShellError::labeled_error( + "Binary not found for argument, and argument is not a builtin", + "not found", + &bin.tag, + )); + } else { + for path in paths { + yield ReturnSuccess::value(entry_path!(item, path.into(), bin.tag.clone())); + } + } + } else { + yield Err(ShellError::labeled_error( + "Error trying to find binary for argument", + "error", + &bin.tag, + )); + } + }; + + Ok(stream.to_output_stream()) + } else { + let stream = async_stream! { + if external { + if let Ok(path) = ichwh::which(&item).await { + yield ReturnSuccess::value(entry_path!(item, path.into(), bin.tag.clone())); + } + } else if commands.has(&item) { + yield ReturnSuccess::value(entry_builtin!(item, bin.tag.clone())); + } else if let Ok(path) = ichwh::which(&item).await { + yield ReturnSuccess::value(entry_path!(item, path.into(), bin.tag.clone())); + } else { + yield Err(ShellError::labeled_error( + "Binary not found for argument, and argument is not a builtin", + "not found", + &bin.tag, + )); + } + }; + + Ok(stream.to_output_stream()) + } }