diff --git a/Cargo.lock b/Cargo.lock index 65f6c957af..486e4ac75a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,9 +82,9 @@ dependencies = [ [[package]] name = "allocator-api2" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45862d1c77f2228b9e10bc609d5bc203d86ebc9b87ad8d5d5167a6c9abf739d9" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alphanumeric-sort" @@ -177,9 +177,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" +checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" [[package]] name = "arbitrary" @@ -284,7 +284,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -295,7 +295,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -697,7 +697,7 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -793,7 +793,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -825,9 +825,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a68f1f47cdf0ec8ee4b941b2eee2a80cb796db73118c0dd09ac63fbe405be22" +checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" dependencies = [ "memchr", "regex-automata", @@ -881,9 +881,9 @@ checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "bytemuck" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8334215b81e418a0a7bdb8ef0849474f40bb10c8b71f1c4ed315cff49f32494d" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" dependencies = [ "bytemuck_derive", ] @@ -896,7 +896,7 @@ checksum = "bcfcc3cd946cb52f0bbfdbbcfa2f4e24f75ebb6c0e1002f7c25904fada18b9ec" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -960,9 +960,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.1" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd9de9f2205d5ef3fd67e685b0df337994ddd4495e2a28d185500d0e1edfea47" +checksum = "27f657647bcff5394bf56c7317665bbf790a137a50eaaa5c6bfbb9e27a518f2d" dependencies = [ "jobserver", "libc", @@ -1019,9 +1019,9 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1135,9 +1135,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.21" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" dependencies = [ "clap_builder", "clap_derive", @@ -1145,9 +1145,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.21" +version = "4.5.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" dependencies = [ "anstream", "anstyle", @@ -1165,14 +1165,14 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "clap_lex" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "clipboard-win" @@ -1200,11 +1200,11 @@ checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "colorz" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc2a5df6ee18d52a36920c93a7736761c6fcffa72b9d960fd9133dd8d57c5184" +checksum = "6ceb37c5798821e37369cb546f430f19da2f585e0364c9615ae340a9f2e6067b" dependencies = [ - "supports-color 2.1.0", + "supports-color", ] [[package]] @@ -1282,18 +1282,18 @@ dependencies = [ [[package]] name = "const_format" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2", "quote", @@ -1334,9 +1334,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -1432,7 +1432,7 @@ checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ "bitflags 2.6.0", "crossterm_winapi", - "mio 1.0.2", + "mio 1.0.3", "parking_lot", "rustix", "serde", @@ -1486,7 +1486,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1573,7 +1573,7 @@ checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1584,7 +1584,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1595,7 +1595,7 @@ checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1662,7 +1662,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1742,9 +1742,9 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "ego-tree" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c6ba7d4eec39eaa9ab24d44a0e73a7949a1095a8b3f3abb11eddf27dbb56a53" +checksum = "b2972feb8dffe7bc8c5463b1dacda1b0dfbed3710e50f977d965429692d74cd8" [[package]] name = "either" @@ -1789,7 +1789,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -1843,12 +1843,12 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1894,9 +1894,9 @@ checksum = "95765f67b4b18863968b4a1bd5bb576f732b29a4a28c7cd84c09fa3e2875f33c" [[package]] name = "fastrand" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fd-lock" @@ -2097,7 +2097,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -2253,8 +2253,10 @@ dependencies = [ [[package]] name = "h2" version = "0.4.6" +version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", @@ -2321,9 +2323,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", @@ -2363,18 +2365,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - [[package]] name = "hex" version = "0.4.3" @@ -2410,7 +2400,7 @@ dependencies = [ "markup5ever 0.12.1", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -2424,7 +2414,7 @@ dependencies = [ "markup5ever 0.14.0", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -2441,8 +2431,10 @@ dependencies = [ [[package]] name = "http" version = "1.1.0" +version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -2540,8 +2532,10 @@ dependencies = [ [[package]] name = "hyper" version = "1.5.0" +version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbbff0a806a4728c99295b254c8838933b5b082d75e3cb70c8dab21fdfbcfa9a" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" dependencies = [ "bytes", "futures-channel", @@ -2758,7 +2752,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -2789,7 +2783,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "serde", ] @@ -2834,9 +2828,9 @@ dependencies = [ [[package]] name = "interprocess" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2f4e4a06d42fab3e85ab1b419ad32b09eab58b901d40c57935ff92db3287a13" +checksum = "894148491d817cb36b6f778017b8ac46b17408d522dd90f539d677ea938362eb" dependencies = [ "doctest-file", "libc", @@ -2866,17 +2860,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "is-terminal" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" -dependencies = [ - "hermit-abi 0.4.0", - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "is-wsl" version = "0.4.0" @@ -2943,9 +2926,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "itoap" @@ -2964,10 +2947,11 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -3010,9 +2994,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.162" +version = "0.2.168" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" [[package]] name = "libflate" @@ -3050,9 +3034,9 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -3150,9 +3134,9 @@ checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "litemap" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" [[package]] name = "lock_api" @@ -3182,7 +3166,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.1", + "hashbrown 0.15.2", ] [[package]] @@ -3338,7 +3322,7 @@ dependencies = [ "cfg-if", "miette-derive", "owo-colors", - "supports-color 3.0.1", + "supports-color", "supports-hyperlinks", "supports-unicode", "terminal_size", @@ -3355,7 +3339,7 @@ checksum = "23c9b935fbe1d6cbd1dac857b54a688145e2d93f48db36010514d0f612d0ad67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3412,11 +3396,10 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi 0.3.9", "libc", "log", "wasi", @@ -3671,7 +3654,7 @@ dependencies = [ "percent-encoding", "reedline", "rstest", - "sysinfo 0.32.0", + "sysinfo 0.32.1", "tempfile", "unicode-segmentation", "uuid", @@ -3818,7 +3801,7 @@ dependencies = [ "pretty_assertions", "print-positions", "procfs", - "quick-xml 0.37.0", + "quick-xml 0.37.1", "quickcheck", "quickcheck_macros", "rand", @@ -3835,11 +3818,11 @@ dependencies = [ "serde_urlencoded", "serde_yaml", "sha2", - "sysinfo 0.32.0", + "sysinfo 0.32.1", "tabled", "tempfile", "titlecase", - "toml 0.8.19", + "toml", "trash", "umask", "unicode-segmentation", @@ -3870,7 +3853,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -3988,7 +3971,7 @@ dependencies = [ "nu-protocol", "nu-utils", "serde", - "thiserror 2.0.3", + "thiserror 2.0.6", "typetag", ] @@ -4094,7 +4077,7 @@ dependencies = [ "strum", "strum_macros", "tempfile", - "thiserror 2.0.3", + "thiserror 2.0.6", "typetag", "windows-sys 0.48.0", ] @@ -4123,7 +4106,7 @@ dependencies = [ "nix 0.29.0", "ntapi", "procfs", - "sysinfo 0.32.0", + "sysinfo 0.32.1", "windows 0.56.0", ] @@ -4607,7 +4590,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -4618,9 +4601,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.4.0+3.4.0" +version = "300.4.1+3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a709e02f2b4aca747929cca5ed248880847c650233cf8b8cdc48f40aaf4898a6" +checksum = "faa4eac4138c62414b5622d1b31c5c304f34b406b013c079c2bbc652fdd6678c" dependencies = [ "cc", ] @@ -4749,9 +4732,9 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c5ce1153ab5b689d0c074c4e7fc613e942dfb7dd9eea5ab202d2ad91fe361" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "percent-encoding" @@ -4767,20 +4750,20 @@ checksum = "f658886ed52e196e850cfbbfddab9eaa7f6d90dd0929e264c31e5cec07e09e57" [[package]] name = "pest" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879952a81a83930934cbf1786752d6dedc3b1f29e8f8fb2ad1d0a36f377cf442" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 1.0.69", + "thiserror 2.0.6", "ucd-trie", ] [[package]] name = "pest_derive" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d214365f632b123a47fd913301e14c946c61d1c183ee245fa76eb752e59a02dd" +checksum = "816518421cfc6887a0d62bf441b6ffb4536fcc926395a69e1a85852d4363f57e" dependencies = [ "pest", "pest_generator", @@ -4788,22 +4771,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb55586734301717aea2ac313f50b2eb8f60d2fc3dc01d190eefa2e625f60c4e" +checksum = "7d1396fd3a870fc7838768d171b4616d5c91f6cc25e377b673d714567d99377b" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "pest_meta" -version = "2.7.14" +version = "2.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b75da2a70cf4d9cb76833c990ac9cd3923c9a8905a8929789ce347c84564d03d" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" dependencies = [ "once_cell", "pest", @@ -4870,7 +4853,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -4985,7 +4968,7 @@ dependencies = [ "ethnum", "fast-float", "getrandom", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "itoa", "itoap", "lz4", @@ -5046,7 +5029,7 @@ dependencies = [ "comfy-table", "either", "hashbrown 0.14.5", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "indexmap", "num-traits", "once_cell", @@ -5090,7 +5073,7 @@ checksum = "ea1b431ed816cba1120cff200f06b962748001bbb2e615ce53cfbbdf701cc136" dependencies = [ "ahash 0.8.11", "bitflags 2.6.0", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "num-traits", "once_cell", "polars-arrow", @@ -5123,7 +5106,7 @@ dependencies = [ "fs4", "futures", "glob", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "home", "itoa", "memchr", @@ -5164,7 +5147,7 @@ dependencies = [ "ahash 0.8.11", "chrono", "fallible-streaming-iterator", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "indexmap", "itoa", "num-traits", @@ -5238,7 +5221,7 @@ dependencies = [ "chrono", "chrono-tz 0.8.6", "either", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "hex", "indexmap", "jsonpath_lib_polars_vendor", @@ -5277,7 +5260,7 @@ dependencies = [ "ethnum", "flate2", "futures", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "lz4", "num-traits", "polars-arrow", @@ -5312,7 +5295,7 @@ dependencies = [ "crossbeam-queue", "enum_dispatch", "futures", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "num-traits", "polars-arrow", "polars-compute", @@ -5343,7 +5326,7 @@ dependencies = [ "ciborium", "either", "futures", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "memmap2", "num-traits", "once_cell", @@ -5473,7 +5456,7 @@ dependencies = [ "bytemuck", "bytes", "compact_str 0.8.0", - "hashbrown 0.15.1", + "hashbrown 0.15.2", "indexmap", "libc", "memmap2", @@ -5500,9 +5483,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "powerfmt" @@ -5577,7 +5560,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.22.22", + "toml_edit", ] [[package]] @@ -5605,9 +5588,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.89" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -5729,7 +5712,7 @@ dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -5742,7 +5725,7 @@ dependencies = [ "proc-macro2", "pyo3-build-config", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -5788,9 +5771,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.37.0" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbfb3ddf5364c9cfcd65549a1e7b801d0e8d1b14c1a1590a6408aa93cfbfa84" +checksum = "f22f29bdff3987b4d8632ef95fd6424ec7e4e0a57e2f4fc63e489e75357f6a03" dependencies = [ "memchr", ] @@ -5829,8 +5812,12 @@ dependencies = [ "quinn-udp", "rustc-hash 2.0.0", "rustls 0.23.19", + "rustc-hash 2.0.0", + "rustls", + "rustc-hash 2.1.0", + "rustls", "socket2", - "thiserror 2.0.3", + "thiserror 2.0.6", "tokio", "tracing", ] @@ -5847,9 +5834,13 @@ dependencies = [ "ring", "rustc-hash 2.0.0", "rustls 0.23.19", + "rustc-hash 2.0.0", + "rustls", + "rustc-hash 2.1.0", + "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.3", + "thiserror 2.0.6", "tinyvec", "tracing", "web-time", @@ -5857,9 +5848,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a626c6807713b15cac82a6acaccd6043c9a5408c24baae07611fec3f243da" +checksum = "52cd4b1eff68bf27940dd39811292c49e007f4d0b4c357358dc9b0197be6b527" dependencies = [ "cfg_aliases 0.2.1", "libc", @@ -5996,7 +5987,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76009fbe0614077fc1a2ce255e3a1881a2e3a3527097d5dc6d8212c585e7e38b" dependencies = [ "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -6007,9 +5998,9 @@ checksum = "d3edd4d5d42c92f0a659926464d4cce56b562761267ecf0f469d85b7de384175" [[package]] name = "redox_syscall" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags 2.6.0", ] @@ -6064,7 +6055,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -6173,7 +6164,7 @@ dependencies = [ "chumsky", "memchr", "quoted_printable", - "thiserror 2.0.3", + "thiserror 2.0.6", ] [[package]] @@ -6287,7 +6278,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.87", + "syn 2.0.90", "unicode-ident", ] @@ -6326,7 +6317,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.87", + "syn 2.0.90", "walkdir", ] @@ -6381,9 +6372,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustc_version" @@ -6396,34 +6387,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.40" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.21.12" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring", - "rustls-webpki 0.101.7", - "sct", -] - -[[package]] -name = "rustls" -version = "0.23.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "once_cell", "ring", @@ -6537,9 +6516,9 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.26" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ "windows-sys 0.59.0", ] @@ -6558,11 +6537,10 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scraper" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0e749d29b2064585327af5038a5a8eb73aeebad4a3472e83531a436563f7208" +checksum = "cc3d051b884f40e309de6c149734eab57aa8cc1347992710dc80bcc1c2194c15" dependencies = [ - "ahash 0.8.11", "cssparser", "ego-tree", "html5ever 0.29.0", @@ -6588,7 +6566,7 @@ checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -6676,29 +6654,29 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.215" +version = "1.0.216" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "serde_json" -version = "1.0.132" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "indexmap", "itoa", @@ -6715,7 +6693,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -6774,7 +6752,7 @@ checksum = "5d69265a08751de7844521fd15003ae0a888e035773ba05695c5c759a6f89eef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -6838,7 +6816,7 @@ checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", "mio 0.8.11", - "mio 1.0.2", + "mio 1.0.3", "signal-hook", ] @@ -6957,9 +6935,9 @@ checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -6987,7 +6965,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d904e7009df136af5297832a3ace3370cd14ff1546a232f4f185036c2736fcac" dependencies = [ "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -7102,7 +7080,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -7113,28 +7091,18 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "supports-color" -version = "2.1.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6398cde53adc3c4557306a96ce67b302968513830a77a95b2b17305d9719a89" -dependencies = [ - "is-terminal", - "is_ci", -] - -[[package]] -name = "supports-color" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8775305acf21c96926c900ad056abeef436701108518cf890020387236ac5a77" +checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" dependencies = [ "is_ci", ] [[package]] name = "supports-hyperlinks" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c0a1e5168041f5f3ff68ff7d95dcb9c8749df29f6e7e89ada40dd4c9de404ee" +checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b" [[package]] name = "supports-unicode" @@ -7176,9 +7144,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" dependencies = [ "proc-macro2", "quote", @@ -7202,7 +7170,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -7229,9 +7197,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.32.0" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ae3f4f7d64646c46c4cae4e3f01d1c5d255c7406fdd7c7f999a94e488791" +checksum = "4c33cd241af0f2e9e3b5c32163b873b29956890b5342e6745b917ce9d490f4af" dependencies = [ "core-foundation-sys", "libc", @@ -7361,11 +7329,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.3" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c006c85c7651b3cf2ada4584faa36773bd07bac24acfb39f3c431b36d7e667aa" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" dependencies = [ - "thiserror-impl 2.0.3", + "thiserror-impl 2.0.6", ] [[package]] @@ -7376,18 +7344,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "thiserror-impl" -version = "2.0.3" +version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f077553d607adc1caf65430528a576c757a71ed73944b66ebb58ef2bbd243568" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -7402,9 +7370,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -7425,9 +7393,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -7478,14 +7446,14 @@ dependencies = [ [[package]] name = "tokio" -version = "1.41.1" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.2", + "mio 1.0.3", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -7502,35 +7470,25 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ - "rustls 0.21.12", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" -dependencies = [ - "rustls 0.23.19", + "rustls", "rustls-pki-types", "tokio", ] [[package]] name = "tokio-util" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -7539,18 +7497,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit 0.19.15", -] - [[package]] name = "toml" version = "0.8.19" @@ -7561,7 +7507,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.22", + "toml_edit", ] [[package]] @@ -7573,19 +7519,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.19.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.22" @@ -7596,7 +7529,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.20", + "winnow", ] [[package]] @@ -7607,9 +7540,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -7624,23 +7557,23 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", ] [[package]] name = "trash" -version = "5.2.0" +version = "5.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defe1fdd4232e407b312377885a2c5396764972bddad87baf304753374a1bfc8" +checksum = "a8e5ca62c20366b4685e3e41fba17bc7c9bbdcb82e65a89d6fda2ceea5fffd2f" dependencies = [ "chrono", "libc", @@ -7648,6 +7581,7 @@ dependencies = [ "objc2", "objc2-foundation", "once_cell", + "percent-encoding", "scopeguard", "urlencoding", "windows 0.56.0", @@ -7717,7 +7651,7 @@ checksum = "70b20a22c42c8f1cd23ce5e34f165d4d37038f5b663ad20fb6adbdf029172483" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -7743,9 +7677,9 @@ checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unicode-linebreak" @@ -7817,9 +7751,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3193f92e105038f98ae68af40c008e3c94f2f046926e0f95e6c835dc6459bac8" +checksum = "02d1a66277ed75f640d608235660df48c8e3c19f3b4edb6a263315626cc3c01d" dependencies = [ "base64 0.22.1", "encoding_rs", @@ -7834,9 +7768,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.3" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d157f1b96d14500ffdc1f10ba712e780825526c03d9a49b4d0324b0d9113ada" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -7991,9 +7925,9 @@ dependencies = [ [[package]] name = "uucore_procs" -version = "0.0.27" +version = "0.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d588f57acb2ba416e072a6fa652f2e11cf727267c697d2e2d65175f3b10c41" +checksum = "d91d598cf92275d9373e1eb0b9dcf85b730bde48186ed7db3bde713803090511" dependencies = [ "proc-macro2", "quote", @@ -8002,9 +7936,9 @@ dependencies = [ [[package]] name = "uuhelp_parser" -version = "0.0.27" +version = "0.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96f26868814bf1ca9deec910a08007c93eb1d8e407ce36451999d4c1c1ea6767" +checksum = "86b4d8c991cc252d4b4ea2958d0d842e36af0d1ca7f1fdc4fdce8fd0a2ff6e9c" [[package]] name = "uuid" @@ -8119,9 +8053,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", "once_cell", @@ -8130,36 +8064,36 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.45" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -8167,22 +8101,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-streams" @@ -8287,9 +8221,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -8438,7 +8372,7 @@ checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -8449,7 +8383,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -8460,7 +8394,7 @@ checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -8471,7 +8405,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] @@ -8661,15 +8595,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.20" @@ -8691,11 +8616,11 @@ dependencies = [ [[package]] name = "winresource" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e2aaaf8cfa92078c0c0375423d631f82f2f57979c2884fdd5f604a11e45329" +checksum = "7276691b353ad4547af8c3268488d1311f4be791ffdc0c65b8cfa8f41eed693b" dependencies = [ - "toml 0.7.8", + "toml", "version_check", ] @@ -8805,9 +8730,9 @@ checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "yoke" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -8817,13 +8742,13 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "synstructure", ] @@ -8845,27 +8770,27 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "zerofrom" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", "synstructure", ] @@ -8894,14 +8819,14 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.87", + "syn 2.0.90", ] [[package]] name = "zip" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc5e4288ea4057ae23afc69a4472434a87a2495cafce6632fd1c4ec9f5cf3494" +checksum = "99d52293fc86ea7cf13971b3bb81eb21683636e7ae24c729cdaf1b7c4157a352" dependencies = [ "arbitrary", "crc32fast", @@ -8910,7 +8835,7 @@ dependencies = [ "flate2", "indexmap", "memchr", - "thiserror 1.0.69", + "thiserror 2.0.6", "zopfli", ] diff --git a/crates/nu-cli/src/completions/completion_common.rs b/crates/nu-cli/src/completions/completion_common.rs index d96ca365eb..4b5ef857e1 100644 --- a/crates/nu-cli/src/completions/completion_common.rs +++ b/crates/nu-cli/src/completions/completion_common.rs @@ -174,14 +174,6 @@ pub fn complete_item( ) -> Vec { let cleaned_partial = surround_remove(partial); let isdir = cleaned_partial.ends_with(is_separator); - #[cfg(windows)] - let cleaned_partial = if let Some(absolute_partial) = - stack.pwd_per_drive.expand_pwd(Path::new(&cleaned_partial)) - { - absolute_partial.display().to_string() - } else { - cleaned_partial - }; let expanded_partial = expand_ndots(Path::new(&cleaned_partial)); let should_collapse_dots = expanded_partial != Path::new(&cleaned_partial); let mut partial = expanded_partial.to_string_lossy().to_string(); diff --git a/crates/nu-cli/src/repl.rs b/crates/nu-cli/src/repl.rs index 0476435aee..4bd86ddbf9 100644 --- a/crates/nu-cli/src/repl.rs +++ b/crates/nu-cli/src/repl.rs @@ -832,12 +832,6 @@ fn do_auto_cd( engine_state: &mut EngineState, span: Span, ) { - #[cfg(windows)] - let path = if let Some(abs_path) = stack.pwd_per_drive.expand_pwd(path.as_path()) { - abs_path - } else { - path - }; let path = { if !path.exists() { report_shell_error( diff --git a/crates/nu-cmd-extra/src/extra/filters/each_while.rs b/crates/nu-cmd-extra/src/extra/filters/each_while.rs index 67f0cc9482..cc5c066185 100644 --- a/crates/nu-cmd-extra/src/extra/filters/each_while.rs +++ b/crates/nu-cmd-extra/src/extra/filters/each_while.rs @@ -25,7 +25,7 @@ impl Command for EachWhile { )]) .required( "closure", - SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), + SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), "the closure to run", ) .category(Category::Filters) diff --git a/crates/nu-cmd-plugin/src/util.rs b/crates/nu-cmd-plugin/src/util.rs index 80d1a766b4..57de225ace 100644 --- a/crates/nu-cmd-plugin/src/util.rs +++ b/crates/nu-cmd-plugin/src/util.rs @@ -135,18 +135,24 @@ pub(crate) fn get_plugin_dirs( engine_state: &EngineState, stack: &Stack, ) -> impl Iterator { - // Get the NU_PLUGIN_DIRS constant or env var + // Get the NU_PLUGIN_DIRS from the constant and/or env var let working_set = StateWorkingSet::new(engine_state); - let value = working_set + let dirs_from_const = working_set .find_variable(b"$NU_PLUGIN_DIRS") .and_then(|var_id| working_set.get_constant(var_id).ok()) - .or_else(|| stack.get_env_var(engine_state, "NU_PLUGIN_DIRS")) - .cloned(); // TODO: avoid this clone - - // Get all of the strings in the list, if possible - value + .cloned() // TODO: avoid this clone .into_iter() .flat_map(|value| value.into_list().ok()) .flatten() - .flat_map(|list_item| list_item.coerce_into_string().ok()) + .flat_map(|list_item| list_item.coerce_into_string().ok()); + + let dirs_from_env = stack + .get_env_var(engine_state, "NU_PLUGIN_DIRS") + .cloned() // TODO: avoid this clone + .into_iter() + .flat_map(|value| value.into_list().ok()) + .flatten() + .flat_map(|list_item| list_item.coerce_into_string().ok()); + + dirs_from_const.chain(dirs_from_env) } diff --git a/crates/nu-command/src/debug/timeit.rs b/crates/nu-command/src/debug/timeit.rs index 7bb492769c..182cab87d7 100644 --- a/crates/nu-command/src/debug/timeit.rs +++ b/crates/nu-command/src/debug/timeit.rs @@ -1,4 +1,5 @@ -use nu_engine::{command_prelude::*, get_eval_block, get_eval_expression_with_input}; +use nu_engine::{command_prelude::*, ClosureEvalOnce}; +use nu_protocol::engine::Closure; use std::time::Instant; #[derive(Clone)] @@ -10,16 +11,18 @@ impl Command for TimeIt { } fn description(&self) -> &str { - "Time the running time of a block." + "Time how long it takes a closure to run." + } + + fn extra_description(&self) -> &str { + "Any pipeline input given to this command is passed to the closure. Note that streaming inputs may affect timing results, and it is recommended to add a `collect` command before this if the input is a stream. + +This command will bubble up any errors encountered when running the closure. The return pipeline of the closure is collected into a value and then discarded." } fn signature(&self) -> nu_protocol::Signature { Signature::build("timeit") - .required( - "command", - SyntaxShape::OneOf(vec![SyntaxShape::Block, SyntaxShape::Expression]), - "The command or block to run.", - ) + .required("command", SyntaxShape::Closure(None), "The closure to run.") .input_output_types(vec![ (Type::Any, Type::Duration), (Type::Nothing, Type::Duration), @@ -46,51 +49,38 @@ impl Command for TimeIt { // reset outdest, so the command can write to stdout and stderr. let stack = &mut stack.push_redirection(None, None); - let command_to_run = call.positional_nth(stack, 0); + let closure: Closure = call.req(engine_state, stack, 0)?; + let closure = ClosureEvalOnce::new_preserve_out_dest(engine_state, stack, closure); // Get the start time after all other computation has been done. let start_time = Instant::now(); + closure.run_with_input(input)?.into_value(call.head)?; + let time = start_time.elapsed(); - if let Some(command_to_run) = command_to_run { - if let Some(block_id) = command_to_run.as_block() { - let eval_block = get_eval_block(engine_state); - let block = engine_state.get_block(block_id); - eval_block(engine_state, stack, block, input)? - } else { - let eval_expression_with_input = get_eval_expression_with_input(engine_state); - let expression = &command_to_run.clone(); - eval_expression_with_input(engine_state, stack, expression, input)? - } - } else { - PipelineData::empty() - } - .into_value(call.head)?; - - let end_time = Instant::now(); - - let output = Value::duration( - end_time.saturating_duration_since(start_time).as_nanos() as i64, - call.head, - ); - + let output = Value::duration(time.as_nanos() as i64, call.head); Ok(output.into_pipeline_data()) } fn examples(&self) -> Vec { vec![ Example { - description: "Times a command within a closure", + description: "Time a closure containing one command", example: "timeit { sleep 500ms }", result: None, }, Example { - description: "Times a command using an existing input", - example: "http get https://www.nushell.sh/book/ | timeit { split chars }", + description: "Time a closure with an input value", + example: "'A really long string' | timeit { split chars }", result: None, }, Example { - description: "Times a command invocation", - example: "timeit ls -la", + description: "Time a closure with an input stream", + example: "open some_file.txt | collect | timeit { split chars }", + result: None, + }, + Example { + description: "Time a closure containing a pipeline", + example: "timeit { open some_file.txt | split chars }", result: None, }, ] diff --git a/crates/nu-command/src/filesystem/cd.rs b/crates/nu-command/src/filesystem/cd.rs index 3b5aa377fe..2af932bcb4 100644 --- a/crates/nu-command/src/filesystem/cd.rs +++ b/crates/nu-command/src/filesystem/cd.rs @@ -87,7 +87,7 @@ impl Command for Cd { }); } } else { - let path = stack.expand_path_with(path_no_whitespace, &cwd, true); + let path = nu_path::expand_path_with(path_no_whitespace, &cwd, true); if !path.exists() { return Err(ShellError::DirectoryNotFound { dir: path_no_whitespace.to_string(), diff --git a/crates/nu-command/src/filesystem/du.rs b/crates/nu-command/src/filesystem/du.rs index 0981d2c0ee..15dc0d78d6 100644 --- a/crates/nu-command/src/filesystem/du.rs +++ b/crates/nu-command/src/filesystem/du.rs @@ -12,8 +12,8 @@ pub struct Du; #[derive(Deserialize, Clone, Debug)] pub struct DuArgs { path: Option>, - all: bool, deref: bool, + long: bool, exclude: Option>, #[serde(rename = "max-depth")] max_depth: Option>, @@ -49,6 +49,11 @@ impl Command for Du { "Dereference symlinks to their targets for size", Some('r'), ) + .switch( + "long", + "Get underlying directories and files for each entry", + Some('l'), + ) .named( "exclude", SyntaxShape::GlobPattern, @@ -94,8 +99,8 @@ impl Command for Du { }); } } - let all = call.has_flag(engine_state, stack, "all")?; let deref = call.has_flag(engine_state, stack, "deref")?; + let long = call.has_flag(engine_state, stack, "long")?; let exclude = call.get_flag(engine_state, stack, "exclude")?; #[allow(deprecated)] let current_dir = current_dir(engine_state, stack)?; @@ -111,8 +116,8 @@ impl Command for Du { None => { let args = DuArgs { path: None, - all, deref, + long, exclude, max_depth, min_size, @@ -127,8 +132,8 @@ impl Command for Du { for p in paths { let args = DuArgs { path: Some(p), - all, deref, + long, exclude: exclude.clone(), max_depth, min_size, @@ -174,7 +179,6 @@ fn du_for_one_pattern( }) })?; - let include_files = args.all; let mut paths = match args.path { Some(p) => nu_engine::glob_from(&p, current_dir, span, None), // The * pattern should never fail. @@ -188,17 +192,10 @@ fn du_for_one_pattern( None, ), } - .map(|f| f.1)? - .filter(move |p| { - if include_files { - true - } else { - matches!(p, Ok(f) if f.is_dir()) - } - }); + .map(|f| f.1)?; - let all = args.all; let deref = args.deref; + let long = args.long; let max_depth = args.max_depth.map(|f| f.item as u64); let min_size = args.min_size.map(|f| f.item as u64); @@ -207,7 +204,7 @@ fn du_for_one_pattern( min: min_size, deref, exclude, - all, + long, }; let mut output: Vec = vec![]; @@ -216,7 +213,7 @@ fn du_for_one_pattern( Ok(a) => { if a.is_dir() { output.push(DirInfo::new(a, ¶ms, max_depth, span, signals)?.into()); - } else if let Ok(v) = FileInfo::new(a, deref, span) { + } else if let Ok(v) = FileInfo::new(a, deref, span, params.long) { output.push(v.into()); } } diff --git a/crates/nu-command/src/filters/all.rs b/crates/nu-command/src/filters/all.rs index e4ffdf2c87..aa36118273 100644 --- a/crates/nu-command/src/filters/all.rs +++ b/crates/nu-command/src/filters/all.rs @@ -14,7 +14,7 @@ impl Command for All { .input_output_types(vec![(Type::List(Box::new(Type::Any)), Type::Bool)]) .required( "predicate", - SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), + SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), "A closure that must evaluate to a boolean.", ) .category(Category::Filters) diff --git a/crates/nu-command/src/filters/any.rs b/crates/nu-command/src/filters/any.rs index cd8a6b65e4..230a96ebe7 100644 --- a/crates/nu-command/src/filters/any.rs +++ b/crates/nu-command/src/filters/any.rs @@ -14,7 +14,7 @@ impl Command for Any { .input_output_types(vec![(Type::List(Box::new(Type::Any)), Type::Bool)]) .required( "predicate", - SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), + SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), "A closure that must evaluate to a boolean.", ) .category(Category::Filters) diff --git a/crates/nu-command/src/filters/filter.rs b/crates/nu-command/src/filters/filter.rs index 93fe5a6e6d..ea7960c4d3 100644 --- a/crates/nu-command/src/filters/filter.rs +++ b/crates/nu-command/src/filters/filter.rs @@ -30,7 +30,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."# ]) .required( "closure", - SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), + SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), "Predicate closure.", ) .category(Category::Filters) diff --git a/crates/nu-command/src/filters/par_each.rs b/crates/nu-command/src/filters/par_each.rs index fc0da7d3d3..4e4d526657 100644 --- a/crates/nu-command/src/filters/par_each.rs +++ b/crates/nu-command/src/filters/par_each.rs @@ -38,7 +38,7 @@ impl Command for ParEach { ) .required( "closure", - SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), + SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), "The closure to run.", ) .allow_variants_without_examples(true) diff --git a/crates/nu-command/src/filters/reduce.rs b/crates/nu-command/src/filters/reduce.rs index ed3c61ec32..9d17339d0e 100644 --- a/crates/nu-command/src/filters/reduce.rs +++ b/crates/nu-command/src/filters/reduce.rs @@ -24,11 +24,7 @@ impl Command for Reduce { ) .required( "closure", - SyntaxShape::Closure(Some(vec![ - SyntaxShape::Any, - SyntaxShape::Any, - SyntaxShape::Int, - ])), + SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Any])), "Reducing function.", ) .allow_variants_without_examples(true) @@ -88,6 +84,15 @@ impl Command for Reduce { "Concatenate a string with itself, using a range to determine the number of times.", result: Some(Value::test_string("StrStrStr")), }, + Example { + example: r#"[{a: 1} {b: 2} {c: 3}] | reduce {|it| merge $it}"#, + description: "Merge multiple records together, making use of the fact that the accumulated value is also supplied as pipeline input to the closure.", + result: Some(Value::test_record(record!( + "a" => Value::test_int(1), + "b" => Value::test_int(2), + "c" => Value::test_int(3), + ))), + } ] } @@ -135,8 +140,8 @@ mod test { #[test] fn test_examples() { - use crate::test_examples; + use crate::{test_examples_with_commands, Merge}; - test_examples(Reduce {}) + test_examples_with_commands(Reduce {}, &[&Merge]) } } diff --git a/crates/nu-command/src/filters/skip/skip_until.rs b/crates/nu-command/src/filters/skip/skip_until.rs index b73c817e9b..6f9ada280c 100644 --- a/crates/nu-command/src/filters/skip/skip_until.rs +++ b/crates/nu-command/src/filters/skip/skip_until.rs @@ -20,7 +20,7 @@ impl Command for SkipUntil { ]) .required( "predicate", - SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), + SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), "The predicate that skipped element must not match.", ) .category(Category::Filters) diff --git a/crates/nu-command/src/filters/skip/skip_while.rs b/crates/nu-command/src/filters/skip/skip_while.rs index 9423915242..494cf91558 100644 --- a/crates/nu-command/src/filters/skip/skip_while.rs +++ b/crates/nu-command/src/filters/skip/skip_while.rs @@ -20,7 +20,7 @@ impl Command for SkipWhile { ]) .required( "predicate", - SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), + SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), "The predicate that skipped element must match.", ) .category(Category::Filters) diff --git a/crates/nu-command/src/filters/take/take_until.rs b/crates/nu-command/src/filters/take/take_until.rs index e1dcd6ceda..4e8f38a3d2 100644 --- a/crates/nu-command/src/filters/take/take_until.rs +++ b/crates/nu-command/src/filters/take/take_until.rs @@ -17,7 +17,7 @@ impl Command for TakeUntil { )]) .required( "predicate", - SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), + SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), "The predicate that element(s) must not match.", ) .category(Category::Filters) diff --git a/crates/nu-command/src/filters/take/take_while.rs b/crates/nu-command/src/filters/take/take_while.rs index 54e9384cba..c9e218f543 100644 --- a/crates/nu-command/src/filters/take/take_while.rs +++ b/crates/nu-command/src/filters/take/take_while.rs @@ -20,7 +20,7 @@ impl Command for TakeWhile { ]) .required( "predicate", - SyntaxShape::Closure(Some(vec![SyntaxShape::Any, SyntaxShape::Int])), + SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), "The predicate that element(s) must match.", ) .category(Category::Filters) diff --git a/crates/nu-command/src/formats/from/csv.rs b/crates/nu-command/src/formats/from/csv.rs index bde84c2c73..74b9bcd33f 100644 --- a/crates/nu-command/src/formats/from/csv.rs +++ b/crates/nu-command/src/formats/from/csv.rs @@ -204,12 +204,45 @@ fn from_csv( #[cfg(test)] mod test { + use nu_cmd_lang::eval_pipeline_without_terminal_expression; + use super::*; + use crate::{Metadata, MetadataSet}; + #[test] fn test_examples() { use crate::test_examples; test_examples(FromCsv {}) } + + #[test] + fn test_content_type_metadata() { + let mut engine_state = Box::new(EngineState::new()); + let delta = { + let mut working_set = StateWorkingSet::new(&engine_state); + + working_set.add_decl(Box::new(FromCsv {})); + working_set.add_decl(Box::new(Metadata {})); + working_set.add_decl(Box::new(MetadataSet {})); + + working_set.render() + }; + + engine_state + .merge_delta(delta) + .expect("Error merging delta"); + + let cmd = r#""a,b\n1,2" | metadata set --content-type 'text/csv' --datasource-ls | from csv | metadata | $in"#; + let result = eval_pipeline_without_terminal_expression( + cmd, + std::env::temp_dir().as_ref(), + &mut engine_state, + ); + assert_eq!( + Value::test_record(record!("source" => Value::test_string("ls"))), + result.expect("There should be a result") + ) + } } diff --git a/crates/nu-command/src/formats/from/delimited.rs b/crates/nu-command/src/formats/from/delimited.rs index 5dfdd4ad82..865bc79a41 100644 --- a/crates/nu-command/src/formats/from/delimited.rs +++ b/crates/nu-command/src/formats/from/delimited.rs @@ -93,9 +93,10 @@ pub(super) fn from_delimited_data( input: PipelineData, name: Span, ) -> Result { + let metadata = input.metadata().map(|md| md.with_content_type(None)); match input { PipelineData::Empty => Ok(PipelineData::Empty), - PipelineData::Value(value, metadata) => { + PipelineData::Value(value, ..) => { let string = value.into_string()?; let byte_stream = ByteStream::read_string(string, name, Signals::empty()); Ok(PipelineData::ListStream( @@ -109,7 +110,7 @@ pub(super) fn from_delimited_data( dst_span: name, src_span: list_stream.span(), }), - PipelineData::ByteStream(byte_stream, metadata) => Ok(PipelineData::ListStream( + PipelineData::ByteStream(byte_stream, ..) => Ok(PipelineData::ListStream( from_delimited_stream(config, byte_stream, name)?, metadata, )), diff --git a/crates/nu-command/src/formats/from/json.rs b/crates/nu-command/src/formats/from/json.rs index e3de2cbafd..36a05ea4e1 100644 --- a/crates/nu-command/src/formats/from/json.rs +++ b/crates/nu-command/src/formats/from/json.rs @@ -70,23 +70,22 @@ impl Command for FromJson { let span = call.head; let strict = call.has_flag(engine_state, stack, "strict")?; + let metadata = input.metadata().map(|md| md.with_content_type(None)); // TODO: turn this into a structured underline of the nu_json error if call.has_flag(engine_state, stack, "objects")? { // Return a stream of JSON values, one for each non-empty line match input { - PipelineData::Value(Value::String { val, .. }, metadata) => { - Ok(PipelineData::ListStream( - read_json_lines( - Cursor::new(val), - span, - strict, - engine_state.signals().clone(), - ), - metadata, - )) - } - PipelineData::ByteStream(stream, metadata) + PipelineData::Value(Value::String { val, .. }, ..) => Ok(PipelineData::ListStream( + read_json_lines( + Cursor::new(val), + span, + strict, + engine_state.signals().clone(), + ), + metadata, + )), + PipelineData::ByteStream(stream, ..) if stream.type_() != ByteStreamType::Binary => { if let Some(reader) = stream.reader() { @@ -107,7 +106,7 @@ impl Command for FromJson { } } else { // Return a single JSON value - let (string_input, span, metadata) = input.collect_string_strict(span)?; + let (string_input, span, ..) = input.collect_string_strict(span)?; if string_input.is_empty() { return Ok(Value::nothing(span).into_pipeline_data()); @@ -267,6 +266,10 @@ fn convert_string_to_value_strict(string_input: &str, span: Span) -> Result Value::test_string("ls"))), + result.expect("There should be a result") + ) + } } diff --git a/crates/nu-command/src/formats/from/msgpack.rs b/crates/nu-command/src/formats/from/msgpack.rs index a3538ea69f..4fe849b8fe 100644 --- a/crates/nu-command/src/formats/from/msgpack.rs +++ b/crates/nu-command/src/formats/from/msgpack.rs @@ -113,7 +113,8 @@ MessagePack: https://msgpack.org/ objects, signals: engine_state.signals().clone(), }; - match input { + let metadata = input.metadata().map(|md| md.with_content_type(None)); + let out = match input { // Deserialize from a byte buffer PipelineData::Value(Value::Binary { val: bytes, .. }, _) => { read_msgpack(Cursor::new(bytes), opts) @@ -136,7 +137,8 @@ MessagePack: https://msgpack.org/ dst_span: call.head, src_span: input.span().unwrap_or(call.head), }), - } + }; + out.map(|pd| pd.set_metadata(metadata)) } } @@ -510,6 +512,10 @@ fn assert_eof(input: &mut impl io::Read, span: Span) -> Result<(), ShellError> { #[cfg(test)] mod test { + use nu_cmd_lang::eval_pipeline_without_terminal_expression; + + use crate::{Metadata, MetadataSet, ToMsgpack}; + use super::*; #[test] @@ -518,4 +524,34 @@ mod test { test_examples(FromMsgpack {}) } + + #[test] + fn test_content_type_metadata() { + let mut engine_state = Box::new(EngineState::new()); + let delta = { + let mut working_set = StateWorkingSet::new(&engine_state); + + working_set.add_decl(Box::new(ToMsgpack {})); + working_set.add_decl(Box::new(FromMsgpack {})); + working_set.add_decl(Box::new(Metadata {})); + working_set.add_decl(Box::new(MetadataSet {})); + + working_set.render() + }; + + engine_state + .merge_delta(delta) + .expect("Error merging delta"); + + let cmd = r#"{a: 1 b: 2} | to msgpack | metadata set --datasource-ls | from msgpack | metadata | $in"#; + let result = eval_pipeline_without_terminal_expression( + cmd, + std::env::temp_dir().as_ref(), + &mut engine_state, + ); + assert_eq!( + Value::test_record(record!("source" => Value::test_string("ls"))), + result.expect("There should be a result") + ) + } } diff --git a/crates/nu-command/src/formats/from/msgpackz.rs b/crates/nu-command/src/formats/from/msgpackz.rs index 81cc901614..4f31f74ec6 100644 --- a/crates/nu-command/src/formats/from/msgpackz.rs +++ b/crates/nu-command/src/formats/from/msgpackz.rs @@ -43,7 +43,8 @@ impl Command for FromMsgpackz { objects, signals: engine_state.signals().clone(), }; - match input { + let metadata = input.metadata().map(|md| md.with_content_type(None)); + let out = match input { // Deserialize from a byte buffer PipelineData::Value(Value::Binary { val: bytes, .. }, _) => { let reader = brotli::Decompressor::new(Cursor::new(bytes), BUFFER_SIZE); @@ -68,6 +69,7 @@ impl Command for FromMsgpackz { dst_span: call.head, src_span: span, }), - } + }; + out.map(|pd| pd.set_metadata(metadata)) } } diff --git a/crates/nu-command/src/formats/from/nuon.rs b/crates/nu-command/src/formats/from/nuon.rs index 107ee9c3b4..7cb45c5721 100644 --- a/crates/nu-command/src/formats/from/nuon.rs +++ b/crates/nu-command/src/formats/from/nuon.rs @@ -49,7 +49,8 @@ impl Command for FromNuon { let (string_input, _span, metadata) = input.collect_string_strict(head)?; match nuon::from_nuon(&string_input, Some(head)) { - Ok(result) => Ok(result.into_pipeline_data_with_metadata(metadata)), + Ok(result) => Ok(result + .into_pipeline_data_with_metadata(metadata.map(|md| md.with_content_type(None)))), Err(err) => Err(ShellError::GenericError { error: "error when loading nuon text".into(), msg: "could not load nuon text".into(), @@ -63,6 +64,10 @@ impl Command for FromNuon { #[cfg(test)] mod test { + use nu_cmd_lang::eval_pipeline_without_terminal_expression; + + use crate::{Metadata, MetadataSet}; + use super::*; #[test] @@ -71,4 +76,33 @@ mod test { test_examples(FromNuon {}) } + + #[test] + fn test_content_type_metadata() { + let mut engine_state = Box::new(EngineState::new()); + let delta = { + let mut working_set = StateWorkingSet::new(&engine_state); + + working_set.add_decl(Box::new(FromNuon {})); + working_set.add_decl(Box::new(Metadata {})); + working_set.add_decl(Box::new(MetadataSet {})); + + working_set.render() + }; + + engine_state + .merge_delta(delta) + .expect("Error merging delta"); + + let cmd = r#"'[[a, b]; [1, 2]]' | metadata set --content-type 'application/x-nuon' --datasource-ls | from nuon | metadata | $in"#; + let result = eval_pipeline_without_terminal_expression( + cmd, + std::env::temp_dir().as_ref(), + &mut engine_state, + ); + assert_eq!( + Value::test_record(record!("source" => Value::test_string("ls"))), + result.expect("There should be a result") + ) + } } diff --git a/crates/nu-command/src/formats/from/ods.rs b/crates/nu-command/src/formats/from/ods.rs index c6f08f4481..f1f4252f1e 100644 --- a/crates/nu-command/src/formats/from/ods.rs +++ b/crates/nu-command/src/formats/from/ods.rs @@ -46,7 +46,8 @@ impl Command for FromOds { vec![] }; - from_ods(input, head, sel_sheets) + let metadata = input.metadata().map(|md| md.with_content_type(None)); + from_ods(input, head, sel_sheets).map(|pd| pd.set_metadata(metadata)) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/formats/from/toml.rs b/crates/nu-command/src/formats/from/toml.rs index a61ced65a0..8f4242e5db 100644 --- a/crates/nu-command/src/formats/from/toml.rs +++ b/crates/nu-command/src/formats/from/toml.rs @@ -29,7 +29,8 @@ impl Command for FromToml { let span = call.head; let (mut string_input, span, metadata) = input.collect_string_strict(span)?; string_input.push('\n'); - Ok(convert_string_to_value(string_input, span)?.into_pipeline_data_with_metadata(metadata)) + Ok(convert_string_to_value(string_input, span)? + .into_pipeline_data_with_metadata(metadata.map(|md| md.with_content_type(None)))) } fn examples(&self) -> Vec { @@ -144,8 +145,11 @@ pub fn convert_string_to_value(string_input: String, span: Span) -> Result Value::test_string("ls"))), + result.expect("There should be a result") + ) + } } diff --git a/crates/nu-command/src/formats/from/tsv.rs b/crates/nu-command/src/formats/from/tsv.rs index 09bee4803f..2d77342307 100644 --- a/crates/nu-command/src/formats/from/tsv.rs +++ b/crates/nu-command/src/formats/from/tsv.rs @@ -165,6 +165,10 @@ fn from_tsv( #[cfg(test)] mod test { + use nu_cmd_lang::eval_pipeline_without_terminal_expression; + + use crate::{Metadata, MetadataSet}; + use super::*; #[test] @@ -173,4 +177,33 @@ mod test { test_examples(FromTsv {}) } + + #[test] + fn test_content_type_metadata() { + let mut engine_state = Box::new(EngineState::new()); + let delta = { + let mut working_set = StateWorkingSet::new(&engine_state); + + working_set.add_decl(Box::new(FromTsv {})); + working_set.add_decl(Box::new(Metadata {})); + working_set.add_decl(Box::new(MetadataSet {})); + + working_set.render() + }; + + engine_state + .merge_delta(delta) + .expect("Error merging delta"); + + let cmd = r#""a\tb\n1\t2" | metadata set --content-type 'text/tab-separated-values' --datasource-ls | from tsv | metadata | $in"#; + let result = eval_pipeline_without_terminal_expression( + cmd, + std::env::temp_dir().as_ref(), + &mut engine_state, + ); + assert_eq!( + Value::test_record(record!("source" => Value::test_string("ls"))), + result.expect("There should be a result") + ) + } } diff --git a/crates/nu-command/src/formats/from/xlsx.rs b/crates/nu-command/src/formats/from/xlsx.rs index 1e02cf432c..bc486d1f18 100644 --- a/crates/nu-command/src/formats/from/xlsx.rs +++ b/crates/nu-command/src/formats/from/xlsx.rs @@ -47,7 +47,8 @@ impl Command for FromXlsx { vec![] }; - from_xlsx(input, head, sel_sheets) + let metadata = input.metadata().map(|md| md.with_content_type(None)); + from_xlsx(input, head, sel_sheets).map(|pd| pd.set_metadata(metadata)) } fn examples(&self) -> Vec { diff --git a/crates/nu-command/src/formats/from/xml.rs b/crates/nu-command/src/formats/from/xml.rs index 4c0675a109..70c1048972 100644 --- a/crates/nu-command/src/formats/from/xml.rs +++ b/crates/nu-command/src/formats/from/xml.rs @@ -206,7 +206,9 @@ fn from_xml(input: PipelineData, info: &ParsingInfo) -> Result Ok(x.into_pipeline_data_with_metadata(metadata)), + Ok(x) => { + Ok(x.into_pipeline_data_with_metadata(metadata.map(|md| md.with_content_type(None)))) + } Err(err) => Err(process_xml_parse_error(err, span)), } } @@ -322,10 +324,14 @@ fn make_cant_convert_error(help: impl Into, span: Span) -> ShellError { #[cfg(test)] mod tests { + use crate::Metadata; + use crate::MetadataSet; + use super::*; use indexmap::indexmap; use indexmap::IndexMap; + use nu_cmd_lang::eval_pipeline_without_terminal_expression; fn string(input: impl Into) -> Value { Value::test_string(input) @@ -480,4 +486,36 @@ mod tests { test_examples(FromXml {}) } + + #[test] + fn test_content_type_metadata() { + let mut engine_state = Box::new(EngineState::new()); + let delta = { + let mut working_set = StateWorkingSet::new(&engine_state); + + working_set.add_decl(Box::new(FromXml {})); + working_set.add_decl(Box::new(Metadata {})); + working_set.add_decl(Box::new(MetadataSet {})); + + working_set.render() + }; + + engine_state + .merge_delta(delta) + .expect("Error merging delta"); + + let cmd = r#"' + + Event +' | metadata set --content-type 'application/xml' --datasource-ls | from xml | metadata | $in"#; + let result = eval_pipeline_without_terminal_expression( + cmd, + std::env::temp_dir().as_ref(), + &mut engine_state, + ); + assert_eq!( + Value::test_record(record!("source" => Value::test_string("ls"))), + result.expect("There should be a result") + ) + } } diff --git a/crates/nu-command/src/formats/from/yaml.rs b/crates/nu-command/src/formats/from/yaml.rs index 5c463cc2a9..649f7e83ac 100644 --- a/crates/nu-command/src/formats/from/yaml.rs +++ b/crates/nu-command/src/formats/from/yaml.rs @@ -235,14 +235,19 @@ fn from_yaml(input: PipelineData, head: Span) -> Result Ok(x.into_pipeline_data_with_metadata(metadata)), + Ok(x) => { + Ok(x.into_pipeline_data_with_metadata(metadata.map(|md| md.with_content_type(None)))) + } Err(other) => Err(other), } } #[cfg(test)] mod test { + use crate::{Metadata, MetadataSet}; + use super::*; + use nu_cmd_lang::eval_pipeline_without_terminal_expression; use nu_protocol::Config; #[test] @@ -395,4 +400,33 @@ mod test { assert!(result.ok().unwrap() == test_case.expected.ok().unwrap()); } } + + #[test] + fn test_content_type_metadata() { + let mut engine_state = Box::new(EngineState::new()); + let delta = { + let mut working_set = StateWorkingSet::new(&engine_state); + + working_set.add_decl(Box::new(FromYaml {})); + working_set.add_decl(Box::new(Metadata {})); + working_set.add_decl(Box::new(MetadataSet {})); + + working_set.render() + }; + + engine_state + .merge_delta(delta) + .expect("Error merging delta"); + + let cmd = r#""a: 1\nb: 2" | metadata set --content-type 'application/yaml' --datasource-ls | from yaml | metadata | $in"#; + let result = eval_pipeline_without_terminal_expression( + cmd, + std::env::temp_dir().as_ref(), + &mut engine_state, + ); + assert_eq!( + Value::test_record(record!("source" => Value::test_string("ls"))), + result.expect("There should be a result") + ) + } } diff --git a/crates/nu-command/src/help/help_commands.rs b/crates/nu-command/src/help/help_commands.rs index f0f8df9c02..9d3ab9c924 100644 --- a/crates/nu-command/src/help/help_commands.rs +++ b/crates/nu-command/src/help/help_commands.rs @@ -87,21 +87,10 @@ pub fn help_commands( name.push_str(&r.item); } - let output = engine_state - .get_decls_sorted(false) - .into_iter() - .filter_map(|(_, decl_id)| { - let decl = engine_state.get_decl(decl_id); - (decl.name() == name).then_some(decl) - }) - .map(|cmd| get_full_help(cmd, engine_state, stack)) - .collect::>(); - - if !output.is_empty() { - Ok( - Value::string(output.join("======================\n\n"), call.head) - .into_pipeline_data(), - ) + if let Some(decl) = engine_state.find_decl(name.as_bytes(), &[]) { + let cmd = engine_state.get_decl(decl); + let help_text = get_full_help(cmd, engine_state, stack); + Ok(Value::string(help_text, call.head).into_pipeline_data()) } else { Err(ShellError::CommandNotFound { span: Span::merge_many(rest.iter().map(|s| s.span)), diff --git a/crates/nu-command/src/help/help_externs.rs b/crates/nu-command/src/help/help_externs.rs index af07835af4..27775b416e 100644 --- a/crates/nu-command/src/help/help_externs.rs +++ b/crates/nu-command/src/help/help_externs.rs @@ -107,21 +107,10 @@ pub fn help_externs( name.push_str(&r.item); } - let output = engine_state - .get_decls_sorted(false) - .into_iter() - .filter_map(|(_, decl_id)| { - let decl = engine_state.get_decl(decl_id); - (decl.name() == name).then_some(decl) - }) - .map(|cmd| get_full_help(cmd, engine_state, stack)) - .collect::>(); - - if !output.is_empty() { - Ok( - Value::string(output.join("======================\n\n"), call.head) - .into_pipeline_data(), - ) + if let Some(decl) = engine_state.find_decl(name.as_bytes(), &[]) { + let cmd = engine_state.get_decl(decl); + let help_text = get_full_help(cmd, engine_state, stack); + Ok(Value::string(help_text, call.head).into_pipeline_data()) } else { Err(ShellError::CommandNotFound { span: Span::merge_many(rest.iter().map(|s| s.span)), diff --git a/crates/nu-command/src/platform/dir_info.rs b/crates/nu-command/src/platform/dir_info.rs index 10ce4f5420..9b8ea1929e 100644 --- a/crates/nu-command/src/platform/dir_info.rs +++ b/crates/nu-command/src/platform/dir_info.rs @@ -9,7 +9,7 @@ pub struct DirBuilder { pub min: Option, pub deref: bool, pub exclude: Option, - pub all: bool, + pub long: bool, } impl DirBuilder { @@ -18,14 +18,14 @@ impl DirBuilder { min: Option, deref: bool, exclude: Option, - all: bool, + long: bool, ) -> DirBuilder { DirBuilder { tag, min, deref, exclude, - all, + long, } } } @@ -39,6 +39,7 @@ pub struct DirInfo { blocks: u64, path: PathBuf, tag: Span, + long: bool, } #[derive(Debug, Clone)] @@ -47,10 +48,16 @@ pub struct FileInfo { size: u64, blocks: Option, tag: Span, + long: bool, } impl FileInfo { - pub fn new(path: impl Into, deref: bool, tag: Span) -> Result { + pub fn new( + path: impl Into, + deref: bool, + tag: Span, + long: bool, + ) -> Result { let path = path.into(); let m = if deref { std::fs::metadata(&path) @@ -67,6 +74,7 @@ impl FileInfo { blocks: block_size, size: d.len(), tag, + long, }) } Err(e) => Err(e.into()), @@ -92,6 +100,7 @@ impl DirInfo { blocks: 0, tag: params.tag, path, + long: params.long, }; match std::fs::metadata(&s.path) { @@ -154,13 +163,13 @@ impl DirInfo { .as_ref() .map_or(true, |x| !x.matches_path(&f)); if include { - match FileInfo::new(f, params.deref, self.tag) { + match FileInfo::new(f, params.deref, self.tag, self.long) { Ok(file) => { let inc = params.min.map_or(true, |s| file.size >= s); if inc { self.size += file.size; self.blocks += file.blocks.unwrap_or(0); - if params.all { + if params.long { self.files.push(file); } } @@ -197,16 +206,27 @@ impl From for Value { // }) // } - Value::record( - record! { - "path" => Value::string(d.path.display().to_string(), d.tag), - "apparent" => Value::filesize(d.size as i64, d.tag), - "physical" => Value::filesize(d.blocks as i64, d.tag), - "directories" => value_from_vec(d.dirs, d.tag), - "files" => value_from_vec(d.files, d.tag) - }, - d.tag, - ) + if d.long { + Value::record( + record! { + "path" => Value::string(d.path.display().to_string(), d.tag), + "apparent" => Value::filesize(d.size as i64, d.tag), + "physical" => Value::filesize(d.blocks as i64, d.tag), + "directories" => value_from_vec(d.dirs, d.tag), + "files" => value_from_vec(d.files, d.tag) + }, + d.tag, + ) + } else { + Value::record( + record! { + "path" => Value::string(d.path.display().to_string(), d.tag), + "apparent" => Value::filesize(d.size as i64, d.tag), + "physical" => Value::filesize(d.blocks as i64, d.tag), + }, + d.tag, + ) + } } } @@ -215,16 +235,27 @@ impl From for Value { // cols.push("errors".into()); // vals.push(Value::nothing(Span::unknown())); - Value::record( - record! { - "path" => Value::string(f.path.display().to_string(), f.tag), - "apparent" => Value::filesize(f.size as i64, f.tag), - "physical" => Value::filesize(f.blocks.unwrap_or(0) as i64, f.tag), - "directories" => Value::nothing(Span::unknown()), - "files" => Value::nothing(Span::unknown()), - }, - f.tag, - ) + if f.long { + Value::record( + record! { + "path" => Value::string(f.path.display().to_string(), f.tag), + "apparent" => Value::filesize(f.size as i64, f.tag), + "physical" => Value::filesize(f.blocks.unwrap_or(0) as i64, f.tag), + "directories" => Value::nothing(Span::unknown()), + "files" => Value::nothing(Span::unknown()), + }, + f.tag, + ) + } else { + Value::record( + record! { + "path" => Value::string(f.path.display().to_string(), f.tag), + "apparent" => Value::filesize(f.size as i64, f.tag), + "physical" => Value::filesize(f.blocks.unwrap_or(0) as i64, f.tag), + }, + f.tag, + ) + } } } diff --git a/crates/nu-command/src/viewers/table.rs b/crates/nu-command/src/viewers/table.rs index 1768590b65..da57198efb 100644 --- a/crates/nu-command/src/viewers/table.rs +++ b/crates/nu-command/src/viewers/table.rs @@ -125,6 +125,7 @@ impl Command for Table { let val = Value::list(supported_table_modes(), Span::test_data()); return Ok(val.into_pipeline_data()); } + #[cfg(feature = "os")] let cwd = engine_state.cwd(Some(stack))?; let cfg = parse_table_config(call, engine_state, stack)?; let input = CmdInput::new(engine_state, stack, call, input); @@ -135,7 +136,12 @@ impl Command for Table { let _ = nu_utils::enable_vt_processing(); } - handle_table_command(input, cfg, cwd) + handle_table_command( + input, + cfg, + #[cfg(feature = "os")] + cwd, + ) } fn examples(&self) -> Vec { @@ -367,7 +373,7 @@ impl<'a> CmdInput<'a> { fn handle_table_command( mut input: CmdInput<'_>, cfg: TableConfig, - cwd: nu_path::PathBuf, + #[cfg(feature = "os")] cwd: nu_path::PathBuf, ) -> Result { let span = input.data.span().unwrap_or(input.call.head); match input.data { @@ -390,11 +396,25 @@ fn handle_table_command( let stream = ListStream::new(vals.into_iter(), span, signals); input.data = PipelineData::Empty; - handle_row_stream(input, cfg, stream, metadata, cwd) + handle_row_stream( + input, + cfg, + stream, + metadata, + #[cfg(feature = "os")] + cwd, + ) } PipelineData::ListStream(stream, metadata) => { input.data = PipelineData::Empty; - handle_row_stream(input, cfg, stream, metadata, cwd) + handle_row_stream( + input, + cfg, + stream, + metadata, + #[cfg(feature = "os")] + cwd, + ) } PipelineData::Value(Value::Record { val, .. }, ..) => { input.data = PipelineData::Empty; @@ -414,7 +434,14 @@ fn handle_table_command( let stream = ListStream::new(val.into_range_iter(span, Signals::empty()), span, signals); input.data = PipelineData::Empty; - handle_row_stream(input, cfg, stream, metadata, cwd) + handle_row_stream( + input, + cfg, + stream, + metadata, + #[cfg(feature = "os")] + cwd, + ) } x => Ok(x), } @@ -606,7 +633,7 @@ fn handle_row_stream( cfg: TableConfig, stream: ListStream, metadata: Option, - cwd: nu_path::PathBuf, + #[cfg(feature = "os")] cwd: nu_path::PathBuf, ) -> Result { let stream = match metadata.as_ref() { // First, `ls` sources: @@ -636,9 +663,14 @@ fn handle_row_stream( if let Some(value) = record.to_mut().get_mut("name") { let span = value.span(); if let Value::String { val, .. } = value { - if let Some(val) = - render_path_name(val, &config, &ls_colors, cwd.clone(), span) - { + if let Some(val) = render_path_name( + val, + &config, + &ls_colors, + #[cfg(feature = "os")] + cwd.clone(), + span, + ) { *value = val; } } @@ -1031,14 +1063,18 @@ fn render_path_name( path: &str, config: &Config, ls_colors: &LsColors, - cwd: nu_path::PathBuf, + #[cfg(feature = "os")] cwd: nu_path::PathBuf, span: Span, ) -> Option { if !config.ls.use_ls_colors { return None; } + #[cfg(feature = "os")] let fullpath = cwd.join(path); + #[cfg(not(feature = "os"))] + let fullpath = path; + let stripped_path = nu_utils::strip_ansi_unlikely(path); let metadata = std::fs::symlink_metadata(fullpath); let has_metadata = metadata.is_ok(); diff --git a/crates/nu-command/tests/commands/debug/timeit.rs b/crates/nu-command/tests/commands/debug/timeit.rs index a59f67d26a..509f5bc4e7 100644 --- a/crates/nu-command/tests/commands/debug/timeit.rs +++ b/crates/nu-command/tests/commands/debug/timeit.rs @@ -2,7 +2,7 @@ use nu_test_support::nu; #[test] fn timeit_show_stdout() { - let actual = nu!("let t = timeit nu --testbin cococo abcdefg"); + let actual = nu!("let t = timeit { nu --testbin cococo abcdefg }"); assert_eq!(actual.out, "abcdefg"); } diff --git a/crates/nu-command/tests/commands/du.rs b/crates/nu-command/tests/commands/du.rs index 1e22d54f2f..c88eb546be 100644 --- a/crates/nu-command/tests/commands/du.rs +++ b/crates/nu-command/tests/commands/du.rs @@ -100,3 +100,17 @@ fn du_with_multiple_path() { let actual = nu!(cwd: "tests/fixtures", "du ...[] | length"); assert_eq!(actual.out, "0"); } + +#[test] +fn test_du_output_columns() { + let actual = nu!( + cwd: "tests/fixtures/formats", + "du -m 1 | columns | str join ','" + ); + assert_eq!(actual.out, "path,apparent,physical"); + let actual = nu!( + cwd: "tests/fixtures/formats", + "du -m 1 -l | columns | str join ','" + ); + assert_eq!(actual.out, "path,apparent,physical,directories,files"); +} diff --git a/crates/nu-command/tests/commands/match_.rs b/crates/nu-command/tests/commands/match_.rs index 23e4450d2b..5d41b3291a 100644 --- a/crates/nu-command/tests/commands/match_.rs +++ b/crates/nu-command/tests/commands/match_.rs @@ -140,6 +140,15 @@ fn match_constant_7() { assert_eq!(actual.out, "success"); } +#[test] +fn match_constant_8() { + let actual = + nu!(r#"match "foo" { r#'foo'# => { print "success" }, _ => { print "failure" } }"#); + // Make sure we don't see any of these values in the output + // As we do not auto-print loops anymore + assert_eq!(actual.out, "success"); +} + #[test] fn match_null() { let actual = nu!(r#"match null { null => { print "success"}, _ => { print "failure" }}"#); diff --git a/crates/nu-command/tests/commands/path/mod.rs b/crates/nu-command/tests/commands/path/mod.rs index d14cbde181..ada11426e8 100644 --- a/crates/nu-command/tests/commands/path/mod.rs +++ b/crates/nu-command/tests/commands/path/mod.rs @@ -4,6 +4,7 @@ mod exists; mod expand; mod join; mod parse; +mod self_; mod split; mod type_; diff --git a/crates/nu-command/tests/commands/path/self_.rs b/crates/nu-command/tests/commands/path/self_.rs new file mode 100644 index 0000000000..b0c47195c8 --- /dev/null +++ b/crates/nu-command/tests/commands/path/self_.rs @@ -0,0 +1,64 @@ +use std::path::Path; + +use itertools::Itertools; +use nu_test_support::{fs::Stub, nu, playground::Playground}; + +#[test] +fn self_path_const() { + Playground::setup("path_self_const", |dirs, sandbox| { + sandbox + .within("scripts") + .with_files(&[Stub::FileWithContentToBeTrimmed( + "foo.nu", + r#" + export const paths = { + self: (path self), + dir: (path self .), + sibling: (path self sibling), + parent_dir: (path self ..), + cousin: (path self ../cousin), + } + "#, + )]); + + let actual = nu!(cwd: dirs.test(), r#"use scripts/foo.nu; $foo.paths | values | str join (char nul)"#); + let (self_, dir, sibling, parent_dir, cousin) = actual + .out + .split("\0") + .collect_tuple() + .expect("should have 5 NUL separated paths"); + + let mut pathbuf = dirs.test().to_path_buf(); + + pathbuf.push("scripts"); + assert_eq!(pathbuf, Path::new(dir)); + + pathbuf.push("foo.nu"); + assert_eq!(pathbuf, Path::new(self_)); + + pathbuf.pop(); + pathbuf.push("sibling"); + assert_eq!(pathbuf, Path::new(sibling)); + + pathbuf.pop(); + pathbuf.pop(); + assert_eq!(pathbuf, Path::new(parent_dir)); + + pathbuf.push("cousin"); + assert_eq!(pathbuf, Path::new(cousin)); + }) +} + +#[test] +fn self_path_runtime() { + let actual = nu!("path self"); + assert!(!actual.status.success()); + assert!(actual.err.contains("can only run during parse-time")); +} + +#[test] +fn self_path_repl() { + let actual = nu!("const foo = path self; $foo"); + assert!(!actual.status.success()); + assert!(actual.err.contains("nu::shell::file_not_found")); +} diff --git a/crates/nu-engine/src/closure_eval.rs b/crates/nu-engine/src/closure_eval.rs index b271d90cbe..66c6287cca 100644 --- a/crates/nu-engine/src/closure_eval.rs +++ b/crates/nu-engine/src/closure_eval.rs @@ -88,6 +88,29 @@ impl ClosureEval { } } + pub fn new_preserve_out_dest( + engine_state: &EngineState, + stack: &Stack, + closure: Closure, + ) -> Self { + let engine_state = engine_state.clone(); + let stack = stack.captures_to_stack_preserve_out_dest(closure.captures); + let block = engine_state.get_block(closure.block_id).clone(); + let env_vars = stack.env_vars.clone(); + let env_hidden = stack.env_hidden.clone(); + let eval = get_eval_block_with_early_return(&engine_state); + + Self { + engine_state, + stack, + block, + arg_index: 0, + env_vars, + env_hidden, + eval, + } + } + /// Sets whether to enable debugging when evaluating the closure. /// /// By default, this is controlled by the [`EngineState`] used to create this [`ClosureEval`]. @@ -189,6 +212,22 @@ impl<'a> ClosureEvalOnce<'a> { } } + pub fn new_preserve_out_dest( + engine_state: &'a EngineState, + stack: &Stack, + closure: Closure, + ) -> Self { + let block = engine_state.get_block(closure.block_id); + let eval = get_eval_block_with_early_return(engine_state); + Self { + engine_state, + stack: stack.captures_to_stack_preserve_out_dest(closure.captures), + block, + arg_index: 0, + eval, + } + } + /// Sets whether to enable debugging when evaluating the closure. /// /// By default, this is controlled by the [`EngineState`] used to create this [`ClosureEvalOnce`]. diff --git a/crates/nu-engine/src/compile/call.rs b/crates/nu-engine/src/compile/call.rs index 4112e889b1..e58a7b3efe 100644 --- a/crates/nu-engine/src/compile/call.rs +++ b/crates/nu-engine/src/compile/call.rs @@ -20,12 +20,11 @@ pub(crate) fn compile_call( // Check if this call has --help - if so, just redirect to `help` if call.named_iter().any(|(name, _, _)| name.item == "help") { - return compile_help( - working_set, - builder, - decl.name().into_spanned(call.head), - io_reg, - ); + let name = working_set + .find_decl_name(call.decl_id) // check for name in scope + .and_then(|name| std::str::from_utf8(name).ok()) + .unwrap_or(decl.name()); // fall back to decl's name + return compile_help(working_set, builder, name.into_spanned(call.head), io_reg); } // Try to figure out if this is a keyword call like `if`, and handle those specially diff --git a/crates/nu-engine/src/env.rs b/crates/nu-engine/src/env.rs index dc6c354fce..2ef7ecc1d9 100644 --- a/crates/nu-engine/src/env.rs +++ b/crates/nu-engine/src/env.rs @@ -33,14 +33,20 @@ pub fn convert_env_values(engine_state: &mut EngineState, stack: &Stack) -> Resu let env_vars = engine_state.render_env_vars(); for (name, val) in env_vars { - match get_converted_value(engine_state, stack, name, val, "from_string") { - ConversionResult::Ok(v) => { - let _ = new_scope.insert(name.to_string(), v); - } - ConversionResult::ConversionError(e) => error = error.or(Some(e)), - ConversionResult::CellPathError => { - let _ = new_scope.insert(name.to_string(), val.clone()); + if let Value::String { .. } = val { + // Only run from_string on string values + match get_converted_value(engine_state, stack, name, val, "from_string") { + ConversionResult::Ok(v) => { + let _ = new_scope.insert(name.to_string(), v); + } + ConversionResult::ConversionError(e) => error = error.or(Some(e)), + ConversionResult::CellPathError => { + let _ = new_scope.insert(name.to_string(), val.clone()); + } } + } else { + // Skip values that are already converted (not a string) + let _ = new_scope.insert(name.to_string(), val.clone()); } } @@ -150,9 +156,6 @@ pub fn env_to_strings( } } - #[cfg(windows)] - stack.pwd_per_drive.get_env_vars(&mut env_vars_str); - Ok(env_vars_str) } diff --git a/crates/nu-engine/src/eval.rs b/crates/nu-engine/src/eval.rs index d41e5753bd..0e3917290f 100644 --- a/crates/nu-engine/src/eval.rs +++ b/crates/nu-engine/src/eval.rs @@ -194,11 +194,6 @@ pub fn redirect_env(engine_state: &EngineState, caller_stack: &mut Stack, callee caller_stack.add_env_var(var, value); } - #[cfg(windows)] - { - caller_stack.pwd_per_drive = callee_stack.pwd_per_drive.clone(); - } - // set config to callee config, to capture any updates to that caller_stack.config.clone_from(&callee_stack.config); } diff --git a/crates/nu-engine/src/eval_ir.rs b/crates/nu-engine/src/eval_ir.rs index 7b4c0a28f5..afcb58a90a 100644 --- a/crates/nu-engine/src/eval_ir.rs +++ b/crates/nu-engine/src/eval_ir.rs @@ -1,6 +1,6 @@ use std::{borrow::Cow, fs::File, sync::Arc}; -use nu_path::AbsolutePathBuf; +use nu_path::{expand_path_with, AbsolutePathBuf}; use nu_protocol::{ ast::{Bits, Block, Boolean, CellPath, Comparison, Math, Operator}, debugger::DebugContext, @@ -14,7 +14,7 @@ use nu_protocol::{ }; use nu_utils::IgnoreCaseExt; -use crate::{eval::is_automatic_env_var, eval_block_with_early_return, redirect_env}; +use crate::{eval::is_automatic_env_var, eval_block_with_early_return}; /// Evaluate the compiled representation of a [`Block`]. pub fn eval_ir_block( @@ -870,7 +870,7 @@ fn literal_value( Value::string(path, span) } else { let cwd = ctx.engine_state.cwd(Some(ctx.stack))?; - let path = ctx.stack.expand_path_with(path, cwd, true); + let path = expand_path_with(path, cwd, true); Value::string(path.to_string_lossy(), span) } @@ -890,7 +890,7 @@ fn literal_value( .cwd(Some(ctx.stack)) .map(AbsolutePathBuf::into_std_path_buf) .unwrap_or_default(); - let path = ctx.stack.expand_path_with(path, cwd, true); + let path = expand_path_with(path, cwd, true); Value::string(path.to_string_lossy(), span) } @@ -1405,8 +1405,7 @@ enum RedirectionStream { /// Open a file for redirection fn open_file(ctx: &EvalContext<'_>, path: &Value, append: bool) -> Result, ShellError> { let path_expanded = - ctx.stack - .expand_path_with(path.as_str()?, ctx.engine_state.cwd(Some(ctx.stack))?, true); + expand_path_with(path.as_str()?, ctx.engine_state.cwd(Some(ctx.stack))?, true); let mut options = File::options(); if append { options.append(true); @@ -1486,3 +1485,26 @@ fn eval_iterate( eval_iterate(ctx, dst, stream, end_index) } } + +/// Redirect environment from the callee stack to the caller stack +fn redirect_env(engine_state: &EngineState, caller_stack: &mut Stack, callee_stack: &Stack) { + // TODO: make this more efficient + // Grab all environment variables from the callee + let caller_env_vars = caller_stack.get_env_var_names(engine_state); + + // remove env vars that are present in the caller but not in the callee + // (the callee hid them) + for var in caller_env_vars.iter() { + if !callee_stack.has_env_var(engine_state, var) { + caller_stack.remove_env_var(engine_state, var); + } + } + + // add new env vars from callee to caller + for (var, value) in callee_stack.get_stack_env_vars() { + caller_stack.add_env_var(var, value); + } + + // set config to callee config, to capture any updates to that + caller_stack.config.clone_from(&callee_stack.config); +} diff --git a/crates/nu-engine/src/scope.rs b/crates/nu-engine/src/scope.rs index 45f6f983fc..8774a8996b 100644 --- a/crates/nu-engine/src/scope.rs +++ b/crates/nu-engine/src/scope.rs @@ -56,11 +56,12 @@ impl<'e, 's> ScopeData<'e, 's> { let var_type = Value::string(var.ty.to_string(), span); let is_const = Value::bool(var.const_val.is_some(), span); - let var_value = if let Ok(val) = self.stack.get_var(**var_id, span) { - val - } else { - Value::nothing(span) - }; + let var_value = self + .stack + .get_var(**var_id, span) + .ok() + .or(var.const_val.clone()) + .unwrap_or(Value::nothing(span)); let var_id_val = Value::int(var_id.get() as i64, span); diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 07ab35dc36..d71ef77182 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -1532,7 +1532,9 @@ pub fn parse_int(working_set: &mut StateWorkingSet, span: Span) -> Expression { span: Span, radix: u32, ) -> Expression { - if let Ok(num) = i64::from_str_radix(token, radix) { + // Parse as a u64, then cast to i64, otherwise, for numbers like "0xffffffffffffffef", + // you'll get `Error parsing hex string: number too large to fit in target type`. + if let Ok(num) = u64::from_str_radix(token, radix).map(|val| val as i64) { Expression::new(working_set, Expr::Int(num), span, Type::Int) } else { working_set.error(ParseError::InvalidLiteral( diff --git a/crates/nu-path/src/lib.rs b/crates/nu-path/src/lib.rs index 660fae4b22..cf31a5789f 100644 --- a/crates/nu-path/src/lib.rs +++ b/crates/nu-path/src/lib.rs @@ -6,8 +6,6 @@ pub mod expansions; pub mod form; mod helpers; mod path; -#[cfg(windows)] -pub mod pwd_per_drive; mod tilde; mod trailing_slash; @@ -15,7 +13,5 @@ pub use components::components; pub use expansions::{canonicalize_with, expand_path_with, expand_to_real_path, locate_in_dirs}; pub use helpers::{cache_dir, data_dir, home_dir, nu_config_dir}; pub use path::*; -#[cfg(windows)] -pub use pwd_per_drive::DriveToPwdMap; pub use tilde::expand_tilde; pub use trailing_slash::{has_trailing_slash, strip_trailing_slash}; diff --git a/crates/nu-path/src/pwd_per_drive.rs b/crates/nu-path/src/pwd_per_drive.rs deleted file mode 100644 index d7a395174f..0000000000 --- a/crates/nu-path/src/pwd_per_drive.rs +++ /dev/null @@ -1,331 +0,0 @@ -/// Usage for pwd_per_drive on windows -/// -/// let mut map = DriveToPwdMap::new(); -/// -/// Upon change PWD, call map.set_pwd() with absolute path -/// -/// Call map.expand_pwd() with relative path to get absolution path -/// -/// ``` -/// use std::path::{Path, PathBuf}; -/// use nu_path::DriveToPwdMap; -/// -/// let mut map = DriveToPwdMap::new(); -/// -/// // Set PWD for drive C -/// assert!(map.set_pwd(Path::new(r"C:\Users\Home")).is_ok()); -/// -/// // Expand a relative path -/// let expanded = map.expand_pwd(Path::new("c:test")); -/// assert_eq!(expanded, Some(PathBuf::from(r"C:\Users\Home\test"))); -/// -/// // Will NOT expand an absolute path -/// let expanded = map.expand_pwd(Path::new(r"C:\absolute\path")); -/// assert_eq!(expanded, None); -/// -/// // Expand with no drive letter -/// let expanded = map.expand_pwd(Path::new(r"\no_drive")); -/// assert_eq!(expanded, None); -/// -/// // Expand with no PWD set for the drive -/// let expanded = map.expand_pwd(Path::new("D:test")); -/// assert!(expanded.is_some()); -/// let abs_path = expanded.unwrap().as_path().to_str().expect("OK").to_string(); -/// assert!(abs_path.starts_with(r"D:\")); -/// assert!(abs_path.ends_with(r"\test")); -/// -/// // Get env vars for child process -/// use std::collections::HashMap; -/// let mut env = HashMap::::new(); -/// map.get_env_vars(&mut env); -/// assert_eq!(env.get("=C:").unwrap(), r"C:\Users\Home"); -/// ``` -use std::collections::HashMap; -use std::path::{Path, PathBuf}; - -#[derive(Debug, PartialEq)] -pub enum PathError { - InvalidDriveLetter, - InvalidPath, -} - -/// Helper to check if input path is relative path -/// with drive letter, it can be expanded with PWD-per-drive. -fn need_expand(path: &Path) -> bool { - if let Some(path_str) = path.to_str() { - let chars: Vec = path_str.chars().collect(); - if chars.len() >= 2 { - return chars[1] == ':' && (chars.len() == 2 || (chars[2] != '/' && chars[2] != '\\')); - } - } - false -} - -#[derive(Clone, Debug)] -pub struct DriveToPwdMap { - map: [Option; 26], // Fixed-size array for A-Z -} - -impl Default for DriveToPwdMap { - fn default() -> Self { - Self::new() - } -} - -impl DriveToPwdMap { - pub fn new() -> Self { - Self { - map: Default::default(), - } - } - - pub fn env_var_for_drive(drive_letter: char) -> String { - let drive_letter = drive_letter.to_ascii_uppercase(); - format!("={}:", drive_letter) - } - - /// Collect PWD-per-drive as env vars (for child process) - pub fn get_env_vars(&self, env: &mut HashMap) { - for (drive_index, drive_letter) in ('A'..='Z').enumerate() { - if let Some(pwd) = self.map[drive_index].clone() { - if pwd.len() > 3 { - let env_var_for_drive = Self::env_var_for_drive(drive_letter); - env.insert(env_var_for_drive, pwd); - } - } - } - } - - /// Set the PWD for the drive letter in the absolute path. - /// Return PathError for error. - pub fn set_pwd(&mut self, path: &Path) -> Result<(), PathError> { - if let (Some(drive_letter), Some(path_str)) = - (Self::extract_drive_letter(path), path.to_str()) - { - if drive_letter.is_ascii_alphabetic() { - let drive_letter = drive_letter.to_ascii_uppercase(); - // Make sure saved drive letter is upper case - let mut c = path_str.chars(); - match c.next() { - None => Err(PathError::InvalidDriveLetter), - Some(_) => { - let drive_index = drive_letter as usize - 'A' as usize; - let normalized_pwd = drive_letter.to_string() + c.as_str(); - self.map[drive_index] = Some(normalized_pwd); - Ok(()) - } - } - } else { - Err(PathError::InvalidDriveLetter) - } - } else { - Err(PathError::InvalidPath) - } - } - - /// Get the PWD for drive, if not yet, ask GetFullPathNameW() or omnipath, - /// or else return default r"X:\". - fn get_pwd(&self, drive_letter: char) -> Result { - if drive_letter.is_ascii_alphabetic() { - let drive_letter = drive_letter.to_ascii_uppercase(); - let drive_index = drive_letter as usize - 'A' as usize; - Ok(self.map[drive_index].clone().unwrap_or_else(|| { - if let Some(sys_pwd) = get_full_path_name_w(&format!("{}:", drive_letter)) { - sys_pwd - } else { - format!(r"{}:\", drive_letter) - } - })) - } else { - Err(PathError::InvalidDriveLetter) - } - } - - /// Expand a relative path using the PWD-per-drive, return PathBuf - /// of absolute path. - /// Return None if path is not valid or can't get drive letter. - pub fn expand_pwd(&self, path: &Path) -> Option { - if need_expand(path) { - let path_str = path.to_str()?; - if let Some(drive_letter) = Self::extract_drive_letter(path) { - if let Ok(pwd) = self.get_pwd(drive_letter) { - // Combine current PWD with the relative path - let mut base = PathBuf::from(Self::ensure_trailing_delimiter(&pwd)); - // need_expand() and extract_drive_letter() all ensure path_str.len() >= 2 - base.push(&path_str[2..]); // Join PWD with path parts after "C:" - return Some(base); - } - } - } - None // Invalid path or has no drive letter - } - - /// Helper to extract the drive letter from a path, keep case - /// (e.g., `C:test` -> `C`, `d:\temp` -> `d`) - fn extract_drive_letter(path: &Path) -> Option { - path.to_str() - .and_then(|s| s.chars().next()) - .filter(|c| c.is_ascii_alphabetic()) - } - - /// Ensure a path has a trailing `\\` or '/' - fn ensure_trailing_delimiter(path: &str) -> String { - if !path.ends_with('\\') && !path.ends_with('/') { - format!(r"{}\", path) - } else { - path.to_string() - } - } -} - -fn get_full_path_name_w(path_str: &str) -> Option { - use omnipath::sys_absolute; - if let Ok(path_sys_abs) = sys_absolute(Path::new(path_str)) { - Some(path_sys_abs.to_str()?.to_string()) - } else { - None - } -} - -/// Test for Drive2PWD map -#[cfg(test)] -mod tests { - use super::*; - - /// Test or demo usage of PWD-per-drive - /// In doctest, there's no get_full_path_name_w available so can't foresee - /// possible result, here can have more accurate test assert - #[test] - fn test_usage_for_pwd_per_drive() { - let mut map = DriveToPwdMap::new(); - - // Set PWD for drive E - assert!(map.set_pwd(Path::new(r"E:\Users\Home")).is_ok()); - - // Expand a relative path - let expanded = map.expand_pwd(Path::new("e:test")); - assert_eq!(expanded, Some(PathBuf::from(r"E:\Users\Home\test"))); - - // Will NOT expand an absolute path - let expanded = map.expand_pwd(Path::new(r"E:\absolute\path")); - assert_eq!(expanded, None); - - // Expand with no drive letter - let expanded = map.expand_pwd(Path::new(r"\no_drive")); - assert_eq!(expanded, None); - - // Expand with no PWD set for the drive - let expanded = map.expand_pwd(Path::new("F:test")); - if let Some(sys_abs) = get_full_path_name_w("F:") { - assert_eq!( - expanded, - Some(PathBuf::from(format!( - "{}test", - DriveToPwdMap::ensure_trailing_delimiter(&sys_abs) - ))) - ); - } else { - assert_eq!(expanded, Some(PathBuf::from(r"F:\test"))); - } - } - - #[test] - fn test_get_env_vars() { - let mut map = DriveToPwdMap::new(); - map.set_pwd(Path::new(r"I:\Home")).unwrap(); - map.set_pwd(Path::new(r"j:\User")).unwrap(); - - let mut env = HashMap::::new(); - map.get_env_vars(&mut env); - assert_eq!( - env.get(&DriveToPwdMap::env_var_for_drive('I')).unwrap(), - r"I:\Home" - ); - assert_eq!( - env.get(&DriveToPwdMap::env_var_for_drive('J')).unwrap(), - r"J:\User" - ); - } - - #[test] - fn test_expand_pwd() { - let mut drive_map = DriveToPwdMap::new(); - - // Set PWD for drive 'M:' - assert_eq!(drive_map.set_pwd(Path::new(r"M:\Users")), Ok(())); - // or 'm:' - assert_eq!(drive_map.set_pwd(Path::new(r"m:\Users\Home")), Ok(())); - - // Expand a relative path on "M:" - let expanded = drive_map.expand_pwd(Path::new(r"M:test")); - assert_eq!(expanded, Some(PathBuf::from(r"M:\Users\Home\test"))); - // or on "m:" - let expanded = drive_map.expand_pwd(Path::new(r"m:test")); - assert_eq!(expanded, Some(PathBuf::from(r"M:\Users\Home\test"))); - - // Expand an absolute path - let expanded = drive_map.expand_pwd(Path::new(r"m:\absolute\path")); - assert_eq!(expanded, None); - - // Expand with no drive letter - let expanded = drive_map.expand_pwd(Path::new(r"\no_drive")); - assert_eq!(expanded, None); - - // Expand with no PWD set for the drive - let expanded = drive_map.expand_pwd(Path::new("N:test")); - if let Some(pwd_on_drive) = get_full_path_name_w("N:") { - assert_eq!( - expanded, - Some(PathBuf::from(format!( - r"{}test", - DriveToPwdMap::ensure_trailing_delimiter(&pwd_on_drive) - ))) - ); - } else { - assert_eq!(expanded, Some(PathBuf::from(r"N:\test"))); - } - } - - #[test] - fn test_set_and_get_pwd() { - let mut drive_map = DriveToPwdMap::new(); - - // Set PWD for drive 'O' - assert!(drive_map.set_pwd(Path::new(r"O:\Users")).is_ok()); - // Or for drive 'o' - assert!(drive_map.set_pwd(Path::new(r"o:\Users\Example")).is_ok()); - // Get PWD for drive 'O' - assert_eq!(drive_map.get_pwd('O'), Ok(r"O:\Users\Example".to_string())); - // or 'o' - assert_eq!(drive_map.get_pwd('o'), Ok(r"O:\Users\Example".to_string())); - - // Get PWD for drive P (not set yet, but system might already - // have PWD on this drive) - if let Some(pwd_on_drive) = get_full_path_name_w("P:") { - assert_eq!(drive_map.get_pwd('P'), Ok(pwd_on_drive)); - } else { - assert_eq!(drive_map.get_pwd('P'), Ok(r"P:\".to_string())); - } - } - - #[test] - fn test_set_pwd_invalid_path() { - let mut drive_map = DriveToPwdMap::new(); - - // Invalid path (no drive letter) - let result = drive_map.set_pwd(Path::new(r"\InvalidPath")); - assert!(result.is_err()); - assert_eq!(result.unwrap_err(), PathError::InvalidPath); - } - - #[test] - fn test_get_pwd_invalid_drive() { - let drive_map = DriveToPwdMap::new(); - - // Get PWD for a drive not set (e.g., Z) - assert_eq!(drive_map.get_pwd('Z'), Ok(r"Z:\".to_string())); - - // Invalid drive letter (non-alphabetic) - assert_eq!(drive_map.get_pwd('1'), Err(PathError::InvalidDriveLetter)); - } -} diff --git a/crates/nu-protocol/src/config/error.rs b/crates/nu-protocol/src/config/error.rs index b13dceeb02..c8fbd3f85a 100644 --- a/crates/nu-protocol/src/config/error.rs +++ b/crates/nu-protocol/src/config/error.rs @@ -65,6 +65,8 @@ impl<'a> ConfigErrors<'a> { }); } + // We'll probably need this again in the future so allow dead code for now + #[allow(dead_code)] pub fn deprecated_option(&mut self, path: &ConfigPath, suggestion: &'static str, span: Span) { self.error(ConfigError::Deprecated { path: path.to_string(), diff --git a/crates/nu-protocol/src/config/mod.rs b/crates/nu-protocol/src/config/mod.rs index c66c41e455..85ae9ce1e3 100644 --- a/crates/nu-protocol/src/config/mod.rs +++ b/crates/nu-protocol/src/config/mod.rs @@ -156,10 +156,6 @@ impl UpdateFromValue for Config { "filesize" => self.filesize.update(val, path, errors), "explore" => self.explore.update(val, path, errors), "color_config" => self.color_config.update(val, path, errors), - "use_grid_icons" => { - // TODO: delete it after 0.99 - errors.deprecated_option(path, "use `grid -i`", val.span()); - } "footer_mode" => self.footer_mode.update(val, path, errors), "float_precision" => self.float_precision.update(val, path, errors), "use_ansi_coloring" => self.use_ansi_coloring.update(val, path, errors), diff --git a/crates/nu-protocol/src/engine/pattern_match.rs b/crates/nu-protocol/src/engine/pattern_match.rs index 3284527cc6..32c34d22d3 100644 --- a/crates/nu-protocol/src/engine/pattern_match.rs +++ b/crates/nu-protocol/src/engine/pattern_match.rs @@ -128,7 +128,7 @@ impl Matcher for Pattern { false } } - Expr::String(x) => { + Expr::String(x) | Expr::RawString(x) => { if let Value::String { val, .. } = &value { x == val } else { diff --git a/crates/nu-protocol/src/engine/stack.rs b/crates/nu-protocol/src/engine/stack.rs index 66f59b78f6..ccd38cc5d3 100644 --- a/crates/nu-protocol/src/engine/stack.rs +++ b/crates/nu-protocol/src/engine/stack.rs @@ -9,7 +9,6 @@ use nu_utils::IgnoreCaseExt; use std::{ collections::{HashMap, HashSet}, fs::File, - path::{Path, PathBuf}, sync::Arc, }; @@ -54,8 +53,6 @@ pub struct Stack { /// Locally updated config. Use [`.get_config()`](Self::get_config) to access correctly. pub config: Option>, pub(crate) out_dest: StackOutDest, - #[cfg(windows)] - pub pwd_per_drive: nu_path::DriveToPwdMap, } impl Default for Stack { @@ -85,8 +82,6 @@ impl Stack { parent_deletions: vec![], config: None, out_dest: StackOutDest::new(), - #[cfg(windows)] - pwd_per_drive: nu_path::DriveToPwdMap::new(), } } @@ -107,8 +102,6 @@ impl Stack { parent_deletions: vec![], config: parent.config.clone(), out_dest: parent.out_dest.clone(), - #[cfg(windows)] - pwd_per_drive: parent.pwd_per_drive.clone(), parent_stack: Some(parent), } } @@ -135,10 +128,6 @@ impl Stack { unique_stack.env_hidden = child.env_hidden; unique_stack.active_overlays = child.active_overlays; unique_stack.config = child.config; - #[cfg(windows)] - { - unique_stack.pwd_per_drive = child.pwd_per_drive.clone(); - } unique_stack } @@ -330,8 +319,6 @@ impl Stack { parent_deletions: vec![], config: self.config.clone(), out_dest: self.out_dest.clone(), - #[cfg(windows)] - pwd_per_drive: self.pwd_per_drive.clone(), } } @@ -365,8 +352,6 @@ impl Stack { parent_deletions: vec![], config: self.config.clone(), out_dest: self.out_dest.clone(), - #[cfg(windows)] - pwd_per_drive: self.pwd_per_drive.clone(), } } @@ -776,29 +761,9 @@ impl Stack { let path = nu_path::strip_trailing_slash(path); let value = Value::string(path.to_string_lossy(), Span::unknown()); self.add_env_var("PWD".into(), value); - // Sync with PWD-per-drive - #[cfg(windows)] - { - let _ = self.pwd_per_drive.set_pwd(&path); - } Ok(()) } } - - // Helper stub/proxy for nu_path::expand_path_with::(path, relative_to, expand_tilde) - // Facilitates file system commands to easily gain the ability to expand PWD-per-drive - pub fn expand_path_with(&self, path: P, relative_to: Q, expand_tilde: bool) -> PathBuf - where - P: AsRef, - Q: AsRef, - { - #[cfg(windows)] - if let Some(absolute_path) = self.pwd_per_drive.expand_pwd(path.as_ref()) { - return absolute_path; - } - - nu_path::expand_path_with::(path, relative_to, expand_tilde) - } } #[cfg(test)] diff --git a/crates/nu-protocol/src/engine/state_working_set.rs b/crates/nu-protocol/src/engine/state_working_set.rs index 0d59068dbf..5cbc959f63 100644 --- a/crates/nu-protocol/src/engine/state_working_set.rs +++ b/crates/nu-protocol/src/engine/state_working_set.rs @@ -459,21 +459,48 @@ impl<'a> StateWorkingSet<'a> { } // check overlay in perma - for overlay_frame in self - .permanent_state - .active_overlays(&removed_overlays) - .rev() - { - visibility.append(&overlay_frame.visibility); + self.permanent_state.find_decl(name, &removed_overlays) + } + + pub fn find_decl_name(&self, decl_id: DeclId) -> Option<&[u8]> { + let mut removed_overlays = vec![]; + + let mut visibility: Visibility = Visibility::new(); + + for scope_frame in self.delta.scope.iter().rev() { + if self.search_predecls { + for (name, id) in scope_frame.predecls.iter() { + if id == &decl_id { + return Some(name); + } + } + } + + // check overlay in delta + for overlay_frame in scope_frame.active_overlays(&mut removed_overlays).rev() { + visibility.append(&overlay_frame.visibility); + + if self.search_predecls { + for (name, id) in overlay_frame.predecls.iter() { + if id == &decl_id { + return Some(name); + } + } + } - if let Some(decl_id) = overlay_frame.get_decl(name) { if visibility.is_decl_id_visible(&decl_id) { - return Some(decl_id); + for (name, id) in overlay_frame.decls.iter() { + if id == &decl_id { + return Some(name); + } + } } } } - None + // check overlay in perma + self.permanent_state + .find_decl_name(decl_id, &removed_overlays) } pub fn find_module(&self, name: &[u8]) -> Option { diff --git a/crates/nu-std/std/iter/mod.nu b/crates/nu-std/std/iter/mod.nu index 8c25269690..daa62d2dba 100644 --- a/crates/nu-std/std/iter/mod.nu +++ b/crates/nu-std/std/iter/mod.nu @@ -101,8 +101,9 @@ export def intersperse [ # -> list # Returns a list of intermediate steps performed by `reduce` # (`fold`). It takes two arguments, an initial value to seed the # initial state and a closure that takes two arguments, the first -# being the internal state and the second the list element in the -# current iteration. +# being the list element in the current iteration and the second +# the internal state. +# The internal state is also provided as pipeline input. # # # Example # ``` @@ -123,7 +124,8 @@ export def scan [ # -> list --noinit(-n) # remove the initial value from the result ] { reduce --fold [$init] {|it, acc| - $acc ++ [(do $fn ($acc | last) $it)] + let acc_last = $acc | last + $acc ++ [($acc_last | do $fn $it $acc_last)] } | if $noinit { $in | skip diff --git a/crates/nu-std/tests/test_iter.nu b/crates/nu-std/tests/test_iter.nu index 2b768c3d9d..3ace342788 100644 --- a/crates/nu-std/tests/test_iter.nu +++ b/crates/nu-std/tests/test_iter.nu @@ -49,7 +49,10 @@ def iter_scan [] { let scanned = ([1 2 3] | iter scan 0 {|x, y| $x + $y}) assert equal $scanned [0, 1, 3, 6] - let scanned = ([a b c d] | iter scan "" {|x, y| [$x, $y] | str join} -n) + let scanned = ([a b c d] | iter scan "" {|it, acc| [$acc, $it] | str join} -n) + assert equal $scanned ["a" "ab" "abc" "abcd"] + + let scanned = ([a b c d] | iter scan "" {|it, acc| append $it | str join} -n) assert equal $scanned ["a" "ab" "abc" "abcd"] } diff --git a/crates/nu-utils/src/default_files/default_config.nu b/crates/nu-utils/src/default_files/default_config.nu index dcefb70fff..ce60d29663 100644 --- a/crates/nu-utils/src/default_files/default_config.nu +++ b/crates/nu-utils/src/default_files/default_config.nu @@ -20,6 +20,8 @@ $env.config.color_config = { row_index: green_bold record: white list: white + closure: green_bold + glob:cyan_bold block: white hints: dark_gray search_result: { bg: red fg: white } diff --git a/crates/nu-utils/src/default_files/default_env.nu b/crates/nu-utils/src/default_files/default_env.nu index cb85e519ba..39dcd5c9d0 100644 --- a/crates/nu-utils/src/default_files/default_env.nu +++ b/crates/nu-utils/src/default_files/default_env.nu @@ -3,7 +3,7 @@ # # version = "0.100.1" -$env.PROMPT_COMMAND = $env.PROMPT_COMMAND? | default {|| +$env.PROMPT_COMMAND = $env.PROMPT_COMMAND? | default {|| let dir = match (do -i { $env.PWD | path relative-to $nu.home-path }) { null => $env.PWD '' => '~' @@ -17,12 +17,7 @@ $env.PROMPT_COMMAND = $env.PROMPT_COMMAND? | default {|| $path_segment | str replace --all (char path_sep) $"($separator_color)(char path_sep)($path_color)" } -$env.PROMPT_INDICATOR = $env.PROMPT_INDICATOR? | default "> " -$env.PROMPT_INDICATOR_VI_NORMAL = $env.PROMPT_INDICATOR_VI_NORMAL? | default "> " -$env.PROMPT_INDICATOR_VI_INSERT = $env.PROMPT_INDICATOR_VI_INSERT? | default ": " -$env.PROMPT_MULTILINE_INDICATOR = $env.PROMPT_MULTILINE_INDICATOR? | default "::: " - -$env.PROMPT_COMMAND_RIGHT = $env.PROMPT_COMMAND_RIGHT? | default {|| +$env.PROMPT_COMMAND_RIGHT = $env.PROMPT_COMMAND_RIGHT? | default {|| # create a right prompt in magenta with green separators and am/pm underlined let time_segment = ([ (ansi reset) @@ -39,19 +34,3 @@ $env.PROMPT_COMMAND_RIGHT = $env.PROMPT_COMMAND_RIGHT? | default {|| ([$last_exit_code, (char space), $time_segment] | str join) } - -$env.ENV_CONVERSIONS = { - "PATH": { - from_string: { |s| $s | split row (char esep) | path expand --no-symlink } - to_string: { |v| $v | path expand --no-symlink | str join (char esep) } - } -} - -$env.NU_LIB_DIRS = $env.NU_LIB_DIRS? | default [ - ($nu.default-config-dir | path join 'scripts') # add /scripts - ($nu.data-dir | path join 'completions') # default home for nushell completions -] - -$env.NU_PLUGIN_DIRS = $env.NU_PLUGIN_DIRS | default [ - ($nu.default-config-dir | path join 'plugins') # add /plugins -] diff --git a/crates/nu-utils/src/default_files/sample_config.nu b/crates/nu-utils/src/default_files/sample_config.nu index 143e56aae4..1a91b59f5e 100644 --- a/crates/nu-utils/src/default_files/sample_config.nu +++ b/crates/nu-utils/src/default_files/sample_config.nu @@ -1,6 +1,9 @@ -# Nushell Config File +# Nushell Sample Config File # -# version = "0.99.2" +# Warning: This file is intended for documentation purposes only and +# is not intended to be used as an actual configuration file as-is. +# +# version = "0.100.1" # # A `config.nu` file is used to override default Nushell settings, # define (or import) custom commands, or run any other startup tasks. @@ -86,14 +89,14 @@ $env.config.recursion_limit = 50 # --------------------------- # edit_mode (string) "vi" or "emacs" sets the editing behavior of Reedline -edit_mode: "emacs" +$env.config.edit_mode = "emacs" # Command that will be used to edit the current line buffer with Ctrl+O. # If unset, uses $env.VISUAL and then $env.EDITOR # # Tip: Set to "editor" to use the default editor on Unix platforms using # the Alternatives system or equivalent -buffer_editor: "editor" +$env.config.buffer_editor = "editor" # cursor_shape_* (string) # ----------------------- @@ -120,7 +123,7 @@ $env.config.completions.algorithm = "prefix" $env.config.completions.sort = "smart" # case_sensitive (bool): true/false to enable/disable case-sensitive completions -$env.config.completions.case_sensitive = false +$env.config.completions.case_sensitive = false # quick (bool): # true: auto-select the completion when only one remains @@ -132,7 +135,7 @@ $env.config.completions.quick = true # false: Do not partially complete # Partial Example: If a directory contains only files named "forage", "food", and "forest", # then typing "ls " and pressing will partially complete the first two -# letters, "f" and "o". If the directory also includes a file named "faster", +# letters, "f" and "o". If the directory also includes a file named "faster", # then only "f" would be partially completed. $env.config.completions.partial = true @@ -145,7 +148,7 @@ $env.config.completions.use_ls_colors = true # completions.external.*: Settings related to completing external commands # and additional completers -# external.exnable (bool) +# external.enable (bool) # true: search for external commands on the Path # false: disabling might be desired for performance if your path includes # directories on a slower filesystem @@ -156,16 +159,16 @@ $env.config.completions.external.enable = true $env.config.completions.external.max_results = 50 # completer (closure with a |spans| parameter): A command to call for *argument* completions -# to commands (internal or external). +# to commands (internal or external). # # The |spans| parameter is a list of strings representing the tokens (spans) -# on the current commandline. It is always a list of at least two strings - The +# on the current commandline. It is always a list of at least two strings - The # command being completed plus the first argument of that command ("" if no argument has # been partially typed yet), and additional strings for additional arguments beyond # the first. # # This setting is usually set to a closure which will call a third-party completion system, such -# as Carapace. +# as Carapace. # # Note: The following is an over-simplified completer command that will call Carapace if it # is installed. Please use the official Carapace completer, which can be generated automatically @@ -206,8 +209,8 @@ $env.config.shell_integration.osc9_9 = false # osc8 (bool): # When true, the `ls` command will generate clickable links that can be launched in another # application by the terminal. -# Note: This setting replaces the now deprecated `ls.show_clickable_links` -$env.config.shell.integration.osc8: true +# Note: This setting replaces the now deprecated `ls.clickable_links` +$env.config.shell_integration.osc8 = true # Deprecated # $env.config.ls.clickable_links = true @@ -229,13 +232,13 @@ $env.config.shell_integration.osc633 = true # reset_application_mode (bool): # true/false to enable/disable sending ESC[?1l to the terminal -# This sequence is commonly used to keep cursor key modes in sync between the local +# This sequence is commonly used to keep cursor key modes in sync between the local # terminal and a remove SSH host. $env.config.shell_integration.reset_application_mode = true # bracketed_paste (bool): # true/false to enable/disable the bracketed-paste feature, which allows multiple-lines -# to be pasted into Nushell at once without immediate execution. When disabled, +# to be pasted into Nushell at once without immediate execution. When disabled, # each pasted line is executed as it is received. # Note that bracketed paste is not currently supported on the Windows version of # Nushell. @@ -266,7 +269,7 @@ $env.config.display_errors.exit_code = false # display_errors.termination_signal (bool): # true/false to enable/disable displaying a Nushell error when a child process is -# terminated via any signal +# terminated via any signal $env.config.display_errors.termination_signal = true # ------------- @@ -282,7 +285,7 @@ $env.config.display_errors.termination_signal = true $env.config.footer_mode = 25 # table.* -# table_mode (string): +# table_mode (string): # One of: "default", "basic", "compact", "compact_double", "heavy", "light", "none", "reinforced", # "rounded", "thin", "with_love", "psql", "markdown", "dots", "restructured", "ascii_rounded", # or "basic_compact" @@ -344,7 +347,7 @@ $env.config.table.footer_inheritance = false # Datetime Display # ---------------- # datetime_format.* (string or nothing): -# Format strings that will be used for datetime values. +# Format strings that will be used for datetime values. # When set to `null`, the default behavior is to "humanize" the value (e.g., "now" or "a day ago") # datetime_format.table (string or nothing): @@ -389,7 +392,7 @@ $env.config.float_precision = 2 # ls.use_ls_colors (bool): # true: The `ls` command will apply the $env.LS_COLORS standard to filenames # false: Filenames in the `ls` table will use the color_config for strings -$env.config.ls = true +$env.config.ls.use_ls_colors = true # Hooks # ----- @@ -402,12 +405,19 @@ $env.config.ls = true # WARNING: A malformed display_output hook can suppress all Nushell output to the terminal. # It can be reset by assigning an empty string as below: -$env.config.hooks.pre_prompt = [] # Before each prompt is displayed -$env.config.hooks.pre_execution = [] # After is pressed; before the commandline - # is executed -$env.config.hooks.env_change = [] # When a specified environment variable changes -$env.config.hooks.display_output = "" # Before Nushell output is displayed in the terminal -$env.config.hooks.command_not_found = [] # When a command is not found +# Before each prompt is displayed +$env.config.hooks.pre_prompt = [] +# After is pressed; before the commandline is executed +$env.config.hooks.pre_execution = [] +# When a specified environment variable changes +$env.config.hooks.env_change = { + # run if the PWD environment is different since the last repl input + PWD: [{|before, after| null }] +} +# Before Nushell output is displayed in the terminal +$env.config.hooks.display_output = "if (term size).columns >= 100 { table -e } else { table }" +# When a command is not found +$env.config.hooks.command_not_found = [] # ----------- # Keybindings @@ -462,7 +472,7 @@ $env.config.menus ++= [ type: { layout: description columns: 4 - col_width: 20 # Optional value. If missing all the screen width is used to calculate column width + col_width: 20 # Optional value. If missing all the screen width is used to calculate column width col_padding: 2 selection_rows: 4 description_rows: 10 @@ -480,27 +490,22 @@ $env.config.menus ++= [ # Plugin behavior # --------------- # Per-plugin configuration. See https://www.nushell.sh/contributor-book/plugins.html#configuration. -plugins: {} $env.config.plugins + +# Configuration for plugin garbage collection $env.config.plugin_gc $env.config.plugin_gc.default +# true to enable stopping of inactive plugins $env.config.plugin_gc.default.enabled +# How long to wait after a plugin is inactive before stopping it $env.config.plugin_gc.default.stop_after -$env.config.plugin_gc.plugins - plugin_gc: { - # Configuration for plugin garbage collection - default: { - enabled: true # true to enable stopping of inactive plugins - stop_after: 10sec # how long to wait after a plugin is inactive to stop it - } - plugins: { - # alternate configuration for specific plugins, by name, for example: - # - # gstat: { - # enabled: false - # } - } - } +$env.config.plugin_gc.plugins = { + # Alternate configuration for specific plugins, by name, for example: + # + # gstat: { + # enabled: false + # } +} # ------------------------------------- @@ -532,12 +537,12 @@ use std/config dark-theme $env.config.color_config = (dark-theme) # Or, individual color settings can be configured or overridden. -# +# # Values can be one of: # - A color name such as "red" (see `ansi -l` for a list) # - A color RGB value in the form of "#C4C9C6" # - A record including: -# * `fg` (color) +# * `fg` (color) # * `bg` (color) # * `attr`: a string with one or more of: # - 'n': normal @@ -547,7 +552,7 @@ $env.config.color_config = (dark-theme) # - 'i': italics # - 'd': dimmed -# foreground, background, and cursor colors are not handled by Nushell, but can be used by +# foreground, background, and cursor colors are not handled by Nushell, but can be used by # custom-commands such as `theme` from the nu_scripts repository. That `theme` command can be # used to set the terminal foreground, background, and cursor colors. $env.config.color_config.foreground @@ -557,7 +562,7 @@ $env.config.color_config.cursor # ------------------------------------------------------------------------------------------------- # shape_: Applies syntax highlighting based on the "shape" (inferred or declared type) of an # element on the commandline. Nushell's parser can identify shapes based on many criteria, often -# as the commandline is being typed. +# as the commandline is being typed. # shape_string: Can appear as a single-or-quoted value, a bareword string, the key of a record, # an argument which has been declared as a string, and other parsed strings. @@ -733,7 +738,7 @@ $env.config.color_config.custom # Custom value (often from a plugin) $env.config.color_config.nothing # Not used, since a null is not displayed $env.config.color_config.date # datetime value $env.config.color_config.filesize # filesize value -$env.config.color_config.list # Not currently used. Lists are displayed using their +$env.config.color_config.list # Not currently used. Lists are displayed using their # members' styles $env.config.color_config.record # Not currently used. Records are displayed using their # member's styles @@ -785,3 +790,145 @@ $env.config.explore = { }, selected_cell: { bg: light_blue }, } + +# --------------------------------------------------------------------------------------- +# Environment Variables +# --------------------------------------------------------------------------------------- + +# In addition to the $env.config record, a number of other environment variables +# also affect Nushell's behavior: + +# PROMPT_* +# -------- +# Prompt configuration +# PROMPT_ variables accept either a string or a closure that returns a string + +# PROMPT_COMMAND +# -------------- +# Defines the primary prompt. Note that the PROMPT_INDICATOR (below) is appended to this value. +# Simple example - Static string: +$env.PROMPT_COMMAND = "Nushell" +# Simple example - Dynamic closure displaying the path: +$env.PROMPT_COMMAND = {|| pwd} + +# PROMPT_COMMAND_RIGHT +# -------------------- +# Defines a prompt which will appear right-aligned in the terminal +$env.PROMPT_COMMAND_RIGHT = {|| date now | format date "%d-%a %r" } + +# PROMPT_INDICATOR* +# ----------------- +# The prompt indicators are environmental variables that represent +# the state of the prompt. The specified character(s) will appear +# immediately following the PROMPT_COMMAND + +# When in Emacs mode (default): +$env.PROMPT_INDICATOR = "> " + +# When in normal vi mode: +$env.PROMPT_INDICATOR_VI_NORMAL = "> " +# When in vi insert-mode: +$env.PROMPT_INDICATOR_VI_INSERT = ": " + +# When a commandline extends across multiple lines: +$env.PROMPT_MULTILINE_INDICATOR = "::: " + +# TRANSIENT_PROMPT_* +# ------------------ +# Allows a different prompt to be shown after a command has been executed. This +# can be useful if you have a 2-line prompt. Instead of each previously-entered +# command taking up at least 2 lines, the transient prompt can condense it to a +# shorter version. The following example shows a rocket emoji before each +# previously-entered command: +$env.TRANSIENT_PROMPT_COMMAND = "🚀 " +$env.TRANSIENT_PROMPT_INDICATOR = "" +$env.TRANSIENT_PROMPT_INDICATOR_VI_INSERT = "" +$env.TRANSIENT_PROMPT_INDICATOR_VI_NORMAL = "" +# Tip: Removing the transient multiline indicator and right-prompt can simplify +# copying from the terminal +$env.TRANSIENT_PROMPT_MULTILINE_INDICATOR = "" +$env.TRANSIENT_PROMPT_COMMAND_RIGHT = "" + +# ENV_CONVERSIONS +# --------------- +# Certain variables, such as those containing multiple paths, are often stored as a +# colon-separated string in other shells. Nushell can convert these automatically to a +# more convenient Nushell list. The ENV_CONVERSIONS variable specifies how environment +# variables are: +# - converted from a string to a value on Nushell startup (from_string) +# - converted from a value back to a string when running external commands (to_string) +# +# Note: The OS Path variable is automatically converted before env.nu loads, so it can +# be treated a list in this file. +# +# Note: Environment variables are not case-sensitive, so the following will work +# for both Windows and Unix-like platforms. +# +# By default, the internal conversion looks something like the following, so there +# is no need to add this in your actual env.nu: +$env.ENV_CONVERSIONS = { + "Path": { + from_string: { |s| $s | split row (char esep) | path expand --no-symlink } + to_string: { |v| $v | path expand --no-symlink | str join (char esep) } + } +} + +# Here's an example converts the XDG_DATA_DIRS variable to and from a list: +$env.ENV_CONVERSIONS = $env.ENV_CONVERSIONS | merge { + "XDG_DATA_DIRS": { + from_string: { |s| $s | split row (char esep) | path expand --no-symlink } + to_string: { |v| $v | path expand --no-symlink | str join (char esep) } + } +} +# +# Other common directory-lists for conversion: TERMINFO_DIRS. +# Note that other variable conversions take place after `config.nu` is loaded. + +# NU_LIB_DIRS +# ----------- +# Directories in this constant are searched by the +# `use` and `source` commands. +# +# By default, the `scripts` subdirectory of the default configuration +# directory is included: +const NU_LIB_DIRS = [ + ($nu.default-config-dir | path join 'scripts') # add /scripts + ($nu.data-dir | path join 'completions') # default home for nushell completions +] +# You can replace (override) or append to this list by shadowing the constant +const NU_LIB_DIRS = $NU_LIB_DIRS ++ [($nu.default-config-dir | path join 'modules')] + +# An environment variable version of this also exists. It is searched after the constant. +$env.NU_LIB_DIRS ++= [ ($nu.data-dir | path join "nu_scripts") ] + +# NU_PLUGIN_DIRS +# -------------- +# Directories to search for plugin binaries when calling add. + +# By default, the `plugins` subdirectory of the default configuration +# directory is included: +const NU_PLUGIN_DIRS = [ + ($nu.default-config-dir | path join 'plugins') # add /plugins +] +# You can replace (override) or append to this list by shadowing the constant +const NU_PLUGIN_DIRS = $NU_PLUGIN_DIRS ++ [($nu.default-config-dir | path join 'plugins')] + +# As with NU_LIB_DIRS, an $env.NU_PLUGIN_DIRS is searched after the constant version + +# Appending to the OS path is a common configuration task. +# Because of the previous ENV_CONVERSIONS (performed internally +# before your config.nu loads), the path variable is a list that can +# be appended to using, for example: +$env.PATH ++= [ "~/.local/bin" ] + +# Or prepend using +$env.PATH = [ "~/.local/bin" ] ++ $env.PATH + +# The `path add` function from the Standard Library also provides +# a convenience method for prepending to the path: +use std/util "path add" +path add "~/.local/bin" +path add ($env.CARGO_HOME | path join "bin") + +# You can remove duplicate directories from the path using: +$env.PATH = ($env.PATH | uniq) diff --git a/crates/nu-utils/src/default_files/sample_env.nu b/crates/nu-utils/src/default_files/sample_env.nu index 23dc925ccd..a69363cdf7 100644 --- a/crates/nu-utils/src/default_files/sample_env.nu +++ b/crates/nu-utils/src/default_files/sample_env.nu @@ -1,140 +1,11 @@ # Sample Nushell Environment Config File # -# Environment variables are usually configured in `env.nu`. Nushell -# sets sensible defaults for many environment variables, so the user's -# `env.nu` only needs to override these defaults if desired. +# version = "0.100.1" # -# This file serves as simple "in-shell" documentation for these -# settings, or you can view a more complete discussion online at: -# https://nushell.sh/book/configuration -# -# You can pretty-print and page this file using: -# config env --sample | nu-highlight | less -R +# Previously, environment variables were typically configured in `env.nu`. +# In general, most configuration can and should be performed in `config.nu` +# or one of the autoload directories. -# PROMPT_* -# -------- -# Prompt configuration -# PROMPT_ variables accept either a string or a closure that returns a string - -# PROMPT_COMMAND -# -------------- -# Defines the primary prompt. Note that the PROMPT_INDICATOR (below) is appended to this value. -# Simple example - Static string: -$env.PROMPT_COMMAND = "Nushell" -# Simple example - Dynamic closure displaying the path: -$env.PROMPT_COMMAND = {|| pwd} - -# PROMPT_COMMAND_RIGHT -# -------------------- -# Defines a prompt which will appear right-aligned in the terminal -$env.PROMPT_COMMAND_RIGHT = {|| date now | format date "%d-%a %r" } - -# PROMPT_INDICATOR* -# ----------------- -# The prompt indicators are environmental variables that represent -# the state of the prompt. The specified character(s) will appear -# immediately following the PROMPT_COMMAND - -# When in Emacs mode (default): -$env.PROMPT_INDICATOR = "> " - -# When in normal vi mode: -$env.PROMPT_INDICATOR_VI_NORMAL = "> " -# When in vi insert-mode: -$env.PROMPT_INDICATOR_VI_INSERT = ": " - -# When a commandline extends across multiple lines: -$env.PROMPT_MULTILINE_INDICATOR = "::: " - -# TRANSIENT_PROMPT_* -# ------------------ -# Allows a different prompt to be shown after a command has been executed. This -# can be useful if you have a 2-line prompt. Instead of each previously-entered -# command taking up at least 2 lines, the transient prompt can condense it to a -# shorter version. The following example shows a rocket emoji before each -# previously-entered command: -$env.TRANSIENT_PROMPT_COMMAND = "🚀 " -$env.TRANSIENT_PROMPT_INDICATOR = "" -$env.TRANSIENT_PROMPT_INDICATOR_VI_INSERT = "" -$env.TRANSIENT_PROMPT_INDICATOR_VI_NORMAL = "" -# Tip: Removing the transient multiline indicator and right-prompt can simplify -# copying from the terminal -$env.TRANSIENT_PROMPT_MULTILINE_INDICATOR = "" -$env.TRANSIENT_PROMPT_COMMAND_RIGHT = "" - -# ENV_CONVERSIONS -# --------------- -# Certain variables, such as those containing multiple paths, are often stored as a -# colon-separated string in other shells. Nushell can convert these automatically to a -# more convenient Nushell list. The ENV_CONVERSIONS variable specifies how environment -# variables are: -# - converted from a string to a value on Nushell startup (from_string) -# - converted from a value back to a string when running external commands (to_string) -# -# Note: The OS Path variable is automatically converted before env.nu loads, so it can -# be treated a list in this file. -# -# Note: Environment variables are not case-sensitive, so the following will work -# for both Windows and Unix-like platforms. -# -# By default, the internal conversion looks something like the following, so there -# is no need to add this in your actual env.nu: -$env.ENV_CONVERSIONS = { - "Path": { - from_string: { |s| $s | split row (char esep) | path expand --no-symlink } - to_string: { |v| $v | path expand --no-symlink | str join (char esep) } - } -} - -# Here's an example converts the XDG_DATA_DIRS variable to and from a list: -$env.ENV_CONVERSIONS = $env.ENV_CONVERSIONS | merge { - "XDG_DATA_DIRS": { - from_string: { |s| $s | split row (char esep) | path expand --no-symlink } - to_string: { |v| $v | path expand --no-symlink | str join (char esep) } - } -} -# -# Other common directory-lists for conversion: TERMINFO_DIRS. -# Note that other variable conversions take place after `config.nu` is loaded. - -# NU_LIB_DIRS -# ----------- -# Directories in this environment variable are searched by the -# `use` and `source` commands. -# -# By default, the `scripts` subdirectory of the default configuration -# directory is included: -$env.NU_LIB_DIRS = [ - ($nu.default-config-dir | path join 'scripts') # add /scripts - ($nu.data-dir | path join 'completions') # default home for nushell completions -] -# You can replace (override) or append to this list: -$env.NU_LIB_DIRS ++= ($nu.default-config-dir | path join 'modules') - -# NU_PLUGIN_DIRS -# -------------- -# Directories to search for plugin binaries when calling register. - -# By default, the `plugins` subdirectory of the default configuration -# directory is included: -$env.NU_PLUGIN_DIRS = [ - ($nu.default-config-dir | path join 'plugins') # add /plugins -] - -# Appending to the OS path is a common configuration task. -# Because of the previous ENV_CONVERSIONS (performed internally -# before your env.nu loads), the path variable is a list that can -# be appended to using, for example: -$env.path ++= "~/.local/bin" - -# Or prepend using -$env.path = "~/.local/bin" ++ $env.path - -# The `path add` function from the Standard Library also provides -# a convenience method for prepending to the path: -use std/util "path add" -path add "~/.local/bin" -path add ($env.CARGO_HOME | path join "bin") - -# You can remove duplicate directories from the path using: -$env.PATH = ($env.PATH | uniq) +# To pretty-print the in-shell documentation for Nushell's various configuration +# settings, you can run: +config nu --sample | nu-highlight | less -R diff --git a/crates/nu-utils/src/default_files/sample_login.nu b/crates/nu-utils/src/default_files/sample_login.nu index 8e0a651499..511e3b803c 100644 --- a/crates/nu-utils/src/default_files/sample_login.nu +++ b/crates/nu-utils/src/default_files/sample_login.nu @@ -1,4 +1,7 @@ # Example Nushell Loginshell Config File +# +# version = "0.100.1" +# # - has to be as login.nu in the default config directory # - will be sourced after config.nu and env.nu in case of nushell started as login shell diff --git a/crates/nu-utils/src/default_files/scaffold_config.nu b/crates/nu-utils/src/default_files/scaffold_config.nu index 7bf7ecc632..fa6d834c73 100644 --- a/crates/nu-utils/src/default_files/scaffold_config.nu +++ b/crates/nu-utils/src/default_files/scaffold_config.nu @@ -1,11 +1,14 @@ # config.nu # +# Installed by: +# version = "0.100.1" +# # This file is used to override default Nushell settings, define # (or import) custom commands, or run any other startup tasks. # See https://www.nushell.sh/book/configuration.html # # This file is loaded after env.nu and before login.nu -# +# # You can open this file in your default editor using: # config nu # diff --git a/crates/nu-utils/src/default_files/scaffold_env.nu b/crates/nu-utils/src/default_files/scaffold_env.nu index a3ce3cab07..d7a2e00627 100644 --- a/crates/nu-utils/src/default_files/scaffold_env.nu +++ b/crates/nu-utils/src/default_files/scaffold_env.nu @@ -1,17 +1,21 @@ # env.nu # -# This file is typically used to add or override environment variables. +# Installed by: +# version = "0.100.1" +# +# Previously, environment variables were typically configured in `env.nu`. +# In general, most configuration can and should be performed in `config.nu` +# or one of the autoload directories. +# +# This file is generated for backwards compatibility for now. +# It is loaded before config.nu and login.nu +# # See https://www.nushell.sh/book/configuration.html # -# This file is loaded before config.nu and login.nu +# To pretty-print a sample of the configuration settings, run: +# config nu --sample | nu-highlight | less -R # -# You can open this file in your default editor using: -# config env -# -# To pretty-print a sample env.nu with documentation, run: -# config env --sample | nu-highlight | less -R -# -# To pretty-print the default environment values, run: +# To pretty-print the default env.nu, run: # config env --default | nu-highlight | less -R # # You can remove these comments if you want or leave diff --git a/crates/nu_plugin_polars/src/dataframe/command/data/join.rs b/crates/nu_plugin_polars/src/dataframe/command/data/join.rs index ee18e17567..b1c13fef00 100644 --- a/crates/nu_plugin_polars/src/dataframe/command/data/join.rs +++ b/crates/nu_plugin_polars/src/dataframe/command/data/join.rs @@ -27,8 +27,8 @@ impl PluginCommand for LazyJoin { fn signature(&self) -> Signature { Signature::build(self.name()) .required("other", SyntaxShape::Any, "LazyFrame to join with") - .required("left_on", SyntaxShape::Any, "Left column(s) to join on") - .required("right_on", SyntaxShape::Any, "Right column(s) to join on") + .optional("left_on", SyntaxShape::Any, "Left column(s) to join on") + .optional("right_on", SyntaxShape::Any, "Right column(s) to join on") .switch( "inner", "inner joining between lazyframes (default)", @@ -54,8 +54,8 @@ impl PluginCommand for LazyJoin { vec![ Example { description: "Join two lazy dataframes", - example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | polars into-lazy); - let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | polars into-lazy); + example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | polars into-lazy) + let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | polars into-lazy) $df_a | polars join $df_b a foo | polars collect"#, result: Some( NuDataFrame::try_from_columns( @@ -114,8 +114,8 @@ impl PluginCommand for LazyJoin { }, Example { description: "Join one eager dataframe with a lazy dataframe", - example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | polars into-df); - let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | polars into-lazy); + example: r#"let df_a = ([[a b c];[1 "a" 0] [2 "b" 1] [1 "c" 2] [1 "c" 3]] | polars into-df) + let df_b = ([["foo" "bar" "ham"];[1 "a" "let"] [2 "c" "var"] [3 "c" "const"]] | polars into-lazy) $df_a | polars join $df_b a foo"#, result: Some( NuDataFrame::try_from_columns( @@ -172,6 +172,43 @@ impl PluginCommand for LazyJoin { .into_value(Span::test_data()), ), }, + Example { + description: "Join one eager dataframe with another using a cross join", + example: r#"let tokens = [[monopoly_token]; [hat] [shoe] [boat]] | polars into-df + let players = [[name, cash]; [Alice, 78] [Bob, 135]] | polars into-df + $players | polars select (polars col name) | polars join --cross $tokens | polars collect"#, + result: Some( + NuDataFrame::try_from_columns( + vec![ + Column::new( + "name".to_string(), + vec![ + Value::test_string("Alice"), + Value::test_string("Alice"), + Value::test_string("Alice"), + Value::test_string("Bob"), + Value::test_string("Bob"), + Value::test_string("Bob"), + ], + ), + Column::new( + "monopoly_token".to_string(), + vec![ + Value::test_string("hat"), + Value::test_string("shoe"), + Value::test_string("boat"), + Value::test_string("hat"), + Value::test_string("shoe"), + Value::test_string("boat"), + ], + ), + ], + None, + ) + .expect("simple df for test should not fail") + .into_value(Span::test_data()), + ), + }, ] } @@ -200,11 +237,21 @@ impl PluginCommand for LazyJoin { let other = NuLazyFrame::try_from_value_coerce(plugin, &other)?; let other = other.to_polars(); - let left_on: Value = call.req(1)?; - let left_on = NuExpression::extract_exprs(plugin, left_on)?; + let left_on_opt: Option = call.opt(1)?; + let left_on = match left_on_opt { + Some(left_on_value) if left || left_on_opt.is_some() => { + NuExpression::extract_exprs(plugin, left_on_value)? + } + _ => vec![], + }; - let right_on: Value = call.req(2)?; - let right_on = NuExpression::extract_exprs(plugin, right_on)?; + let right_on_opt: Option = call.opt(2)?; + let right_on = match right_on_opt { + Some(right_on_value) if full || right_on_opt.is_some() => { + NuExpression::extract_exprs(plugin, right_on_value)? + } + _ => vec![], + }; if left_on.len() != right_on.len() { let right_on: Value = call.req(2)?; @@ -232,16 +279,25 @@ impl PluginCommand for LazyJoin { let lazy = NuLazyFrame::try_from_value_coerce(plugin, &value)?; let from_eager = lazy.from_eager; let lazy = lazy.to_polars(); - - let lazy = lazy - .join_builder() - .with(other) - .left_on(left_on) - .right_on(right_on) - .how(how) - .force_parallel(true) - .suffix(suffix) - .finish(); + let lazy = if cross { + lazy.join_builder() + .with(other) + .left_on(vec![]) + .right_on(vec![]) + .how(how) + .force_parallel(true) + .suffix(suffix) + .finish() + } else { + lazy.join_builder() + .with(other) + .left_on(left_on) + .right_on(right_on) + .how(how) + .force_parallel(true) + .suffix(suffix) + .finish() + }; let lazy = NuLazyFrame::new(from_eager, lazy); lazy.to_pipeline_data(plugin, engine, call.head) diff --git a/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/conversion.rs b/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/conversion.rs index 7d5a4ace3f..d196ed8ba6 100644 --- a/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/conversion.rs +++ b/crates/nu_plugin_polars/src/dataframe/values/nu_dataframe/conversion.rs @@ -223,57 +223,30 @@ pub fn insert_value( inner: vec![], }) } - } - // Checking that the type for the value is the same - // for the previous value in the column - else if col_val.values.is_empty() { - if let Some(schema) = maybe_schema { - if let Some(field) = schema.schema.get_field(&key) { - col_val.column_type = Some(field.dtype().clone()); - } - } - + } else { + let current_data_type = value_to_data_type(&value); if col_val.column_type.is_none() { - col_val.column_type = Some(value_to_data_type(&value)); + col_val.column_type = value_to_data_type(&value); + } else if let Some(current_data_type) = current_data_type { + if col_val.column_type.as_ref() != Some(¤t_data_type) { + col_val.column_type = Some(DataType::Object("Value", None)); + } } col_val.values.push(value); Ok(()) - } else { - let prev_value = &col_val.values[col_val.values.len() - 1]; - - match (&prev_value, &value) { - (Value::Int { .. }, Value::Int { .. }) - | (Value::Float { .. }, Value::Float { .. }) - | (Value::String { .. }, Value::String { .. }) - | (Value::Bool { .. }, Value::Bool { .. }) - | (Value::Date { .. }, Value::Date { .. }) - | (Value::Filesize { .. }, Value::Filesize { .. }) - | (Value::Binary { .. }, Value::Binary { .. }) - | (Value::Duration { .. }, Value::Duration { .. }) => col_val.values.push(value), - (_, Value::Nothing { .. }) => col_val.values.push(value), - (Value::List { .. }, _) => { - col_val.column_type = Some(value_to_data_type(&value)); - col_val.values.push(value); - } - _ => { - col_val.column_type = Some(DataType::Object("Value", None)); - col_val.values.push(value); - } - } - Ok(()) } } -fn value_to_data_type(value: &Value) -> DataType { +fn value_to_data_type(value: &Value) -> Option { match &value { - Value::Int { .. } => DataType::Int64, - Value::Float { .. } => DataType::Float64, - Value::String { .. } => DataType::String, - Value::Bool { .. } => DataType::Boolean, - Value::Date { .. } => DataType::Date, - Value::Duration { .. } => DataType::Duration(TimeUnit::Nanoseconds), - Value::Filesize { .. } => DataType::Int64, - Value::Binary { .. } => DataType::Binary, + Value::Int { .. } => Some(DataType::Int64), + Value::Float { .. } => Some(DataType::Float64), + Value::String { .. } => Some(DataType::String), + Value::Bool { .. } => Some(DataType::Boolean), + Value::Date { .. } => Some(DataType::Date), + Value::Duration { .. } => Some(DataType::Duration(TimeUnit::Nanoseconds)), + Value::Filesize { .. } => Some(DataType::Int64), + Value::Binary { .. } => Some(DataType::Binary), Value::List { vals, .. } => { // We need to determined the type inside of the list. // Since Value::List does not have any kind of @@ -286,243 +259,247 @@ fn value_to_data_type(value: &Value) -> DataType { .filter(|v| !matches!(v, Value::Nothing { .. })) .map(value_to_data_type) .nth(1) + .flatten() .unwrap_or(DataType::Object("Value", None)); - DataType::List(Box::new(list_type)) + Some(DataType::List(Box::new(list_type))) } - _ => DataType::Object("Value", None), + _ => None, } } fn typed_column_to_series(name: PlSmallStr, column: TypedColumn) -> Result { - if let Some(column_type) = &column.column_type { - match column_type { - DataType::Float32 => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| { - value_to_option(v, |v| match v { - Value::Float { val, .. } => Ok(*val as f32), - Value::Int { val, .. } => Ok(*val as f32), - x => Err(ShellError::GenericError { - error: "Error converting to f32".into(), - msg: "".into(), - span: None, - help: Some(format!("Unexpected type: {x:?}")), - inner: vec![], - }), - }) + let column_type = &column + .column_type + .clone() + .unwrap_or(DataType::Object("Value", None)); + match column_type { + DataType::Float32 => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| { + value_to_option(v, |v| match v { + Value::Float { val, .. } => Ok(*val as f32), + Value::Int { val, .. } => Ok(*val as f32), + x => Err(ShellError::GenericError { + error: "Error converting to f32".into(), + msg: "".into(), + span: None, + help: Some(format!("Unexpected type: {x:?}")), + inner: vec![], + }), }) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::Float64 => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| { - value_to_option(v, |v| match v { - Value::Float { val, .. } => Ok(*val), - Value::Int { val, .. } => Ok(*val as f64), - x => Err(ShellError::GenericError { - error: "Error converting to f64".into(), - msg: "".into(), - span: None, - help: Some(format!("Unexpected type: {x:?}")), - inner: vec![], - }), - }) + }) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::Float64 => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| { + value_to_option(v, |v| match v { + Value::Float { val, .. } => Ok(*val), + Value::Int { val, .. } => Ok(*val as f64), + x => Err(ShellError::GenericError { + error: "Error converting to f64".into(), + msg: "".into(), + span: None, + help: Some(format!("Unexpected type: {x:?}")), + inner: vec![], + }), }) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::UInt8 => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as u8))) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::UInt16 => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as u16))) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::UInt32 => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as u32))) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::UInt64 => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as u64))) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::Int8 => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as i8))) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::Int16 => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as i16))) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::Int32 => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as i32))) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::Int64 => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| value_to_option(v, value_to_int)) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::Boolean => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| value_to_option(v, |v| v.as_bool())) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::String => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| value_to_option(v, |v| v.coerce_string())) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::Binary | DataType::BinaryOffset => { - let series_values: Result, _> = - column.values.iter().map(|v| v.coerce_binary()).collect(); - Ok(Series::new(name, series_values?)) - } - DataType::Object(_, _) => value_to_series(name, &column.values), - DataType::Duration(time_unit) => { - let series_values: Result, _> = column - .values - .iter() - .map(|v| { - value_to_option(v, |v| { - v.as_duration().map(|v| nanos_from_timeunit(v, *time_unit)) - }) + }) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::UInt8 => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as u8))) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::UInt16 => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as u16))) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::UInt32 => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as u32))) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::UInt64 => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as u64))) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::Int8 => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as i8))) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::Int16 => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as i16))) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::Int32 => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| value_to_option(v, |v| value_to_int(v).map(|v| v as i32))) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::Int64 => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| value_to_option(v, value_to_int)) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::Boolean => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| value_to_option(v, |v| v.as_bool())) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::String => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| value_to_option(v, |v| v.coerce_string())) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::Binary | DataType::BinaryOffset => { + let series_values: Result, _> = + column.values.iter().map(|v| v.coerce_binary()).collect(); + Ok(Series::new(name, series_values?)) + } + DataType::Object(_, _) => value_to_series(name, &column.values), + DataType::Duration(time_unit) => { + let series_values: Result, _> = column + .values + .iter() + .map(|v| { + value_to_option(v, |v| { + v.as_duration().map(|v| nanos_from_timeunit(v, *time_unit)) }) - .collect(); - Ok(Series::new(name, series_values?)) - } - DataType::List(list_type) => { - match input_type_list_to_series(&name, list_type.as_ref(), &column.values) { - Ok(series) => Ok(series), - Err(_) => { - // An error case will occur when there are lists of mixed types. - // If this happens, fallback to object list - input_type_list_to_series( - &name, - &DataType::Object("unknown", None), - &column.values, - ) - } + }) + .collect(); + Ok(Series::new(name, series_values?)) + } + DataType::List(list_type) => { + match input_type_list_to_series(&name, list_type.as_ref(), &column.values) { + Ok(series) => Ok(series), + Err(_) => { + // An error case will occur when there are lists of mixed types. + // If this happens, fallback to object list + input_type_list_to_series( + &name, + &DataType::Object("unknown", None), + &column.values, + ) } } - DataType::Date => { - let it = column.values.iter().map(|v| { + } + DataType::Date => { + let it = column.values.iter().map(|v| { + if let Value::Date { val, .. } = &v { + Some(val.timestamp_nanos_opt().unwrap_or_default()) + } else { + None + } + }); + + let res: DatetimeChunked = ChunkedArray::::from_iter_options(name, it) + .into_datetime(TimeUnit::Nanoseconds, None); + + Ok(res.into_series()) + } + DataType::Datetime(tu, maybe_tz) => { + let dates = column + .values + .iter() + .map(|v| { if let Value::Date { val, .. } = &v { - Some(val.timestamp_nanos_opt().unwrap_or_default()) - } else { - None - } - }); - - let res: DatetimeChunked = ChunkedArray::::from_iter_options(name, it) - .into_datetime(TimeUnit::Nanoseconds, None); - - Ok(res.into_series()) - } - DataType::Datetime(tu, maybe_tz) => { - let dates = column - .values - .iter() - .map(|v| { - if let Value::Date { val, .. } = &v { - // If there is a timezone specified, make sure - // the value is converted to it - Ok(maybe_tz - .as_ref() - .map(|tz| tz.parse::().map(|tz| val.with_timezone(&tz))) - .transpose() - .map_err(|e| ShellError::GenericError { - error: "Error parsing timezone".into(), - msg: "".into(), - span: None, - help: Some(e.to_string()), - inner: vec![], - })? - .and_then(|dt| dt.timestamp_nanos_opt()) - .map(|nanos| nanos_from_timeunit(nanos, *tu))) - } else { - Ok(None) - } - }) - .collect::>, ShellError>>()?; - - let res: DatetimeChunked = - ChunkedArray::::from_iter_options(name, dates.into_iter()) - .into_datetime(*tu, maybe_tz.clone()); - - Ok(res.into_series()) - } - DataType::Struct(fields) => { - let schema = Some(NuSchema::new(Schema::from_iter(fields.clone()))); - // let mut structs: Vec = Vec::new(); - let mut structs: HashMap = HashMap::new(); - - for v in column.values.iter() { - let mut column_values: ColumnMap = IndexMap::new(); - let record = v.as_record()?; - insert_record(&mut column_values, record.clone(), &schema)?; - let df = from_parsed_columns(column_values)?; - for name in df.df.get_column_names() { - let series = df - .df - .column(name) + // If there is a timezone specified, make sure + // the value is converted to it + Ok(maybe_tz + .as_ref() + .map(|tz| tz.parse::().map(|tz| val.with_timezone(&tz))) + .transpose() .map_err(|e| ShellError::GenericError { - error: format!( - "Error creating struct, could not get column name {name}: {e}" - ), + error: "Error parsing timezone".into(), msg: "".into(), span: None, - help: None, + help: Some(e.to_string()), inner: vec![], })? - .as_materialized_series(); + .and_then(|dt| dt.timestamp_nanos_opt()) + .map(|nanos| nanos_from_timeunit(nanos, *tu))) + } else { + Ok(None) + } + }) + .collect::>, ShellError>>()?; - if let Some(v) = structs.get_mut(name) { - let _ = v.append(series) + let res: DatetimeChunked = + ChunkedArray::::from_iter_options(name, dates.into_iter()) + .into_datetime(*tu, maybe_tz.clone()); + + Ok(res.into_series()) + } + DataType::Struct(fields) => { + let schema = Some(NuSchema::new(Schema::from_iter(fields.clone()))); + // let mut structs: Vec = Vec::new(); + let mut structs: HashMap = HashMap::new(); + + for v in column.values.iter() { + let mut column_values: ColumnMap = IndexMap::new(); + let record = v.as_record()?; + insert_record(&mut column_values, record.clone(), &schema)?; + let df = from_parsed_columns(column_values)?; + for name in df.df.get_column_names() { + let series = df + .df + .column(name) + .map_err(|e| ShellError::GenericError { + error: format!( + "Error creating struct, could not get column name {name}: {e}" + ), + msg: "".into(), + span: None, + help: None, + inner: vec![], + })? + .as_materialized_series(); + + if let Some(v) = structs.get_mut(name) { + let _ = v.append(series) .map_err(|e| ShellError::GenericError { error: format!("Error creating struct, could not append to series for col {name}: {e}"), msg: "".into(), @@ -530,44 +507,32 @@ fn typed_column_to_series(name: PlSmallStr, column: TypedColumn) -> Result = structs.into_values().collect(); - - let chunked = StructChunked::from_series( - column.name().to_owned(), - structs.len(), - structs.iter(), - ) - .map_err(|e| ShellError::GenericError { - error: format!("Error creating struct: {e}"), - msg: "".into(), - span: None, - help: None, - inner: vec![], - })?; - Ok(chunked.into_series()) } - _ => Err(ShellError::GenericError { - error: format!("Error creating dataframe: Unsupported type: {column_type:?}"), - msg: "".into(), - span: None, - help: None, - inner: vec![], - }), + + let structs: Vec = structs.into_values().collect(); + + let chunked = + StructChunked::from_series(column.name().to_owned(), structs.len(), structs.iter()) + .map_err(|e| ShellError::GenericError { + error: format!("Error creating struct: {e}"), + msg: "".into(), + span: None, + help: None, + inner: vec![], + })?; + Ok(chunked.into_series()) } - } else { - Err(ShellError::GenericError { - error: "Passed a type column with no type".into(), + _ => Err(ShellError::GenericError { + error: format!("Error creating dataframe: Unsupported type: {column_type:?}"), msg: "".into(), span: None, help: None, inner: vec![], - }) + }), } } diff --git a/crates/nu_plugin_query/Cargo.toml b/crates/nu_plugin_query/Cargo.toml index 431b728f62..260b909c90 100644 --- a/crates/nu_plugin_query/Cargo.toml +++ b/crates/nu_plugin_query/Cargo.toml @@ -20,7 +20,7 @@ nu-plugin = { path = "../nu-plugin", version = "0.100.1" } nu-protocol = { path = "../nu-protocol", version = "0.100.1" } gjson = "0.8" -scraper = { default-features = false, version = "0.21" } +scraper = { default-features = false, version = "0.22" } sxd-document = "0.3" sxd-xpath = "0.4" webpage = { version = "2.0.1", features = ["serde"] } diff --git a/src/main.rs b/src/main.rs index bef8d07caf..4ebc215531 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,8 +24,8 @@ use nu_cli::gather_parent_env_vars; use nu_lsp::LanguageServer; use nu_path::canonicalize_with; use nu_protocol::{ - engine::EngineState, report_shell_error, ByteStream, Config, IntoValue, PipelineData, - ShellError, Span, Spanned, Value, + engine::EngineState, record, report_shell_error, ByteStream, Config, IntoValue, PipelineData, + ShellError, Span, Spanned, Type, Value, }; use nu_std::load_standard_library; use nu_utils::perf; @@ -147,22 +147,43 @@ fn main() -> Result<()> { let mut default_nu_lib_dirs_path = nushell_config_path.clone(); default_nu_lib_dirs_path.push("scripts"); - engine_state.add_env_var( - "NU_LIB_DIRS".to_string(), + // env.NU_LIB_DIRS to be replaced by constant (below) - Eventual deprecation + // but an empty list for now to allow older code to work + engine_state.add_env_var("NU_LIB_DIRS".to_string(), Value::test_list(vec![])); + + let mut working_set = nu_protocol::engine::StateWorkingSet::new(&engine_state); + let var_id = working_set.add_variable( + b"$NU_LIB_DIRS".into(), + Span::unknown(), + Type::List(Box::new(Type::String)), + false, + ); + working_set.set_variable_const_val( + var_id, Value::test_list(vec![ Value::test_string(default_nu_lib_dirs_path.to_string_lossy()), Value::test_string(default_nushell_completions_path.to_string_lossy()), ]), ); + engine_state.merge_delta(working_set.render())?; let mut default_nu_plugin_dirs_path = nushell_config_path; default_nu_plugin_dirs_path.push("plugins"); - engine_state.add_env_var( - "NU_PLUGIN_DIRS".to_string(), + engine_state.add_env_var("NU_PLUGIN_DIRS".to_string(), Value::test_list(vec![])); + let mut working_set = nu_protocol::engine::StateWorkingSet::new(&engine_state); + let var_id = working_set.add_variable( + b"$NU_PLUGIN_DIRS".into(), + Span::unknown(), + Type::List(Box::new(Type::String)), + false, + ); + working_set.set_variable_const_val( + var_id, Value::test_list(vec![Value::test_string( default_nu_plugin_dirs_path.to_string_lossy(), )]), ); + engine_state.merge_delta(working_set.render())?; // End: Default NU_LIB_DIRS, NU_PLUGIN_DIRS // This is the real secret sauce to having an in-memory sqlite db. You must @@ -264,6 +285,11 @@ fn main() -> Result<()> { ); perf!("$env.config setup", start_time, use_color); + engine_state.add_env_var( + "ENV_CONVERSIONS".to_string(), + Value::test_record(record! {}), + ); + start_time = std::time::Instant::now(); if let Some(include_path) = &parsed_nu_cli_args.include_path { let span = include_path.span; @@ -273,7 +299,15 @@ fn main() -> Result<()> { .map(|x| Value::string(x.trim().to_string(), span)) .collect(); - engine_state.add_env_var("NU_LIB_DIRS".into(), Value::list(vals, span)); + let mut working_set = nu_protocol::engine::StateWorkingSet::new(&engine_state); + let var_id = working_set.add_variable( + b"$NU_LIB_DIRS".into(), + span, + Type::List(Box::new(Type::String)), + false, + ); + working_set.set_variable_const_val(var_id, Value::list(vals, span)); + engine_state.merge_delta(working_set.render())?; } perf!("NU_LIB_DIRS setup", start_time, use_color); @@ -286,9 +320,29 @@ fn main() -> Result<()> { "NU_VERSION".to_string(), Value::string(env!("CARGO_PKG_VERSION"), Span::unknown()), ); - // Add SHLVL if interactive if engine_state.is_interactive { + engine_state.add_env_var("PROMPT_INDICATOR".to_string(), Value::test_string("> ")); + engine_state.add_env_var( + "PROMPT_INDICATOR_VI_NORMAL".to_string(), + Value::test_string("> "), + ); + engine_state.add_env_var( + "PROMPT_INDICATOR_VI_INSERT".to_string(), + Value::test_string(": "), + ); + engine_state.add_env_var( + "PROMPT_MULTILINE_INDICATOR".to_string(), + Value::test_string("::: "), + ); + engine_state.add_env_var( + "TRANSIENT_PROMPT_MULTILINE_INDICATOR".to_string(), + Value::test_string(""), + ); + engine_state.add_env_var( + "TRANSIENT_PROMPT_COMMAND_RIGHT".to_string(), + Value::test_string(""), + ); let mut shlvl = engine_state .get_env_var("SHLVL") .map(|x| x.as_str().unwrap_or("0").parse::().unwrap_or(0)) diff --git a/src/run.rs b/src/run.rs index eb2a9b2e98..89bad3866f 100644 --- a/src/run.rs +++ b/src/run.rs @@ -12,30 +12,6 @@ use nu_protocol::{ }; use nu_utils::perf; -#[cfg(windows)] -fn init_pwd_per_drive(engine_state: &EngineState, stack: &mut Stack) { - use nu_path::DriveToPwdMap; - use std::path::Path; - - // Read environment for PWD-per-drive - for drive_letter in 'A'..='Z' { - let env_var = DriveToPwdMap::env_var_for_drive(drive_letter); - if let Some(env_pwd) = engine_state.get_env_var(&env_var) { - if let Ok(pwd_str) = nu_engine::env_to_string(&env_var, env_pwd, engine_state, stack) { - trace!("Get Env({}) {}", env_var, pwd_str); - let _ = stack.pwd_per_drive.set_pwd(Path::new(&pwd_str)); - stack.remove_env_var(engine_state, &env_var); - } - } - } - - if let Ok(abs_pwd) = engine_state.cwd(None) { - if let Some(abs_pwd_str) = abs_pwd.to_str() { - let _ = stack.pwd_per_drive.set_pwd(Path::new(abs_pwd_str)); - } - } -} - pub(crate) fn run_commands( engine_state: &mut EngineState, parsed_nu_cli_args: command::NushellCliArgs, @@ -50,8 +26,6 @@ pub(crate) fn run_commands( let create_scaffold = nu_path::nu_config_dir().map_or(false, |p| !p.exists()); let mut stack = Stack::new(); - #[cfg(windows)] - init_pwd_per_drive(engine_state, &mut stack); // if the --no-config-file(-n) option is NOT passed, load the plugin file, // load the default env file or custom (depending on parsed_nu_cli_args.env_file), @@ -141,8 +115,6 @@ pub(crate) fn run_file( ) { trace!("run_file"); let mut stack = Stack::new(); - #[cfg(windows)] - init_pwd_per_drive(engine_state, &mut stack); // if the --no-config-file(-n) option is NOT passed, load the plugin file, // load the default env file or custom (depending on parsed_nu_cli_args.env_file), @@ -210,9 +182,6 @@ pub(crate) fn run_repl( ) -> Result<(), miette::ErrReport> { trace!("run_repl"); let mut stack = Stack::new(); - #[cfg(windows)] - init_pwd_per_drive(engine_state, &mut stack); - let start_time = std::time::Instant::now(); if parsed_nu_cli_args.no_config_file.is_none() { diff --git a/tests/repl/test_engine.rs b/tests/repl/test_engine.rs index 90dd1e86b0..5c2fb8e533 100644 --- a/tests/repl/test_engine.rs +++ b/tests/repl/test_engine.rs @@ -90,12 +90,19 @@ fn help_works_with_missing_requirements() -> TestResult { run_test(r#"each --help | lines | length"#, "72") } -#[test] -fn scope_variable() -> TestResult { - run_test( - r#"let x = 3; scope variables | where name == "$x" | get type.0"#, - "int", - ) +#[rstest] +#[case("let x = 3", "$x", "int", "3")] +#[case("const x = 3", "$x", "int", "3")] +fn scope_variable( + #[case] var_decl: &str, + #[case] exp_name: &str, + #[case] exp_type: &str, + #[case] exp_value: &str, +) -> TestResult { + let get_var_info = + format!(r#"{var_decl}; scope variables | where name == "{exp_name}" | first"#); + run_test(&format!(r#"{get_var_info} | get type"#), exp_type)?; + run_test(&format!(r#"{get_var_info} | get value"#), exp_value) } #[rstest] diff --git a/tests/repl/test_env.rs b/tests/repl/test_env.rs index 7963f7580b..d540ce2fd4 100644 --- a/tests/repl/test_env.rs +++ b/tests/repl/test_env.rs @@ -17,13 +17,33 @@ fn shorthand_env_3() -> TestResult { } #[test] -fn default_nu_lib_dirs_type() { +fn default_nu_lib_dirs_env_type() { + // Previously, this was a list + // While we are transitioning to const NU_LIB_DIRS + // the env version will be empty, and thus a + // list let actual = nu!("$env.NU_LIB_DIRS | describe"); + assert_eq!(actual.out, "list"); +} + +#[test] +fn default_nu_lib_dirs_type() { + let actual = nu!("$NU_LIB_DIRS | describe"); assert_eq!(actual.out, "list"); } #[test] -fn default_nu_plugin_dirs_type() { +fn default_nu_plugin_dirs_env_type() { + // Previously, this was a list + // While we are transitioning to const NU_PLUGIN_DIRS + // the env version will be empty, and thus a + // list let actual = nu!("$env.NU_PLUGIN_DIRS | describe"); + assert_eq!(actual.out, "list"); +} + +#[test] +fn default_nu_plugin_dirs_type() { + let actual = nu!("$NU_PLUGIN_DIRS | describe"); assert_eq!(actual.out, "list"); }