Merge branch 'main' into ecow-record

This commit is contained in:
Ian Manske 2024-05-01 23:02:47 -04:00
commit 4fa58435bd
417 changed files with 8877 additions and 6519 deletions

View File

@ -19,7 +19,7 @@ jobs:
# Prevent sudden announcement of a new advisory from failing ci:
continue-on-error: true
steps:
- uses: actions/checkout@v4.1.2
- uses: actions/checkout@v4.1.4
- uses: rustsec/audit-check@v1.4.1
with:
token: ${{ secrets.GITHUB_TOKEN }}

View File

@ -44,7 +44,7 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4.1.2
- uses: actions/checkout@v4.1.4
- name: Setup Rust toolchain and cache
uses: actions-rust-lang/setup-rust-toolchain@v1.8.0
@ -89,7 +89,7 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4.1.2
- uses: actions/checkout@v4.1.4
- name: Setup Rust toolchain and cache
uses: actions-rust-lang/setup-rust-toolchain@v1.8.0
@ -121,7 +121,7 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4.1.2
- uses: actions/checkout@v4.1.4
- name: Setup Rust toolchain and cache
uses: actions-rust-lang/setup-rust-toolchain@v1.8.0
@ -174,7 +174,7 @@ jobs:
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4.1.2
- uses: actions/checkout@v4.1.4
- name: Setup Rust toolchain and cache
uses: actions-rust-lang/setup-rust-toolchain@v1.8.0

View File

@ -27,7 +27,7 @@ jobs:
# if: github.repository == 'nushell/nightly'
steps:
- name: Checkout
uses: actions/checkout@v4.1.2
uses: actions/checkout@v4.1.4
if: github.repository == 'nushell/nightly'
with:
ref: main
@ -36,7 +36,7 @@ jobs:
token: ${{ secrets.WORKFLOW_TOKEN }}
- name: Setup Nushell
uses: hustcer/setup-nu@v3.9
uses: hustcer/setup-nu@v3.10
if: github.repository == 'nushell/nightly'
with:
version: 0.91.0
@ -123,7 +123,7 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4.1.2
- uses: actions/checkout@v4.1.4
with:
ref: main
fetch-depth: 0
@ -139,7 +139,7 @@ jobs:
rustflags: ''
- name: Setup Nushell
uses: hustcer/setup-nu@v3.9
uses: hustcer/setup-nu@v3.10
with:
version: 0.91.0
@ -235,7 +235,7 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4.1.2
- uses: actions/checkout@v4.1.4
with:
ref: main
fetch-depth: 0
@ -251,7 +251,7 @@ jobs:
rustflags: ''
- name: Setup Nushell
uses: hustcer/setup-nu@v3.9
uses: hustcer/setup-nu@v3.10
with:
version: 0.91.0
@ -310,12 +310,12 @@ jobs:
- name: Waiting for Release
run: sleep 1800
- uses: actions/checkout@v4.1.2
- uses: actions/checkout@v4.1.4
with:
ref: main
- name: Setup Nushell
uses: hustcer/setup-nu@v3.9
uses: hustcer/setup-nu@v3.10
with:
version: 0.91.0

View File

