mirror of
https://github.com/nushell/nushell.git
synced 2025-07-01 15:11:52 +02:00
Compare commits
21 Commits
Author | SHA1 | Date | |
---|---|---|---|
6c07bc10e2 | |||
6365ba0286 | |||
545b1dcd94 | |||
fb89f2f48c | |||
f6ee21f76b | |||
d69a4db2e7 | |||
d4bfbb5eaf | |||
507f24d029 | |||
230c36f2fb | |||
219c719e98 | |||
50146bdef3 | |||
2042f7f769 | |||
0594f9e7aa | |||
3b8deb9ec7 | |||
727ff5f2d4 | |||
3d62528d8c | |||
a42d419b66 | |||
9602e82029 | |||
8e98df8b28 | |||
2daf8ec72d | |||
afcacda35f |
155
.github/workflows/release-pkg.nu
vendored
Executable file
155
.github/workflows/release-pkg.nu
vendored
Executable file
@ -0,0 +1,155 @@
|
||||
#!/usr/bin/env nu
|
||||
|
||||
# Created: 2022/05/26 19:05:20
|
||||
# Description:
|
||||
# A script to do the github release task, need nushell to be installed.
|
||||
# REF:
|
||||
# 1. https://github.com/volks73/cargo-wix
|
||||
|
||||
# The main binary file to be released
|
||||
let bin = 'nu'
|
||||
let os = $env.OS
|
||||
let target = $env.TARGET
|
||||
# Repo source dir like `/home/runner/work/nushell/nushell`
|
||||
let src = $env.GITHUB_WORKSPACE
|
||||
let flags = $env.TARGET_RUSTFLAGS
|
||||
let dist = $'($env.GITHUB_WORKSPACE)/output'
|
||||
let version = (open Cargo.toml | get package.version)
|
||||
|
||||
# $env
|
||||
|
||||
$'(char nl)Packaging ($bin) v($version) for ($target) in ($src)...'; hr-line -b
|
||||
if not ('Cargo.lock' | path exists) { cargo generate-lockfile }
|
||||
|
||||
$'Start building ($bin)...'; hr-line
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Build for Ubuntu and macOS
|
||||
# ----------------------------------------------------------------------------
|
||||
if $os in ['ubuntu-latest', 'macos-latest'] {
|
||||
if $os == 'ubuntu-latest' {
|
||||
sudo apt-get install libxcb-composite0-dev -y
|
||||
}
|
||||
if $target == 'aarch64-unknown-linux-gnu' {
|
||||
sudo apt-get install gcc-aarch64-linux-gnu -y
|
||||
let-env CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER = 'aarch64-linux-gnu-gcc'
|
||||
cargo-build-nu $flags
|
||||
} else if $target == 'armv7-unknown-linux-gnueabihf' {
|
||||
sudo apt-get install pkg-config gcc-arm-linux-gnueabihf -y
|
||||
let-env CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER = 'arm-linux-gnueabihf-gcc'
|
||||
cargo-build-nu $flags
|
||||
} else {
|
||||
# musl-tools to fix 'Failed to find tool. Is `musl-gcc` installed?'
|
||||
# Actually just for x86_64-unknown-linux-musl target
|
||||
sudo apt install musl-tools -y
|
||||
cargo-build-nu $flags
|
||||
}
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Build for Windows without static-link-openssl feature
|
||||
# ----------------------------------------------------------------------------
|
||||
if $os in ['windows-latest'] {
|
||||
if ($flags | str trim | empty?) {
|
||||
cargo build --release --all --target $target --features=extra
|
||||
} else {
|
||||
cargo build --release --all --target $target --features=extra $flags
|
||||
}
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Prepare for the release archive
|
||||
# ----------------------------------------------------------------------------
|
||||
let suffix = if $os == 'windows-latest' { '.exe' }
|
||||
# nu, nu_plugin_* were all included
|
||||
let executable = $'target/($target)/release/($bin)*($suffix)'
|
||||
$'Current executable file: ($executable)'
|
||||
|
||||
cd $src; mkdir $dist;
|
||||
rm -rf $'target/($target)/release/*.d' $'target/($target)/release/nu_pretty_hex*'
|
||||
$'(char nl)All executable files:'; hr-line
|
||||
ls -f $executable
|
||||
|
||||
$'(char nl)Copying release files...'; hr-line
|
||||
cp -v README.release.txt $'($dist)/README.txt'
|
||||
[LICENSE $executable] | each {|it| cp -rv $it $dist } | flatten
|
||||
|
||||
$'(char nl)Check binary release version detail:'; hr-line
|
||||
let ver = if $os == 'windows-latest' {
|
||||
(do -i { ./output/nu.exe -c 'version' }) | str collect
|
||||
} else {
|
||||
(do -i { ./output/nu -c 'version' }) | str collect
|
||||
}
|
||||
if ($ver | str trim | empty?) {
|
||||
$'(ansi r)Incompatible nu binary...(ansi reset)'
|
||||
} else { $ver }
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Create a release archive and send it to output for the following steps
|
||||
# ----------------------------------------------------------------------------
|
||||
cd $dist; $'(char nl)Creating release archive...'; hr-line
|
||||
if $os in ['ubuntu-latest', 'macos-latest'] {
|
||||
|
||||
$'(char nl)(ansi g)Archive contents:(ansi reset)'; hr-line; ls
|
||||
|
||||
let archive = $'($dist)/($bin)-($version)-($target).tar.gz'
|
||||
tar czf $archive *
|
||||
print $'archive: ---> ($archive)'; ls $archive
|
||||
echo $'::set-output name=archive::($archive)'
|
||||
|
||||
} else if $os == 'windows-latest' {
|
||||
|
||||
let releaseStem = $'($bin)-($version)-($target)'
|
||||
|
||||
$'(char nl)Download less related stuffs...'; hr-line
|
||||
curl https://github.com/jftuga/less-Windows/releases/download/less-v590/less.exe -o $'($dist)\less.exe'
|
||||
curl https://raw.githubusercontent.com/jftuga/less-Windows/master/LICENSE -o $'($dist)\LICENSE-for-less.txt'
|
||||
|
||||
# Create Windows msi release package
|
||||
if (get-env _EXTRA_) == 'msi' {
|
||||
|
||||
let wixRelease = $'($src)/target/wix/($releaseStem).msi'
|
||||
$'(char nl)Start creating Windows msi package...'
|
||||
cd $src; hr-line
|
||||
# Wix need the binaries be stored in target/release/
|
||||
cp -r $'($dist)/*' target/release/
|
||||
cargo install cargo-wix --version 0.3.2
|
||||
cargo wix --no-build --nocapture --package nu --output $wixRelease
|
||||
echo $'::set-output name=archive::($wixRelease)'
|
||||
|
||||
} else {
|
||||
|
||||
$'(char nl)(ansi g)Archive contents:(ansi reset)'; hr-line; ls
|
||||
let archive = $'($dist)/($releaseStem).zip'
|
||||
7z a $archive *
|
||||
print $'archive: ---> ($archive)';
|
||||
let pkg = (ls -f $archive | get name)
|
||||
if not ($pkg | empty?) {
|
||||
echo $'::set-output name=archive::($pkg | get 0)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def 'cargo-build-nu' [ options: string ] {
|
||||
if ($options | str trim | empty?) {
|
||||
cargo build --release --all --target $target --features=extra,static-link-openssl
|
||||
} else {
|
||||
cargo build --release --all --target $target --features=extra,static-link-openssl $options
|
||||
}
|
||||
}
|
||||
|
||||
# Print a horizontal line marker
|
||||
def 'hr-line' [
|
||||
--blank-line(-b): bool
|
||||
] {
|
||||
print $'(ansi g)---------------------------------------------------------------------------->(ansi reset)'
|
||||
if $blank-line { char nl }
|
||||
}
|
||||
|
||||
# Get the specified env key's value or ''
|
||||
def 'get-env' [
|
||||
key: string # The key to get it's env value
|
||||
default: string = '' # The default value for an empty env
|
||||
] {
|
||||
$env | get -i $key | default $default
|
||||
}
|
517
.github/workflows/release.yml
vendored
517
.github/workflows/release.yml
vendored
@ -1,3 +1,7 @@
|
||||
#
|
||||
# REF:
|
||||
# 1. https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrixinclude
|
||||
#
|
||||
name: Create Release Draft
|
||||
|
||||
on:
|
||||
@ -5,434 +9,89 @@ on:
|
||||
push:
|
||||
tags: ["[0-9]+.[0-9]+.[0-9]+*"]
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
name: Build Linux
|
||||
runs-on: ubuntu-latest
|
||||
all:
|
||||
name: All
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
- aarch64-apple-darwin
|
||||
- x86_64-apple-darwin
|
||||
- x86_64-pc-windows-msvc
|
||||
- x86_64-unknown-linux-gnu
|
||||
- x86_64-unknown-linux-musl
|
||||
- aarch64-unknown-linux-gnu
|
||||
- armv7-unknown-linux-gnueabihf
|
||||
extra: ['bin']
|
||||
include:
|
||||
- target: aarch64-apple-darwin
|
||||
os: macos-latest
|
||||
target_rustflags: ''
|
||||
- target: x86_64-apple-darwin
|
||||
os: macos-latest
|
||||
target_rustflags: ''
|
||||
- target: x86_64-pc-windows-msvc
|
||||
extra: 'bin'
|
||||
os: windows-latest
|
||||
target_rustflags: ''
|
||||
- target: x86_64-pc-windows-msvc
|
||||
extra: msi
|
||||
os: windows-latest
|
||||
target_rustflags: ''
|
||||
- target: x86_64-unknown-linux-gnu
|
||||
os: ubuntu-latest
|
||||
target_rustflags: ''
|
||||
- target: x86_64-unknown-linux-musl
|
||||
os: ubuntu-latest
|
||||
target_rustflags: ''
|
||||
- target: aarch64-unknown-linux-gnu
|
||||
os: ubuntu-latest
|
||||
target_rustflags: ''
|
||||
- target: armv7-unknown-linux-gnueabihf
|
||||
os: ubuntu-latest
|
||||
target_rustflags: ''
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install libxcb
|
||||
run: sudo apt-get install libxcb-composite0-dev
|
||||
|
||||
- name: Set up cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
- name: Build
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --release --all --features=extra,static-link-openssl
|
||||
|
||||
# - name: Strip binaries (nu)
|
||||
# run: strip target/release/nu
|
||||
|
||||
# - name: Strip binaries (nu_plugin_inc)
|
||||
# run: strip target/release/nu_plugin_inc
|
||||
|
||||
# - name: Strip binaries (nu_plugin_match)
|
||||
# run: strip target/release/nu_plugin_match
|
||||
|
||||
# - name: Strip binaries (nu_plugin_textview)
|
||||
# run: strip target/release/nu_plugin_textview
|
||||
|
||||
# - name: Strip binaries (nu_plugin_binaryview)
|
||||
# run: strip target/release/nu_plugin_binaryview
|
||||
|
||||
# - name: Strip binaries (nu_plugin_chart_bar)
|
||||
# run: strip target/release/nu_plugin_chart_bar
|
||||
|
||||
# - name: Strip binaries (nu_plugin_chart_line)
|
||||
# run: strip target/release/nu_plugin_chart_line
|
||||
|
||||
# - name: Strip binaries (nu_plugin_from_bson)
|
||||
# run: strip target/release/nu_plugin_from_bson
|
||||
|
||||
# - name: Strip binaries (nu_plugin_from_sqlite)
|
||||
# run: strip target/release/nu_plugin_from_sqlite
|
||||
|
||||
# - name: Strip binaries (nu_plugin_from_mp4)
|
||||
# run: strip target/release/nu_plugin_from_mp4
|
||||
|
||||
# - name: Strip binaries (nu_plugin_query_json)
|
||||
# run: strip target/release/nu_plugin_query_json
|
||||
|
||||
# - name: Strip binaries (nu_plugin_s3)
|
||||
# run: strip target/release/nu_plugin_s3
|
||||
|
||||
# - name: Strip binaries (nu_plugin_selector)
|
||||
# run: strip target/release/nu_plugin_selector
|
||||
|
||||
# - name: Strip binaries (nu_plugin_start)
|
||||
# run: strip target/release/nu_plugin_start
|
||||
|
||||
# - name: Strip binaries (nu_plugin_to_bson)
|
||||
# run: strip target/release/nu_plugin_to_bson
|
||||
|
||||
# - name: Strip binaries (nu_plugin_to_sqlite)
|
||||
# run: strip target/release/nu_plugin_to_sqlite
|
||||
|
||||
# - name: Strip binaries (nu_plugin_tree)
|
||||
# run: strip target/release/nu_plugin_tree
|
||||
|
||||
# - name: Strip binaries (nu_plugin_xpath)
|
||||
# run: strip target/release/nu_plugin_xpath
|
||||
|
||||
- name: Create output directory
|
||||
run: mkdir output
|
||||
|
||||
- name: Copy files to output
|
||||
run: |
|
||||
cp target/release/nu target/release/nu_plugin_* output/
|
||||
cp README.release.txt output/README.txt
|
||||
cp LICENSE output/LICENSE
|
||||
rm output/*.d
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: linux
|
||||
path: output/*
|
||||
|
||||
macos:
|
||||
name: Build macOS
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
- name: Build
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --release --all --features=extra,static-link-openssl
|
||||
|
||||
# - name: Strip binaries (nu)
|
||||
# run: strip target/release/nu
|
||||
|
||||
# - name: Strip binaries (nu_plugin_inc)
|
||||
# run: strip target/release/nu_plugin_inc
|
||||
|
||||
# - name: Strip binaries (nu_plugin_match)
|
||||
# run: strip target/release/nu_plugin_match
|
||||
|
||||
# - name: Strip binaries (nu_plugin_textview)
|
||||
# run: strip target/release/nu_plugin_textview
|
||||
|
||||
# - name: Strip binaries (nu_plugin_binaryview)
|
||||
# run: strip target/release/nu_plugin_binaryview
|
||||
|
||||
# - name: Strip binaries (nu_plugin_chart_bar)
|
||||
# run: strip target/release/nu_plugin_chart_bar
|
||||
|
||||
# - name: Strip binaries (nu_plugin_chart_line)
|
||||
# run: strip target/release/nu_plugin_chart_line
|
||||
|
||||
# - name: Strip binaries (nu_plugin_from_bson)
|
||||
# run: strip target/release/nu_plugin_from_bson
|
||||
|
||||
# - name: Strip binaries (nu_plugin_from_sqlite)
|
||||
# run: strip target/release/nu_plugin_from_sqlite
|
||||
|
||||
# - name: Strip binaries (nu_plugin_from_mp4)
|
||||
# run: strip target/release/nu_plugin_from_mp4
|
||||
|
||||
# - name: Strip binaries (nu_plugin_query_json)
|
||||
# run: strip target/release/nu_plugin_query_json
|
||||
|
||||
# - name: Strip binaries (nu_plugin_s3)
|
||||
# run: strip target/release/nu_plugin_s3
|
||||
|
||||
# - name: Strip binaries (nu_plugin_selector)
|
||||
# run: strip target/release/nu_plugin_selector
|
||||
|
||||
# - name: Strip binaries (nu_plugin_start)
|
||||
# run: strip target/release/nu_plugin_start
|
||||
|
||||
# - name: Strip binaries (nu_plugin_to_bson)
|
||||
# run: strip target/release/nu_plugin_to_bson
|
||||
|
||||
# - name: Strip binaries (nu_plugin_to_sqlite)
|
||||
# run: strip target/release/nu_plugin_to_sqlite
|
||||
|
||||
# - name: Strip binaries (nu_plugin_tree)
|
||||
# run: strip target/release/nu_plugin_tree
|
||||
|
||||
# - name: Strip binaries (nu_plugin_xpath)
|
||||
# run: strip target/release/nu_plugin_xpath
|
||||
|
||||
- name: Create output directory
|
||||
run: mkdir output
|
||||
|
||||
- name: Copy files to output
|
||||
run: |
|
||||
cp target/release/nu target/release/nu_plugin_* output/
|
||||
cp README.release.txt output/README.txt
|
||||
cp LICENSE output/LICENSE
|
||||
rm output/*.d
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: macos
|
||||
path: output/*
|
||||
|
||||
windows:
|
||||
name: Build Windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up cargo
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
- name: Add cargo-wix subcommand
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: install
|
||||
args: cargo-wix --version 0.3.1
|
||||
|
||||
- name: Build
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --release --all --features=extra,static-link-openssl
|
||||
|
||||
# - name: Strip binaries (nu.exe)
|
||||
# run: strip target/release/nu.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_inc.exe)
|
||||
# run: strip target/release/nu_plugin_inc.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_match.exe)
|
||||
# run: strip target/release/nu_plugin_match.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_textview.exe)
|
||||
# run: strip target/release/nu_plugin_textview.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_binaryview.exe)
|
||||
# run: strip target/release/nu_plugin_binaryview.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_chart_bar.exe)
|
||||
# run: strip target/release/nu_plugin_chart_bar.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_chart_line.exe)
|
||||
# run: strip target/release/nu_plugin_chart_line.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_from_bson.exe)
|
||||
# run: strip target/release/nu_plugin_from_bson.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_from_sqlite.exe)
|
||||
# run: strip target/release/nu_plugin_from_sqlite.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_from_mp4.exe)
|
||||
# run: strip target/release/nu_plugin_from_mp4.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_query_json.exe)
|
||||
# run: strip target/release/nu_plugin_query_json.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_s3.exe)
|
||||
# run: strip target/release/nu_plugin_s3.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_selector.exe)
|
||||
# run: strip target/release/nu_plugin_selector.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_start.exe)
|
||||
# run: strip target/release/nu_plugin_start.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_to_bson.exe)
|
||||
# run: strip target/release/nu_plugin_to_bson.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_to_sqlite.exe)
|
||||
# run: strip target/release/nu_plugin_to_sqlite.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_tree.exe)
|
||||
# run: strip target/release/nu_plugin_tree.exe
|
||||
|
||||
# - name: Strip binaries (nu_plugin_xpath.exe)
|
||||
# run: strip target/release/nu_plugin_xpath.exe
|
||||
|
||||
- name: Create output directory
|
||||
run: mkdir output
|
||||
|
||||
- name: Download Less Binary
|
||||
run: Invoke-WebRequest -Uri "https://github.com/jftuga/less-Windows/releases/download/less-v562.0/less.exe" -OutFile "target\release\less.exe"
|
||||
|
||||
- name: Download Less License
|
||||
run: Invoke-WebRequest -Uri "https://raw.githubusercontent.com/jftuga/less-Windows/master/LICENSE" -OutFile "target\release\LICENSE-for-less.txt"
|
||||
|
||||
- name: Copy files to output
|
||||
run: |
|
||||
cp target\release\nu.exe output\
|
||||
cp LICENSE output\
|
||||
cp target\release\LICENSE-for-less.txt output\
|
||||
cp target\release\nu_plugin_*.exe output\
|
||||
cp README.release.txt output\README.txt
|
||||
cp target\release\less.exe output\
|
||||
# Note: If the version of `less.exe` needs to be changed, update this URL
|
||||
# Similarly, if `less.exe` is checked into the repo, copy from the local path here
|
||||
# moved this stuff down to create wix after we download less
|
||||
|
||||
- name: Create msi with wix
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: wix
|
||||
args: --no-build --nocapture --output target\wix\nushell-windows.msi
|
||||
|
||||
- name: Upload installer
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: windows-installer
|
||||
path: target\wix\nushell-windows.msi
|
||||
|
||||
- name: Upload zip
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: windows-zip
|
||||
path: output\*
|
||||
|
||||
release:
|
||||
name: Publish Release
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- linux
|
||||
- macos
|
||||
- windows
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Determine Release Info
|
||||
id: info
|
||||
env:
|
||||
GITHUB_REF: ${{ github.ref }}
|
||||
run: |
|
||||
VERSION=${GITHUB_REF##*/}
|
||||
MAJOR=${VERSION%%.*}
|
||||
MINOR=${VERSION%.*}
|
||||
MINOR=${MINOR#*.}
|
||||
PATCH=${VERSION##*.}
|
||||
echo "::set-output name=version::${VERSION}"
|
||||
echo "::set-output name=linuxdir::nu_${MAJOR}_${MINOR}_${PATCH}_linux"
|
||||
echo "::set-output name=macosdir::nu_${MAJOR}_${MINOR}_${PATCH}_macOS"
|
||||
echo "::set-output name=windowsdir::nu_${MAJOR}_${MINOR}_${PATCH}_windows"
|
||||
echo "::set-output name=innerdir::nushell-${VERSION}"
|
||||
|
||||
- name: Create Release Draft
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: ${{ steps.info.outputs.version }} Release
|
||||
draft: true
|
||||
|
||||
- name: Create Linux Directory
|
||||
run: mkdir -p ${{ steps.info.outputs.linuxdir }}/${{ steps.info.outputs.innerdir }}
|
||||
|
||||
- name: Download Linux Artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: linux
|
||||
path: ${{ steps.info.outputs.linuxdir }}/${{ steps.info.outputs.innerdir }}
|
||||
|
||||
- name: Restore Linux File Modes
|
||||
run: |
|
||||
chmod 755 ${{ steps.info.outputs.linuxdir }}/${{ steps.info.outputs.innerdir }}/nu*
|
||||
|
||||
- name: Create Linux tarball
|
||||
run: tar -zcvf ${{ steps.info.outputs.linuxdir }}.tar.gz ${{ steps.info.outputs.linuxdir }}
|
||||
|
||||
- name: Upload Linux Artifact
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./${{ steps.info.outputs.linuxdir }}.tar.gz
|
||||
asset_name: ${{ steps.info.outputs.linuxdir }}.tar.gz
|
||||
asset_content_type: application/gzip
|
||||
|
||||
- name: Create macOS Directory
|
||||
run: mkdir -p ${{ steps.info.outputs.macosdir }}/${{ steps.info.outputs.innerdir }}
|
||||
|
||||
- name: Download macOS Artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: macos
|
||||
path: ${{ steps.info.outputs.macosdir }}/${{ steps.info.outputs.innerdir }}
|
||||
|
||||
- name: Restore macOS File Modes
|
||||
run: chmod 755 ${{ steps.info.outputs.macosdir }}/${{ steps.info.outputs.innerdir }}/nu*
|
||||
|
||||
- name: Create macOS Archive
|
||||
run: zip -r ${{ steps.info.outputs.macosdir }}.zip ${{ steps.info.outputs.macosdir }}
|
||||
|
||||
- name: Upload macOS Artifact
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./${{ steps.info.outputs.macosdir }}.zip
|
||||
asset_name: ${{ steps.info.outputs.macosdir }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Create Windows Directory
|
||||
run: mkdir -p ${{ steps.info.outputs.windowsdir }}/${{ steps.info.outputs.innerdir }}
|
||||
|
||||
- name: Download Windows zip
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: windows-zip
|
||||
path: ${{ steps.info.outputs.windowsdir }}/${{ steps.info.outputs.innerdir }}
|
||||
|
||||
- name: Show Windows Artifacts
|
||||
run: ls -la ${{ steps.info.outputs.windowsdir }}/${{ steps.info.outputs.innerdir }}
|
||||
|
||||
- name: Create macOS Archive
|
||||
run: zip -r ${{ steps.info.outputs.windowsdir }}.zip ${{ steps.info.outputs.windowsdir }}
|
||||
|
||||
- name: Upload Windows zip
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./${{ steps.info.outputs.windowsdir }}.zip
|
||||
asset_name: ${{ steps.info.outputs.windowsdir }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: Download Windows installer
|
||||
uses: actions/download-artifact@v2
|
||||
with:
|
||||
name: windows-installer
|
||||
path: ./
|
||||
|
||||
- name: Upload Windows installer
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./nushell-windows.msi
|
||||
asset_name: ${{ steps.info.outputs.windowsdir }}.msi
|
||||
asset_content_type: application/x-msi
|
||||
- uses: actions/checkout@v3.0.2
|
||||
|
||||
- name: Install Rust Toolchain Components
|
||||
uses: actions-rs/toolchain@v1.0.6
|
||||
with:
|
||||
override: true
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
target: ${{ matrix.target }}
|
||||
|
||||
- name: Setup Nushell
|
||||
uses: hustcer/setup-nu@v1
|
||||
with:
|
||||
version: 0.63.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Release Nu Binary
|
||||
id: nu
|
||||
run: nu .github/workflows/release-pkg.nu
|
||||
env:
|
||||
OS: ${{ matrix.os }}
|
||||
REF: ${{ github.ref }}
|
||||
TARGET: ${{ matrix.target }}
|
||||
_EXTRA_: ${{ matrix.extra }}
|
||||
TARGET_RUSTFLAGS: ${{ matrix.target_rustflags }}
|
||||
|
||||
# REF: https://github.com/marketplace/actions/gh-release
|
||||
- name: Publish Archive
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/') }}
|
||||
with:
|
||||
draft: true
|
||||
files: ${{ steps.nu.outputs.archive }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -25,3 +25,7 @@ debian/nu/
|
||||
# Helix configuration folder
|
||||
.helix/*
|
||||
.helix
|
||||
|
||||
# Coverage tools
|
||||
lcov.info
|
||||
tarpaulin-report.html
|
||||
|
713
Cargo.lock
generated
713
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
41
Cargo.toml
41
Cargo.toml
@ -11,7 +11,7 @@ name = "nu"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/nushell/nushell"
|
||||
rust-version = "1.60"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@ -38,28 +38,31 @@ ctrlc = "3.2.1"
|
||||
log = "0.4"
|
||||
miette = "4.5.0"
|
||||
nu-ansi-term = "0.45.1"
|
||||
nu-cli = { path="./crates/nu-cli", version = "0.63.0" }
|
||||
nu-color-config = { path = "./crates/nu-color-config", version = "0.63.0" }
|
||||
nu-command = { path="./crates/nu-command", version = "0.63.0" }
|
||||
nu-engine = { path="./crates/nu-engine", version = "0.63.0" }
|
||||
nu-json = { path="./crates/nu-json", version = "0.63.0" }
|
||||
nu-parser = { path="./crates/nu-parser", version = "0.63.0" }
|
||||
nu-path = { path="./crates/nu-path", version = "0.63.0" }
|
||||
nu-plugin = { path = "./crates/nu-plugin", optional = true, version = "0.63.0" }
|
||||
nu-pretty-hex = { path = "./crates/nu-pretty-hex", version = "0.63.0" }
|
||||
nu-protocol = { path = "./crates/nu-protocol", version = "0.63.0" }
|
||||
nu-system = { path = "./crates/nu-system", version = "0.63.0" }
|
||||
nu-table = { path = "./crates/nu-table", version = "0.63.0" }
|
||||
nu-term-grid = { path = "./crates/nu-term-grid", version = "0.63.0" }
|
||||
nu-utils = { path = "./crates/nu-utils", version = "0.63.0" }
|
||||
openssl = { version = "0.10.38", features = ["vendored"], optional = true }
|
||||
nu-cli = { path="./crates/nu-cli", version = "0.63.1" }
|
||||
nu-color-config = { path = "./crates/nu-color-config", version = "0.63.1" }
|
||||
nu-command = { path="./crates/nu-command", version = "0.63.1" }
|
||||
nu-engine = { path="./crates/nu-engine", version = "0.63.1" }
|
||||
nu-json = { path="./crates/nu-json", version = "0.63.1" }
|
||||
nu-parser = { path="./crates/nu-parser", version = "0.63.1" }
|
||||
nu-path = { path="./crates/nu-path", version = "0.63.1" }
|
||||
nu-plugin = { path = "./crates/nu-plugin", optional = true, version = "0.63.1" }
|
||||
nu-pretty-hex = { path = "./crates/nu-pretty-hex", version = "0.63.1" }
|
||||
nu-protocol = { path = "./crates/nu-protocol", version = "0.63.1" }
|
||||
nu-system = { path = "./crates/nu-system", version = "0.63.1" }
|
||||
nu-table = { path = "./crates/nu-table", version = "0.63.1" }
|
||||
nu-term-grid = { path = "./crates/nu-term-grid", version = "0.63.1" }
|
||||
nu-utils = { path = "./crates/nu-utils", version = "0.63.1" }
|
||||
pretty_env_logger = "0.4.0"
|
||||
rayon = "1.5.1"
|
||||
reedline = { version = "0.6.0", features = ["bashisms"]}
|
||||
reedline = { git = "https://github.com/nushell/reedline", branch = "main", features = ["bashisms"]}
|
||||
is_executable = "1.0.1"
|
||||
|
||||
[target.'cfg(not(target_os = "windows"))'.dependencies]
|
||||
# Our dependencies don't use OpenSSL on Windows
|
||||
openssl = { version = "0.10.38", features = ["vendored"], optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
nu-test-support = { path="./crates/nu-test-support", version = "0.63.0" }
|
||||
nu-test-support = { path="./crates/nu-test-support", version = "0.63.1" }
|
||||
tempfile = "3.2.0"
|
||||
assert_cmd = "2.0.2"
|
||||
pretty_assertions = "1.0.0"
|
||||
@ -69,7 +72,7 @@ rstest = "0.12.0"
|
||||
itertools = "0.10.3"
|
||||
|
||||
[target.'cfg(windows)'.build-dependencies]
|
||||
embed-resource = "1"
|
||||
winres = "0.1"
|
||||
|
||||
[features]
|
||||
plugin = ["nu-plugin", "nu-cli/plugin", "nu-parser/plugin", "nu-command/plugin", "nu-protocol/plugin", "nu-engine/plugin"]
|
||||
|
@ -1,49 +0,0 @@
|
||||
#include <winver.h>
|
||||
|
||||
#define VER_FILEVERSION 0,62,1,0
|
||||
#define VER_FILEVERSION_STR "0.62.1"
|
||||
|
||||
#define VER_PRODUCTVERSION 0,62,1,0
|
||||
#define VER_PRODUCTVERSION_STR "0.62.1"
|
||||
|
||||
#ifdef RC_INVOKED
|
||||
|
||||
#ifdef DEBUG // TODO: Actually define DEBUG
|
||||
#define VER_DEBUG VS_FF_DEBUG
|
||||
#else
|
||||
#define VER_DEBUG 0
|
||||
#endif
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_PRODUCTVERSION
|
||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||
FILEFLAGS VER_DEBUG
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_APP
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "nushell"
|
||||
VALUE "FileDescription", "Nushell"
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", "nu.exe"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2022"
|
||||
VALUE "OriginalFilename", "nu.exe"
|
||||
VALUE "ProductName", "Nushell"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#define IDI_ICON 0x101
|
||||
IDI_ICON ICON "assets/nu_logo.ico"
|
||||
#endif
|
8
build.rs
8
build.rs
@ -1,6 +1,12 @@
|
||||
#[cfg(windows)]
|
||||
fn main() {
|
||||
embed_resource::compile_for("assets/nushell.rc", &["nu"])
|
||||
let mut res = winres::WindowsResource::new();
|
||||
res.set("ProductName", "Nushell");
|
||||
res.set("FileDescription", "Nushell");
|
||||
res.set("LegalCopyright", "Copyright (C) 2022");
|
||||
res.set_icon("assets/nu_logo.ico");
|
||||
res.compile()
|
||||
.expect("Failed to run the Windows resource compiler (rc.exe)");
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
|
@ -4,21 +4,21 @@ description = "CLI-related functionality for Nushell"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-cli"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[dev-dependencies]
|
||||
nu-test-support = { path="../nu-test-support", version = "0.63.0" }
|
||||
nu-command = { path = "../nu-command", version = "0.63.0" }
|
||||
nu-test-support = { path="../nu-test-support", version = "0.63.1" }
|
||||
nu-command = { path = "../nu-command", version = "0.63.1" }
|
||||
|
||||
[dependencies]
|
||||
nu-engine = { path = "../nu-engine", version = "0.63.0" }
|
||||
nu-path = { path = "../nu-path", version = "0.63.0" }
|
||||
nu-parser = { path = "../nu-parser", version = "0.63.0" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.0" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.63.0" }
|
||||
nu-engine = { path = "../nu-engine", version = "0.63.1" }
|
||||
nu-path = { path = "../nu-path", version = "0.63.1" }
|
||||
nu-parser = { path = "../nu-parser", version = "0.63.1" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.1" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.63.1" }
|
||||
nu-ansi-term = "0.45.1"
|
||||
nu-color-config = { path = "../nu-color-config", version = "0.63.0" }
|
||||
reedline = { version = "0.6.0", features = ["bashisms"]}
|
||||
reedline = { git = "https://github.com/nushell/reedline", branch = "main", features = ["bashisms"]}
|
||||
nu-color-config = { path = "../nu-color-config", version = "0.63.1" }
|
||||
crossterm = "0.23.0"
|
||||
miette = { version = "4.5.0", features = ["fancy"] }
|
||||
thiserror = "1.0.29"
|
||||
|
@ -37,7 +37,10 @@ impl NuCompleter {
|
||||
) -> Vec<Suggestion> {
|
||||
let config = self.engine_state.get_config();
|
||||
|
||||
let mut options = CompletionOptions::default();
|
||||
let mut options = CompletionOptions {
|
||||
case_sensitive: config.case_sensitive_completions,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if config.completion_algorithm == "fuzzy" {
|
||||
options.match_algorithm = MatchAlgorithm::Fuzzy;
|
||||
|
@ -70,7 +70,18 @@ impl Completer for VariableCompletion {
|
||||
self.var_context.1.clone().into_iter().skip(1).collect();
|
||||
|
||||
if let Some(val) = env_vars.get(&target_var_str) {
|
||||
return nested_suggestions(val.clone(), nested_levels, current_span);
|
||||
for suggestion in
|
||||
nested_suggestions(val.clone(), nested_levels, current_span)
|
||||
{
|
||||
if options
|
||||
.match_algorithm
|
||||
.matches_u8(suggestion.value.as_bytes(), &prefix)
|
||||
{
|
||||
output.push(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
} else {
|
||||
// No nesting provided, return all env vars
|
||||
@ -105,7 +116,18 @@ impl Completer for VariableCompletion {
|
||||
end: current_span.end,
|
||||
},
|
||||
) {
|
||||
return nested_suggestions(nuval, self.var_context.1.clone(), current_span);
|
||||
for suggestion in
|
||||
nested_suggestions(nuval, self.var_context.1.clone(), current_span)
|
||||
{
|
||||
if options
|
||||
.match_algorithm
|
||||
.matches_u8(suggestion.value.as_bytes(), &prefix)
|
||||
{
|
||||
output.push(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,7 +144,18 @@ impl Completer for VariableCompletion {
|
||||
|
||||
// If the value exists and it's of type Record
|
||||
if let Ok(value) = var {
|
||||
return nested_suggestions(value, self.var_context.1.clone(), current_span);
|
||||
for suggestion in
|
||||
nested_suggestions(value, self.var_context.1.clone(), current_span)
|
||||
{
|
||||
if options
|
||||
.match_algorithm
|
||||
.matches_u8(suggestion.value.as_bytes(), &prefix)
|
||||
{
|
||||
output.push(suggestion);
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -42,6 +42,16 @@ pub fn new_engine() -> (PathBuf, String, EngineState, Stack) {
|
||||
},
|
||||
},
|
||||
);
|
||||
stack.add_env_var(
|
||||
"TEST".to_string(),
|
||||
Value::String {
|
||||
val: "NUSHELL".to_string(),
|
||||
span: nu_protocol::Span {
|
||||
start: 0,
|
||||
end: dir_str.len(),
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// Merge delta
|
||||
let merge_result = engine_state.merge_delta(delta, Some(&mut stack), &dir);
|
||||
|
@ -35,6 +35,16 @@ fn variables_completions() {
|
||||
// Match results
|
||||
match_suggestions(expected, suggestions);
|
||||
|
||||
// Test completions for $nu.h (filter)
|
||||
let suggestions = completer.complete("$nu.h".into(), 5);
|
||||
|
||||
assert_eq!(2, suggestions.len());
|
||||
|
||||
let expected: Vec<String> = vec!["history-path".into(), "home-path".into()];
|
||||
|
||||
// Match results
|
||||
match_suggestions(expected, suggestions);
|
||||
|
||||
// Test completions for custom var
|
||||
let suggestions = completer.complete("$actor.".into(), 7);
|
||||
|
||||
@ -45,12 +55,32 @@ fn variables_completions() {
|
||||
// Match results
|
||||
match_suggestions(expected, suggestions);
|
||||
|
||||
// Test completions for $env
|
||||
let suggestions = completer.complete("$env.".into(), 5);
|
||||
// Test completions for custom var (filtering)
|
||||
let suggestions = completer.complete("$actor.n".into(), 7);
|
||||
|
||||
assert_eq!(1, suggestions.len());
|
||||
|
||||
let expected: Vec<String> = vec!["PWD".into()];
|
||||
let expected: Vec<String> = vec!["name".into()];
|
||||
|
||||
// Match results
|
||||
match_suggestions(expected, suggestions);
|
||||
|
||||
// Test completions for $env
|
||||
let suggestions = completer.complete("$env.".into(), 5);
|
||||
|
||||
assert_eq!(2, suggestions.len());
|
||||
|
||||
let expected: Vec<String> = vec!["PWD".into(), "TEST".into()];
|
||||
|
||||
// Match results
|
||||
match_suggestions(expected, suggestions);
|
||||
|
||||
// Test completions for $env
|
||||
let suggestions = completer.complete("$env.T".into(), 5);
|
||||
|
||||
assert_eq!(1, suggestions.len());
|
||||
|
||||
let expected: Vec<String> = vec!["TEST".into()];
|
||||
|
||||
// Match results
|
||||
match_suggestions(expected, suggestions);
|
||||
|
@ -4,11 +4,11 @@ description = "Color configuration code used by Nushell"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-color-config"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[dependencies]
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.0" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.1" }
|
||||
nu-ansi-term = "0.45.1"
|
||||
nu-json = { path = "../nu-json", version = "0.63.0" }
|
||||
nu-table = { path = "../nu-table", version = "0.63.0" }
|
||||
nu-json = { path = "../nu-json", version = "0.63.1" }
|
||||
nu-table = { path = "../nu-table", version = "0.63.1" }
|
||||
serde = { version="1.0.123", features=["derive"] }
|
||||
|
@ -4,25 +4,25 @@ description = "Nushell's built-in commands"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-command"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
build = "build.rs"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nu-color-config = { path = "../nu-color-config", version = "0.63.0" }
|
||||
nu-engine = { path = "../nu-engine", version = "0.63.0" }
|
||||
nu-glob = { path = "../nu-glob", version = "0.63.0" }
|
||||
nu-json = { path = "../nu-json", version = "0.63.0" }
|
||||
nu-parser = { path = "../nu-parser", version = "0.63.0" }
|
||||
nu-path = { path = "../nu-path", version = "0.63.0" }
|
||||
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.63.0" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.0" }
|
||||
nu-system = { path = "../nu-system", version = "0.63.0" }
|
||||
nu-table = { path = "../nu-table", version = "0.63.0" }
|
||||
nu-term-grid = { path = "../nu-term-grid", version = "0.63.0" }
|
||||
nu-test-support = { path = "../nu-test-support", version = "0.63.0" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.63.0" }
|
||||
nu-color-config = { path = "../nu-color-config", version = "0.63.1" }
|
||||
nu-engine = { path = "../nu-engine", version = "0.63.1" }
|
||||
nu-glob = { path = "../nu-glob", version = "0.63.1" }
|
||||
nu-json = { path = "../nu-json", version = "0.63.1" }
|
||||
nu-parser = { path = "../nu-parser", version = "0.63.1" }
|
||||
nu-path = { path = "../nu-path", version = "0.63.1" }
|
||||
nu-pretty-hex = { path = "../nu-pretty-hex", version = "0.63.1" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.1" }
|
||||
nu-system = { path = "../nu-system", version = "0.63.1" }
|
||||
nu-table = { path = "../nu-table", version = "0.63.1" }
|
||||
nu-term-grid = { path = "../nu-term-grid", version = "0.63.1" }
|
||||
nu-test-support = { path = "../nu-test-support", version = "0.63.1" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.63.1" }
|
||||
nu-ansi-term = "0.45.1"
|
||||
|
||||
# Potential dependencies for extras
|
||||
@ -82,7 +82,7 @@ unicode-segmentation = "1.8.0"
|
||||
url = "2.2.1"
|
||||
uuid = { version = "0.8.2", features = ["v4"] }
|
||||
which = { version = "4.2.2", optional = true }
|
||||
reedline = { version = "0.6.0", features = ["bashisms"]}
|
||||
reedline = { git = "https://github.com/nushell/reedline", branch = "main", features = ["bashisms"]}
|
||||
wax = { version = "0.4.0", features = ["diagnostics"] }
|
||||
rusqlite = { version = "0.27.0", features = ["bundled"], optional = true }
|
||||
sqlparser = { version = "0.16.0", features = ["serde"], optional = true }
|
||||
|
@ -26,8 +26,8 @@ impl Command for Alias {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -27,8 +27,8 @@ impl Command for Def {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -27,8 +27,8 @@ impl Command for DefEnv {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -13,7 +13,7 @@ impl Command for Describe {
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Describe the value(s) piped in."
|
||||
"Describe the type and structure of the value(s) piped in."
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
@ -55,6 +55,10 @@ impl Command for Describe {
|
||||
result: Some(Value::test_string("string")),
|
||||
}]
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["type", "typeof", "info", "structure"]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -24,6 +24,10 @@ impl Command for ErrorMake {
|
||||
"Create an error."
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["err", "panic", "crash", "throw"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -22,8 +22,8 @@ impl Command for ExportCommand {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -26,8 +26,8 @@ impl Command for ExportAlias {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -27,8 +27,8 @@ impl Command for ExportDef {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -27,8 +27,8 @@ impl Command for ExportDefEnv {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -30,8 +30,8 @@ impl Command for ExportEnv {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -22,8 +22,8 @@ impl Command for ExportExtern {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -22,8 +22,8 @@ impl Command for Extern {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -45,8 +45,8 @@ impl Command for For {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -25,9 +25,8 @@ impl Command for Hide {
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"Symbols are hidden by priority: First aliases, then custom commands, then environment variables.
|
||||
|
||||
This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages
|
||||
"#
|
||||
This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -34,8 +34,8 @@ impl Command for If {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -27,8 +27,8 @@ impl Command for Let {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -26,8 +26,8 @@ impl Command for Module {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -34,8 +34,8 @@ impl Command for OverlayAdd {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -22,8 +22,8 @@ impl Command for Overlay {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -1,9 +1,11 @@
|
||||
mod add;
|
||||
mod command;
|
||||
mod list;
|
||||
mod new;
|
||||
mod remove;
|
||||
|
||||
pub use add::OverlayAdd;
|
||||
pub use command::Overlay;
|
||||
pub use list::OverlayList;
|
||||
pub use new::OverlayNew;
|
||||
pub use remove::OverlayRemove;
|
||||
|
74
crates/nu-command/src/core_commands/overlay/new.rs
Normal file
74
crates/nu-command/src/core_commands/overlay/new.rs
Normal file
@ -0,0 +1,74 @@
|
||||
use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, Spanned, SyntaxShape};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct OverlayNew;
|
||||
|
||||
impl Command for OverlayNew {
|
||||
fn name(&self) -> &str {
|
||||
"overlay new"
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Create an empty overlay"
|
||||
}
|
||||
|
||||
fn signature(&self) -> nu_protocol::Signature {
|
||||
Signature::build("overlay new")
|
||||
.required("name", SyntaxShape::String, "Name of the overlay")
|
||||
// TODO:
|
||||
// .switch(
|
||||
// "prefix",
|
||||
// "Prepend module name to the imported symbols",
|
||||
// Some('p'),
|
||||
// )
|
||||
.category(Category::Core)
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"The command will first create an empty module, then add it as an overlay.
|
||||
|
||||
This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
stack: &mut Stack,
|
||||
call: &Call,
|
||||
_input: PipelineData,
|
||||
) -> Result<PipelineData, ShellError> {
|
||||
let name_arg: Spanned<String> = call.req(engine_state, stack, 0)?;
|
||||
|
||||
stack.add_overlay(name_arg.item);
|
||||
|
||||
Ok(PipelineData::new(call.head))
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Create an empty overlay",
|
||||
example: r#"overlay new spam"#,
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
use crate::test_examples;
|
||||
|
||||
test_examples(OverlayNew {})
|
||||
}
|
||||
}
|
@ -29,8 +29,8 @@ impl Command for OverlayRemove {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -42,8 +42,8 @@ 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_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -27,8 +27,8 @@ impl Command for Source {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -24,8 +24,8 @@ impl Command for Use {
|
||||
}
|
||||
|
||||
fn extra_usage(&self) -> &str {
|
||||
r#"This command is a parser keyword. For details, check
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html#parsing-and-evaluation-are-different-stages"#
|
||||
r#"This command is a parser keyword. For details, check:
|
||||
https://www.nushell.sh/book/thinking_in_nushell.html"#
|
||||
}
|
||||
|
||||
fn is_parser_keyword(&self) -> bool {
|
||||
|
@ -55,6 +55,7 @@ pub fn create_default_context(cwd: impl AsRef<Path>) -> EngineState {
|
||||
Overlay,
|
||||
OverlayAdd,
|
||||
OverlayList,
|
||||
OverlayNew,
|
||||
OverlayRemove,
|
||||
Let,
|
||||
Metadata,
|
||||
|
@ -1,8 +1,9 @@
|
||||
use std::fs::read_link;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use nu_engine::env::current_dir;
|
||||
use nu_engine::CallExt;
|
||||
use nu_path::canonicalize_with;
|
||||
use nu_path::{canonicalize_with, expand_path_with};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
@ -54,6 +55,11 @@ impl Command for Cp {
|
||||
// TODO: add back in additional features
|
||||
// .switch("force", "suppress error when no file", Some('f'))
|
||||
.switch("interactive", "ask user to confirm action", Some('i'))
|
||||
.switch(
|
||||
"no-dereference",
|
||||
"If the -r option is specified, no symbolic links are followed.",
|
||||
Some('p'),
|
||||
)
|
||||
.category(Category::FileSystem)
|
||||
}
|
||||
|
||||
@ -70,9 +76,9 @@ impl Command for Cp {
|
||||
let verbose = call.has_flag("verbose");
|
||||
let interactive = call.has_flag("interactive");
|
||||
|
||||
let path = current_dir(engine_state, stack)?;
|
||||
let source = path.join(src.item.as_str());
|
||||
let destination = path.join(dst.item.as_str());
|
||||
let current_dir_path = current_dir(engine_state, stack)?;
|
||||
let source = current_dir_path.join(src.item.as_str());
|
||||
let destination = current_dir_path.join(dst.item.as_str());
|
||||
|
||||
// check if destination is a dir and it exists
|
||||
let path_last_char = destination.as_os_str().to_string_lossy().chars().last();
|
||||
@ -140,7 +146,7 @@ impl Command for Cp {
|
||||
if entry.is_file() {
|
||||
let sources = sources.paths_applying_with(|(source_file, _depth_level)| {
|
||||
if destination.is_dir() {
|
||||
let mut dest = canonicalize_with(&dst.item, &path)?;
|
||||
let mut dest = canonicalize_with(&dst.item, ¤t_dir_path)?;
|
||||
if let Some(name) = entry.file_name() {
|
||||
dest.push(name);
|
||||
}
|
||||
@ -153,7 +159,7 @@ impl Command for Cp {
|
||||
for (src, dst) in sources {
|
||||
if src.is_file() {
|
||||
let res = if interactive && dst.exists() {
|
||||
interactive_copy_file(interactive, src, dst, span)
|
||||
interactive_copy(interactive, src, dst, span, copy_file)
|
||||
} else {
|
||||
copy_file(src, dst, span)
|
||||
};
|
||||
@ -188,9 +194,23 @@ impl Command for Cp {
|
||||
)
|
||||
})?;
|
||||
|
||||
let not_follow_symlink = call.has_flag("no-dereference");
|
||||
let sources = sources.paths_applying_with(|(source_file, depth_level)| {
|
||||
let mut dest = destination.clone();
|
||||
let path = canonicalize_with(&source_file, &path)?;
|
||||
|
||||
let path = if not_follow_symlink {
|
||||
expand_path_with(&source_file, ¤t_dir_path)
|
||||
} else {
|
||||
canonicalize_with(&source_file, ¤t_dir_path).or_else(|err| {
|
||||
// check if dangling symbolic link.
|
||||
let path = expand_path_with(&source_file, ¤t_dir_path);
|
||||
if path.is_symlink() && !path.exists() {
|
||||
Ok(path)
|
||||
} else {
|
||||
Err(err)
|
||||
}
|
||||
})?
|
||||
};
|
||||
|
||||
#[allow(clippy::needless_collect)]
|
||||
let comps: Vec<_> = path
|
||||
@ -220,14 +240,21 @@ impl Command for Cp {
|
||||
})?;
|
||||
}
|
||||
|
||||
if s.is_file() {
|
||||
if s.is_symlink() && not_follow_symlink {
|
||||
let res = if interactive && d.exists() {
|
||||
interactive_copy_file(interactive, s, d, span)
|
||||
interactive_copy(interactive, s, d, span, copy_symlink)
|
||||
} else {
|
||||
copy_symlink(s, d, span)
|
||||
};
|
||||
result.push(res);
|
||||
} else if s.is_file() {
|
||||
let res = if interactive && d.exists() {
|
||||
interactive_copy(interactive, s, d, span, copy_file)
|
||||
} else {
|
||||
copy_file(s, d, span)
|
||||
};
|
||||
result.push(res);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,7 +292,13 @@ impl Command for Cp {
|
||||
}
|
||||
}
|
||||
|
||||
fn interactive_copy_file(interactive: bool, src: PathBuf, dst: PathBuf, span: Span) -> Value {
|
||||
fn interactive_copy(
|
||||
interactive: bool,
|
||||
src: PathBuf,
|
||||
dst: PathBuf,
|
||||
span: Span,
|
||||
copy_impl: impl Fn(PathBuf, PathBuf, Span) -> Value,
|
||||
) -> Value {
|
||||
let (interaction, confirmed) =
|
||||
try_interaction(interactive, "cp: overwrite", &dst.to_string_lossy());
|
||||
if let Err(e) = interaction {
|
||||
@ -282,7 +315,7 @@ fn interactive_copy_file(interactive: bool, src: PathBuf, dst: PathBuf, span: Sp
|
||||
let msg = format!("{:} not copied to {:}", src.display(), dst.display());
|
||||
Value::String { val: msg, span }
|
||||
} else {
|
||||
copy_file(src, dst, span)
|
||||
copy_impl(src, dst, span)
|
||||
}
|
||||
}
|
||||
|
||||
@ -293,13 +326,51 @@ fn copy_file(src: PathBuf, dst: PathBuf, span: Span) -> Value {
|
||||
Value::String { val: msg, span }
|
||||
}
|
||||
Err(e) => Value::Error {
|
||||
error: ShellError::GenericError(
|
||||
e.to_string(),
|
||||
e.to_string(),
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
),
|
||||
error: ShellError::FileNotFoundCustom(format!("copy file {src:?} failed: {e}"), span),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn copy_symlink(src: PathBuf, dst: PathBuf, span: Span) -> Value {
|
||||
let target_path = read_link(src.as_path());
|
||||
let target_path = match target_path {
|
||||
Ok(p) => p,
|
||||
Err(err) => {
|
||||
return Value::Error {
|
||||
error: ShellError::GenericError(
|
||||
err.to_string(),
|
||||
err.to_string(),
|
||||
Some(span),
|
||||
None,
|
||||
vec![],
|
||||
),
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let create_symlink = {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
std::os::unix::fs::symlink
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if !target_path.exists() || target_path.is_file() {
|
||||
std::os::windows::fs::symlink_file
|
||||
} else {
|
||||
std::os::windows::fs::symlink_dir
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
match create_symlink(target_path.as_path(), dst.as_path()) {
|
||||
Ok(_) => {
|
||||
let msg = format!("copied {:} to {:}", src.display(), dst.display());
|
||||
Value::String { val: msg, span }
|
||||
}
|
||||
Err(e) => Value::Error {
|
||||
error: ShellError::GenericError(e.to_string(), e.to_string(), Some(span), None, vec![]),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ impl Command for All {
|
||||
"Test if every element of the input matches a predicate."
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["every"]
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
|
@ -27,6 +27,10 @@ impl Command for Any {
|
||||
"Tests if any element of the input matches a predicate."
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["some"]
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
|
@ -27,7 +27,14 @@ impl Command for Columns {
|
||||
Example {
|
||||
example: "[[name,age,grade]; [bill,20,a]] | columns",
|
||||
description: "Get the columns from the table",
|
||||
result: None,
|
||||
result: Some(Value::List {
|
||||
vals: vec![
|
||||
Value::test_string("name"),
|
||||
Value::test_string("age"),
|
||||
Value::test_string("grade"),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
example: "[[name,age,grade]; [bill,20,a]] | columns | first",
|
||||
|
@ -57,11 +57,18 @@ impl Command for DropColumn {
|
||||
description: "Remove the last column of a table",
|
||||
example: "echo [[lib, extension]; [nu-lib, rs] [nu-core, rb]] | drop column",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::Record {
|
||||
cols: vec!["lib".into()],
|
||||
vals: vec![Value::test_string("nu-lib"), Value::test_string("nu-core")],
|
||||
span: Span::test_data(),
|
||||
}],
|
||||
vals: vec![
|
||||
Value::Record {
|
||||
cols: vec!["lib".into()],
|
||||
vals: vec![Value::test_string("nu-lib")],
|
||||
span: Span::test_data(),
|
||||
},
|
||||
Value::Record {
|
||||
cols: vec!["lib".into()],
|
||||
vals: vec![Value::test_string("nu-core")],
|
||||
span: Span::test_data(),
|
||||
},
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
}]
|
||||
@ -180,3 +187,13 @@ fn get_keep_columns(input: Vec<String>, mut num_of_columns_to_drop: i64) -> Vec<
|
||||
let num_of_columns_to_keep = (vlen - num_of_columns_to_drop) as usize;
|
||||
input[0..num_of_columns_to_keep].to_vec()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
use super::DropColumn;
|
||||
use crate::test_examples;
|
||||
test_examples(DropColumn {})
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,10 @@ impl Command for Length {
|
||||
.category(Category::Filters)
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["count", "len", "size"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -59,6 +59,14 @@ impl Command for Merge {
|
||||
vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)],
|
||||
)),
|
||||
},
|
||||
Example {
|
||||
example: "{a: 1, b: 3} | merge { {b: 2, c: 4} }",
|
||||
description: "Merge two records with overlap key",
|
||||
result: Some(Value::test_record(
|
||||
vec!["a", "b", "c"],
|
||||
vec![Value::test_int(1), Value::test_int(2), Value::test_int(4)],
|
||||
)),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@ -106,8 +114,10 @@ impl Command for Merge {
|
||||
(Ok((inp_cols, inp_vals)), Some(to_merge)) => {
|
||||
match to_merge.as_record() {
|
||||
Ok((to_merge_cols, to_merge_vals)) => {
|
||||
let cols = [inp_cols, to_merge_cols].concat();
|
||||
let vals = [inp_vals, to_merge_vals].concat();
|
||||
let (cols, vals) = do_merge(
|
||||
(inp_cols.to_vec(), inp_vals.to_vec()),
|
||||
(to_merge_cols.to_vec(), to_merge_vals.to_vec()),
|
||||
);
|
||||
Value::Record {
|
||||
cols,
|
||||
vals,
|
||||
@ -146,12 +156,10 @@ impl Command for Merge {
|
||||
..,
|
||||
),
|
||||
) => {
|
||||
let mut cols = inp_cols.to_vec();
|
||||
cols.extend(to_merge_cols.to_vec());
|
||||
|
||||
let mut vals = inp_vals.to_vec();
|
||||
vals.extend(to_merge_vals.to_vec());
|
||||
|
||||
let (cols, vals) = do_merge(
|
||||
(inp_cols.to_vec(), inp_vals.to_vec()),
|
||||
(to_merge_cols.to_vec(), to_merge_vals.to_vec()),
|
||||
);
|
||||
Ok(Value::Record {
|
||||
cols,
|
||||
vals,
|
||||
@ -181,6 +189,29 @@ impl Command for Merge {
|
||||
}
|
||||
}
|
||||
|
||||
fn do_merge(
|
||||
input_record: (Vec<String>, Vec<Value>),
|
||||
to_merge_record: (Vec<String>, Vec<Value>),
|
||||
) -> (Vec<String>, Vec<Value>) {
|
||||
let (mut result_cols, mut result_vals) = input_record;
|
||||
let (to_merge_cols, to_merge_vals) = to_merge_record;
|
||||
|
||||
for (col, val) in to_merge_cols.into_iter().zip(to_merge_vals) {
|
||||
let pos = result_cols.iter().position(|c| c == &col);
|
||||
// if find, replace existing data, else, push new data.
|
||||
match pos {
|
||||
Some(index) => {
|
||||
result_vals[index] = val;
|
||||
}
|
||||
None => {
|
||||
result_cols.push(col);
|
||||
result_vals.push(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
(result_cols, result_vals)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
@ -205,3 +205,13 @@ fn reject_record_columns(cols: &mut Vec<String>, vals: &mut Vec<Value>, rejects:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
use super::Reject;
|
||||
use crate::test_examples;
|
||||
test_examples(Reject {})
|
||||
}
|
||||
}
|
||||
|
@ -70,13 +70,35 @@ impl Command for Wrap {
|
||||
description: "Wrap a list into a table with a given column name",
|
||||
example: "echo [1 2 3] | wrap num",
|
||||
result: Some(Value::List {
|
||||
vals: vec![Value::Record {
|
||||
cols: vec!["num".into()],
|
||||
vals: vec![Value::test_int(1), Value::test_int(2), Value::test_int(3)],
|
||||
span: Span::test_data(),
|
||||
}],
|
||||
vals: vec![
|
||||
Value::Record {
|
||||
cols: vec!["num".into()],
|
||||
vals: vec![Value::test_int(1)],
|
||||
span: Span::test_data(),
|
||||
},
|
||||
Value::Record {
|
||||
cols: vec!["num".into()],
|
||||
vals: vec![Value::test_int(2)],
|
||||
span: Span::test_data(),
|
||||
},
|
||||
Value::Record {
|
||||
cols: vec!["num".into()],
|
||||
vals: vec![Value::test_int(3)],
|
||||
span: Span::test_data(),
|
||||
},
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
use super::Wrap;
|
||||
use crate::test_examples;
|
||||
test_examples(Wrap {})
|
||||
}
|
||||
}
|
||||
|
@ -55,12 +55,12 @@ impl Command for FromOds {
|
||||
vec![
|
||||
Example {
|
||||
description: "Convert binary .ods data to a table",
|
||||
example: "open test.txt | from ods",
|
||||
example: "open --raw test.ods | from ods",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Convert binary .ods data to a table, specifying the tables",
|
||||
example: "open test.txt | from ods -s [Spreadsheet1]",
|
||||
example: "open --raw test.ods | from ods -s [Spreadsheet1]",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
|
@ -55,12 +55,12 @@ impl Command for FromXlsx {
|
||||
vec![
|
||||
Example {
|
||||
description: "Convert binary .xlsx data to a table",
|
||||
example: "open test.txt | from xlsx",
|
||||
example: "open --raw test.xlsx | from xlsx",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Convert binary .xlsx data to a table, specifying the tables",
|
||||
example: "open test.txt | from xlsx -s [Spreadsheet1]",
|
||||
example: "open --raw test.xlsx | from xlsx -s [Spreadsheet1]",
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
|
@ -39,7 +39,7 @@ impl Command for ToNuon {
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Outputs a nuon string representing the contents of this table",
|
||||
description: "Outputs a nuon string representing the contents of this list",
|
||||
example: "[1 2 3] | to nuon",
|
||||
result: Some(Value::test_string("[1, 2, 3]")),
|
||||
}]
|
||||
@ -147,3 +147,13 @@ fn to_nuon(call: &Call, input: PipelineData) -> Result<String, ShellError> {
|
||||
|
||||
value_to_string(&v, call.head)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
use super::ToNuon;
|
||||
use crate::test_examples;
|
||||
test_examples(ToNuon {})
|
||||
}
|
||||
}
|
||||
|
@ -232,9 +232,15 @@ fn action(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{action, ActionType, Base64Config};
|
||||
use super::{action, ActionType, Base64, Base64Config};
|
||||
use nu_protocol::{Span, Value};
|
||||
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
use crate::test_examples;
|
||||
test_examples(Base64 {})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn base64_encode_standard() {
|
||||
let word = Value::string("username:password", Span::test_data());
|
||||
|
@ -77,7 +77,21 @@ On Windows, an extra 'prefix' column is added."#
|
||||
Example {
|
||||
description: "Parse a single path",
|
||||
example: r"'C:\Users\viking\spam.txt' | path parse",
|
||||
result: None,
|
||||
result: Some(Value::Record {
|
||||
cols: vec![
|
||||
"prefix".into(),
|
||||
"parent".into(),
|
||||
"stem".into(),
|
||||
"extension".into(),
|
||||
],
|
||||
vals: vec![
|
||||
Value::test_string("C:"),
|
||||
Value::test_string(r"C:\Users\viking"),
|
||||
Value::test_string("spam"),
|
||||
Value::test_string("txt"),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "Replace a complex extension",
|
||||
@ -87,7 +101,21 @@ On Windows, an extra 'prefix' column is added."#
|
||||
Example {
|
||||
description: "Ignore the extension",
|
||||
example: r"'C:\Users\viking.d' | path parse -e ''",
|
||||
result: None,
|
||||
result: Some(Value::Record {
|
||||
cols: vec![
|
||||
"prefix".into(),
|
||||
"parent".into(),
|
||||
"stem".into(),
|
||||
"extension".into(),
|
||||
],
|
||||
vals: vec![
|
||||
Value::test_string("C:"),
|
||||
Value::test_string(r"C:\Users"),
|
||||
Value::test_string("viking.d"),
|
||||
Value::test_string(""),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "Parse all paths under the 'name' column",
|
||||
@ -103,7 +131,15 @@ On Windows, an extra 'prefix' column is added."#
|
||||
Example {
|
||||
description: "Parse a path",
|
||||
example: r"'/home/viking/spam.txt' | path parse",
|
||||
result: None,
|
||||
result: Some(Value::Record {
|
||||
cols: vec!["parent".into(), "stem".into(), "extension".into()],
|
||||
vals: vec![
|
||||
Value::test_string("/home/viking"),
|
||||
Value::test_string("spam"),
|
||||
Value::test_string("txt"),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "Replace a complex extension",
|
||||
@ -113,7 +149,15 @@ On Windows, an extra 'prefix' column is added."#
|
||||
Example {
|
||||
description: "Ignore the extension",
|
||||
example: r"'/etc/conf.d' | path parse -e ''",
|
||||
result: None,
|
||||
result: Some(Value::Record {
|
||||
cols: vec!["parent".into(), "stem".into(), "extension".into()],
|
||||
vals: vec![
|
||||
Value::test_string("/etc"),
|
||||
Value::test_string("conf.d"),
|
||||
Value::test_string(""),
|
||||
],
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "Parse all paths under the 'name' column",
|
||||
|
@ -21,6 +21,10 @@ impl Command for Keybindings {
|
||||
"Keybindings related commands"
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["shortcut", "hotkey"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
&self,
|
||||
engine_state: &EngineState,
|
||||
|
@ -18,7 +18,11 @@ impl Command for RandomCommand {
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Generate a random values."
|
||||
"Generate a random value."
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
vec!["generate", "generator"]
|
||||
}
|
||||
|
||||
fn run(
|
||||
|
@ -139,7 +139,7 @@ prints out the list properly."#
|
||||
description: "Render a simple list to a grid",
|
||||
example: "[1 2 3 a b c] | grid",
|
||||
result: Some(Value::String {
|
||||
val: "1 │ 2 │ 3 │ a │ b │ c".to_string(),
|
||||
val: "1 │ 2 │ 3 │ a │ b │ c\n".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
@ -147,7 +147,7 @@ prints out the list properly."#
|
||||
description: "The above example is the same as:",
|
||||
example: "[1 2 3 a b c] | wrap name | grid",
|
||||
result: Some(Value::String {
|
||||
val: "1 │ 2 │ 3 │ a │ b │ c".to_string(),
|
||||
val: "1 │ 2 │ 3 │ a │ b │ c\n".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
@ -155,7 +155,7 @@ prints out the list properly."#
|
||||
description: "Render a record to a grid",
|
||||
example: "{name: 'foo', b: 1, c: 2} | grid",
|
||||
result: Some(Value::String {
|
||||
val: "foo".to_string(),
|
||||
val: "foo\n".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
@ -163,7 +163,7 @@ prints out the list properly."#
|
||||
description: "Render a list of records to a grid",
|
||||
example: "[{name: 'A', v: 1} {name: 'B', v: 2} {name: 'C', v: 3}] | grid",
|
||||
result: Some(Value::String {
|
||||
val: "A │ B │ C".to_string(),
|
||||
val: "A │ B │ C\n".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
@ -171,7 +171,7 @@ prints out the list properly."#
|
||||
description: "Render a table with 'name' column in it to a grid",
|
||||
example: "[[name patch]; [0.1.0 false] [0.1.1 true] [0.2.0 false]] | grid",
|
||||
result: Some(Value::String {
|
||||
val: "0.1.0 │ 0.1.1 │ 0.2.0".to_string(),
|
||||
val: "0.1.0 │ 0.1.1 │ 0.2.0\n".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
@ -358,3 +358,13 @@ fn convert_to_list(
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
#[test]
|
||||
fn test_examples() {
|
||||
use super::Griddle;
|
||||
use crate::test_examples;
|
||||
test_examples(Griddle {})
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,16 @@ use terminal_size::{Height, Width};
|
||||
const STREAM_PAGE_SIZE: usize = 1000;
|
||||
const STREAM_TIMEOUT_CHECK_INTERVAL: usize = 100;
|
||||
|
||||
fn get_width_param(width_param: Option<i64>) -> usize {
|
||||
if let Some(col) = width_param {
|
||||
col as usize
|
||||
} else if let Some((Width(w), Height(_h))) = terminal_size::terminal_size() {
|
||||
(w - 1) as usize
|
||||
} else {
|
||||
80usize
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Table;
|
||||
|
||||
@ -44,6 +54,12 @@ impl Command for Table {
|
||||
Some('n'),
|
||||
)
|
||||
.switch("list", "list available table modes/themes", Some('l'))
|
||||
.named(
|
||||
"width",
|
||||
SyntaxShape::Int,
|
||||
"number of terminal columns wide (not output columns)",
|
||||
Some('w'),
|
||||
)
|
||||
.category(Category::Viewers)
|
||||
}
|
||||
|
||||
@ -62,11 +78,8 @@ impl Command for Table {
|
||||
let row_offset = start_num.unwrap_or_default() as usize;
|
||||
let list: bool = call.has_flag("list");
|
||||
|
||||
let term_width = if let Some((Width(w), Height(_h))) = terminal_size::terminal_size() {
|
||||
(w - 1) as usize
|
||||
} else {
|
||||
80usize
|
||||
};
|
||||
let width_param: Option<i64> = call.get_flag(engine_state, stack, "width")?;
|
||||
let term_width = get_width_param(width_param);
|
||||
|
||||
if list {
|
||||
let table_modes = vec![
|
||||
@ -222,7 +235,7 @@ impl Command for Table {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn handle_row_stream(
|
||||
engine_state: &EngineState,
|
||||
stack: &Stack,
|
||||
stack: &mut Stack,
|
||||
stream: ListStream,
|
||||
call: &Call,
|
||||
row_offset: usize,
|
||||
@ -306,6 +319,7 @@ fn handle_row_stream(
|
||||
};
|
||||
|
||||
let head = call.head;
|
||||
let width_param: Option<i64> = call.get_flag(engine_state, stack, "width")?;
|
||||
|
||||
Ok(PipelineData::ExternalStream {
|
||||
stdout: Some(RawStream::new(
|
||||
@ -315,6 +329,7 @@ fn handle_row_stream(
|
||||
ctrlc: ctrlc.clone(),
|
||||
head,
|
||||
stream,
|
||||
width_param,
|
||||
}),
|
||||
ctrlc,
|
||||
head,
|
||||
@ -469,6 +484,7 @@ struct PagingTableCreator {
|
||||
ctrlc: Option<Arc<AtomicBool>>,
|
||||
config: Config,
|
||||
row_offset: usize,
|
||||
width_param: Option<i64>,
|
||||
}
|
||||
|
||||
impl Iterator for PagingTableCreator {
|
||||
@ -507,12 +523,7 @@ impl Iterator for PagingTableCreator {
|
||||
}
|
||||
|
||||
let color_hm = get_color_config(&self.config);
|
||||
|
||||
let term_width = if let Some((Width(w), Height(_h))) = terminal_size::terminal_size() {
|
||||
(w - 1) as usize
|
||||
} else {
|
||||
80usize
|
||||
};
|
||||
let term_width = get_width_param(self.width_param);
|
||||
|
||||
let table = convert_to_table(
|
||||
self.row_offset,
|
||||
|
@ -1,3 +1,4 @@
|
||||
use nu_test_support::fs::file_contents;
|
||||
use nu_test_support::fs::{files_exist_at, AbsoluteFile, Stub::EmptyFile};
|
||||
use nu_test_support::nu;
|
||||
use nu_test_support::playground::Playground;
|
||||
@ -249,3 +250,71 @@ fn copy_to_non_existing_dir() {
|
||||
assert!(actual.err.contains("destination directory does not exist"));
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn copy_dir_contains_symlink_ignored() {
|
||||
Playground::setup("cp_test_12", |_dirs, sandbox| {
|
||||
sandbox
|
||||
.within("tmp_dir")
|
||||
.with_files(vec![EmptyFile("hello_there"), EmptyFile("good_bye")])
|
||||
.within("tmp_dir")
|
||||
.symlink("good_bye", "dangle_symlink");
|
||||
|
||||
// make symbolic link and copy.
|
||||
nu!(
|
||||
cwd: sandbox.cwd(),
|
||||
"rm tmp_dir/good_bye; cp -r tmp_dir tmp_dir_2",
|
||||
);
|
||||
|
||||
// check hello_there exists inside `tmp_dir_2`, and `dangle_symlink` don't exists inside `tmp_dir_2`.
|
||||
let expected = sandbox.cwd().join("tmp_dir_2");
|
||||
assert!(files_exist_at(vec!["hello_there"], expected.clone()));
|
||||
let path = expected.join("dangle_symlink");
|
||||
assert!(!path.exists() && !path.is_symlink());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn copy_dir_contains_symlink() {
|
||||
Playground::setup("cp_test_13", |_dirs, sandbox| {
|
||||
sandbox
|
||||
.within("tmp_dir")
|
||||
.with_files(vec![EmptyFile("hello_there"), EmptyFile("good_bye")])
|
||||
.within("tmp_dir")
|
||||
.symlink("good_bye", "dangle_symlink");
|
||||
|
||||
// make symbolic link and copy.
|
||||
nu!(
|
||||
cwd: sandbox.cwd(),
|
||||
"rm tmp_dir/good_bye; cp -r -p tmp_dir tmp_dir_2",
|
||||
);
|
||||
|
||||
// check hello_there exists inside `tmp_dir_2`, and `dangle_symlink` also exists inside `tmp_dir_2`.
|
||||
let expected = sandbox.cwd().join("tmp_dir_2");
|
||||
assert!(files_exist_at(vec!["hello_there"], expected.clone()));
|
||||
let path = expected.join("dangle_symlink");
|
||||
assert!(path.is_symlink());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn copy_dir_symlink_file_body_not_changed() {
|
||||
Playground::setup("cp_test_14", |_dirs, sandbox| {
|
||||
sandbox
|
||||
.within("tmp_dir")
|
||||
.with_files(vec![EmptyFile("hello_there"), EmptyFile("good_bye")])
|
||||
.within("tmp_dir")
|
||||
.symlink("good_bye", "dangle_symlink");
|
||||
|
||||
// make symbolic link and copy.
|
||||
nu!(
|
||||
cwd: sandbox.cwd(),
|
||||
"rm tmp_dir/good_bye; cp -r -p tmp_dir tmp_dir_2; rm -r tmp_dir; cp -r -p tmp_dir_2 tmp_dir; echo hello_data | save tmp_dir/good_bye",
|
||||
);
|
||||
|
||||
// check dangle_symlink in tmp_dir is no longer dangling.
|
||||
let expected_file = sandbox.cwd().join("tmp_dir").join("dangle_symlink");
|
||||
let actual = file_contents(expected_file);
|
||||
assert!(actual.contains("hello_data"));
|
||||
});
|
||||
}
|
||||
|
@ -81,3 +81,29 @@ fn ignores_duplicate_columns_rejected() {
|
||||
|
||||
assert_eq!(actual.out, "last name");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reject_record_from_raw_eval() {
|
||||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
{"a": 3, "a": 4} | reject a | describe
|
||||
"#
|
||||
)
|
||||
);
|
||||
|
||||
assert!(actual.out.contains("record<>"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reject_table_from_raw_eval() {
|
||||
let actual = nu!(
|
||||
cwd: ".", pipeline(
|
||||
r#"
|
||||
[{"a": 3, "a": 4}] | reject a
|
||||
"#
|
||||
)
|
||||
);
|
||||
|
||||
assert!(actual.out.contains("record 0 fields"));
|
||||
}
|
||||
|
@ -4,13 +4,13 @@ description = "Nushell's evaluation engine"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-engine"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[dependencies]
|
||||
nu-protocol = { path = "../nu-protocol", features = ["plugin"], version = "0.63.0" }
|
||||
nu-path = { path = "../nu-path", version = "0.63.0" }
|
||||
nu-glob = { path = "../nu-glob", version = "0.63.0" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.63.0" }
|
||||
nu-protocol = { path = "../nu-protocol", features = ["plugin"], version = "0.63.1" }
|
||||
nu-path = { path = "../nu-path", version = "0.63.1" }
|
||||
nu-glob = { path = "../nu-glob", version = "0.63.1" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.63.1" }
|
||||
|
||||
chrono = { version="0.4.19", features=["serde"] }
|
||||
sysinfo = "0.23.10"
|
||||
|
@ -472,8 +472,18 @@ pub fn eval_expression(
|
||||
let mut cols = vec![];
|
||||
let mut vals = vec![];
|
||||
for (col, val) in fields {
|
||||
cols.push(eval_expression(engine_state, stack, col)?.as_string()?);
|
||||
vals.push(eval_expression(engine_state, stack, val)?);
|
||||
// avoid duplicate cols.
|
||||
let col_name = eval_expression(engine_state, stack, col)?.as_string()?;
|
||||
let pos = cols.iter().position(|c| c == &col_name);
|
||||
match pos {
|
||||
Some(index) => {
|
||||
vals[index] = eval_expression(engine_state, stack, val)?;
|
||||
}
|
||||
None => {
|
||||
cols.push(col_name);
|
||||
vals.push(eval_expression(engine_state, stack, val)?);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Value::Record {
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nu-glob"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
authors = ["The Nushell Project Developers", "The Rust Project Developers"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = """
|
||||
|
@ -4,7 +4,7 @@ description = "Fork of serde-hjson"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-json"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@ -20,5 +20,5 @@ lazy_static = "1"
|
||||
linked-hash-map = { version="0.5", optional=true }
|
||||
|
||||
[dev-dependencies]
|
||||
nu-path = { path="../nu-path", version = "0.63.0" }
|
||||
nu-path = { path="../nu-path", version = "0.63.1" }
|
||||
serde_json = "1.0"
|
||||
|
@ -4,16 +4,16 @@ description = "Nushell's parser"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-parser"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4.19"
|
||||
miette = "4.5.0"
|
||||
thiserror = "1.0.29"
|
||||
serde_json = "1.0"
|
||||
nu-path = {path = "../nu-path", version = "0.63.0" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.0" }
|
||||
nu-plugin = { path = "../nu-plugin", optional = true, version = "0.63.0" }
|
||||
nu-path = {path = "../nu-path", version = "0.63.1" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.1" }
|
||||
nu-plugin = { path = "../nu-plugin", optional = true, version = "0.63.1" }
|
||||
log = "0.4"
|
||||
|
||||
[features]
|
||||
|
@ -78,6 +78,16 @@ pub enum ParseError {
|
||||
)]
|
||||
BuiltinCommandInPipeline(String, #[label("not allowed in pipeline")] Span),
|
||||
|
||||
#[error("Let statement used in pipeline.")]
|
||||
#[diagnostic(
|
||||
code(nu::parser::unexpected_keyword),
|
||||
url(docsrs),
|
||||
help(
|
||||
"Assigning '{0}' to '{1}' does not produce a value to be piped. If the pipeline is meant to apply to '{0}' by itself, use 'let {1} = ({0} | ...)'."
|
||||
)
|
||||
)]
|
||||
LetInPipeline(String, String, #[label("let in pipeline")] Span),
|
||||
|
||||
#[error("Incorrect value")]
|
||||
#[diagnostic(code(nu::parser::incorrect_value), url(docsrs), help("{2}"))]
|
||||
IncorrectValue(String, #[label("unexpected {0}")] Span, String),
|
||||
@ -300,6 +310,7 @@ impl ParseError {
|
||||
ParseError::ExpectedKeyword(_, s) => *s,
|
||||
ParseError::UnexpectedKeyword(_, s) => *s,
|
||||
ParseError::BuiltinCommandInPipeline(_, s) => *s,
|
||||
ParseError::LetInPipeline(_, _, s) => *s,
|
||||
ParseError::IncorrectValue(_, s, _) => *s,
|
||||
ParseError::MultipleRestParams(s) => *s,
|
||||
ParseError::VariableNotFound(s) => *s,
|
||||
|
@ -1745,6 +1745,9 @@ pub fn parse_overlay(
|
||||
None,
|
||||
);
|
||||
}
|
||||
b"new" => {
|
||||
return parse_overlay_new(working_set, spans, expand_aliases_denylist);
|
||||
}
|
||||
b"remove" => {
|
||||
return parse_overlay_remove(working_set, spans, expand_aliases_denylist);
|
||||
}
|
||||
@ -1802,6 +1805,96 @@ pub fn parse_overlay(
|
||||
)
|
||||
}
|
||||
|
||||
pub fn parse_overlay_new(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
expand_aliases_denylist: &[usize],
|
||||
) -> (Pipeline, Option<ParseError>) {
|
||||
if spans.len() > 1 && working_set.get_span_contents(span(&spans[0..2])) != b"overlay new" {
|
||||
return (
|
||||
garbage_pipeline(spans),
|
||||
Some(ParseError::UnknownState(
|
||||
"internal error: Wrong call name for 'overlay new' command".into(),
|
||||
span(spans),
|
||||
)),
|
||||
);
|
||||
}
|
||||
|
||||
let (call, call_span) = match working_set.find_decl(b"overlay new") {
|
||||
Some(decl_id) => {
|
||||
let (call, mut err) = parse_internal_call(
|
||||
working_set,
|
||||
span(&spans[0..2]),
|
||||
&spans[2..],
|
||||
decl_id,
|
||||
expand_aliases_denylist,
|
||||
);
|
||||
let decl = working_set.get_decl(decl_id);
|
||||
|
||||
let call_span = span(spans);
|
||||
|
||||
err = check_call(call_span, &decl.signature(), &call).or(err);
|
||||
if err.is_some() || call.has_flag("help") {
|
||||
return (
|
||||
Pipeline::from_vec(vec![Expression {
|
||||
expr: Expr::Call(call),
|
||||
span: call_span,
|
||||
ty: Type::Any,
|
||||
custom_completion: None,
|
||||
}]),
|
||||
err,
|
||||
);
|
||||
}
|
||||
|
||||
(call, call_span)
|
||||
}
|
||||
None => {
|
||||
return (
|
||||
garbage_pipeline(spans),
|
||||
Some(ParseError::UnknownState(
|
||||
"internal error: 'overlay new' declaration not found".into(),
|
||||
span(spans),
|
||||
)),
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let (overlay_name, _) = if let Some(expr) = call.positional_nth(0) {
|
||||
if let Some(s) = expr.as_string() {
|
||||
(s, expr.span)
|
||||
} else {
|
||||
return (
|
||||
garbage_pipeline(spans),
|
||||
Some(ParseError::UnknownState(
|
||||
"internal error: Module name not a string".into(),
|
||||
expr.span,
|
||||
)),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
return (
|
||||
garbage_pipeline(spans),
|
||||
Some(ParseError::UnknownState(
|
||||
"internal error: Missing required positional after call parsing".into(),
|
||||
call_span,
|
||||
)),
|
||||
);
|
||||
};
|
||||
|
||||
let pipeline = Pipeline::from_vec(vec![Expression {
|
||||
expr: Expr::Call(call),
|
||||
span: span(spans),
|
||||
ty: Type::Any,
|
||||
custom_completion: None,
|
||||
}]);
|
||||
|
||||
let module_id = working_set.add_module(&overlay_name, Module::new());
|
||||
|
||||
working_set.add_overlay(overlay_name.as_bytes().to_vec(), module_id, vec![], vec![]);
|
||||
|
||||
(pipeline, None)
|
||||
}
|
||||
|
||||
pub fn parse_overlay_add(
|
||||
working_set: &mut StateWorkingSet,
|
||||
spans: &[Span],
|
||||
|
@ -4371,7 +4371,12 @@ pub fn parse_expression(
|
||||
expand_aliases_denylist,
|
||||
)
|
||||
.0,
|
||||
Some(ParseError::BuiltinCommandInPipeline("let".into(), spans[0])),
|
||||
Some(ParseError::LetInPipeline(
|
||||
String::from_utf8_lossy(working_set.get_span_contents(spans[spans.len() - 1]))
|
||||
.to_string(),
|
||||
String::from_utf8_lossy(working_set.get_span_contents(spans[1])).to_string(),
|
||||
spans[0],
|
||||
)),
|
||||
),
|
||||
b"alias" => (
|
||||
parse_call(
|
||||
|
@ -4,7 +4,7 @@ description = "Path handling library for Nushell"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-path"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[dependencies]
|
||||
dirs-next = "2.0.0"
|
||||
|
@ -4,11 +4,11 @@ description = "Functionality for building Nushell plugins"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-plugin"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[dependencies]
|
||||
capnp = "0.14.3"
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.0" }
|
||||
nu-engine = { path = "../nu-engine", version = "0.63.0" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.1" }
|
||||
nu-engine = { path = "../nu-engine", version = "0.63.1" }
|
||||
serde = {version = "1.0.130", features = ["derive"]}
|
||||
serde_json = { version = "1.0"}
|
||||
|
@ -4,7 +4,7 @@ description = "Pretty hex dump of bytes slice in the common style."
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-pretty-hex"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
@ -4,12 +4,12 @@ description = "Nushell's internal protocols, including its abstract syntax tree"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-protocol"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nu-utils = { path = "../nu-utils", version = "0.63.0" }
|
||||
nu-utils = { path = "../nu-utils", version = "0.63.1" }
|
||||
thiserror = "1.0.29"
|
||||
miette = { version = "4.5.0", features = ["fancy"] }
|
||||
serde = {version = "1.0.130", features = ["derive"]}
|
||||
@ -18,7 +18,7 @@ indexmap = { version="1.7", features=["serde-1"] }
|
||||
chrono-humanize = "0.2.1"
|
||||
byte-unit = "4.0.9"
|
||||
serde_json = { version = "1.0", optional = true }
|
||||
nu-json = { path = "../nu-json", version = "0.63.0" }
|
||||
nu-json = { path = "../nu-json", version = "0.63.1" }
|
||||
typetag = "0.1.8"
|
||||
num-format = "0.4.0"
|
||||
sys-locale = "0.2.0"
|
||||
|
@ -75,6 +75,7 @@ pub struct Config {
|
||||
pub buffer_editor: String,
|
||||
pub disable_table_indexes: bool,
|
||||
pub cd_with_abbreviations: bool,
|
||||
pub case_sensitive_completions: bool,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
@ -105,6 +106,7 @@ impl Default for Config {
|
||||
buffer_editor: String::new(),
|
||||
disable_table_indexes: false,
|
||||
cd_with_abbreviations: false,
|
||||
case_sensitive_completions: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -311,7 +313,14 @@ impl Value {
|
||||
if let Ok(b) = value.as_bool() {
|
||||
config.cd_with_abbreviations = b;
|
||||
} else {
|
||||
eprintln!("$config.disable_table_indexes is not a bool")
|
||||
eprintln!("$config.cd_with_abbreviations is not a bool")
|
||||
}
|
||||
}
|
||||
"case_sensitive_completions" => {
|
||||
if let Ok(b) = value.as_bool() {
|
||||
config.case_sensitive_completions = b;
|
||||
} else {
|
||||
eprintln!("$config.case_sensitive_completions is not a bool")
|
||||
}
|
||||
}
|
||||
x => {
|
||||
|
2
crates/nu-system/Cargo.lock
generated
2
crates/nu-system/Cargo.lock
generated
@ -148,7 +148,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nu-system"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
dependencies = [
|
||||
"errno",
|
||||
"libproc",
|
||||
|
@ -2,7 +2,7 @@
|
||||
authors = ["The Nushell Project Developers", "procs creators"]
|
||||
description = "Nushell system querying"
|
||||
name = "nu-system"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
|
||||
|
@ -4,7 +4,7 @@ description = "Nushell table printing"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-table"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[[bin]]
|
||||
@ -13,7 +13,7 @@ path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
nu-ansi-term = "0.45.1"
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.0" }
|
||||
nu-protocol = { path = "../nu-protocol", version = "0.63.1" }
|
||||
regex = "1.4"
|
||||
unicode-width = "0.1.8"
|
||||
strip-ansi-escapes = "0.1.1"
|
||||
|
@ -491,14 +491,20 @@ pub fn draw_table(
|
||||
config: &Config,
|
||||
) -> String {
|
||||
// Remove the edges, if used
|
||||
let termwidth = if table.theme.print_left_border && table.theme.print_right_border {
|
||||
termwidth - 3
|
||||
let edges_width = if table.theme.print_left_border && table.theme.print_right_border {
|
||||
3
|
||||
} else if table.theme.print_left_border || table.theme.print_right_border {
|
||||
termwidth - 1
|
||||
1
|
||||
} else {
|
||||
termwidth
|
||||
0
|
||||
};
|
||||
|
||||
if termwidth < edges_width {
|
||||
return format!("Couldn't fit table into {} columns!", termwidth);
|
||||
}
|
||||
|
||||
let termwidth = termwidth - edges_width;
|
||||
|
||||
let mut processed_table = process_table(table);
|
||||
|
||||
let max_per_column = get_max_column_widths(&processed_table);
|
||||
|
@ -4,7 +4,7 @@ description = "Nushell grid printing"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-term-grid"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[[bin]]
|
||||
|
@ -4,14 +4,14 @@ description = "Support for writing Nushell tests"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu-test-support"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
nu-path = { path="../nu-path", version = "0.63.0" }
|
||||
nu-glob = { path = "../nu-glob", version = "0.63.0" }
|
||||
nu-path = { path="../nu-path", version = "0.63.1" }
|
||||
nu-glob = { path = "../nu-glob", version = "0.63.1" }
|
||||
|
||||
getset = "0.1.1"
|
||||
num-bigint = { version="0.4.3", features=["serde"] }
|
||||
|
@ -228,7 +228,9 @@ impl<'a> Playground<'a> {
|
||||
|
||||
pub fn within(&mut self, directory: &str) -> &mut Self {
|
||||
self.cwd.push(directory);
|
||||
std::fs::create_dir(&self.cwd).expect("can not create directory");
|
||||
if !(self.cwd.exists() && self.cwd.is_dir()) {
|
||||
std::fs::create_dir(&self.cwd).expect("can not create directory");
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ description = "Nushell utility functions"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu-utils"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[[bin]]
|
||||
|
@ -4,8 +4,8 @@ description = "A version incrementer plugin for Nushell"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_example"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[dependencies]
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0", features = ["plugin"]}
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1", features = ["plugin"]}
|
||||
|
@ -4,14 +4,14 @@ description = "A git status plugin for Nushell"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_gstat"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-engine = { path="../nu-engine", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
nu-engine = { path="../nu-engine", version = "0.63.1" }
|
||||
|
||||
git2 = "0.14.2"
|
||||
|
@ -4,13 +4,13 @@ description = "A version incrementer plugin for Nushell"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_inc"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0", features = ["plugin"]}
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1", features = ["plugin"]}
|
||||
|
||||
semver = "0.11.0"
|
||||
|
@ -4,15 +4,15 @@ description = "A Nushell plugin to query JSON, XML, and various web data"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_query"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-engine = { path="../nu-engine", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
nu-engine = { path="../nu-engine", version = "0.63.1" }
|
||||
gjson = "0.8.0"
|
||||
scraper = "0.12.0"
|
||||
sxd-document = "0.3.2"
|
||||
|
@ -4,18 +4,18 @@ description = "A plugin to display charts"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_chart"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
nu-data = { path="../nu-data", version = "0.63.0" }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-source = { path="../nu-source", version = "0.63.0" }
|
||||
nu-value-ext = { path="../nu-value-ext", version = "0.63.0" }
|
||||
nu-data = { path="../nu-data", version = "0.63.1" }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.1" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
nu-source = { path="../nu-source", version = "0.63.1" }
|
||||
nu-value-ext = { path="../nu-value-ext", version = "0.63.1" }
|
||||
|
||||
crossterm = "0.19.0"
|
||||
tui = { version="0.15.0", default-features=false, features=["crossterm"] }
|
||||
|
@ -4,7 +4,7 @@ description = "A converter plugin to the bson format for Nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_from_bson"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
@ -12,9 +12,9 @@ doctest = false
|
||||
[dependencies]
|
||||
bigdecimal = { package = "bigdecimal", version = "0.3.0", features = ["serde"] }
|
||||
bson = { version = "2.0.1", features = [ "chrono-0_4" ] }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-source = { path="../nu-source", version = "0.63.0" }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.1" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
nu-source = { path="../nu-source", version = "0.63.1" }
|
||||
|
||||
[build-dependencies]
|
||||
|
@ -4,16 +4,16 @@ description = "A converter plugin to the mp4 format for Nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_from_mp4"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
nu-errors = { path="../nu-errors", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-source = { path="../nu-source", version = "0.63.0" }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.1" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
nu-source = { path="../nu-source", version = "0.63.1" }
|
||||
tempfile = "3.2.0"
|
||||
mp4 = "0.9.0"
|
||||
|
||||
|
@ -4,17 +4,17 @@ description = "A converter plugin to the bson format for Nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_from_sqlite"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
bigdecimal = { package = "bigdecimal", version = "0.3.0", features = ["serde"] }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-source = { path="../nu-source", version = "0.63.0" }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.1" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
nu-source = { path="../nu-source", version = "0.63.1" }
|
||||
tempfile = "3.2.0"
|
||||
|
||||
[dependencies.rusqlite]
|
||||
|
@ -4,17 +4,17 @@ description = "An S3 plugin for Nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_s3"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
futures = { version="0.3.12", features=["compat", "io-compat"] }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-source = { path="../nu-source", version = "0.63.0" }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.1" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
nu-source = { path="../nu-source", version = "0.63.1" }
|
||||
s3handler = "0.7.5"
|
||||
|
||||
[build-dependencies]
|
||||
|
@ -4,17 +4,17 @@ description = "A plugin to open files/URLs directly from Nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_start"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
glob = "0.3.0"
|
||||
nu-errors = { path="../nu-errors", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-source = { path="../nu-source", version = "0.63.0" }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.1" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
nu-source = { path="../nu-source", version = "0.63.1" }
|
||||
url = "2.2.0"
|
||||
webbrowser = "0.5.5"
|
||||
|
||||
@ -22,5 +22,5 @@ webbrowser = "0.5.5"
|
||||
open = "1.4.0"
|
||||
|
||||
[build-dependencies]
|
||||
nu-errors = { version = "0.63.0", path="../nu-errors" }
|
||||
nu-source = { version = "0.63.0", path="../nu-source" }
|
||||
nu-errors = { version = "0.63.1", path="../nu-errors" }
|
||||
nu-source = { version = "0.63.1", path="../nu-source" }
|
||||
|
@ -4,17 +4,17 @@ description = "A converter plugin to the bson format for Nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_to_bson"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
bson = { version = "2.0.1", features = [ "chrono-0_4" ] }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-source = { path="../nu-source", version = "0.63.0" }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.1" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
nu-source = { path="../nu-source", version = "0.63.1" }
|
||||
num-traits = "0.2.14"
|
||||
|
||||
[features]
|
||||
|
@ -4,17 +4,17 @@ description = "A converter plugin to the SQLite format for Nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_to_sqlite"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
hex = "0.4.2"
|
||||
nu-errors = { path="../nu-errors", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-source = { path="../nu-source", version = "0.63.0" }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.1" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
nu-source = { path="../nu-source", version = "0.63.1" }
|
||||
tempfile = "3.2.0"
|
||||
|
||||
[dependencies.rusqlite]
|
||||
|
@ -4,16 +4,16 @@ description = "Tree viewer plugin for Nushell"
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
name = "nu_plugin_tree"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
derive-new = "0.5.8"
|
||||
nu-errors = { path="../nu-errors", version = "0.63.0" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.0" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.0" }
|
||||
nu-errors = { path="../nu-errors", version = "0.63.1" }
|
||||
nu-plugin = { path="../nu-plugin", version = "0.63.1" }
|
||||
nu-protocol = { path="../nu-protocol", version = "0.63.1" }
|
||||
ptree = { version = "0.4.0", default-features = false }
|
||||
|
||||
|
||||
|
@ -199,6 +199,8 @@ let-env config = {
|
||||
shell_integration: true # enables terminal markers and a workaround to arrow keys stop working issue
|
||||
disable_table_indexes: false # set to true to remove the index column from tables
|
||||
cd_with_abbreviations: false # set to true to allow you to do things like cd s/o/f and nushell expand it to cd some/other/folder
|
||||
case_sensitive_completions: false # set to true to enable case-sensitive completions
|
||||
|
||||
hooks: {
|
||||
pre_prompt: [{
|
||||
$nothing # replace with source code to run before the prompt is shown
|
||||
|
@ -2,7 +2,7 @@
|
||||
authors = ["Nu authors"]
|
||||
edition = "2018"
|
||||
name = "wasm"
|
||||
version = "0.63.0"
|
||||
version = "0.63.1"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
@ -496,3 +496,14 @@ fn reset_overrides() {
|
||||
assert_eq!(actual.out, "foo");
|
||||
assert_eq!(actual_repl.out, "foo");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overlay_new() {
|
||||
let inp = &[r#"overlay new spam"#, r#"overlay list | last"#];
|
||||
|
||||
let actual = nu!(cwd: "tests/overlays", pipeline(&inp.join("; ")));
|
||||
let actual_repl = nu_repl("tests/overlays", inp);
|
||||
|
||||
assert_eq!(actual.out, "spam");
|
||||
assert_eq!(actual_repl.out, "spam");
|
||||
}
|
||||
|
Reference in New Issue
Block a user