diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2193598686..07e0b2b891 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -26,6 +26,13 @@ updates: patterns: - "polars" - "polars-*" + # uutils/coreutils also versions all their workspace crates the same at the moment + # Most of them have bleeding edge version requirements (some not) + # see: https://github.com/uutils/coreutils/blob/main/Cargo.toml + uutils: + patterns: + - "uucore" + - "uu_*" - package-ecosystem: "github-actions" directory: "/" schedule: diff --git a/.github/workflows/nightly-build.yml b/.github/workflows/nightly-build.yml index 8097b02fe6..c581e4a274 100644 --- a/.github/workflows/nightly-build.yml +++ b/.github/workflows/nightly-build.yml @@ -99,13 +99,13 @@ jobs: extra: msi os: windows-latest - target: x86_64-unknown-linux-gnu - os: ubuntu-20.04 + os: ubuntu-22.04 - target: x86_64-unknown-linux-musl - os: ubuntu-20.04 + os: ubuntu-22.04 - target: aarch64-unknown-linux-gnu - os: ubuntu-20.04 + os: ubuntu-22.04 - target: armv7-unknown-linux-gnueabihf - os: ubuntu-20.04 + os: ubuntu-22.04 - target: riscv64gc-unknown-linux-gnu os: ubuntu-latest @@ -161,7 +161,7 @@ jobs: # REF: https://github.com/marketplace/actions/gh-release # Create a release only in nushell/nightly repo - name: Publish Archive - uses: softprops/action-gh-release@v2.0.6 + uses: softprops/action-gh-release@v2.0.8 if: ${{ startsWith(github.repository, 'nushell/nightly') }} with: prerelease: true diff --git a/.github/workflows/release-pkg.nu b/.github/workflows/release-pkg.nu index da2779f6d1..562f42b4a4 100755 --- a/.github/workflows/release-pkg.nu +++ b/.github/workflows/release-pkg.nu @@ -161,8 +161,12 @@ if $os in ['macos-latest'] or $USE_UBUNTU { let releaseStem = $'($bin)-($version)-($target)' print $'(char nl)Download less related stuffs...'; hr-line + # todo: less-v661 is out but is released as a zip file. maybe we should switch to that and extract it? aria2c https://github.com/jftuga/less-Windows/releases/download/less-v608/less.exe -o less.exe - aria2c https://raw.githubusercontent.com/jftuga/less-Windows/master/LICENSE -o LICENSE-for-less.txt + # the below was renamed because it was failing to download for darren. it should work but it wasn't + # todo: maybe we should get rid of this aria2c dependency and just use http get? + #aria2c https://raw.githubusercontent.com/jftuga/less-Windows/master/LICENSE -o LICENSE-for-less.txt + aria2c https://github.com/jftuga/less-Windows/blob/master/LICENSE -o LICENSE-for-less.txt # Create Windows msi release package if (get-env _EXTRA_) == 'msi' { diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dd3371e0d3..53f22cec66 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -49,13 +49,13 @@ jobs: extra: msi os: windows-latest - target: x86_64-unknown-linux-gnu - os: ubuntu-20.04 + os: ubuntu-22.04 - target: x86_64-unknown-linux-musl - os: ubuntu-20.04 + os: ubuntu-22.04 - target: aarch64-unknown-linux-gnu - os: ubuntu-20.04 + os: ubuntu-22.04 - target: armv7-unknown-linux-gnueabihf - os: ubuntu-20.04 + os: ubuntu-22.04 - target: riscv64gc-unknown-linux-gnu os: ubuntu-latest @@ -91,7 +91,7 @@ jobs: # REF: https://github.com/marketplace/actions/gh-release - name: Publish Archive - uses: softprops/action-gh-release@v2.0.6 + uses: softprops/action-gh-release@v2.0.8 if: ${{ startsWith(github.ref, 'refs/tags/') }} with: draft: true diff --git a/.github/workflows/typos.yml b/.github/workflows/typos.yml index 95fc51b970..98ace3be57 100644 --- a/.github/workflows/typos.yml +++ b/.github/workflows/typos.yml @@ -10,4 +10,4 @@ jobs: uses: actions/checkout@v4.1.7 - name: Check spelling - uses: crate-ci/typos@v1.22.9 + uses: crate-ci/typos@v1.23.5 diff --git a/Cargo.lock b/Cargo.lock index 72b7f72b3b..902210ffbc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -605,7 +605,7 @@ dependencies = [ "encoding_rs", "log", "once_cell", - "quick-xml", + "quick-xml 0.31.0", "serde", "zip", ] @@ -1219,24 +1219,24 @@ dependencies = [ ] [[package]] -name = "dirs-next" -version = "2.0.0" +name = "dirs" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" dependencies = [ - "cfg-if", - "dirs-sys-next", + "dirs-sys", ] [[package]] -name = "dirs-sys-next" -version = "0.1.2" +name = "dirs-sys" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" dependencies = [ "libc", + "option-ext", "redox_users", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -2342,9 +2342,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.154" +version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] name = "libflate" @@ -2382,9 +2382,9 @@ dependencies = [ [[package]] name = "libloading" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d" dependencies = [ "cfg-if", "windows-targets 0.52.5", @@ -2868,12 +2868,12 @@ dependencies = [ [[package]] name = "nu" -version = "0.95.1" +version = "0.96.2" dependencies = [ "assert_cmd", "crossterm", "ctrlc", - "dirs-next", + "dirs", "log", "miette", "mimalloc", @@ -2900,6 +2900,7 @@ dependencies = [ "openssl", "pretty_assertions", "reedline", + "regex", "rstest", "serde_json", "serial_test", @@ -2912,16 +2913,16 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.50.0" +version = "0.50.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd2800e1520bdc966782168a627aa5d1ad92e33b984bf7c7615d31280c83ff14" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "nu-cli" -version = "0.95.1" +version = "0.96.2" dependencies = [ "chrono", "crossterm", @@ -2956,7 +2957,7 @@ dependencies = [ [[package]] name = "nu-cmd-base" -version = "0.95.1" +version = "0.96.2" dependencies = [ "indexmap", "miette", @@ -2968,7 +2969,7 @@ dependencies = [ [[package]] name = "nu-cmd-extra" -version = "0.95.1" +version = "0.96.2" dependencies = [ "fancy-regex", "heck 0.5.0", @@ -2993,7 +2994,7 @@ dependencies = [ [[package]] name = "nu-cmd-lang" -version = "0.95.1" +version = "0.96.2" dependencies = [ "itertools 0.12.1", "nu-engine", @@ -3005,7 +3006,7 @@ dependencies = [ [[package]] name = "nu-cmd-plugin" -version = "0.95.1" +version = "0.96.2" dependencies = [ "itertools 0.12.1", "nu-engine", @@ -3016,7 +3017,7 @@ dependencies = [ [[package]] name = "nu-color-config" -version = "0.95.1" +version = "0.96.2" dependencies = [ "nu-ansi-term", "nu-engine", @@ -3028,7 +3029,7 @@ dependencies = [ [[package]] name = "nu-command" -version = "0.95.1" +version = "0.96.2" dependencies = [ "alphanumeric-sort", "base64 0.22.1", @@ -3046,7 +3047,7 @@ dependencies = [ "deunicode", "dialoguer", "digest", - "dirs-next", + "dirs", "dtparse", "encoding_rs", "fancy-regex", @@ -3093,7 +3094,7 @@ dependencies = [ "pretty_assertions", "print-positions", "procfs", - "quick-xml", + "quick-xml 0.31.0", "quickcheck", "quickcheck_macros", "rand", @@ -3138,7 +3139,7 @@ dependencies = [ [[package]] name = "nu-derive-value" -version = "0.95.1" +version = "0.96.2" dependencies = [ "convert_case", "proc-macro-error", @@ -3149,17 +3150,19 @@ dependencies = [ [[package]] name = "nu-engine" -version = "0.95.1" +version = "0.96.2" dependencies = [ + "log", "nu-glob", "nu-path", "nu-protocol", "nu-utils", + "terminal_size", ] [[package]] name = "nu-explore" -version = "0.95.1" +version = "0.96.2" dependencies = [ "ansi-str", "anyhow", @@ -3184,16 +3187,19 @@ dependencies = [ [[package]] name = "nu-glob" -version = "0.95.1" +version = "0.96.2" dependencies = [ "doc-comment", ] [[package]] name = "nu-json" -version = "0.95.1" +version = "0.96.2" dependencies = [ + "fancy-regex", "linked-hash-map", + "nu-path", + "nu-test-support", "num-traits", "serde", "serde_json", @@ -3201,7 +3207,7 @@ dependencies = [ [[package]] name = "nu-lsp" -version = "0.95.1" +version = "0.96.2" dependencies = [ "assert-json-diff", "crossbeam-channel", @@ -3222,7 +3228,7 @@ dependencies = [ [[package]] name = "nu-parser" -version = "0.95.1" +version = "0.96.2" dependencies = [ "bytesize", "chrono", @@ -3238,16 +3244,16 @@ dependencies = [ [[package]] name = "nu-path" -version = "0.95.1" +version = "0.96.2" dependencies = [ - "dirs-next", + "dirs", "omnipath", "pwd", ] [[package]] name = "nu-plugin" -version = "0.95.1" +version = "0.96.2" dependencies = [ "log", "nix", @@ -3255,6 +3261,7 @@ dependencies = [ "nu-plugin-core", "nu-plugin-protocol", "nu-protocol", + "nu-utils", "serde", "thiserror", "typetag", @@ -3262,7 +3269,7 @@ dependencies = [ [[package]] name = "nu-plugin-core" -version = "0.95.1" +version = "0.96.2" dependencies = [ "interprocess", "log", @@ -3276,7 +3283,7 @@ dependencies = [ [[package]] name = "nu-plugin-engine" -version = "0.95.1" +version = "0.96.2" dependencies = [ "log", "nu-engine", @@ -3284,6 +3291,7 @@ dependencies = [ "nu-plugin-protocol", "nu-protocol", "nu-system", + "nu-utils", "serde", "typetag", "windows 0.54.0", @@ -3291,7 +3299,7 @@ dependencies = [ [[package]] name = "nu-plugin-protocol" -version = "0.95.1" +version = "0.96.2" dependencies = [ "bincode", "nu-protocol", @@ -3303,7 +3311,7 @@ dependencies = [ [[package]] name = "nu-plugin-test-support" -version = "0.95.1" +version = "0.96.2" dependencies = [ "nu-ansi-term", "nu-cmd-lang", @@ -3321,7 +3329,7 @@ dependencies = [ [[package]] name = "nu-pretty-hex" -version = "0.95.1" +version = "0.96.2" dependencies = [ "heapless", "nu-ansi-term", @@ -3330,15 +3338,18 @@ dependencies = [ [[package]] name = "nu-protocol" -version = "0.95.1" +version = "0.96.2" dependencies = [ "brotli", "byte-unit", "chrono", "chrono-humanize", "convert_case", + "dirs", + "dirs-sys", "fancy-regex", "indexmap", + "log", "lru", "miette", "nix", @@ -3359,11 +3370,12 @@ dependencies = [ "tempfile", "thiserror", "typetag", + "windows-sys 0.48.0", ] [[package]] name = "nu-std" -version = "0.95.1" +version = "0.96.2" dependencies = [ "log", "miette", @@ -3374,7 +3386,7 @@ dependencies = [ [[package]] name = "nu-system" -version = "0.95.1" +version = "0.96.2" dependencies = [ "chrono", "itertools 0.12.1", @@ -3392,7 +3404,7 @@ dependencies = [ [[package]] name = "nu-table" -version = "0.95.1" +version = "0.96.2" dependencies = [ "fancy-regex", "nu-ansi-term", @@ -3406,7 +3418,7 @@ dependencies = [ [[package]] name = "nu-term-grid" -version = "0.95.1" +version = "0.96.2" dependencies = [ "nu-utils", "unicode-width", @@ -3414,7 +3426,7 @@ dependencies = [ [[package]] name = "nu-test-support" -version = "0.95.1" +version = "0.96.2" dependencies = [ "nu-glob", "nu-path", @@ -3426,7 +3438,7 @@ dependencies = [ [[package]] name = "nu-utils" -version = "0.95.1" +version = "0.96.2" dependencies = [ "crossterm_winapi", "log", @@ -3452,7 +3464,7 @@ dependencies = [ [[package]] name = "nu_plugin_example" -version = "0.95.1" +version = "0.96.2" dependencies = [ "nu-cmd-lang", "nu-plugin", @@ -3462,20 +3474,22 @@ dependencies = [ [[package]] name = "nu_plugin_formats" -version = "0.95.1" +version = "0.96.2" dependencies = [ + "chrono", "eml-parser", "ical", "indexmap", "nu-plugin", "nu-plugin-test-support", "nu-protocol", + "plist", "rust-ini", ] [[package]] name = "nu_plugin_gstat" -version = "0.95.1" +version = "0.96.2" dependencies = [ "git2", "nu-plugin", @@ -3484,7 +3498,7 @@ dependencies = [ [[package]] name = "nu_plugin_inc" -version = "0.95.1" +version = "0.96.2" dependencies = [ "nu-plugin", "nu-protocol", @@ -3493,7 +3507,7 @@ dependencies = [ [[package]] name = "nu_plugin_polars" -version = "0.95.1" +version = "0.96.2" dependencies = [ "chrono", "chrono-tz 0.9.0", @@ -3527,7 +3541,7 @@ dependencies = [ [[package]] name = "nu_plugin_query" -version = "0.95.1" +version = "0.96.2" dependencies = [ "gjson", "nu-plugin", @@ -3542,7 +3556,7 @@ dependencies = [ [[package]] name = "nu_plugin_stress_internals" -version = "0.95.1" +version = "0.96.2" dependencies = [ "interprocess", "serde", @@ -3668,7 +3682,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "nuon" -version = "0.95.1" +version = "0.96.2" dependencies = [ "chrono", "fancy-regex", @@ -3765,9 +3779,9 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "open" -version = "5.2.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d2c909a3fce3bd80efef4cd1c6c056bd9376a8fe06fcfdbebaf32cb485a7e37" +checksum = "61a877bf6abd716642a53ef1b89fb498923a4afca5c754f9050b4d081c05c4b3" dependencies = [ "is-wsl", "libc", @@ -3776,9 +3790,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.64" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ "bitflags 2.5.0", "cfg-if", @@ -3817,9 +3831,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.102" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -3828,6 +3842,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "ordered-multimap" version = "0.7.3" @@ -4130,6 +4150,19 @@ dependencies = [ "winapi", ] +[[package]] +name = "plist" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" +dependencies = [ + "base64 0.22.1", + "indexmap", + "quick-xml 0.32.0", + "serde", + "time", +] + [[package]] name = "polars" version = "0.41.2" @@ -4798,6 +4831,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "quick-xml" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" +dependencies = [ + "memchr", +] + [[package]] name = "quickcheck" version = "1.0.3" @@ -4987,9 +5029,8 @@ dependencies = [ [[package]] name = "reedline" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf59e4c97b5049ba96b052cdb652368305a2eddcbce9bf1c16f9d003139eeea" +version = "0.33.0" +source = "git+https://github.com/nushell/reedline?branch=main#919292e40fd417e3da882692021961b444150c59" dependencies = [ "arboard", "chrono", @@ -5203,9 +5244,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "8.4.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19549741604902eb99a7ed0ee177a0663ee1eda51a29f71401f166e47e77806a" +checksum = "fa66af4a4fdd5e7ebc276f115e895611a34739a9c1c01028383d612d550953c0" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -5572,9 +5613,9 @@ dependencies = [ [[package]] name = "shadow-rs" -version = "0.29.0" +version = "0.30.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a600f795d0894cda22235b44eea4b85c2a35b405f65523645ac8e35b306817a" +checksum = "d253e54681d4be0161e965db57974ae642a0b6aaeb18a999424c4dab062be8c5" dependencies = [ "const_format", "is_debug", @@ -5649,9 +5690,9 @@ checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" [[package]] name = "similar" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" [[package]] name = "simplelog" @@ -6466,9 +6507,9 @@ checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] name = "ureq" -version = "2.9.7" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" +checksum = "72139d247e5f97a3eff96229a7ae85ead5328a39efe76f8bf5a06313d505b6ea" dependencies = [ "base64 0.22.1", "encoding_rs", @@ -6625,9 +6666,9 @@ checksum = "425a23c7b7145bc7620c9c445817c37b1f78b6790aee9f208133f3c028975b60" [[package]] name = "uuid" -version = "1.9.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de17fd2f7da591098415cff336e12965a28061ddace43b59cb3c430179c9439" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "getrandom", "serde", @@ -6855,7 +6896,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b3a62929287001986fb58c789dce9b67604a397c15c611ad9f747300b6c283" dependencies = [ "proc-macro2", - "quick-xml", + "quick-xml 0.31.0", "quote", ] diff --git a/Cargo.toml b/Cargo.toml index 573ace795f..ce62fa745e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,8 +10,8 @@ homepage = "https://www.nushell.sh" license = "MIT" name = "nu" repository = "https://github.com/nushell/nushell" -rust-version = "1.77.2" -version = "0.95.1" +rust-version = "1.78.0" +version = "0.96.2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html @@ -83,7 +83,8 @@ ctrlc = "3.4" deunicode = "1.6.0" dialoguer = { default-features = false, version = "0.11" } digest = { default-features = false, version = "0.10" } -dirs-next = "2.0" +dirs = "5.0" +dirs-sys = "0.4" dtparse = "2.0" encoding_rs = "0.8" fancy-regex = "0.13" @@ -115,12 +116,12 @@ mockito = { version = "1.4", default-features = false } native-tls = "0.2" nix = { version = "0.28", default-features = false } notify-debouncer-full = { version = "0.3", default-features = false } -nu-ansi-term = "0.50.0" +nu-ansi-term = "0.50.1" num-format = "0.4" num-traits = "0.2" omnipath = "0.1" once_cell = "1.18" -open = "5.2" +open = "5.3" os_pipe = { version = "1.2", features = ["io_safety"] } pathdiff = "0.2" percent-encoding = "2" @@ -137,7 +138,7 @@ quote = "1.0" rand = "0.8" ratatui = "0.26" rayon = "1.10" -reedline = "0.32.0" +reedline = "0.33.0" regex = "1.9.5" rmp = "0.8" rmp-serde = "1.3" @@ -145,7 +146,7 @@ ropey = "1.6.1" roxmltree = "0.19" rstest = { version = "0.18", default-features = false } rusqlite = "0.31" -rust-embed = "8.4.0" +rust-embed = "8.5.0" same-file = "1.0" serde = { version = "1.0", default-features = false } serde_json = "1.0" @@ -164,7 +165,7 @@ trash = "3.3" umask = "2.1" unicode-segmentation = "1.11" unicode-width = "0.1" -ureq = { version = "2.9", default-features = false } +ureq = { version = "2.10", default-features = false } url = "2.2" uu_cp = "0.0.27" uu_mkdir = "0.0.27" @@ -173,36 +174,36 @@ uu_mv = "0.0.27" uu_whoami = "0.0.27" uu_uname = "0.0.27" uucore = "0.0.27" -uuid = "1.9.1" +uuid = "1.10.0" v_htmlescape = "0.15.0" wax = "0.6" which = "6.0.0" windows = "0.54" +windows-sys = "0.48" winreg = "0.52" [dependencies] -nu-cli = { path = "./crates/nu-cli", version = "0.95.1" } -nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.95.1" } -nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.95.1" } -nu-cmd-plugin = { path = "./crates/nu-cmd-plugin", version = "0.95.1", optional = true } -nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.95.1" } -nu-command = { path = "./crates/nu-command", version = "0.95.1" } -nu-engine = { path = "./crates/nu-engine", version = "0.95.1" } -nu-explore = { path = "./crates/nu-explore", version = "0.95.1" } -nu-lsp = { path = "./crates/nu-lsp/", version = "0.95.1" } -nu-parser = { path = "./crates/nu-parser", version = "0.95.1" } -nu-path = { path = "./crates/nu-path", version = "0.95.1" } -nu-plugin-engine = { path = "./crates/nu-plugin-engine", optional = true, version = "0.95.1" } -nu-protocol = { path = "./crates/nu-protocol", version = "0.95.1" } -nu-std = { path = "./crates/nu-std", version = "0.95.1" } -nu-system = { path = "./crates/nu-system", version = "0.95.1" } -nu-utils = { path = "./crates/nu-utils", version = "0.95.1" } - +nu-cli = { path = "./crates/nu-cli", version = "0.96.2" } +nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.96.2" } +nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.96.2" } +nu-cmd-plugin = { path = "./crates/nu-cmd-plugin", version = "0.96.2", optional = true } +nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.96.2" } +nu-command = { path = "./crates/nu-command", version = "0.96.2" } +nu-engine = { path = "./crates/nu-engine", version = "0.96.2" } +nu-explore = { path = "./crates/nu-explore", version = "0.96.2" } +nu-lsp = { path = "./crates/nu-lsp/", version = "0.96.2" } +nu-parser = { path = "./crates/nu-parser", version = "0.96.2" } +nu-path = { path = "./crates/nu-path", version = "0.96.2" } +nu-plugin-engine = { path = "./crates/nu-plugin-engine", optional = true, version = "0.96.2" } +nu-protocol = { path = "./crates/nu-protocol", version = "0.96.2" } +nu-std = { path = "./crates/nu-std", version = "0.96.2" } +nu-system = { path = "./crates/nu-system", version = "0.96.2" } +nu-utils = { path = "./crates/nu-utils", version = "0.96.2" } reedline = { workspace = true, features = ["bashisms", "sqlite"] } crossterm = { workspace = true } ctrlc = { workspace = true } -dirs-next = { workspace = true } +dirs = { workspace = true } log = { workspace = true } miette = { workspace = true, features = ["fancy-no-backtrace", "fancy"] } mimalloc = { version = "0.1.42", default-features = false, optional = true } @@ -226,13 +227,14 @@ nix = { workspace = true, default-features = false, features = [ ] } [dev-dependencies] -nu-test-support = { path = "./crates/nu-test-support", version = "0.95.1" } -nu-plugin-protocol = { path = "./crates/nu-plugin-protocol", version = "0.95.1" } -nu-plugin-core = { path = "./crates/nu-plugin-core", version = "0.95.1" } +nu-test-support = { path = "./crates/nu-test-support", version = "0.96.2" } +nu-plugin-protocol = { path = "./crates/nu-plugin-protocol", version = "0.96.2" } +nu-plugin-core = { path = "./crates/nu-plugin-core", version = "0.96.2" } assert_cmd = "2.0" -dirs-next = { workspace = true } +dirs = { workspace = true } tango-bench = "0.5" pretty_assertions = { workspace = true } +regex = { workspace = true } rstest = { workspace = true, default-features = false } serial_test = "3.1" tempfile = { workspace = true } @@ -304,11 +306,11 @@ bench = false # To use a development version of a dependency please use a global override here # changing versions in each sub-crate of the workspace is tedious [patch.crates-io] -# reedline = { git = "https://github.com/nushell/reedline", branch = "main" } +reedline = { git = "https://github.com/nushell/reedline", branch = "main" } # nu-ansi-term = {git = "https://github.com/nushell/nu-ansi-term.git", branch = "main"} # Run all benchmarks with `cargo bench` # Run individual benchmarks like `cargo bench -- ` e.g. `cargo bench -- parse` [[bench]] name = "benchmarks" -harness = false \ No newline at end of file +harness = false diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000000..3f161a77f9 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,29 @@ +# Security Policy + +As a shell and programming language Nushell provides you with great powers and the potential to do dangerous things to your computer and data. Whenever there is a risk that a malicious actor can abuse a bug or a violation of documented behavior/assumptions in Nushell to harm you this is a *security* risk. +We want to fix those issues without exposing our users to unnecessary risk. Thus we want to explain our security policy. +Additional issues may be part of *safety* where the behavior of Nushell as designed and implemented can cause unintended harm or a bug causes damage without the involvement of a third party. + +## Supported Versions + +As Nushell is still under very active pre-stable development, the only version the core team prioritizes for security and safety fixes is the [most recent version as published on GitHub](https://github.com/nushell/nushell/releases/latest). +Only if you provide a strong reasoning and the necessary resources, will we consider blessing a backported fix with an official patch release for a previous version. + +## Reporting a Vulnerability + +If you suspect that a bug or behavior of Nushell can affect security or may be potentially exploitable, please report the issue to us in private. +Either reach out to the core team on [our Discord server](https://discord.gg/NtAbbGn) to arrange a private channel or use the [GitHub vulnerability reporting form](https://github.com/nushell/nushell/security/advisories/new). +Please try to answer the following questions: +- How can we reach you for further questions? +- What is the bug? Which system of Nushell may be affected? +- Do you have proof-of-concept for a potential exploit or have you observed an exploit in the wild? +- What is your assessment of the severity based on what could be impacted should the bug be exploited? +- Are additional people aware of the issue or deserve credit for identifying the issue? + +We will try to get back to you within a week with: +- acknowledging the receipt of the report +- an initial plan of how we want to address this including the primary points of contact for further communication +- our preliminary assessment of how severe we judge the issue +- a proposal for how we can coordinate responsible disclosure (e.g. how we ship the bugfix, if we need to coordinate with distribution maintainers, when you can release a blog post if you want to etc.) + +For purely *safety* related issues where the impact is severe by direct user action instead of malicious input or third parties, feel free to open a regular issue. If we deem that there may be an additional *security* risk on a *safety* issue we may continue discussions in a restricted forum. diff --git a/benches/benchmarks.rs b/benches/benchmarks.rs index 7a23715c8d..4efb666507 100644 --- a/benches/benchmarks.rs +++ b/benches/benchmarks.rs @@ -4,11 +4,14 @@ use nu_plugin_protocol::{PluginCallResponse, PluginOutput}; use nu_protocol::{ engine::{EngineState, Stack}, - PipelineData, Span, Spanned, Value, + PipelineData, Signals, Span, Spanned, Value, }; use nu_std::load_standard_library; use nu_utils::{get_default_config, get_default_env}; -use std::rc::Rc; +use std::{ + rc::Rc, + sync::{atomic::AtomicBool, Arc}, +}; use std::hint::black_box; @@ -42,6 +45,10 @@ fn setup_stack_and_engine_from_command(command: &str) -> (Stack, EngineState) { }; let mut stack = Stack::new(); + + // Support running benchmarks with IR mode + stack.use_ir = std::env::var_os("NU_USE_IR").is_some(); + evaluate_commands( &commands, &mut engine, @@ -248,14 +255,12 @@ fn bench_eval_interleave(n: i32) -> impl IntoBenchmarks { ) } -fn bench_eval_interleave_with_ctrlc(n: i32) -> impl IntoBenchmarks { +fn bench_eval_interleave_with_interrupt(n: i32) -> impl IntoBenchmarks { let mut engine = setup_engine(); - engine.ctrlc = Some(std::sync::Arc::new(std::sync::atomic::AtomicBool::new( - false, - ))); + engine.set_signals(Signals::new(Arc::new(AtomicBool::new(false)))); let stack = Stack::new(); bench_command( - &format!("eval_interleave_with_ctrlc_{n}"), + &format!("eval_interleave_with_interrupt_{n}"), &format!("seq 1 {n} | wrap a | interleave {{ seq 1 {n} | wrap b }} | ignore"), stack, engine, @@ -443,9 +448,9 @@ tango_benchmarks!( bench_eval_interleave(100), bench_eval_interleave(1_000), bench_eval_interleave(10_000), - bench_eval_interleave_with_ctrlc(100), - bench_eval_interleave_with_ctrlc(1_000), - bench_eval_interleave_with_ctrlc(10_000), + bench_eval_interleave_with_interrupt(100), + bench_eval_interleave_with_interrupt(1_000), + bench_eval_interleave_with_interrupt(10_000), // For bench_eval_for(1), bench_eval_for(10), diff --git a/crates/nu-cli/Cargo.toml b/crates/nu-cli/Cargo.toml index 2ed504d502..54af510916 100644 --- a/crates/nu-cli/Cargo.toml +++ b/crates/nu-cli/Cargo.toml @@ -5,27 +5,27 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cli" edition = "2021" license = "MIT" name = "nu-cli" -version = "0.95.1" +version = "0.96.2" [lib] bench = false [dev-dependencies] -nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.95.1" } -nu-command = { path = "../nu-command", version = "0.95.1" } -nu-test-support = { path = "../nu-test-support", version = "0.95.1" } +nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.96.2" } +nu-command = { path = "../nu-command", version = "0.96.2" } +nu-test-support = { path = "../nu-test-support", version = "0.96.2" } rstest = { workspace = true, default-features = false } tempfile = { workspace = true } [dependencies] -nu-cmd-base = { path = "../nu-cmd-base", version = "0.95.1" } -nu-engine = { path = "../nu-engine", version = "0.95.1" } -nu-path = { path = "../nu-path", version = "0.95.1" } -nu-parser = { path = "../nu-parser", version = "0.95.1" } -nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.95.1", optional = true } -nu-protocol = { path = "../nu-protocol", version = "0.95.1" } -nu-utils = { path = "../nu-utils", version = "0.95.1" } -nu-color-config = { path = "../nu-color-config", version = "0.95.1" } +nu-cmd-base = { path = "../nu-cmd-base", version = "0.96.2" } +nu-engine = { path = "../nu-engine", version = "0.96.2" } +nu-path = { path = "../nu-path", version = "0.96.2" } +nu-parser = { path = "../nu-parser", version = "0.96.2" } +nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.96.2", optional = true } +nu-protocol = { path = "../nu-protocol", version = "0.96.2" } +nu-utils = { path = "../nu-utils", version = "0.96.2" } +nu-color-config = { path = "../nu-color-config", version = "0.96.2" } nu-ansi-term = { workspace = true } reedline = { workspace = true, features = ["bashisms", "sqlite"] } diff --git a/crates/nu-cli/README.md b/crates/nu-cli/README.md new file mode 100644 index 0000000000..e0eca3c9bd --- /dev/null +++ b/crates/nu-cli/README.md @@ -0,0 +1,7 @@ +This crate implements the core functionality of the interactive Nushell REPL and interfaces with `reedline`. +Currently implements the syntax highlighting and completions logic. +Furthermore includes a few commands that are specific to `reedline` + +## Internal Nushell crate + +This crate implements components of Nushell and is not designed to support plugin authors or other users directly. diff --git a/crates/nu-cli/src/commands/history/history_.rs b/crates/nu-cli/src/commands/history/history_.rs index 8b0714216e..c270cef003 100644 --- a/crates/nu-cli/src/commands/history/history_.rs +++ b/crates/nu-cli/src/commands/history/history_.rs @@ -47,7 +47,7 @@ impl Command for History { if let Some(config_path) = nu_path::config_dir() { let clear = call.has_flag(engine_state, stack, "clear")?; let long = call.has_flag(engine_state, stack, "long")?; - let ctrlc = engine_state.ctrlc.clone(); + let signals = engine_state.signals().clone(); let mut history_path = config_path; history_path.push("nushell"); @@ -67,7 +67,7 @@ impl Command for History { } else { let history_reader: Option> = match history.file_format { HistoryFileFormat::Sqlite => { - SqliteBackedHistory::with_file(history_path.clone(), None, None) + SqliteBackedHistory::with_file(history_path.clone().into(), None, None) .map(|inner| { let boxed: Box = Box::new(inner); boxed @@ -77,7 +77,7 @@ impl Command for History { HistoryFileFormat::PlainText => FileBackedHistory::with_file( history.max_size as usize, - history_path.clone(), + history_path.clone().into(), ) .map(|inner| { let boxed: Box = Box::new(inner); @@ -107,7 +107,7 @@ impl Command for History { file: history_path.display().to_string(), span: head, })? - .into_pipeline_data(head, ctrlc)), + .into_pipeline_data(head, signals)), HistoryFileFormat::Sqlite => Ok(history_reader .and_then(|h| { h.search(SearchQuery::everything(SearchDirection::Forward, None)) @@ -122,7 +122,7 @@ impl Command for History { file: history_path.display().to_string(), span: head, })? - .into_pipeline_data(head, ctrlc)), + .into_pipeline_data(head, signals)), } } } else { @@ -156,58 +156,34 @@ fn create_history_record(idx: usize, entry: HistoryItem, long: bool, head: Span) //2. Create a record of either short or long columns and values let item_id_value = Value::int( - match entry.id { - Some(id) => { - let ids = id.to_string(); - match ids.parse::() { - Ok(i) => i, - _ => 0i64, - } - } - None => 0i64, - }, + entry + .id + .and_then(|id| id.to_string().parse::().ok()) + .unwrap_or_default(), head, ); let start_timestamp_value = Value::string( - match entry.start_timestamp { - Some(time) => time.to_string(), - None => "".into(), - }, + entry + .start_timestamp + .map(|time| time.to_string()) + .unwrap_or_default(), head, ); let command_value = Value::string(entry.command_line, head); let session_id_value = Value::int( - match entry.session_id { - Some(sid) => { - let sids = sid.to_string(); - match sids.parse::() { - Ok(i) => i, - _ => 0i64, - } - } - None => 0i64, - }, - head, - ); - let hostname_value = Value::string( - match entry.hostname { - Some(host) => host, - None => "".into(), - }, - head, - ); - let cwd_value = Value::string( - match entry.cwd { - Some(cwd) => cwd, - None => "".into(), - }, + entry + .session_id + .and_then(|id| id.to_string().parse::().ok()) + .unwrap_or_default(), head, ); + let hostname_value = Value::string(entry.hostname.unwrap_or_default(), head); + let cwd_value = Value::string(entry.cwd.unwrap_or_default(), head); let duration_value = Value::duration( - match entry.duration { - Some(d) => d.as_nanos().try_into().unwrap_or(0), - None => 0, - }, + entry + .duration + .and_then(|d| d.as_nanos().try_into().ok()) + .unwrap_or(0), head, ); let exit_status_value = Value::int(entry.exit_status.unwrap_or(0), head); diff --git a/crates/nu-cli/src/commands/keybindings_list.rs b/crates/nu-cli/src/commands/keybindings_list.rs index f4450c0c23..abb5909a97 100644 --- a/crates/nu-cli/src/commands/keybindings_list.rs +++ b/crates/nu-cli/src/commands/keybindings_list.rs @@ -49,22 +49,26 @@ impl Command for KeybindingsList { fn run( &self, - _engine_state: &EngineState, - _stack: &mut Stack, + engine_state: &EngineState, + stack: &mut Stack, call: &Call, _input: PipelineData, ) -> Result { - let records = if call.named_len() == 0 { - let all_options = ["modifiers", "keycodes", "edits", "modes", "events"]; - all_options - .iter() - .flat_map(|argument| get_records(argument, call.head)) - .collect() - } else { - call.named_iter() - .flat_map(|(argument, _, _)| get_records(argument.item.as_str(), call.head)) - .collect() - }; + let all_options = ["modifiers", "keycodes", "edits", "modes", "events"]; + + let presence = all_options + .iter() + .map(|option| call.has_flag(engine_state, stack, option)) + .collect::, ShellError>>()?; + + let no_option_specified = presence.iter().all(|present| !*present); + + let records = all_options + .iter() + .zip(presence) + .filter(|(_, present)| no_option_specified || *present) + .flat_map(|(option, _)| get_records(option, call.head)) + .collect(); Ok(Value::list(records, call.head).into_pipeline_data()) } diff --git a/crates/nu-cli/src/completions/command_completions.rs b/crates/nu-cli/src/completions/command_completions.rs index 7970d852ab..f8107f8ed7 100644 --- a/crates/nu-cli/src/completions/command_completions.rs +++ b/crates/nu-cli/src/completions/command_completions.rs @@ -99,10 +99,9 @@ impl CommandCompletion { suggestion: Suggestion { value: String::from_utf8_lossy(&x.0).to_string(), description: x.1, - style: None, - extra: None, span: reedline::Span::new(span.start - offset, span.end - offset), append_whitespace: true, + ..Suggestion::default() }, kind: Some(SuggestionKind::Command(x.2)), }) @@ -118,11 +117,9 @@ impl CommandCompletion { .map(move |x| SemanticSuggestion { suggestion: Suggestion { value: x, - description: None, - style: None, - extra: None, span: reedline::Span::new(span.start - offset, span.end - offset), append_whitespace: true, + ..Suggestion::default() }, // TODO: is there a way to create a test? kind: None, @@ -136,11 +133,9 @@ impl CommandCompletion { results.push(SemanticSuggestion { suggestion: Suggestion { value: format!("^{}", external.suggestion.value), - description: None, - style: None, - extra: None, span: external.suggestion.span, append_whitespace: true, + ..Suggestion::default() }, kind: external.kind, }) diff --git a/crates/nu-cli/src/completions/completer.rs b/crates/nu-cli/src/completions/completer.rs index 2c407beb1e..91fc1132a5 100644 --- a/crates/nu-cli/src/completions/completer.rs +++ b/crates/nu-cli/src/completions/completer.rs @@ -444,14 +444,11 @@ pub fn map_value_completions<'a>( return Some(SemanticSuggestion { suggestion: Suggestion { value: s, - description: None, - style: None, - extra: None, span: reedline::Span { start: span.start - offset, end: span.end - offset, }, - append_whitespace: false, + ..Suggestion::default() }, kind: Some(SuggestionKind::Type(x.get_type())), }); @@ -461,14 +458,11 @@ pub fn map_value_completions<'a>( if let Ok(record) = x.as_record() { let mut suggestion = Suggestion { value: String::from(""), // Initialize with empty string - description: None, - style: None, - extra: None, span: reedline::Span { start: span.start - offset, end: span.end - offset, }, - append_whitespace: false, + ..Suggestion::default() }; // Iterate the cols looking for `value` and `description` diff --git a/crates/nu-cli/src/completions/completion_common.rs b/crates/nu-cli/src/completions/completion_common.rs index 8c322478bd..cc9f6f109e 100644 --- a/crates/nu-cli/src/completions/completion_common.rs +++ b/crates/nu-cli/src/completions/completion_common.rs @@ -11,9 +11,7 @@ use nu_protocol::{ CompletionSort, Span, }; use nu_utils::get_ls_colors; -use std::path::{ - is_separator, Component, Path, PathBuf, MAIN_SEPARATOR as SEP, MAIN_SEPARATOR_STR, -}; +use std::path::{is_separator, Component, Path, PathBuf, MAIN_SEPARATOR as SEP}; use super::MatchAlgorithm; @@ -23,12 +21,21 @@ pub struct PathBuiltFromString { isdir: bool, } -fn complete_rec( +/// Recursively goes through paths that match a given `partial`. +/// built: State struct for a valid matching path built so far. +/// +/// `isdir`: whether the current partial path has a trailing slash. +/// Parsing a path string into a pathbuf loses that bit of information. +/// +/// want_directory: Whether we want only directories as completion matches. +/// Some commands like `cd` can only be run on directories whereas others +/// like `ls` can be run on regular files as well. +pub fn complete_rec( partial: &[&str], built: &PathBuiltFromString, cwd: &Path, options: &CompletionOptions, - dir: bool, + want_directory: bool, isdir: bool, ) -> Vec { let mut completions = vec![]; @@ -38,7 +45,7 @@ fn complete_rec( let mut built = built.clone(); built.parts.push(base.to_string()); built.isdir = true; - return complete_rec(rest, &built, cwd, options, dir, isdir); + return complete_rec(rest, &built, cwd, options, want_directory, isdir); } } @@ -59,7 +66,7 @@ fn complete_rec( built.parts.push(entry_name.clone()); built.isdir = entry_isdir; - if !dir || entry_isdir { + if !want_directory || entry_isdir { entries.push((entry_name, built)); } } @@ -71,12 +78,29 @@ fn complete_rec( match partial.split_first() { Some((base, rest)) => { if matches(base, &entry_name, options) { + // We use `isdir` to confirm that the current component has + // at least one next component or a slash. + // Serves as confirmation to ignore longer completions for + // components in between. if !rest.is_empty() || isdir { - completions.extend(complete_rec(rest, &built, cwd, options, dir, isdir)); + completions.extend(complete_rec( + rest, + &built, + cwd, + options, + want_directory, + isdir, + )); } else { completions.push(built); } } + if entry_name.eq(base) + && matches!(options.match_algorithm, MatchAlgorithm::Prefix) + && isdir + { + break; + } } None => { completions.push(built); @@ -94,16 +118,16 @@ enum OriginalCwd { } impl OriginalCwd { - fn apply(&self, mut p: PathBuiltFromString) -> String { + fn apply(&self, mut p: PathBuiltFromString, path_separator: char) -> String { match self { Self::None => {} Self::Home => p.parts.insert(0, "~".to_string()), Self::Prefix(s) => p.parts.insert(0, s.clone()), }; - let mut ret = p.parts.join(MAIN_SEPARATOR_STR); + let mut ret = p.parts.join(&path_separator.to_string()); if p.isdir { - ret.push(SEP); + ret.push(path_separator); } ret } @@ -134,6 +158,14 @@ pub fn complete_item( ) -> Vec<(nu_protocol::Span, String, Option