Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ jobs:
mkdir -p "$HOME/.local/bin"
ln -s "$(which fdfind)" "$HOME/.local/bin/fd"
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- name: Dependencies for e2e/shell/test_nushell
run: npm install --global nushell
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: mise-ubuntu-latest
Expand Down
38 changes: 38 additions & 0 deletions e2e/shell/test_nushell
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#! /usr/bin/env sh
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would you mind adding nushell to either the coverage github action tests or mise.toml so they actually get run in CI? these tests otherwise won't do any good

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure thing!

Copy link
Contributor Author

@jokeyrhyme jokeyrhyme Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh, any special reason why the Windows end-to-end tests were automated via GitHub Actions, but not the rest of the end-to-end tests?

edit: ignore me, i found them in the "nightly" Action, although they don't seem to log any output to stdout which is intriguing ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mise run e2e --list works on my machine and outputs the full list to stdout

i'm not sure mise run e2e (what is already in "nightly") or even mise run e2e --all actually does anything at the moment ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jdx well, i've explicitly added the nushell end-to-end tests in "nightly", but i think a follow-up PR is needed to fix the rest of the end-to-end tests, unless you're okay with only the nushell ones running? 🤷


# run this test with either:
# - mise run e2e nushell
# - LD_LIBRARY_PATH=/usr/lib:/home/linuxbrew/.linuxbrew/lib mise run e2e nushell

set -eu

if ! command -v nu >/dev/null 2>&1; then
# for now, treat these tests as optional if `nu` is unavailable
exit 0
fi

MISE_NUSHELL_INIT=$(mktemp e2e_nushell_init.XXXXXXXXXX)

# nushell's `source` is a parser keyword:
# https://www.nushell.sh/commands/docs/source.html
# this means the sourced mise init file must exist before we run `nu`

# use `env` to control the environment variables available to `nu`
# - we need LD_LIBRARY_PATH so that mise can find libbz2.so.1.0
# - we need PATH so that this test can find `mise`
env --ignore-environment LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" PATH="${PATH}" mise activate nu >"${MISE_NUSHELL_INIT}"

# equivalent of try/catch so we always cleanup the temporary file,
# even if the test fails
set +e

# use `env` to control the environment variables available to `nu`
# - we need LD_LIBRARY_PATH so that mise can find libbz2.so.1.0
# - we need PATH so that this test can find `nu`
env --ignore-environment LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" PATH="${PATH}" nu --no-config-file --commands "source ${MISE_NUSHELL_INIT}"
NUSHELL_EXIT_CODE=${?}

set -e
rm --force --verbose "${MISE_NUSHELL_INIT}"

exit "${NUSHELL_EXIT_CODE}"
39 changes: 39 additions & 0 deletions e2e/shell/test_nushell_deactivation
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#! /usr/bin/env sh

# run this test with either:
# - mise run e2e nushell
# - LD_LIBRARY_PATH=/usr/lib:/home/linuxbrew/.linuxbrew/lib mise run e2e nushell

set -eu

if ! command -v nu >/dev/null 2>&1; then
# for now, treat these tests as optional if `nu` is unavailable
exit 0
fi

MISE_NUSHELL_INIT=$(mktemp e2e_nushell_init.XXXXXXXXXX)

# nushell's `source` is a parser keyword:
# https://www.nushell.sh/commands/docs/source.html
# this means the sourced mise init file must exist before we run `nu`

# use `env` to control the environment variables available to `nu`
# - we need __MISE_DIFF to trigger the deactivation code path
# - we need LD_LIBRARY_PATH so that mise can find libbz2.so.1.0
# - we need PATH so that this test can find `mise`
env --ignore-environment __MISE_DIFF=1 LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" PATH="${PATH}" mise activate nu >"${MISE_NUSHELL_INIT}"

# equivalent of try/catch so we always cleanup the temporary file,
# even if the test fails
set +e

# use `env` to control the environment variables available to `nu`
# - we need LD_LIBRARY_PATH so that mise can find libbz2.so.1.0
# - we need PATH so that this test can find `nu`
env --ignore-environment LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" PATH="${PATH}" nu --no-config-file --commands "source ${MISE_NUSHELL_INIT}"
NUSHELL_EXIT_CODE=${?}