@ -134,9 +134,15 @@ print $'(char nl)All executable files:'; hr-line
print (ls -f ($executable | into glob)); sleep 1sec
print $'(char nl)Copying release files...'; hr-line
"To use Nu plugins, use the register command to tell Nu where to find the plugin. For example:
"To use the included Nushell plugins, register the binaries with the `plugin add` command to tell Nu where to find the plugin.
Then you can use `plugin use` to load the plugin into your session.
For example:
> register ./nu_plugin_query" | save $'($dist)/README.txt' -f
> plugin add ./nu_plugin_query
> plugin use query
For more information, refer to https://www.nushell.sh/book/plugins.html
" | save $'($dist)/README.txt' -f
[LICENSE ...(glob $executable)] | each {|it| cp -rv $it $dist } | flatten
print $'(char nl)Check binary release version detail:'; hr-line
@ -186,7 +192,7 @@ if $os in ['macos-latest'] or $USE_UBUNTU {
# Wix need the binaries be stored in target/release/
cp -r ($'($dist)/*' | into glob) target/release/
ls target/release/* | print
cargo install cargo-wix --version 0.3.4
cargo install cargo-wix --version 0.3.8
cargo wix --no-build --nocapture --package nu --output $wixRelease
# Workaround for https://github.com/softprops/action-gh-release/issues/280
let archive = ($wixRelease | str replace --all '\' '/')

View File

@ -73,7 +73,7 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4.1.2
- uses: actions/checkout@v4.1.4
- name: Update Rust Toolchain Target
run: |
@ -87,7 +87,7 @@ jobs:
rustflags: ''
- name: Setup Nushell
uses: hustcer/setup-nu@v3.9
uses: hustcer/setup-nu@v3.10
with:
version: 0.91.0
@ -163,7 +163,7 @@ jobs:
runs-on: ${{matrix.os}}
steps:
- uses: actions/checkout@v4.1.2
- uses: actions/checkout@v4.1.4
- name: Update Rust Toolchain Target
run: |
@ -177,7 +177,7 @@ jobs:
rustflags: ''
- name: Setup Nushell
uses: hustcer/setup-nu@v3.9
uses: hustcer/setup-nu@v3.10
with:
version: 0.91.0

View File

@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Actions Repository
uses: actions/checkout@v4.1.2
uses: actions/checkout@v4.1.4
- name: Check spelling
uses: crate-ci/typos@v1.20.9
uses: crate-ci/typos@v1.21.0

205
Cargo.lock generated
View File

@ -165,6 +165,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "anyhow"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
[[package]]
name = "arboard"
version = "3.3.2"
@ -1155,19 +1161,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "dashmap"
version = "5.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856"
dependencies = [
"cfg-if",
"hashbrown 0.14.3",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]]
name = "deranged"
version = "0.3.11"
@ -2875,7 +2868,7 @@ dependencies = [
[[package]]
name = "nu"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"assert_cmd",
"crossterm",
@ -2898,7 +2891,9 @@ dependencies = [
"nu-lsp",
"nu-parser",
"nu-path",
"nu-plugin",
"nu-plugin-core",
"nu-plugin-engine",
"nu-plugin-protocol",
"nu-protocol",
"nu-std",
"nu-system",
@ -2927,7 +2922,7 @@ dependencies = [
[[package]]
name = "nu-cli"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"chrono",
"crossterm",
@ -2945,7 +2940,7 @@ dependencies = [
"nu-engine",
"nu-parser",
"nu-path",
"nu-plugin",
"nu-plugin-engine",
"nu-protocol",
"nu-test-support",
"nu-utils",
@ -2962,7 +2957,7 @@ dependencies = [
[[package]]
name = "nu-cmd-base"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"indexmap",
"miette",
@ -2974,7 +2969,7 @@ dependencies = [
[[package]]
name = "nu-cmd-dataframe"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"chrono",
"chrono-tz 0.8.6",
@ -2997,7 +2992,7 @@ dependencies = [
[[package]]
name = "nu-cmd-extra"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"fancy-regex",
"heck 0.5.0",
@ -3022,7 +3017,7 @@ dependencies = [
[[package]]
name = "nu-cmd-lang"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"itertools 0.12.1",
"nu-engine",
@ -3034,18 +3029,18 @@ dependencies = [
[[package]]
name = "nu-cmd-plugin"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"itertools 0.12.1",
"nu-engine",
"nu-path",
"nu-plugin",
"nu-plugin-engine",
"nu-protocol",
]
[[package]]
name = "nu-color-config"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"nu-ansi-term",
"nu-engine",
@ -3057,11 +3052,12 @@ dependencies = [
[[package]]
name = "nu-command"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"alphanumeric-sort",
"base64 0.22.0",
"bracoxide",
"brotli 5.0.0",
"byteorder",
"bytesize",
"calamine",
@ -3117,6 +3113,7 @@ dependencies = [
"os_pipe",
"pathdiff",
"percent-encoding",
"pretty_assertions",
"print-positions",
"procfs",
"quick-xml",
@ -3125,6 +3122,7 @@ dependencies = [
"rand",
"rayon",
"regex",
"rmp",
"roxmltree",
"rstest",
"rusqlite",
@ -3162,7 +3160,7 @@ dependencies = [
[[package]]
name = "nu-engine"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"nu-glob",
"nu-path",
@ -3172,10 +3170,12 @@ dependencies = [
[[package]]
name = "nu-explore"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"ansi-str",
"anyhow",
"crossterm",
"log",
"lscolors",
"nu-ansi-term",
"nu-color-config",
@ -3186,6 +3186,7 @@ dependencies = [
"nu-protocol",
"nu-table",
"nu-utils",
"once_cell",
"ratatui",
"strip-ansi-escapes",
"terminal_size",
@ -3194,14 +3195,14 @@ dependencies = [
[[package]]
name = "nu-glob"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"doc-comment",
]
[[package]]
name = "nu-json"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"linked-hash-map",
"num-traits",
@ -3211,7 +3212,7 @@ dependencies = [
[[package]]
name = "nu-lsp"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"assert-json-diff",
"crossbeam-channel",
@ -3232,7 +3233,7 @@ dependencies = [
[[package]]
name = "nu-parser"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"bytesize",
"chrono",
@ -3240,7 +3241,7 @@ dependencies = [
"log",
"nu-engine",
"nu-path",
"nu-plugin",
"nu-plugin-engine",
"nu-protocol",
"rstest",
"serde_json",
@ -3248,7 +3249,7 @@ dependencies = [
[[package]]
name = "nu-path"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"dirs-next",
"omnipath",
@ -3257,35 +3258,72 @@ dependencies = [
[[package]]
name = "nu-plugin"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"bincode",
"interprocess",
"log",
"miette",
"nix",
"nu-engine",
"nu-plugin-core",
"nu-plugin-protocol",
"nu-protocol",
"serde",
"thiserror",
"typetag",
]
[[package]]
name = "nu-plugin-core"
version = "0.93.1"
dependencies = [
"interprocess",
"log",
"nu-plugin-protocol",
"nu-protocol",
"nu-system",
"nu-utils",
"rmp-serde",
"semver",
"serde",
"serde_json",
"thiserror",
"windows 0.54.0",
]
[[package]]
name = "nu-plugin-engine"
version = "0.93.1"
dependencies = [
"log",
"nu-engine",
"nu-plugin-core",
"nu-plugin-protocol",
"nu-protocol",
"nu-system",
"serde",
"typetag",
"windows 0.54.0",
]
[[package]]
name = "nu-plugin-protocol"
version = "0.93.1"
dependencies = [
"bincode",
"nu-protocol",
"nu-utils",
"semver",
"serde",
"typetag",
]
[[package]]
name = "nu-plugin-test-support"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"nu-ansi-term",
"nu-cmd-lang",
"nu-engine",
"nu-parser",
"nu-plugin",
"nu-plugin-core",
"nu-plugin-engine",
"nu-plugin-protocol",
"nu-protocol",
"serde",
"similar",
@ -3294,7 +3332,7 @@ dependencies = [
[[package]]
name = "nu-pretty-hex"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"heapless",
"nu-ansi-term",
@ -3303,7 +3341,7 @@ dependencies = [
[[package]]
name = "nu-protocol"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"brotli 5.0.0",
"byte-unit",
@ -3332,7 +3370,7 @@ dependencies = [
[[package]]
name = "nu-std"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"log",
"miette",
@ -3343,7 +3381,7 @@ dependencies = [
[[package]]
name = "nu-system"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"chrono",
"libc",
@ -3360,7 +3398,7 @@ dependencies = [
[[package]]
name = "nu-table"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"fancy-regex",
"nu-ansi-term",
@ -3374,7 +3412,7 @@ dependencies = [
[[package]]
name = "nu-term-grid"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"nu-utils",
"unicode-width",
@ -3382,7 +3420,7 @@ dependencies = [
[[package]]
name = "nu-test-support"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"nu-glob",
"nu-path",
@ -3394,7 +3432,7 @@ dependencies = [
[[package]]
name = "nu-utils"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"crossterm_winapi",
"log",
@ -3420,7 +3458,7 @@ dependencies = [
[[package]]
name = "nu_plugin_example"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"nu-cmd-lang",
"nu-plugin",
@ -3430,7 +3468,7 @@ dependencies = [
[[package]]
name = "nu_plugin_formats"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"eml-parser",
"ical",
@ -3443,7 +3481,7 @@ dependencies = [
[[package]]
name = "nu_plugin_gstat"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"git2",
"nu-plugin",
@ -3452,7 +3490,7 @@ dependencies = [
[[package]]
name = "nu_plugin_inc"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"nu-plugin",
"nu-protocol",
@ -3461,7 +3499,7 @@ dependencies = [
[[package]]
name = "nu_plugin_polars"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"chrono",
"chrono-tz 0.9.0",
@ -3491,7 +3529,7 @@ dependencies = [
[[package]]
name = "nu_plugin_query"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"gjson",
"nu-plugin",
@ -3503,7 +3541,7 @@ dependencies = [
[[package]]
name = "nu_plugin_stress_internals"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"interprocess",
"serde",
@ -3629,7 +3667,7 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
[[package]]
name = "nuon"
version = "0.92.3"
version = "0.93.1"
dependencies = [
"chrono",
"fancy-regex",
@ -4859,8 +4897,9 @@ dependencies = [
[[package]]
name = "reedline"
version = "0.31.0"
source = "git+https://github.com/nushell/reedline?branch=main#cc9a957184800065bbc9741ef483a2dee19c2106"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abf59e4c97b5049ba96b052cdb652368305a2eddcbce9bf1c16f9d003139eeea"
dependencies = [
"arboard",
"chrono",
@ -5000,9 +5039,9 @@ checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
[[package]]
name = "rmp"
version = "0.8.13"
version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bddb316f4b9cae1a3e89c02f1926d557d1142d0d2e684b038c11c1b77705229a"
checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4"
dependencies = [
"byteorder",
"num-traits",
@ -5011,9 +5050,9 @@ dependencies = [
[[package]]
name = "rmp-serde"
version = "1.2.0"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "938a142ab806f18b88a97b0dea523d39e0fd730a064b035726adcfc58a8a5188"
checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db"
dependencies = [
"byteorder",
"rmp",
@ -5114,12 +5153,13 @@ dependencies = [
[[package]]
name = "rust-ini"
version = "0.20.0"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e0698206bcb8882bf2a9ecb4c1e7785db57ff052297085a6efd4fe42302068a"
checksum = "0d625ed57d8f49af6cfa514c42e1a71fadcff60eb0b1c517ff82fe41aa025b41"
dependencies = [
"cfg-if",
"ordered-multimap",
"trim-in-place",
]
[[package]]
@ -5193,6 +5233,15 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "scc"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec96560eea317a9cc4e0bb1f6a2c93c09a19b8c4fc5cb3fcc0ec1c094cd783e2"
dependencies = [
"sdd",
]
[[package]]
name = "schannel"
version = "0.1.23"
@ -5229,6 +5278,12 @@ dependencies = [
"tendril",
]
[[package]]
name = "sdd"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b84345e4c9bd703274a082fb80caaa99b7612be48dfaa1dd9266577ec412309d"
[[package]]
name = "seahash"
version = "4.1.0"
@ -5368,23 +5423,23 @@ dependencies = [
[[package]]
name = "serial_test"
version = "3.0.0"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ad9342b3aaca7cb43c45c097dd008d4907070394bd0751a0aa8817e5a018d"
checksum = "adb86f9315df5df6a70eae0cc22395a44e544a0d8897586820770a35ede74449"
dependencies = [
"dashmap",
"futures",
"lazy_static",
"log",
"once_cell",
"parking_lot",
"scc",
"serial_test_derive",
]
[[package]]
name = "serial_test_derive"
version = "3.0.0"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b93fb4adc70021ac1b47f7d45e8cc4169baaa7ea58483bc5b721d19a26202212"
checksum = "a9bb72430492e9549b0c4596725c0f82729bff861c45aa8099c0a8e67fc3b721"
dependencies = [
"proc-macro2",
"quote",
@ -6168,6 +6223,12 @@ dependencies = [
"petgraph",
]
[[package]]
name = "trim-in-place"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc"
[[package]]
name = "try-lock"
version = "0.2.5"

View File

@ -11,7 +11,7 @@ license = "MIT"
name = "nu"
repository = "https://github.com/nushell/nushell"
rust-version = "1.77.2"
version = "0.92.3"
version = "0.93.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -41,6 +41,9 @@ members = [
"crates/nu-pretty-hex",
"crates/nu-protocol",
"crates/nu-plugin",
"crates/nu-plugin-core",
"crates/nu-plugin-engine",
"crates/nu-plugin-protocol",
"crates/nu-plugin-test-support",
"crates/nu_plugin_inc",
"crates/nu_plugin_gstat",
@ -61,6 +64,7 @@ members = [
[workspace.dependencies]
alphanumeric-sort = "1.5"
ansi-str = "0.8"
anyhow = "1.0.82"
base64 = "0.22"
bracoxide = "0.1.2"
brotli = "5.0"
@ -90,6 +94,7 @@ heck = "0.5.0"
human-date-parser = "0.1.1"
indexmap = "2.2"
indicatif = "0.17"
interprocess = "1.2.1"
is_executable = "1.0"
itertools = "0.12"
libc = "0.2"
@ -117,6 +122,7 @@ open = "5.1"
os_pipe = "1.1"
pathdiff = "0.2"
percent-encoding = "2"
pretty_assertions = "1.4"
print-positions = "0.6"
procfs = "0.16.0"
pwd = "1.3"
@ -126,9 +132,10 @@ quickcheck_macros = "1.0"
rand = "0.8"
ratatui = "0.26"
rayon = "1.10"
reedline = "0.31.0"
reedline = "0.32.0"
regex = "1.9.5"
rmp-serde = "1.2"
rmp = "0.8"
rmp-serde = "1.3"
ropey = "1.6.1"
roxmltree = "0.19"
rstest = { version = "0.18", default-features = false }
@ -168,25 +175,25 @@ windows = "0.54"
winreg = "0.52"
[dependencies]
nu-cli = { path = "./crates/nu-cli", version = "0.92.3" }
nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.92.3" }
nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.92.3" }
nu-cmd-plugin = { path = "./crates/nu-cmd-plugin", version = "0.92.3", optional = true }
nu-cmd-dataframe = { path = "./crates/nu-cmd-dataframe", version = "0.92.3", features = [
nu-cli = { path = "./crates/nu-cli", version = "0.93.1" }
nu-cmd-base = { path = "./crates/nu-cmd-base", version = "0.93.1" }
nu-cmd-lang = { path = "./crates/nu-cmd-lang", version = "0.93.1" }
nu-cmd-plugin = { path = "./crates/nu-cmd-plugin", version = "0.93.1", optional = true }
nu-cmd-dataframe = { path = "./crates/nu-cmd-dataframe", version = "0.93.1", features = [
"dataframe",
], optional = true }
nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.92.3" }
nu-command = { path = "./crates/nu-command", version = "0.92.3" }
nu-engine = { path = "./crates/nu-engine", version = "0.92.3" }
nu-explore = { path = "./crates/nu-explore", version = "0.92.3" }
nu-lsp = { path = "./crates/nu-lsp/", version = "0.92.3" }
nu-parser = { path = "./crates/nu-parser", version = "0.92.3" }
nu-path = { path = "./crates/nu-path", version = "0.92.3" }
nu-plugin = { path = "./crates/nu-plugin", optional = true, version = "0.92.3" }
nu-protocol = { path = "./crates/nu-protocol", version = "0.92.3" }
nu-std = { path = "./crates/nu-std", version = "0.92.3" }
nu-system = { path = "./crates/nu-system", version = "0.92.3" }
nu-utils = { path = "./crates/nu-utils", version = "0.92.3" }
nu-cmd-extra = { path = "./crates/nu-cmd-extra", version = "0.93.1" }
nu-command = { path = "./crates/nu-command", version = "0.93.1" }
nu-engine = { path = "./crates/nu-engine", version = "0.93.1" }
nu-explore = { path = "./crates/nu-explore", version = "0.93.1" }
nu-lsp = { path = "./crates/nu-lsp/", version = "0.93.1" }
nu-parser = { path = "./crates/nu-parser", version = "0.93.1" }
nu-path = { path = "./crates/nu-path", version = "0.93.1" }
nu-plugin-engine = { path = "./crates/nu-plugin-engine", optional = true, version = "0.93.1" }
nu-protocol = { path = "./crates/nu-protocol", version = "0.93.1" }
nu-std = { path = "./crates/nu-std", version = "0.93.1" }
nu-system = { path = "./crates/nu-system", version = "0.93.1" }
nu-utils = { path = "./crates/nu-utils", version = "0.93.1" }
reedline = { workspace = true, features = ["bashisms", "sqlite"] }
@ -215,18 +222,20 @@ nix = { workspace = true, default-features = false, features = [
] }
[dev-dependencies]
nu-test-support = { path = "./crates/nu-test-support", version = "0.92.3" }
nu-test-support = { path = "./crates/nu-test-support", version = "0.93.1" }
nu-plugin-protocol = { path = "./crates/nu-plugin-protocol", version = "0.93.1" }
nu-plugin-core = { path = "./crates/nu-plugin-core", version = "0.93.1" }
assert_cmd = "2.0"
dirs-next = { workspace = true }
divan = "0.1.14"
pretty_assertions = "1.4"
pretty_assertions = { workspace = true }
rstest = { workspace = true, default-features = false }
serial_test = "3.0"
serial_test = "3.1"
tempfile = { workspace = true }
[features]
plugin = [
"nu-plugin",
"nu-plugin-engine",
"nu-cmd-plugin",
"nu-cli/plugin",
"nu-parser/plugin",
@ -296,7 +305,7 @@ 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`

View File

@ -1,6 +1,7 @@
use nu_cli::{eval_source, evaluate_commands};
use nu_parser::parse;
use nu_plugin::{Encoder, EncodingType, PluginCallResponse, PluginOutput};
use nu_plugin_core::{Encoder, EncodingType};
use nu_plugin_protocol::{PluginCallResponse, PluginOutput};
use nu_protocol::{
engine::{EngineState, Stack},
eval_const::create_nu_constant,

View File

@ -5,26 +5,26 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cli"
edition = "2021"
license = "MIT"
name = "nu-cli"
version = "0.92.3"
version = "0.93.1"
[lib]
bench = false
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.92.3" }
nu-command = { path = "../nu-command", version = "0.92.3" }
nu-test-support = { path = "../nu-test-support", version = "0.92.3" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.93.1" }
nu-command = { path = "../nu-command", version = "0.93.1" }
nu-test-support = { path = "../nu-test-support", version = "0.93.1" }
rstest = { workspace = true, default-features = false }
[dependencies]
nu-cmd-base = { path = "../nu-cmd-base", version = "0.92.3" }
nu-engine = { path = "../nu-engine", version = "0.92.3" }
nu-path = { path = "../nu-path", version = "0.92.3" }
nu-parser = { path = "../nu-parser", version = "0.92.3" }
nu-plugin = { path = "../nu-plugin", version = "0.92.3", optional = true }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" }
nu-utils = { path = "../nu-utils", version = "0.92.3" }
nu-color-config = { path = "../nu-color-config", version = "0.92.3" }
nu-cmd-base = { path = "../nu-cmd-base", version = "0.93.1" }
nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-path = { path = "../nu-path", version = "0.93.1" }
nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.93.1", optional = true }
nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
nu-utils = { path = "../nu-utils", version = "0.93.1" }
nu-color-config = { path = "../nu-color-config", version = "0.93.1" }
nu-ansi-term = { workspace = true }
reedline = { workspace = true, features = ["bashisms", "sqlite"] }
@ -45,5 +45,5 @@ uuid = { workspace = true, features = ["v4"] }
which = { workspace = true }
[features]
plugin = ["nu-plugin"]
plugin = ["nu-plugin-engine"]
system-clipboard = ["reedline/system_clipboard"]

View File

@ -1,5 +1,4 @@
use nu_engine::command_prelude::*;
use unicode_segmentation::UnicodeSegmentation;
#[derive(Clone)]
pub struct Commandline;
@ -11,45 +10,12 @@ impl Command for Commandline {
fn signature(&self) -> Signature {
Signature::build("commandline")
.input_output_types(vec![
(Type::Nothing, Type::Nothing),
(Type::String, Type::String),
])
.switch(
"cursor",
"Set or get the current cursor position",
Some('c'),
)
.switch(
"cursor-end",
"Set the current cursor position to the end of the buffer",
Some('e'),
)
.switch(
"append",
"appends the string to the end of the buffer",
Some('a'),
)
.switch(
"insert",
"inserts the string into the buffer at the cursor position",
Some('i'),
)
.switch(
"replace",
"replaces the current contents of the buffer (default)",
Some('r'),
)
.optional(
"cmd",
SyntaxShape::String,
"the string to perform the operation with",
)
.input_output_types(vec![(Type::Nothing, Type::String)])
.category(Category::Core)
}
fn usage(&self) -> &str {
"View or modify the current command line input buffer."
"View the current command line input buffer."
}
fn search_terms(&self) -> Vec<&str> {
@ -59,126 +25,11 @@ impl Command for Commandline {
fn run(
&self,
engine_state: &EngineState,
stack: &mut Stack,
_stack: &mut Stack,
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
if let Some(cmd) = call.opt::<Value>(engine_state, stack, 0)? {
let span = cmd.span();
let cmd = cmd.coerce_into_string()?;
let mut repl = engine_state.repl_state.lock().expect("repl state mutex");
if call.has_flag(engine_state, stack, "cursor")? {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--cursor (-c)` is deprecated".into(),
msg: "Setting the current cursor position by `--cursor (-c)` is deprecated"
.into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline set-cursor`".into()),
inner: vec![],
},
);
match cmd.parse::<i64>() {
Ok(n) => {
repl.cursor_pos = if n <= 0 {
0usize
} else {
repl.buffer
.grapheme_indices(true)
.map(|(i, _c)| i)
.nth(n as usize)
.unwrap_or(repl.buffer.len())
}
}
Err(_) => {
return Err(ShellError::CantConvert {
to_type: "int".to_string(),
from_type: "string".to_string(),
span,
help: Some(format!(r#"string "{cmd}" does not represent a valid int"#)),
})
}
}
} else if call.has_flag(engine_state, stack, "append")? {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--append (-a)` is deprecated".into(),
msg: "Appending the string to the end of the buffer by `--append (-a)` is deprecated".into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline edit --append (-a)`".into()),
inner: vec![],
},
);
repl.buffer.push_str(&cmd);
} else if call.has_flag(engine_state, stack, "insert")? {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--insert (-i)` is deprecated".into(),
msg: "Inserts the string into the buffer at the cursor position by `--insert (-i)` is deprecated".into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline edit --insert (-i)`".into()),
inner: vec![],
},
);
let cursor_pos = repl.cursor_pos;
repl.buffer.insert_str(cursor_pos, &cmd);
repl.cursor_pos += cmd.len();
} else {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--replace (-r)` is deprecated".into(),
msg: "Replacing the current contents of the buffer by `--replace (-p)` or positional argument is deprecated".into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline edit --replace (-r)`".into()),
inner: vec![],
},
);
repl.buffer = cmd;
repl.cursor_pos = repl.buffer.len();
}
Ok(Value::nothing(call.head).into_pipeline_data())
} else {
let mut repl = engine_state.repl_state.lock().expect("repl state mutex");
if call.has_flag(engine_state, stack, "cursor-end")? {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--cursor-end (-e)` is deprecated".into(),
msg: "Setting the current cursor position to the end of the buffer by `--cursor-end (-e)` is deprecated".into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline set-cursor --end (-e)`".into()),
inner: vec![],
},
);
repl.cursor_pos = repl.buffer.len();
Ok(Value::nothing(call.head).into_pipeline_data())
} else if call.has_flag(engine_state, stack, "cursor")? {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "`--cursor (-c)` is deprecated".into(),
msg: "Getting the current cursor position by `--cursor (-c)` is deprecated"
.into(),
span: Some(call.arguments_span()),
help: Some("Use `commandline get-cursor`".into()),
inner: vec![],
},
);
let char_pos = repl
.buffer
.grapheme_indices(true)
.chain(std::iter::once((repl.buffer.len(), "")))
.position(|(i, _c)| i == repl.cursor_pos)
.expect("Cursor position isn't on a grapheme boundary");
Ok(Value::string(char_pos.to_string(), call.head).into_pipeline_data())
} else {
Ok(Value::string(repl.buffer.to_string(), call.head).into_pipeline_data())
}
}
let repl = engine_state.repl_state.lock().expect("repl state mutex");
Ok(Value::string(repl.buffer.clone(), call.head).into_pipeline_data())
}
}

View File

@ -12,7 +12,7 @@ impl Command for KeybindingsDefault {
fn signature(&self) -> Signature {
Signature::build(self.name())
.category(Category::Platform)
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))])
.input_output_types(vec![(Type::Nothing, Type::table())])
}
fn usage(&self) -> &str {

View File

@ -14,7 +14,7 @@ impl Command for KeybindingsList {
fn signature(&self) -> Signature {
Signature::build(self.name())
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))])
.input_output_types(vec![(Type::Nothing, Type::table())])
.switch("modifiers", "list of modifiers", Some('m'))
.switch("keycodes", "list of keycodes", Some('k'))
.switch("modes", "list of edit modes", Some('o'))

View File

@ -6,7 +6,7 @@ use nu_protocol::{
report_error, HistoryFileFormat, PipelineData,
};
#[cfg(feature = "plugin")]
use nu_protocol::{ParseError, PluginCacheFile, Spanned};
use nu_protocol::{ParseError, PluginRegistryFile, Spanned};
#[cfg(feature = "plugin")]
use nu_utils::utils::perf;
use std::path::PathBuf;
@ -51,7 +51,7 @@ pub fn read_plugin_file(
}
let mut start_time = std::time::Instant::now();
// Reading signatures from plugin cache file
// Reading signatures from plugin registry file
// The plugin.msgpackz file stores the parsed signature collected from each registered plugin
add_plugin_file(engine_state, plugin_file.clone(), storage_path);
perf(
@ -89,7 +89,7 @@ pub fn read_plugin_file(
engine_state,
&ShellError::GenericError {
error: format!(
"Error while opening plugin cache file: {}",
"Error while opening plugin registry file: {}",
plugin_path.display()
),
msg: "plugin path defined here".into(),
@ -113,15 +113,15 @@ pub fn read_plugin_file(
}
// Read the contents of the plugin file
let contents = match PluginCacheFile::read_from(&mut file, span) {
let contents = match PluginRegistryFile::read_from(&mut file, span) {
Ok(contents) => contents,
Err(err) => {
log::warn!("Failed to read plugin cache file: {err:?}");
log::warn!("Failed to read plugin registry file: {err:?}");
report_error_new(
engine_state,
&ShellError::GenericError {
error: format!(
"Error while reading plugin cache file: {}",
"Error while reading plugin registry file: {}",
plugin_path.display()
),
msg: "plugin path defined here".into(),
@ -150,7 +150,7 @@ pub fn read_plugin_file(
let mut working_set = StateWorkingSet::new(engine_state);
nu_plugin::load_plugin_file(&mut working_set, &contents, span);
nu_plugin_engine::load_plugin_file(&mut working_set, &contents, span);
if let Err(err) = engine_state.merge_delta(working_set.render()) {
report_error_new(engine_state, &err);
@ -265,8 +265,8 @@ pub(crate) fn get_history_path(storage_path: &str, mode: HistoryFileFormat) -> O
#[cfg(feature = "plugin")]
pub fn migrate_old_plugin_file(engine_state: &EngineState, storage_path: &str) -> bool {
use nu_protocol::{
report_error_new, PluginCacheItem, PluginCacheItemData, PluginExample, PluginIdentity,
PluginSignature, ShellError,
report_error_new, PluginExample, PluginIdentity, PluginRegistryItem,
PluginRegistryItemData, PluginSignature, ShellError,
};
use std::collections::BTreeMap;
@ -318,7 +318,7 @@ pub fn migrate_old_plugin_file(engine_state: &EngineState, storage_path: &str) -
}
// Now that the plugin commands are loaded, we just have to generate the file
let mut contents = PluginCacheFile::new();
let mut contents = PluginRegistryFile::new();
let mut groups = BTreeMap::<PluginIdentity, Vec<PluginSignature>>::new();
@ -339,11 +339,11 @@ pub fn migrate_old_plugin_file(engine_state: &EngineState, storage_path: &str) -
}
for (identity, commands) in groups {
contents.upsert_plugin(PluginCacheItem {
contents.upsert_plugin(PluginRegistryItem {
name: identity.name().to_owned(),
filename: identity.filename().to_owned(),
shell: identity.shell().map(|p| p.to_owned()),
data: PluginCacheItemData::Valid { commands },
data: PluginRegistryItemData::Valid { commands },
});
}

View File

@ -5,13 +5,11 @@ use nu_engine::{convert_env_values, current_dir, eval_block};
use nu_parser::parse;
use nu_path::canonicalize_with;
use nu_protocol::{
ast::Call,
debugger::WithoutDebug,
engine::{EngineState, Stack, StateWorkingSet},
report_error, Config, PipelineData, ShellError, Span, Value,
};
use nu_utils::stdout_write_all_and_flush;
use std::sync::Arc;
use std::{io::Write, sync::Arc};
/// Entry point for evaluating a file.
///
@ -210,29 +208,8 @@ pub(crate) fn print_table_or_error(
std::process::exit(1);
}
if let Some(decl_id) = engine_state.find_decl("table".as_bytes(), &[]) {
let command = engine_state.get_decl(decl_id);
if command.get_block_id().is_some() {
print_or_exit(pipeline_data, engine_state, config, no_newline);
} else {
// The final call on table command, it's ok to set redirect_output to false.
let call = Call::new(Span::new(0, 0));
let table = command.run(engine_state, stack, &call, pipeline_data);
match table {
Ok(table) => {
print_or_exit(table, engine_state, config, no_newline);
}
Err(error) => {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &error);
std::process::exit(1);
}
}
}
} else {
print_or_exit(pipeline_data, engine_state, config, no_newline);
}
// We don't need to do anything special to print a table because print() handles it
print_or_exit(pipeline_data, engine_state, stack, no_newline);
// Make sure everything has finished
if let Some(exit_code) = exit_code {
@ -250,23 +227,19 @@ pub(crate) fn print_table_or_error(
fn print_or_exit(
pipeline_data: PipelineData,
engine_state: &mut EngineState,
config: &Config,
engine_state: &EngineState,
stack: &mut Stack,
no_newline: bool,
) {
for item in pipeline_data {
if let Value::Error { error, .. } = item {
let working_set = StateWorkingSet::new(engine_state);
let result = pipeline_data.print(engine_state, stack, no_newline, false);
report_error(&working_set, &*error);
let _ = std::io::stdout().flush();
let _ = std::io::stderr().flush();
std::process::exit(1);
}
let mut out = item.to_expanded_string("\n", config);
if !no_newline {
out.push('\n');
}
let _ = stdout_write_all_and_flush(out).map_err(|err| eprintln!("{err}"));
if let Err(error) = result {
let working_set = StateWorkingSet::new(engine_state);
report_error(&working_set, &error);
let _ = std::io::stderr().flush();
std::process::exit(1);
}
}

View File

@ -361,7 +361,7 @@ fn find_matching_block_end_in_expr(
Expr::Nothing => None,
Expr::Garbage => None,
Expr::Table(hdr, rows) => {
Expr::Table(table) => {
if expr_last == global_cursor_offset {
// cursor is at table end
Some(expr_first)
@ -370,11 +370,11 @@ fn find_matching_block_end_in_expr(
Some(expr_last)
} else {
// cursor is inside table
for inner_expr in hdr {
for inner_expr in table.columns.as_ref() {
find_in_expr_or_continue!(inner_expr);
}
for row in rows {
for inner_expr in row {
for row in table.rows.as_ref() {
for inner_expr in row.as_ref() {
find_in_expr_or_continue!(inner_expr);
}
}

View File

@ -5,15 +5,15 @@ edition = "2021"
license = "MIT"
name = "nu-cmd-base"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-base"
version = "0.92.3"
version = "0.93.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.92.3" }
nu-parser = { path = "../nu-parser", version = "0.92.3" }
nu-path = { path = "../nu-path", version = "0.92.3" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" }
nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-path = { path = "../nu-path", version = "0.93.1" }
nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
indexmap = { workspace = true }
miette = { workspace = true }

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu-cmd-dataframe"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-dataframe"
version = "0.92.3"
version = "0.93.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -13,9 +13,9 @@ version = "0.92.3"
bench = false
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.92.3" }
nu-parser = { path = "../nu-parser", version = "0.92.3" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" }
nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
# Potential dependencies for extras
chrono = { workspace = true, features = ["std", "unstable-locales"], default-features = false }
@ -72,4 +72,4 @@ dataframe = ["num", "polars", "polars-io", "polars-arrow", "polars-ops", "polars
default = []
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.92.3" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.93.1" }

View File

@ -24,7 +24,7 @@ impl Command for ToNu {
.switch("tail", "shows tail rows", Some('t'))
.input_output_types(vec![
(Type::Custom("expression".into()), Type::Any),
(Type::Custom("dataframe".into()), Type::Table(vec![])),
(Type::Custom("dataframe".into()), Type::table()),
])
//.input_output_type(Type::Any, Type::Any)
.category(Category::Custom("dataframe".into()))

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu-cmd-extra"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-extra"
version = "0.92.3"
version = "0.93.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -13,13 +13,13 @@ version = "0.92.3"
bench = false
[dependencies]
nu-cmd-base = { path = "../nu-cmd-base", version = "0.92.3" }
nu-engine = { path = "../nu-engine", version = "0.92.3" }
nu-json = { version = "0.92.3", path = "../nu-json" }
nu-parser = { path = "../nu-parser", version = "0.92.3" }
nu-pretty-hex = { version = "0.92.3", path = "../nu-pretty-hex" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" }
nu-utils = { path = "../nu-utils", version = "0.92.3" }
nu-cmd-base = { path = "../nu-cmd-base", version = "0.93.1" }
nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-json = { version = "0.93.1", path = "../nu-json" }
nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-pretty-hex = { version = "0.93.1", path = "../nu-pretty-hex" }
nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
nu-utils = { path = "../nu-utils", version = "0.93.1" }
# Potential dependencies for extras
heck = { workspace = true }
@ -37,6 +37,6 @@ extra = ["default"]
default = []
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.92.3" }
nu-command = { path = "../nu-command", version = "0.92.3" }
nu-test-support = { path = "../nu-test-support", version = "0.92.3" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.93.1" }
nu-command = { path = "../nu-command", version = "0.93.1" }
nu-test-support = { path = "../nu-test-support", version = "0.93.1" }

View File

@ -30,8 +30,8 @@ impl Command for BitsInto {
(Type::Duration, Type::String),
(Type::String, Type::String),
(Type::Bool, Type::String),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true) // TODO: supply exhaustive examples
.rest(
@ -64,7 +64,7 @@ impl Command for BitsInto {
vec![
Example {
description: "convert a binary value into a string, padded to 8 places with 0s",
example: "01b | into bits",
example: "0x[1] | into bits",
result: Some(Value::string("00000001",
Span::test_data(),
)),

View File

@ -15,7 +15,7 @@ impl Command for Fmt {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("fmt")
.input_output_types(vec![(Type::Number, Type::Record(vec![]))])
.input_output_types(vec![(Type::Number, Type::record())])
.category(Category::Conversions)
}

View File

@ -16,7 +16,7 @@ impl Command for RollDown {
fn signature(&self) -> Signature {
Signature::build(self.name())
// TODO: It also operates on List
.input_output_types(vec![(Type::Table(vec![]), Type::Table(vec![]))])
.input_output_types(vec![(Type::table(), Type::table())])
.named("by", SyntaxShape::Int, "Number of rows to roll", Some('b'))
.category(Category::Filters)
}

View File

@ -16,8 +16,8 @@ impl Command for RollLeft {
fn signature(&self) -> Signature {
Signature::build(self.name())
.input_output_types(vec![
(Type::Record(vec![]), Type::Record(vec![])),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::record(), Type::record()),
(Type::table(), Type::table()),
])
.named(
"by",

View File

@ -16,8 +16,8 @@ impl Command for RollRight {
fn signature(&self) -> Signature {
Signature::build(self.name())
.input_output_types(vec![
(Type::Record(vec![]), Type::Record(vec![])),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::record(), Type::record()),
(Type::table(), Type::table()),
])
.named(
"by",

View File

@ -16,7 +16,7 @@ impl Command for RollUp {
fn signature(&self) -> Signature {
Signature::build(self.name())
// TODO: It also operates on List
.input_output_types(vec![(Type::Table(vec![]), Type::Table(vec![]))])
.input_output_types(vec![(Type::table(), Type::table())])
.named("by", SyntaxShape::Int, "Number of rows to roll", Some('b'))
.category(Category::Filters)
}

View File

@ -11,8 +11,8 @@ impl Command for Rotate {
fn signature(&self) -> Signature {
Signature::build("rotate")
.input_output_types(vec![
(Type::Record(vec![]), Type::Table(vec![])),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::record(), Type::table()),
(Type::table(), Type::table()),
])
.switch("ccw", "rotate counter clockwise", None)
.rest(

View File

@ -12,7 +12,7 @@ impl Command for UpdateCells {
fn signature(&self) -> Signature {
Signature::build("update cells")
.input_output_types(vec![(Type::Table(vec![]), Type::Table(vec![]))])
.input_output_types(vec![(Type::table(), Type::table())])
.required(
"closure",
SyntaxShape::Closure(Some(vec![SyntaxShape::Any])),

View File

@ -10,7 +10,7 @@ impl Command for FromUrl {
fn signature(&self) -> Signature {
Signature::build("from url")
.input_output_types(vec![(Type::String, Type::Record(vec![]))])
.input_output_types(vec![(Type::String, Type::record())])
.category(Category::Formats)
}

View File

@ -46,8 +46,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.category(Category::Platform)

View File

@ -17,8 +17,8 @@ impl Command for DecodeHex {
Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::Binary)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.rest(

View File

@ -17,8 +17,8 @@ impl Command for EncodeHex {
Type::List(Box::new(Type::Binary)),
Type::List(Box::new(Type::String)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.rest(

View File

@ -13,8 +13,8 @@ impl Command for FormatPattern {
fn signature(&self) -> Signature {
Signature::build("format pattern")
.input_output_types(vec![
(Type::Table(vec![]), Type::List(Box::new(Type::String))),
(Type::Record(vec![]), Type::Any),
(Type::table(), Type::List(Box::new(Type::String))),
(Type::record(), Type::Any),
])
.required(
"pattern",

View File

@ -18,8 +18,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.rest(

View File

@ -14,8 +14,8 @@ impl Command for SubCommand {
Signature::build("str kebab-case")
.input_output_types(vec![
(Type::String, Type::String),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
(
Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)),

View File

@ -14,8 +14,8 @@ impl Command for SubCommand {
Signature::build("str pascal-case")
.input_output_types(vec![
(Type::String, Type::String),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
(
Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)),

View File

@ -18,8 +18,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.rest(

View File

@ -18,8 +18,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.rest(

View File

@ -18,8 +18,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::String)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.rest(

View File

@ -6,16 +6,16 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-lang"
edition = "2021"
license = "MIT"
name = "nu-cmd-lang"
version = "0.92.3"
version = "0.93.1"
[lib]
bench = false
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.92.3" }
nu-parser = { path = "../nu-parser", version = "0.92.3" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" }
nu-utils = { path = "../nu-utils", version = "0.92.3" }
nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
nu-utils = { path = "../nu-utils", version = "0.93.1" }
itertools = { workspace = true }
shadow-rs = { version = "0.27", default-features = false }

View File

@ -38,12 +38,12 @@ impl Command for Collect {
) -> Result<PipelineData, ShellError> {
let closure: Closure = call.req(engine_state, stack, 0)?;
let block = engine_state.get_block(closure.block_id).clone();
let block = engine_state.get_block(closure.block_id);
let mut stack_captures =
stack.captures_to_stack_preserve_out_dest(closure.captures.clone());
let metadata = input.metadata();
let input: Value = input.into_value(call.head);
let input = input.into_value(call.head);
let mut saved_positional = None;
if let Some(var) = block.signature.get_positional(0) {
@ -58,7 +58,7 @@ impl Command for Collect {
let result = eval_block(
engine_state,
&mut stack_captures,
&block,
block,
input.into_pipeline_data(),
)
.map(|x| x.set_metadata(metadata));

View File

@ -46,6 +46,19 @@ impl Command for Describe {
detailed: call.has_flag(engine_state, stack, "detailed")?,
collect_lazyrecords: call.has_flag(engine_state, stack, "collect-lazyrecords")?,
};
if options.collect_lazyrecords {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "Deprecated flag".into(),
msg: "the `--collect-lazyrecords` flag is deprecated, since lazy records will be removed in 0.94.0"
.into(),
span: Some(call.head),
help: None,
inner: vec![],
},
);
}
run(Some(engine_state), call, input, options)
}

View File

@ -117,7 +117,7 @@ impl Command for Do {
None,
)
})
.map_err(|e| e.into_spanned(call.head))
.err_span(call.head)
})
.transpose()?;

View File

@ -41,11 +41,7 @@ impl Command for HideEnv {
for name in env_var_names {
if !stack.remove_env_var(engine_state, &name.item) && !ignore_errors {
let all_names: Vec<String> = stack
.get_env_var_names(engine_state)
.iter()
.cloned()
.collect();
let all_names = stack.get_env_var_names(engine_state);
if let Some(closest_match) = did_you_mean(&all_names, &name.item) {
return Err(ShellError::DidYouMeanCustom {
msg: format!("Environment variable '{}' not found", name.item),

View File

@ -59,43 +59,27 @@ impl Command for If {
.expect("internal error: missing block");
let else_case = call.positional_nth(2);
let result = eval_constant(working_set, cond)?;
match &result {
Value::Bool { val, .. } => {
if *val {
let block = working_set.get_block(then_block);
if eval_constant(working_set, cond)?.as_bool()? {
let block = working_set.get_block(then_block);
eval_const_subexpression(working_set, block, input, block.span.unwrap_or(call.head))
} else if let Some(else_case) = else_case {
if let Some(else_expr) = else_case.as_keyword() {
if let Some(block_id) = else_expr.as_block() {
let block = working_set.get_block(block_id);
eval_const_subexpression(
working_set,
block,
input,
block.span.unwrap_or(call.head),
)
} else if let Some(else_case) = else_case {
if let Some(else_expr) = else_case.as_keyword() {
if let Some(block_id) = else_expr.as_block() {
let block = working_set.get_block(block_id);
eval_const_subexpression(
working_set,
block,
input,
block.span.unwrap_or(call.head),
)
} else {
eval_constant_with_input(working_set, else_expr, input)
}
} else {
eval_constant_with_input(working_set, else_case, input)
}
} else {
Ok(PipelineData::empty())
eval_constant_with_input(working_set, else_expr, input)
}
} else {
eval_constant_with_input(working_set, else_case, input)
}
x => Err(ShellError::CantConvert {
to_type: "bool".into(),
from_type: x.get_type().to_string(),
span: result.span(),
help: None,
}),
} else {
Ok(PipelineData::empty())
}
}
@ -118,35 +102,23 @@ impl Command for If {
let eval_expression_with_input = get_eval_expression_with_input(engine_state);
let eval_block = get_eval_block(engine_state);
let result = eval_expression(engine_state, stack, cond)?;
match &result {
Value::Bool { val, .. } => {
if *val {
let block = engine_state.get_block(then_block);
if eval_expression(engine_state, stack, cond)?.as_bool()? {
let block = engine_state.get_block(then_block);
eval_block(engine_state, stack, block, input)
} else if let Some(else_case) = else_case {
if let Some(else_expr) = else_case.as_keyword() {
if let Some(block_id) = else_expr.as_block() {
let block = engine_state.get_block(block_id);
eval_block(engine_state, stack, block, input)
} else if let Some(else_case) = else_case {
if let Some(else_expr) = else_case.as_keyword() {
if let Some(block_id) = else_expr.as_block() {
let block = engine_state.get_block(block_id);
eval_block(engine_state, stack, block, input)
} else {
eval_expression_with_input(engine_state, stack, else_expr, input)
.map(|res| res.0)
}
} else {
eval_expression_with_input(engine_state, stack, else_case, input)
.map(|res| res.0)
}
} else {
Ok(PipelineData::empty())
eval_expression_with_input(engine_state, stack, else_expr, input)
.map(|res| res.0)
}
} else {
eval_expression_with_input(engine_state, stack, else_case, input).map(|res| res.0)
}
x => Err(ShellError::CantConvert {
to_type: "bool".into(),
from_type: x.get_type().to_string(),
span: result.span(),
help: None,
}),
} else {
Ok(PipelineData::empty())
}
}

View File

@ -15,7 +15,7 @@ impl Command for LazyMake {
fn signature(&self) -> Signature {
Signature::build("lazy make")
.input_output_types(vec![(Type::Nothing, Type::Record(vec![]))])
.input_output_types(vec![(Type::Nothing, Type::record())])
.required_named(
"columns",
SyntaxShape::List(Box::new(SyntaxShape::String)),
@ -54,6 +54,18 @@ impl Command for LazyMake {
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
nu_protocol::report_error_new(
engine_state,
&ShellError::GenericError {
error: "Deprecated command".into(),
msg: "warning: lazy records and the `lazy make` command will be removed in 0.94.0"
.into(),
span: Some(call.head),
help: None,
inner: vec![],
},
);
let span = call.head;
let columns: Vec<Spanned<String>> = call
.get_flag(engine_state, stack, "columns")?

View File

@ -61,7 +61,7 @@ impl Command for Let {
let eval_block = get_eval_block(engine_state);
let stack = &mut stack.start_capture();
let pipeline_data = eval_block(engine_state, stack, block, input)?;
let mut value = pipeline_data.into_value(call.head);
let value = pipeline_data.into_value(call.head);
// if given variable type is Glob, and our result is string
// then nushell need to convert from Value::String to Value::Glob
@ -69,12 +69,12 @@ impl Command for Let {
// if we pass it to other commands.
let var_type = &engine_state.get_var(var_id).ty;
let val_span = value.span();
match value {
let value = match value {
Value::String { val, .. } if var_type == &Type::Glob => {
value = Value::glob(val, false, val_span);
Value::glob(val, false, val_span)
}
_ => {}
}
value => value,
};
stack.add_var(var_id, value);
Ok(PipelineData::empty())

View File

@ -1,10 +1,7 @@
use nu_engine::{
command_prelude::*, get_eval_block, get_eval_expression, get_eval_expression_with_input,
};
use nu_protocol::{
ast::{Expr, Expression},
engine::Matcher,
};
use nu_protocol::engine::Matcher;
#[derive(Clone)]
pub struct Match;
@ -38,45 +35,45 @@ impl Command for Match {
input: PipelineData,
) -> Result<PipelineData, ShellError> {
let value: Value = call.req(engine_state, stack, 0)?;
let block = call.positional_nth(1);
let matches = call
.positional_nth(1)
.expect("checked through parser")
.as_match_block()
.expect("missing match block");
let eval_expression = get_eval_expression(engine_state);
let eval_expression_with_input = get_eval_expression_with_input(engine_state);
let eval_block = get_eval_block(engine_state);
if let Some(Expression {
expr: Expr::MatchBlock(matches),
..
}) = block
{
for match_ in matches {
let mut match_variables = vec![];
if match_.0.match_value(&value, &mut match_variables) {
// This case does match, go ahead and return the evaluated expression
for match_variable in match_variables {
stack.add_var(match_variable.0, match_variable.1);
}
let mut match_variables = vec![];
for (pattern, expr) in matches {
if pattern.match_value(&value, &mut match_variables) {
// This case does match, go ahead and return the evaluated expression
for (id, value) in match_variables.drain(..) {
stack.add_var(id, value);
}
let guard_matches = if let Some(guard) = &match_.0.guard {
let Value::Bool { val, .. } = eval_expression(engine_state, stack, guard)?
else {
return Err(ShellError::MatchGuardNotBool { span: guard.span });
};
val
} else {
true
let guard_matches = if let Some(guard) = &pattern.guard {
let Value::Bool { val, .. } = eval_expression(engine_state, stack, guard)?
else {
return Err(ShellError::MatchGuardNotBool { span: guard.span });
};
if guard_matches {
return if let Some(block_id) = match_.1.as_block() {
let block = engine_state.get_block(block_id);
eval_block(engine_state, stack, block, input)
} else {
eval_expression_with_input(engine_state, stack, &match_.1, input)
.map(|x| x.0)
};
}
val
} else {
true
};
if guard_matches {
return if let Some(block_id) = expr.as_block() {
let block = engine_state.get_block(block_id);
eval_block(engine_state, stack, block, input)
} else {
eval_expression_with_input(engine_state, stack, expr, input).map(|x| x.0)
};
}
} else {
match_variables.clear();
}
}

View File

@ -61,7 +61,7 @@ impl Command for Mut {
let eval_block = get_eval_block(engine_state);
let stack = &mut stack.start_capture();
let pipeline_data = eval_block(engine_state, stack, block, input)?;
let mut value = pipeline_data.into_value(call.head);
let value = pipeline_data.into_value(call.head);
// if given variable type is Glob, and our result is string
// then nushell need to convert from Value::String to Value::Glob
@ -69,12 +69,12 @@ impl Command for Mut {
// if we pass it to other commands.
let var_type = &engine_state.get_var(var_id).ty;
let val_span = value.span();
match value {
let value = match value {
Value::String { val, .. } if var_type == &Type::Glob => {
value = Value::glob(val, false, val_span);
Value::glob(val, false, val_span)
}
_ => {}
}
value => value,
};
stack.add_var(var_id, value);
Ok(PipelineData::empty())

View File

@ -40,17 +40,11 @@ impl Command for Return {
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
let return_value: Option<Value> = call.opt(engine_state, stack, 0)?;
if let Some(value) = return_value {
Err(ShellError::Return {
span: call.head,
value: Box::new(value),
})
} else {
Err(ShellError::Return {
span: call.head,
value: Box::new(Value::nothing(call.head)),
})
}
let value = return_value.unwrap_or(Value::nothing(call.head));
Err(ShellError::Return {
span: call.head,
value: Box::new(value),
})
}
fn examples(&self) -> Vec<Example> {

View File

@ -49,9 +49,7 @@ impl Command for Try {
let try_block = engine_state.get_block(try_block);
let eval_block = get_eval_block(engine_state);
let result = eval_block(engine_state, stack, try_block, input);
match result {
match eval_block(engine_state, stack, try_block, input) {
Err(error) => {
let error = intercept_block_control(error)?;
let err_record = err_to_record(error, call.head);
@ -66,9 +64,8 @@ impl Command for Try {
Ok(pipeline) => {
let (pipeline, external_failed) = pipeline.check_external_failed();
if external_failed {
// Because external command errors aren't "real" errors,
// (unless do -c is in effect)
// they can't be passed in as Nushell values.
let exit_code = pipeline.drain_with_exit_code()?;
stack.add_env_var("LAST_EXIT_CODE".into(), Value::int(exit_code, call.head));
let err_value = Value::nothing(call.head);
handle_catch(err_value, catch_block, engine_state, stack, eval_block)
} else {

View File

@ -16,7 +16,7 @@ impl Command for Version {
fn signature(&self) -> Signature {
Signature::build("version")
.input_output_types(vec![(Type::Nothing, Type::Record(vec![]))])
.input_output_types(vec![(Type::Nothing, Type::record())])
.allow_variants_without_examples(true)
.category(Category::Core)
}
@ -36,7 +36,7 @@ impl Command for Version {
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
version(engine_state, call)
version(engine_state, call.head)
}
fn run_const(
@ -45,7 +45,7 @@ impl Command for Version {
call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
version(working_set.permanent(), call)
version(working_set.permanent(), call.head)
}
fn examples(&self) -> Vec<Example> {
@ -57,7 +57,13 @@ impl Command for Version {
}
}
pub fn version(engine_state: &EngineState, call: &Call) -> Result<PipelineData, ShellError> {
fn push_non_empty(record: &mut Record, name: &str, value: &str, span: Span) {
if !value.is_empty() {
record.push(name, Value::string(value, span))
}
}
pub fn version(engine_state: &EngineState, span: Span) -> Result<PipelineData, ShellError> {
// Pre-allocate the arrays in the worst case (17 items):
// - version
// - major
@ -69,6 +75,7 @@ pub fn version(engine_state: &EngineState, call: &Call) -> Result<PipelineData,
// - build_os
// - build_target
// - rust_version
// - rust_channel
// - cargo_version
// - build_time
// - build_rust_channel
@ -77,68 +84,36 @@ pub fn version(engine_state: &EngineState, call: &Call) -> Result<PipelineData,
// - installed_plugins
let mut record = Record::with_capacity(17);
record.push(
"version",
Value::string(env!("CARGO_PKG_VERSION"), call.head),
record.push("version", Value::string(env!("CARGO_PKG_VERSION"), span));
push_version_numbers(&mut record, span);
push_non_empty(&mut record, "pre", build::PKG_VERSION_PRE, span);
record.push("branch", Value::string(build::BRANCH, span));
if let Some(commit_hash) = option_env!("NU_COMMIT_HASH") {
record.push("commit_hash", Value::string(commit_hash, span));
}
push_non_empty(&mut record, "build_os", build::BUILD_OS, span);
push_non_empty(&mut record, "build_target", build::BUILD_TARGET, span);
push_non_empty(&mut record, "rust_version", build::RUST_VERSION, span);
push_non_empty(&mut record, "rust_channel", build::RUST_CHANNEL, span);
push_non_empty(&mut record, "cargo_version", build::CARGO_VERSION, span);
push_non_empty(&mut record, "build_time", build::BUILD_TIME, span);
push_non_empty(
&mut record,
"build_rust_channel",
build::BUILD_RUST_CHANNEL,
span,
);
push_version_numbers(&mut record, call.head);
let version_pre = Some(build::PKG_VERSION_PRE).filter(|x| !x.is_empty());
if let Some(version_pre) = version_pre {
record.push("pre", Value::string(version_pre, call.head));
}
record.push("branch", Value::string(build::BRANCH, call.head));
let commit_hash = option_env!("NU_COMMIT_HASH");
if let Some(commit_hash) = commit_hash {
record.push("commit_hash", Value::string(commit_hash, call.head));
}
let build_os = Some(build::BUILD_OS).filter(|x| !x.is_empty());
if let Some(build_os) = build_os {
record.push("build_os", Value::string(build_os, call.head));
}
let build_target = Some(build::BUILD_TARGET).filter(|x| !x.is_empty());
if let Some(build_target) = build_target {
record.push("build_target", Value::string(build_target, call.head));
}
let rust_version = Some(build::RUST_VERSION).filter(|x| !x.is_empty());
if let Some(rust_version) = rust_version {
record.push("rust_version", Value::string(rust_version, call.head));
}
let rust_channel = Some(build::RUST_CHANNEL).filter(|x| !x.is_empty());
if let Some(rust_channel) = rust_channel {
record.push("rust_channel", Value::string(rust_channel, call.head));
}
let cargo_version = Some(build::CARGO_VERSION).filter(|x| !x.is_empty());
if let Some(cargo_version) = cargo_version {
record.push("cargo_version", Value::string(cargo_version, call.head));
}
let build_time = Some(build::BUILD_TIME).filter(|x| !x.is_empty());
if let Some(build_time) = build_time {
record.push("build_time", Value::string(build_time, call.head));
}
let build_rust_channel = Some(build::BUILD_RUST_CHANNEL).filter(|x| !x.is_empty());
if let Some(build_rust_channel) = build_rust_channel {
record.push(
"build_rust_channel",
Value::string(build_rust_channel, call.head),
);
}
record.push("allocator", Value::string(global_allocator(), call.head));
record.push("allocator", Value::string(global_allocator(), span));
record.push(
"features",
Value::string(features_enabled().join(", "), call.head),
Value::string(features_enabled().join(", "), span),
);
// Get a list of plugin names
@ -150,10 +125,10 @@ pub fn version(engine_state: &EngineState, call: &Call) -> Result<PipelineData,
record.push(
"installed_plugins",
Value::string(installed_plugins.join(", "), call.head),
Value::string(installed_plugins.join(", "), span),
);
Ok(Value::record(record, call.head).into_pipeline_data())
Ok(Value::record(record, span).into_pipeline_data())
}
/// Add version numbers as integers to the given record
@ -167,9 +142,9 @@ fn push_version_numbers(record: &mut Record, head: Span) {
build::PKG_VERSION_PATCH.parse().expect("Always set"),
)
});
record.push("major", Value::int(major as _, head));
record.push("minor", Value::int(minor as _, head));
record.push("patch", Value::int(patch as _, head));
record.push("major", Value::int(major.into(), head));
record.push("minor", Value::int(minor.into(), head));
record.push("patch", Value::int(patch.into(), head));
}
fn global_allocator() -> &'static str {

View File

@ -5,15 +5,15 @@ edition = "2021"
license = "MIT"
name = "nu-cmd-plugin"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-cmd-plugin"
version = "0.92.3"
version = "0.93.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nu-engine = { path = "../nu-engine", version = "0.92.3" }
nu-path = { path = "../nu-path", version = "0.92.3" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3", features = ["plugin"] }
nu-plugin = { path = "../nu-plugin", version = "0.92.3" }
nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-path = { path = "../nu-path", version = "0.93.1" }
nu-protocol = { path = "../nu-protocol", version = "0.93.1", features = ["plugin"] }
nu-plugin-engine = { path = "../nu-plugin-engine", version = "0.93.1" }
itertools = { workspace = true }

View File

@ -1,10 +1,10 @@
use std::sync::Arc;
use nu_engine::{command_prelude::*, current_dir};
use nu_plugin::{GetPlugin, PersistentPlugin};
use nu_protocol::{PluginCacheItem, PluginGcConfig, PluginIdentity, RegisteredPlugin};
use nu_plugin_engine::{GetPlugin, PersistentPlugin};
use nu_protocol::{PluginGcConfig, PluginIdentity, PluginRegistryItem, RegisteredPlugin};
use crate::util::modify_plugin_file;
use crate::util::{get_plugin_dirs, modify_plugin_file};
#[derive(Clone)]
pub struct PluginAdd;
@ -21,7 +21,7 @@ impl Command for PluginAdd {
.named(
"plugin-config",
SyntaxShape::Filepath,
"Use a plugin cache file other than the one set in `$nu.plugin-path`",
"Use a plugin registry file other than the one set in `$nu.plugin-path`",
None,
)
.named(
@ -39,7 +39,7 @@ impl Command for PluginAdd {
}
fn usage(&self) -> &str {
"Add a plugin to the plugin cache file."
"Add a plugin to the plugin registry file."
}
fn extra_usage(&self) -> &str {
@ -47,14 +47,14 @@ impl Command for PluginAdd {
This does not load the plugin commands into the scope - see `register` for that.
Instead, it runs the plugin to get its command signatures, and then edits the
plugin cache file (by default, `$nu.plugin-path`). The changes will be
apparent the next time `nu` is next launched with that plugin cache file.
plugin registry file (by default, `$nu.plugin-path`). The changes will be
apparent the next time `nu` is next launched with that plugin registry file.
"#
.trim()
}
fn search_terms(&self) -> Vec<&str> {
vec!["plugin", "add", "register", "load", "signature"]
vec!["load", "register", "signature"]
}
fn examples(&self) -> Vec<Example> {
@ -66,7 +66,7 @@ apparent the next time `nu` is next launched with that plugin cache file.
},
Example {
example: "plugin add --plugin-config polars.msgpackz nu_plugin_polars",
description: "Run the `nu_plugin_polars` plugin from the current directory or $env.NU_PLUGIN_DIRS, and install its signatures to the \"polars.msgpackz\" plugin cache file.",
description: "Run the `nu_plugin_polars` plugin from the current directory or $env.NU_PLUGIN_DIRS, and install its signatures to the \"polars.msgpackz\" plugin registry file.",
result: None,
},
]
@ -85,30 +85,14 @@ apparent the next time `nu` is next launched with that plugin cache file.
let cwd = current_dir(engine_state, stack)?;
// Check the current directory, or fall back to NU_PLUGIN_DIRS
let filename_expanded = match nu_path::canonicalize_with(&filename.item, &cwd) {
Ok(path) => path,
Err(err) => {
// Try to find it in NU_PLUGIN_DIRS first, before giving up
let mut found = None;
if let Some(nu_plugin_dirs) = stack.get_env_var(engine_state, "NU_PLUGIN_DIRS") {
for dir in nu_plugin_dirs.into_list().unwrap_or(vec![]) {
if let Ok(path) = nu_path::canonicalize_with(dir.as_str()?, &cwd)
.and_then(|dir| nu_path::canonicalize_with(&filename.item, dir))
{
found = Some(path);
break;
}
}
}
found.ok_or(err.into_spanned(filename.span))?
}
};
let filename_expanded = nu_path::locate_in_dirs(&filename.item, &cwd, || {
get_plugin_dirs(engine_state, stack)
})
.err_span(filename.span)?;
let shell_expanded = shell
.as_ref()
.map(|s| {
nu_path::canonicalize_with(&s.item, &cwd).map_err(|err| err.into_spanned(s.span))
})
.map(|s| nu_path::canonicalize_with(&s.item, &cwd).err_span(s.span))
.transpose()?;
// Parse the plugin filename so it can be used to spawn the plugin
@ -138,7 +122,7 @@ apparent the next time `nu` is next launched with that plugin cache file.
modify_plugin_file(engine_state, stack, call.head, custom_path, |contents| {
// Update the file with the received signatures
let item = PluginCacheItem::new(plugin.identity(), commands);
let item = PluginRegistryItem::new(plugin.identity(), commands);
contents.upsert_plugin(item);
Ok(())
})?;

View File

@ -13,14 +13,17 @@ impl Command for PluginList {
Signature::build("plugin list")
.input_output_type(
Type::Nothing,
Type::Table(vec![
("name".into(), Type::String),
("is_running".into(), Type::Bool),
("pid".into(), Type::Int),
("filename".into(), Type::String),
("shell".into(), Type::String),
("commands".into(), Type::List(Type::String.into())),
]),
Type::Table(
[
("name".into(), Type::String),
("is_running".into(), Type::Bool),
("pid".into(), Type::Int),
("filename".into(), Type::String),
("shell".into(), Type::String),
("commands".into(), Type::List(Type::String.into())),
]
.into(),
),
)
.category(Category::Plugin)
}
@ -29,6 +32,10 @@ impl Command for PluginList {
"List installed plugins."
}
fn search_terms(&self) -> Vec<&str> {
vec!["scope"]
}
fn examples(&self) -> Vec<nu_protocol::Example> {
vec![
Example {

View File

@ -4,11 +4,13 @@ mod add;
mod list;
mod rm;
mod stop;
mod use_;
pub use add::PluginAdd;
pub use list::PluginList;
pub use rm::PluginRm;
pub use stop::PluginStop;
pub use use_::PluginUse;
#[derive(Clone)]
pub struct PluginCommand;
@ -28,10 +30,6 @@ impl Command for PluginCommand {
"Commands for managing plugins."
}
fn extra_usage(&self) -> &str {
"To load a plugin, see `register`."
}
fn run(
&self,
engine_state: &EngineState,
@ -54,6 +52,21 @@ impl Command for PluginCommand {
fn examples(&self) -> Vec<Example> {
vec![
Example {
example: "plugin add nu_plugin_inc",
description: "Run the `nu_plugin_inc` plugin from the current directory and install its signatures.",
result: None,
},
Example {
example: "plugin use inc",
description: "
Load (or reload) the `inc` plugin from the plugin registry file and put its
commands in scope. The plugin must already be in the registry file at parse
time.
"
.trim(),
result: None,
},
Example {
example: "plugin list",
description: "List installed plugins",
@ -64,11 +77,6 @@ impl Command for PluginCommand {
description: "Stop the plugin named `inc`.",
result: None,
},
Example {
example: "plugin add nu_plugin_inc",
description: "Run the `nu_plugin_inc` plugin from the current directory and install its signatures.",
result: None,
},
Example {
example: "plugin rm inc",
description: "Remove the installed signatures for the `inc` plugin.",

View File

@ -1,6 +1,6 @@
use nu_engine::command_prelude::*;
use crate::util::modify_plugin_file;
use crate::util::{canonicalize_possible_filename_arg, modify_plugin_file};
#[derive(Clone)]
pub struct PluginRm;
@ -17,7 +17,7 @@ impl Command for PluginRm {
.named(
"plugin-config",
SyntaxShape::Filepath,
"Use a plugin cache file other than the one set in `$nu.plugin-path`",
"Use a plugin registry file other than the one set in `$nu.plugin-path`",
None,
)
.switch(
@ -28,21 +28,21 @@ impl Command for PluginRm {
.required(
"name",
SyntaxShape::String,
"The name of the plugin to remove (not the filename)",
"The name, or filename, of the plugin to remove",
)
.category(Category::Plugin)
}
fn usage(&self) -> &str {
"Remove a plugin from the plugin cache file."
"Remove a plugin from the plugin registry file."
}
fn extra_usage(&self) -> &str {
r#"
This does not remove the plugin commands from the current scope or from `plugin
list` in the current shell. It instead removes the plugin from the plugin
cache file (by default, `$nu.plugin-path`). The changes will be apparent the
next time `nu` is launched with that plugin cache file.
registry file (by default, `$nu.plugin-path`). The changes will be apparent the
next time `nu` is launched with that plugin registry file.
This can be useful for removing an invalid plugin signature, if it can't be
fixed with `plugin add`.
@ -51,7 +51,7 @@ fixed with `plugin add`.
}
fn search_terms(&self) -> Vec<&str> {
vec!["plugin", "rm", "remove", "delete", "signature"]
vec!["remove", "delete", "signature"]
}
fn examples(&self) -> Vec<Example> {
@ -61,9 +61,14 @@ fixed with `plugin add`.
description: "Remove the installed signatures for the `inc` plugin.",
result: None,
},
Example {
example: "plugin rm ~/.cargo/bin/nu_plugin_inc",
description: "Remove the installed signatures for the plugin with the filename `~/.cargo/bin/nu_plugin_inc`.",
result: None,
},
Example {
example: "plugin rm --plugin-config polars.msgpackz polars",
description: "Remove the installed signatures for the `polars` plugin from the \"polars.msgpackz\" plugin cache file.",
description: "Remove the installed signatures for the `polars` plugin from the \"polars.msgpackz\" plugin registry file.",
result: None,
},
]
@ -80,18 +85,26 @@ fixed with `plugin add`.
let custom_path = call.get_flag(engine_state, stack, "plugin-config")?;
let force = call.has_flag(engine_state, stack, "force")?;
let filename = canonicalize_possible_filename_arg(engine_state, stack, &name.item);
modify_plugin_file(engine_state, stack, call.head, custom_path, |contents| {
if !force && !contents.plugins.iter().any(|p| p.name == name.item) {
if let Some(index) = contents
.plugins
.iter()
.position(|p| p.name == name.item || p.filename == filename)
{
contents.plugins.remove(index);
Ok(())
} else if force {
Ok(())
} else {
Err(ShellError::GenericError {
error: format!("Failed to remove the `{}` plugin", name.item),
msg: "couldn't find a plugin with this name in the cache file".into(),
msg: "couldn't find a plugin with this name in the registry file".into(),
span: Some(name.span),
help: None,
inner: vec![],
})
} else {
contents.remove_plugin(&name.item);
Ok(())
}
})?;

View File

@ -1,5 +1,7 @@
use nu_engine::command_prelude::*;
use crate::util::canonicalize_possible_filename_arg;
#[derive(Clone)]
pub struct PluginStop;
@ -14,7 +16,7 @@ impl Command for PluginStop {
.required(
"name",
SyntaxShape::String,
"The name of the plugin to stop.",
"The name, or filename, of the plugin to stop",
)
.category(Category::Plugin)
}
@ -30,6 +32,11 @@ impl Command for PluginStop {
description: "Stop the plugin named `inc`.",
result: None,
},
Example {
example: "plugin stop ~/.cargo/bin/nu_plugin_inc",
description: "Stop the plugin with the filename `~/.cargo/bin/nu_plugin_inc`.",
result: None,
},
Example {
example: "plugin list | each { |p| plugin stop $p.name }",
description: "Stop all plugins.",
@ -47,9 +54,12 @@ impl Command for PluginStop {
) -> Result<PipelineData, ShellError> {
let name: Spanned<String> = call.req(engine_state, stack, 0)?;
let filename = canonicalize_possible_filename_arg(engine_state, stack, &name.item);
let mut found = false;
for plugin in engine_state.plugins() {
if plugin.identity().name() == name.item {
let id = &plugin.identity();
if id.name() == name.item || id.filename() == filename {
plugin.stop()?;
found = true;
}

View File

@ -0,0 +1,89 @@
use nu_engine::command_prelude::*;
#[derive(Clone)]
pub struct PluginUse;
impl Command for PluginUse {
fn name(&self) -> &str {
"plugin use"
}
fn usage(&self) -> &str {
"Load a plugin from the plugin registry file into scope."
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build(self.name())
.input_output_types(vec![(Type::Nothing, Type::Nothing)])
.named(
"plugin-config",
SyntaxShape::Filepath,
"Use a plugin registry file other than the one set in `$nu.plugin-path`",
None,
)
.required(
"name",
SyntaxShape::String,
"The name, or filename, of the plugin to load",
)
.category(Category::Plugin)
}
fn extra_usage(&self) -> &str {
r#"
This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html
The plugin definition must be available in the plugin registry file at parse
time. Run `plugin add` first in the REPL to do this, or from a script consider
preparing a plugin registry file and passing `--plugin-config`, or using the
`--plugin` option to `nu` instead.
If the plugin was already loaded, this will reload the latest definition from
the registry file into scope.
Note that even if the plugin filename is specified, it will only be loaded if
it was already previously registered with `plugin add`.
"#
.trim()
}
fn search_terms(&self) -> Vec<&str> {
vec!["add", "register", "scope"]
}
fn is_parser_keyword(&self) -> bool {
true
}
fn run(
&self,
_engine_state: &EngineState,
_stack: &mut Stack,
_call: &Call,
_input: PipelineData,
) -> Result<PipelineData, ShellError> {
Ok(PipelineData::empty())
}
fn examples(&self) -> Vec<Example> {
vec![
Example {
description: "Load the commands for the `query` plugin from $nu.plugin-path",
example: r#"plugin use query"#,
result: None,
},
Example {
description: "Load the commands for the plugin with the filename `~/.cargo/bin/nu_plugin_query` from $nu.plugin-path",
example: r#"plugin use ~/.cargo/bin/nu_plugin_query"#,
result: None,
},
Example {
description:
"Load the commands for the `query` plugin from a custom plugin registry file",
example: r#"plugin use --plugin-config local-plugins.msgpackz query"#,
result: None,
},
]
}
}

View File

@ -35,12 +35,17 @@ impl Command for Register {
}
fn extra_usage(&self) -> &str {
r#"This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html"#
r#"
Deprecated in favor of `plugin add` and `plugin use`.
This command is a parser keyword. For details, check:
https://www.nushell.sh/book/thinking_in_nu.html
"#
.trim()
}
fn search_terms(&self) -> Vec<&str> {
vec!["plugin", "add", "register"]
vec!["add"]
}
fn is_parser_keyword(&self) -> bool {

View File

@ -12,11 +12,12 @@ pub fn add_plugin_command_context(mut engine_state: EngineState) -> EngineState
}
bind_command!(
PluginCommand,
PluginAdd,
PluginCommand,
PluginList,
PluginRm,
PluginStop,
PluginUse,
Register,
);

View File

@ -1,25 +1,28 @@
use std::fs::{self, File};
use std::{
fs::{self, File},
path::PathBuf,
};
use nu_engine::{command_prelude::*, current_dir};
use nu_protocol::PluginCacheFile;
use nu_protocol::{engine::StateWorkingSet, PluginRegistryFile};
pub(crate) fn modify_plugin_file(
engine_state: &EngineState,
stack: &mut Stack,
span: Span,
custom_path: Option<Spanned<String>>,
operate: impl FnOnce(&mut PluginCacheFile) -> Result<(), ShellError>,
operate: impl FnOnce(&mut PluginRegistryFile) -> Result<(), ShellError>,
) -> Result<(), ShellError> {
let cwd = current_dir(engine_state, stack)?;
let plugin_cache_file_path = if let Some(ref custom_path) = custom_path {
let plugin_registry_file_path = if let Some(ref custom_path) = custom_path {
nu_path::expand_path_with(&custom_path.item, cwd, true)
} else {
engine_state
.plugin_path
.clone()
.ok_or_else(|| ShellError::GenericError {
error: "Plugin cache file not set".into(),
error: "Plugin registry file not set".into(),
msg: "pass --plugin-config explicitly here".into(),
span: Some(span),
help: Some("you may be running `nu` with --no-config-file".into()),
@ -28,13 +31,13 @@ pub(crate) fn modify_plugin_file(
};
// Try to read the plugin file if it exists
let mut contents = if fs::metadata(&plugin_cache_file_path).is_ok_and(|m| m.len() > 0) {
PluginCacheFile::read_from(
File::open(&plugin_cache_file_path).map_err(|err| err.into_spanned(span))?,
let mut contents = if fs::metadata(&plugin_registry_file_path).is_ok_and(|m| m.len() > 0) {
PluginRegistryFile::read_from(
File::open(&plugin_registry_file_path).err_span(span)?,
Some(span),
)?
} else {
PluginCacheFile::default()
PluginRegistryFile::default()
};
// Do the operation
@ -42,9 +45,45 @@ pub(crate) fn modify_plugin_file(
// Save the modified file on success
contents.write_to(
File::create(&plugin_cache_file_path).map_err(|err| err.into_spanned(span))?,
File::create(&plugin_registry_file_path).err_span(span)?,
Some(span),
)?;
Ok(())
}
pub(crate) fn canonicalize_possible_filename_arg(
engine_state: &EngineState,
stack: &Stack,
arg: &str,
) -> PathBuf {
// This results in the best possible chance of a match with the plugin item
if let Ok(cwd) = nu_engine::current_dir(engine_state, stack) {
let path = nu_path::expand_path_with(arg, &cwd, true);
// Try to canonicalize
nu_path::locate_in_dirs(&path, &cwd, || get_plugin_dirs(engine_state, stack))
// If we couldn't locate it, return the expanded path alone
.unwrap_or(path)
} else {
arg.into()
}
}
pub(crate) fn get_plugin_dirs(
engine_state: &EngineState,
stack: &Stack,
) -> impl Iterator<Item = String> {
// Get the NU_PLUGIN_DIRS constant or env var
let working_set = StateWorkingSet::new(engine_state);
let value = working_set
.find_variable(b"$NU_PLUGIN_DIRS")
.and_then(|var_id| working_set.get_constant(var_id).ok().cloned())
.or_else(|| stack.get_env_var(engine_state, "NU_PLUGIN_DIRS"));
// Get all of the strings in the list, if possible
value
.into_iter()
.flat_map(|value| value.into_list().ok())
.flatten()
.flat_map(|list_item| list_item.coerce_into_string().ok())
}

View File

@ -5,18 +5,18 @@ repository = "https://github.com/nushell/nushell/tree/main/crates/nu-color-confi
edition = "2021"
license = "MIT"
name = "nu-color-config"
version = "0.92.3"
version = "0.93.1"
[lib]
bench = false
[dependencies]
nu-protocol = { path = "../nu-protocol", version = "0.92.3" }
nu-engine = { path = "../nu-engine", version = "0.92.3" }
nu-json = { path = "../nu-json", version = "0.92.3" }
nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-json = { path = "../nu-json", version = "0.93.1" }
nu-ansi-term = { workspace = true }
serde = { workspace = true, features = ["derive"] }
[dev-dependencies]
nu-test-support = { path = "../nu-test-support", version = "0.92.3" }
nu-test-support = { path = "../nu-test-support", version = "0.93.1" }

View File

@ -5,7 +5,7 @@ edition = "2021"
license = "MIT"
name = "nu-command"
repository = "https://github.com/nushell/nushell/tree/main/crates/nu-command"
version = "0.92.3"
version = "0.93.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -13,25 +13,26 @@ version = "0.92.3"
bench = false
[dependencies]
nu-cmd-base = { path = "../nu-cmd-base", version = "0.92.3" }
nu-color-config = { path = "../nu-color-config", version = "0.92.3" }
nu-engine = { path = "../nu-engine", version = "0.92.3" }
nu-glob = { path = "../nu-glob", version = "0.92.3" }
nu-json = { path = "../nu-json", version = "0.92.3" }
nu-parser = { path = "../nu-parser", version = "0.92.3" }
nu-path = { path = "../nu-path", version = "0.92.3" }
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.92.3" }
nu-protocol = { path = "../nu-protocol", version = "0.92.3" }
nu-system = { path = "../nu-system", version = "0.92.3" }
nu-table = { path = "../nu-table", version = "0.92.3" }
nu-term-grid = { path = "../nu-term-grid", version = "0.92.3" }
nu-utils = { path = "../nu-utils", version = "0.92.3" }
nu-cmd-base = { path = "../nu-cmd-base", version = "0.93.1" }
nu-color-config = { path = "../nu-color-config", version = "0.93.1" }
nu-engine = { path = "../nu-engine", version = "0.93.1" }
nu-glob = { path = "../nu-glob", version = "0.93.1" }
nu-json = { path = "../nu-json", version = "0.93.1" }
nu-parser = { path = "../nu-parser", version = "0.93.1" }
nu-path = { path = "../nu-path", version = "0.93.1" }
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.93.1" }
nu-protocol = { path = "../nu-protocol", version = "0.93.1" }
nu-system = { path = "../nu-system", version = "0.93.1" }
nu-table = { path = "../nu-table", version = "0.93.1" }
nu-term-grid = { path = "../nu-term-grid", version = "0.93.1" }
nu-utils = { path = "../nu-utils", version = "0.93.1" }
nu-ansi-term = { workspace = true }
nuon = { path = "../nuon", version = "0.92.3" }
nuon = { path = "../nuon", version = "0.93.1" }
alphanumeric-sort = { workspace = true }
base64 = { workspace = true }
bracoxide = { workspace = true }
brotli = { workspace = true }
byteorder = { workspace = true }
bytesize = { workspace = true }
calamine = { workspace = true, features = ["dates"] }
@ -74,6 +75,7 @@ rayon = { workspace = true }
regex = { workspace = true }
roxmltree = { workspace = true }
rusqlite = { workspace = true, features = ["bundled", "backup", "chrono"], optional = true }
rmp = { workspace = true }
same-file = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true, features = ["preserve_order"] }
@ -135,11 +137,12 @@ trash-support = ["trash"]
which-support = ["which"]
[dev-dependencies]
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.92.3" }
nu-test-support = { path = "../nu-test-support", version = "0.92.3" }
nu-cmd-lang = { path = "../nu-cmd-lang", version = "0.93.1" }
nu-test-support = { path = "../nu-test-support", version = "0.93.1" }
dirs-next = { workspace = true }
mockito = { workspace = true, default-features = false }
quickcheck = { workspace = true }
quickcheck_macros = { workspace = true }
rstest = { workspace = true, default-features = false }
pretty_assertions = { workspace = true }

View File

@ -31,8 +31,8 @@ impl Command for BytesAdd {
Type::List(Box::new(Type::Binary)),
Type::List(Box::new(Type::Binary)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.required("data", SyntaxShape::Binary, "The binary to add.")

View File

@ -41,8 +41,8 @@ impl Command for BytesAt {
Type::List(Box::new(Type::Binary)),
Type::List(Box::new(Type::Binary)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.required("range", SyntaxShape::Range, "The range to get bytes.")
.rest(

View File

@ -24,14 +24,21 @@ impl Command for BytesBuild {
}
fn examples(&self) -> Vec<Example> {
vec![Example {
example: "bytes build 0x[01 02] 0x[03] 0x[04]",
description: "Builds binary data from 0x[01 02], 0x[03], 0x[04]",
result: Some(Value::binary(
vec![0x01, 0x02, 0x03, 0x04],
Span::test_data(),
)),
}]
vec![
Example {
example: "bytes build 0x[01 02] 0x[03] 0x[04]",
description: "Builds binary data from 0x[01 02], 0x[03], 0x[04]",
result: Some(Value::binary(
vec![0x01, 0x02, 0x03, 0x04],
Span::test_data(),
)),
},
Example {
example: "bytes build 255 254 253 252",
description: "Builds binary data from byte numbers",
result: Some(Value::test_binary(vec![0xff, 0xfe, 0xfd, 0xfc])),
},
]
}
fn run(
@ -46,8 +53,17 @@ impl Command for BytesBuild {
let eval_expression = get_eval_expression(engine_state);
eval_expression(engine_state, stack, expr)
})? {
let val_span = val.span();
match val {
Value::Binary { mut val, .. } => output.append(&mut val),
Value::Int { val, .. } => {
let byte: u8 = val.try_into().map_err(|_| ShellError::IncorrectValue {
msg: format!("{val} is out of range for byte"),
val_span,
call_span: call.head,
})?;
output.push(byte);
}
// Explicitly propagate errors instead of dropping them.
Value::Error { error, .. } => return Err(*error),
other => {

View File

@ -24,8 +24,8 @@ impl Command for BytesEndsWith {
fn signature(&self) -> Signature {
Signature::build("bytes ends-with")
.input_output_types(vec![(Type::Binary, Type::Bool),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.required("pattern", SyntaxShape::Binary, "The pattern to match.")

View File

@ -28,8 +28,8 @@ impl Command for BytesIndexOf {
(Type::Binary, Type::Any),
// FIXME: this shouldn't be needed, cell paths should work with the two
// above
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.required(

View File

@ -17,8 +17,8 @@ impl Command for BytesLen {
Type::List(Box::new(Type::Binary)),
Type::List(Box::new(Type::Int)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.rest(

View File

@ -26,8 +26,8 @@ impl Command for BytesRemove {
Signature::build("bytes remove")
.input_output_types(vec![
(Type::Binary, Type::Binary),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.required("pattern", SyntaxShape::Binary, "The pattern to find.")
.rest(

View File

@ -26,8 +26,8 @@ impl Command for BytesReplace {
Signature::build("bytes replace")
.input_output_types(vec![
(Type::Binary, Type::Binary),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.required("find", SyntaxShape::Binary, "The pattern to find.")

View File

@ -13,8 +13,8 @@ impl Command for BytesReverse {
Signature::build("bytes reverse")
.input_output_types(vec![
(Type::Binary, Type::Binary),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.rest(

View File

@ -25,8 +25,8 @@ impl Command for BytesStartsWith {
Signature::build("bytes starts-with")
.input_output_types(vec![
(Type::Binary, Type::Bool),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.required("pattern", SyntaxShape::Binary, "The pattern to match.")

View File

@ -19,7 +19,7 @@ impl Command for Histogram {
fn signature(&self) -> Signature {
Signature::build("histogram")
.input_output_types(vec![(Type::List(Box::new(Type::Any)), Type::Table(vec![])),])
.input_output_types(vec![(Type::List(Box::new(Type::Any)), Type::table()),])
.optional("column-name", SyntaxShape::String, "Column name to calc frequency, no need to provide if input is a list.")
.optional("frequency-column-name", SyntaxShape::String, "Histogram's frequency column, default to be frequency column output.")
.named("percentage-type", SyntaxShape::String, "percentage calculate method, can be 'normalize' or 'relative', in 'normalize', defaults to be 'normalize'", Some('t'))

View File

@ -30,8 +30,8 @@ impl Command for SubCommand {
(Type::Bool, Type::Binary),
(Type::Filesize, Type::Binary),
(Type::Date, Type::Binary),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true) // TODO: supply exhaustive examples
.switch("compact", "output without padding zeros", Some('c'))

View File

@ -16,9 +16,9 @@ impl Command for SubCommand {
(Type::Number, Type::Bool),
(Type::String, Type::Bool),
(Type::Bool, Type::Bool),
(Type::List(Box::new(Type::Any)), Type::Table(vec![])),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::List(Box::new(Type::Any)), Type::table()),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.rest(

View File

@ -15,10 +15,9 @@ impl Command for IntoCellPath {
(Type::Int, Type::CellPath),
(Type::List(Box::new(Type::Any)), Type::CellPath),
(
Type::List(Box::new(Type::Record(vec![
("value".into(), Type::Any),
("optional".into(), Type::Bool),
]))),
Type::List(Box::new(Type::Record(
[("value".into(), Type::Any), ("optional".into(), Type::Bool)].into(),
))),
Type::CellPath,
),
])

View File

@ -62,8 +62,8 @@ impl Command for SubCommand {
(Type::Int, Type::Date),
(Type::String, Type::Date),
(Type::List(Box::new(Type::String)), Type::List(Box::new(Type::Date))),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true)
.named(

View File

@ -17,9 +17,9 @@ impl Command for SubCommand {
(Type::Int, Type::Duration),
(Type::String, Type::Duration),
(Type::Duration, Type::Duration),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::table(), Type::table()),
//todo: record<hour,minute,sign> | into duration -> Duration
//(Type::Record(vec![]), Type::Record(vec![])),
//(Type::record(), Type::record()),
])
//.allow_variants_without_examples(true)
.named(
@ -203,9 +203,9 @@ fn string_to_duration(s: &str, span: Span) -> Result<i64, ShellError> {
Type::Duration,
|x| x,
) {
if let Expr::ValueWithUnit(value, unit) = expression.expr {
if let Expr::Int(x) = value.expr {
match unit.item {
if let Expr::ValueWithUnit(value) = expression.expr {
if let Expr::Int(x) = value.expr.expr {
match value.unit.item {
Unit::Nanosecond => return Ok(x),
Unit::Microsecond => return Ok(x * 1000),
Unit::Millisecond => return Ok(x * 1000 * 1000),

View File

@ -18,8 +18,8 @@ impl Command for SubCommand {
(Type::Number, Type::Filesize),
(Type::String, Type::Filesize),
(Type::Filesize, Type::Filesize),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
(
Type::List(Box::new(Type::Int)),
Type::List(Box::new(Type::Filesize)),

View File

@ -16,8 +16,8 @@ impl Command for SubCommand {
(Type::String, Type::Float),
(Type::Bool, Type::Float),
(Type::Float, Type::Float),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
(
Type::List(Box::new(Type::Any)),
Type::List(Box::new(Type::Float)),

View File

@ -27,8 +27,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::Glob)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
.rest(

View File

@ -36,8 +36,8 @@ impl Command for SubCommand {
(Type::Duration, Type::Int),
(Type::Filesize, Type::Int),
(Type::Binary, Type::Int),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
(
Type::List(Box::new(Type::String)),
Type::List(Box::new(Type::Int)),

View File

@ -13,11 +13,11 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into record")
.input_output_types(vec![
(Type::Date, Type::Record(vec![])),
(Type::Duration, Type::Record(vec![])),
(Type::List(Box::new(Type::Any)), Type::Record(vec![])),
(Type::Range, Type::Record(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::Date, Type::record()),
(Type::Duration, Type::record()),
(Type::List(Box::new(Type::Any)), Type::record()),
(Type::Range, Type::record()),
(Type::record(), Type::record()),
])
.category(Category::Conversions)
}

View File

@ -40,8 +40,8 @@ impl Command for SubCommand {
Type::List(Box::new(Type::Any)),
Type::List(Box::new(Type::String)),
),
(Type::Table(vec![]), Type::Table(vec![])),
(Type::Record(vec![]), Type::Record(vec![])),
(Type::table(), Type::table()),
(Type::record(), Type::record()),
])
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
.rest(

View File

@ -15,7 +15,7 @@ impl Command for IntoValue {
fn signature(&self) -> Signature {
Signature::build("into value")
.input_output_types(vec![(Type::Table(vec![]), Type::Table(vec![]))])
.input_output_types(vec![(Type::table(), Type::table())])
.named(
"columns",
SyntaxShape::Table(vec![]),

View File

@ -24,8 +24,8 @@ impl Command for IntoSqliteDb {
Signature::build("into sqlite")
.category(Category::Conversions)
.input_output_types(vec![
(Type::Table(vec![]), Type::Nothing),
(Type::Record(vec![]), Type::Nothing),
(Type::table(), Type::Nothing),
(Type::record(), Type::Nothing),
])
.allow_variants_without_examples(true)
.required(

View File

@ -11,7 +11,7 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("date list-timezone")
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))])
.input_output_types(vec![(Type::Nothing, Type::table())])
.category(Category::Date)
}

View File

@ -13,8 +13,8 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("date to-record")
.input_output_types(vec![
(Type::Date, Type::Record(vec![])),
(Type::String, Type::Record(vec![])),
(Type::Date, Type::record()),
(Type::String, Type::record()),
])
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
.category(Category::Date)

View File

@ -13,8 +13,8 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("date to-table")
.input_output_types(vec![
(Type::Date, Type::Table(vec![])),
(Type::String, Type::Table(vec![])),
(Type::Date, Type::table()),
(Type::String, Type::table()),
])
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
.category(Category::Date)

View File

@ -16,7 +16,7 @@ impl Command for Ast {
fn signature(&self) -> Signature {
Signature::build("ast")
.input_output_types(vec![(Type::String, Type::Record(vec![]))])
.input_output_types(vec![(Type::String, Type::record())])
.required(
"pipeline",
SyntaxShape::String,

View File

@ -31,7 +31,7 @@ impl Command for DebugInfo {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("debug info")
.input_output_types(vec![(Type::Nothing, Type::Record(vec![]))])
.input_output_types(vec![(Type::Nothing, Type::record())])
.category(Category::Debug)
}

View File

@ -18,7 +18,7 @@ impl Command for Metadata {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("metadata")
.input_output_types(vec![(Type::Any, Type::Record(vec![]))])
.input_output_types(vec![(Type::Any, Type::record())])
.allow_variants_without_examples(true)
.optional(
"expression",

View File

@ -34,7 +34,7 @@ impl Command for DebugProfile {
"How many blocks/closures deep to step into (default 2)",
Some('m'),
)
.input_output_types(vec![(Type::Any, Type::Table(vec![]))])
.input_output_types(vec![(Type::Any, Type::table())])
.category(Category::Debug)
}

View File

@ -20,12 +20,15 @@ impl Command for ViewFiles {
Signature::build("view files")
.input_output_types(vec![(
Type::Nothing,
Type::Table(vec![
("filename".into(), Type::String),
("start".into(), Type::Int),
("end".into(), Type::Int),
("size".into(), Type::Int),
]),
Type::Table(
[
("filename".into(), Type::String),
("start".into(), Type::Int),
("end".into(), Type::Int),
("size".into(), Type::Int),
]
.into(),
),
)])
.category(Category::Debug)
}

View File

@ -260,6 +260,8 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState {
From,
FromCsv,
FromJson,
FromMsgpack,
FromMsgpackz,
FromNuon,
FromOds,
FromSsv,
@ -273,6 +275,8 @@ pub fn add_shell_command_context(mut engine_state: EngineState) -> EngineState {
ToCsv,
ToJson,
ToMd,
ToMsgpack,
ToMsgpackz,
ToNuon,
ToText,
ToToml,

View File

@ -15,7 +15,7 @@ impl Command for LoadEnv {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("load-env")
.input_output_types(vec![
(Type::Record(vec![]), Type::Nothing),
(Type::record(), Type::Nothing),
(Type::Nothing, Type::Nothing),
])
.allow_variants_without_examples(true)

View File

@ -33,7 +33,7 @@ impl Command for Du {
fn signature(&self) -> Signature {
Signature::build("du")
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))])
.input_output_types(vec![(Type::Nothing, Type::table())])
.allow_variants_without_examples(true)
.rest(
"path",

View File

@ -45,7 +45,7 @@ impl Command for Ls {
fn signature(&self) -> nu_protocol::Signature {
Signature::build("ls")
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))])
.input_output_types(vec![(Type::Nothing, Type::table())])
// LsGlobPattern is similar to string, it won't auto-expand
// and we use it to track if the user input is quoted.
.rest("pattern", SyntaxShape::OneOf(vec![SyntaxShape::GlobPattern, SyntaxShape::String]), "The glob pattern to use.")

Some files were not shown because too many files have changed in this diff Show More