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
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
def main [mode: string] {
if $mode not-in ["config", "parent"] {
error make {msg: "Expected config or parent mode"}
}
$env.HOME = ($env.PWD | path join "user")
$env.XDG_CONFIG_HOME = ($env.HOME | path join "config")
$env.XDG_DATA_DIRS = ($env.HOME | path join "system-data")
$env.VP_HOME = ($env.PWD | path join "installation")
$env.VP_SKIP_DEPS_INSTALL = "1"
$env.VP_VERSION = "nushell-test"
$env.VP_NODE_MANAGER = "no"
$env.VP_PM_MANAGER = "no"
$env.CI = "true"
hide-env -i XDG_DATA_HOME

let config_dir = ($env.XDG_CONFIG_HOME | path join "nushell")
let custom_data = ($env.HOME | path join "custom-data")
# Use a non-default directory on both Linux and macOS so the mismatch is observable.
mkdir $config_dir
'' | save ($config_dir | path join "env.nu")
if $mode == "config" {
'$env.XDG_DATA_HOME = ($env.HOME | path join "custom-data")'
| save ($config_dir | path join "config.nu")
} else {
$env.XDG_DATA_HOME = $custom_data
'' | save ($config_dir | path join "config.nu")
}

# Real interactive startup loads config.nu before invoking the standalone installer.
let install = (^$nu.current-exe --no-history --execute 'try { source install.nu } catch { |err| print -e $err; exit 1 }; exit 0' | complete)
if $install.exit_code != 0 {
error make {msg: $"Installer session failed: ($install.stdout) ($install.stderr)"}
}
let installed = ($install.stdout | from json)
let session_dir = $installed.directory
if $installed.data_home != $custom_data {
error make {msg: "The installer session did not inherit the configured XDG_DATA_HOME"}
}
let snippet = ($custom_data | path join "nushell/vendor/autoload/vite-plus.nu")
if not ($snippet | path exists) {
error make {msg: "Installer did not write vite-plus.nu into the child-resolved directory"}
}
if not ($env.VP_HOME | path join "current/bin/.vp-setup-complete" | path exists) {
error make {msg: "Installer did not complete setup"}
}

# Launch from the original parent environment, not from the modified interactive session.
let fresh = (^$nu.current-exe --no-history --execute 'try { source probe.nu } catch { |err| print -e $err; exit 1 }; exit 0' | complete)
if $fresh.exit_code != 0 {
error make {msg: $"Fresh session failed: ($fresh.stdout) ($fresh.stderr)"}
}
let state = ($fresh.stdout | from json)
if $state.data_home != $custom_data {
error make {msg: "The fresh session did not load the configured XDG_DATA_HOME"}
}
let expected_loaded = ($mode == "parent")
if $state.directory != $session_dir {
error make {msg: "Fresh session did not resolve the original session's autoload directory"}
}
if (($snippet | path dirname) == $session_dir) != $expected_loaded {
error make {msg: "Unexpected agreement between installer and session autoload directories"}
}
if $state.loaded != $expected_loaded {
error make {msg: $"Unexpected Vite+ autoload state: ($state.loaded)"}
}
print "Standalone setup completed and wrote vite-plus.nu"
print "Both sessions have the configured XDG_DATA_HOME after startup: true"
print $"Installer and session directories match: ($expected_loaded)"
print $"Fresh session loaded Vite+ environment: ($state.loaded)"

if $mode == "config" {
# Apply the documented workaround without changing the XDG settings.
# source requires a parse-time path, so write a quoted literal into config.nu.
let env_file = ($env.VP_HOME | path join "env.nu" | to nuon)
$"\nsource ($env_file)\n" | save --append ($config_dir | path join "config.nu")
let repaired = (^$nu.current-exe --no-history --execute 'try { let help = (^vp help | complete); if $help.exit_code != 0 { error make {msg: $help.stderr} }; source probe.nu } catch { |err| print -e $err; exit 1 }; exit 0' | complete)
if $repaired.exit_code != 0 {
error make {msg: $"Session with the documented source line failed: ($repaired.stdout) ($repaired.stderr)"}
}
let repaired_state = ($repaired.stdout | from json)
if not $repaired_state.loaded or $repaired_state.directory != $session_dir or $repaired_state.data_home != $custom_data {
error make {msg: "The source workaround did not load Vite+ with the original XDG configuration"}
}
print "After adding source to config.nu, a fresh session loaded Vite+: true"
print "vp help succeeded in the fresh session"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
let result = (^./external/vp | complete)
if $result.exit_code != 0 or ($result.stderr | str contains "Could not configure shell profiles") {
error make {msg: $"Standalone setup failed: ($result.stdout) ($result.stderr)"}
}
{
directory: ($nu.vendor-autoload-dirs | last)
data_home: $env.XDG_DATA_HOME
} | to json --raw | print
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
directory: ($nu.vendor-autoload-dirs | last)
data_home: $env.XDG_DATA_HOME
loaded: (($env.VP_HOME | path join "bin") in $env.PATH)
} | to json --raw | print
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[[case]]
name = "command_self_setup_nushell_config_xdg_mismatch"
vp = "global"
requires = ["nu"]
skip-platforms = ["windows"]
seed-runtime = false
comment = "Issue #2491: with XDG_DATA_HOME unset in the parent and set in config.nu, installation succeeds but a fresh session does not load Vite+."
steps = [
{ argv = ["vpt", "mkdir", "external"], snapshot = false },
{ argv = ["vpt", "cp", "$VP_HOME/bin/vp", "external/vp"], snapshot = false },
{ argv = ["vpt", "chmod", "+x", "external/vp"], snapshot = false },
["nu", "--no-config-file", "assert.nu", "config"],
]

[[case]]
name = "command_self_setup_nushell_parent_xdg"
vp = "global"
requires = ["nu"]
skip-platforms = ["windows"]
seed-runtime = false
comment = "Setting XDG_DATA_HOME before Nushell starts lets new sessions load the installed snippet."
steps = [
{ argv = ["vpt", "mkdir", "external"], snapshot = false },
{ argv = ["vpt", "cp", "$VP_HOME/bin/vp", "external/vp"], snapshot = false },
{ argv = ["vpt", "chmod", "+x", "external/vp"], snapshot = false },
["nu", "--no-config-file", "assert.nu", "parent"],
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# command_self_setup_nushell_config_xdg_mismatch

Issue #2491: with XDG_DATA_HOME unset in the parent and set in config.nu, installation succeeds but a fresh session does not load Vite+.

## `vpt mkdir external`


## `vpt cp $VP_HOME/bin/vp external/vp`


## `vpt chmod +x external/vp`


## `nu --no-config-file assert.nu config`

```
Standalone setup completed and wrote vite-plus.nu
Both sessions have the configured XDG_DATA_HOME after startup: true
Installer and session directories match: false
Fresh session loaded Vite+ environment: false
After adding source to config.nu, a fresh session loaded Vite+: true
vp help succeeded in the fresh session
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# command_self_setup_nushell_parent_xdg

Setting XDG_DATA_HOME before Nushell starts lets new sessions load the installed snippet.

## `vpt mkdir external`


## `vpt cp $VP_HOME/bin/vp external/vp`


## `vpt chmod +x external/vp`


## `nu --no-config-file assert.nu parent`

```
Standalone setup completed and wrote vite-plus.nu
Both sessions have the configured XDG_DATA_HOME after startup: true
Installer and session directories match: true
Fresh session loaded Vite+ environment: true
```
14 changes: 14 additions & 0 deletions docs/guide/global-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,20 @@ Vite+ sets additional `VP_*` variables during shim dispatch and shell integratio

Vite+ also respects these standard environment variables:

#### Nushell and XDG directories

If you customize `XDG_DATA_HOME` or `XDG_CONFIG_HOME`, set them **before starting Nushell**, through your terminal application, operating system, or parent shell. This is a [Nushell startup requirement](https://www.nushell.sh/book/configuration.html#changing-default-directories); setting them only in `config.nu` or `env.nu` does not configure the running session's startup directories.

Assignments in those files still affect child processes. The Vite+ installer starts a child Nushell to locate its vendor autoload directory, so it can write `vite-plus.nu` to a directory that normal new sessions do not read. Installation can succeed while `vp` remains unavailable in those sessions.

If this happens, open your Nushell configuration with `config nu` and add a `source` line pointing to the installed Vite+ `env.nu` file. For a default fresh macOS or Linux installation without a custom `XDG_CONFIG_HOME`, use:

```nu
source ~/.config/vite-plus/env.nu
```

For a custom `XDG_CONFIG_HOME`, use the absolute path to `<XDG_CONFIG_HOME>/vite-plus/env.nu` as resolved during installation. For an installation under `VP_HOME` or an existing `~/.vite-plus` installation, use `<VP_HOME>/env.nu` or `~/.vite-plus/env.nu` instead. Replace placeholders with actual paths and quote paths containing spaces. Open a new Nushell session and run `vp help` to verify the configuration.

#### `CI`

- **Purpose**: Indicates running in CI environment
Expand Down
2 changes: 2 additions & 0 deletions docs/guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ The `vp-setup.exe` is not yet code-signed. Your browser may show a warning when

The installer scripts and `vp-setup.exe` read [environment variables](/guide/global-cli#installation-variables) such as `VP_VERSION` and `VP_HOME`.

If you use Nushell with custom XDG directories, read the [Nushell startup requirements](/guide/global-cli#nushell-and-xdg-directories) before installing.

After installation, open a new shell and run:

```bash
Expand Down
Loading