set -e
rm --force --verbose "${MISE_NUSHELL_INIT}"

exit "${NUSHELL_EXIT_CODE}"
44 changes: 25 additions & 19 deletions src/shell/nushell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,31 @@ impl Shell for Nushell {

let mut out = String::new();

out.push_str(&shell::build_deactivation_script(self));
out.push_str(&formatdoc! {r#"
def "parse vars" [] {{
$in | from csv --noheaders --no-infer | rename 'op' 'name' 'value'
}}

def --env "update-env" [] {{
for $var in $in {{
if $var.op == "set" {{
if ($var.name | str upcase) == 'PATH' {{
$env.PATH = ($var.value | split row (char esep))
}} else {{
load-env {{($var.name): $var.value}}
}}
}} else if $var.op == "hide" and $var.name in $env {{
hide-env $var.name
}}
}}
}}
"#});

let deactivation_ops_csv = &shell::build_deactivation_script(self);
out.push_str(&formatdoc! {r#"
"{deactivation_ops_csv}" | parse vars | update-env
"#});

let inline_prelude = self.format_activate_prelude_inline(&opts.prelude);
out.push_str(&formatdoc! {r#"
export-env {{
Expand All @@ -73,10 +97,6 @@ impl Shell for Nushell {
$env.config = ($old_config | upsert $field ($old_hooks ++ [$new_hook]))
}}

def "parse vars" [] {{
$in | from csv --noheaders --no-infer | rename 'op' 'name' 'value'
}}

export def --env --wrapped main [command?: string, --help, ...rest: string] {{
let commands = ["deactivate", "shell", "sh"]

Expand All @@ -93,20 +113,6 @@ impl Shell for Nushell {
}}
}}

def --env "update-env" [] {{
for $var in $in {{
if $var.op == "set" {{
if ($var.name | str upcase) == 'PATH' {{
$env.PATH = ($var.value | split row (char esep))
}} else {{
load-env {{($var.name): $var.value}}
}}
}} else if $var.op == "hide" {{
hide-env $var.name
}}
}}
}}

def --env mise_hook [] {{
^"{exe}" hook-env{flags} -s nu
| parse vars
Expand Down
37 changes: 19 additions & 18 deletions src/shell/snapshots/mise__shell__nushell__tests__hook_init.snap
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
---
source: src/shell/nushell.rs
assertion_line: 178
expression: nushell.activate(opts)
---
def "parse vars" [] {
$in | from csv --noheaders --no-infer | rename 'op' 'name' 'value'
}

def --env "update-env" [] {
for $var in $in {
if $var.op == "set" {
if ($var.name | str upcase) == 'PATH' {
$env.PATH = ($var.value | split row (char esep))
} else {
load-env {($var.name): $var.value}
}
} else if $var.op == "hide" and $var.name in $env {
hide-env $var.name
}
}
}
"" | parse vars | update-env
export-env {

$env.MISE_SHELL = "nu"
Expand All @@ -20,10 +39,6 @@ def --env add-hook [field: cell-path new_hook: any] {
$env.config = ($old_config | upsert $field ($old_hooks ++ [$new_hook]))
}

def "parse vars" [] {
$in | from csv --noheaders --no-infer | rename 'op' 'name' 'value'
}

export def --env --wrapped main [command?: string, --help, ...rest: string] {
let commands = ["deactivate", "shell", "sh"]

Expand All @@ -40,20 +55,6 @@ export def --env --wrapped main [command?: string, --help, ...rest: string] {
}
}

def --env "update-env" [] {
for $var in $in {
if $var.op == "set" {
if ($var.name | str upcase) == 'PATH' {
$env.PATH = ($var.value | split row (char esep))
} else {
load-env {($var.name): $var.value}
}
} else if $var.op == "hide" {
hide-env $var.name
}
}
}

def --env mise_hook [] {
^"/some/dir/mise" hook-env --status -s nu
| parse vars
Expand Down
Loading