Skip to content

fix(env): call fish built-ins with builtin in env.fish - #3353

Merged
fengmk2 merged 4 commits into
voidzero-dev:mainfrom
naokihaba:fix/fish-builtin-commands
Nov 5, 2026
Merged

fengmk2 merged 4 commits into
voidzero-dev:mainfrom
naokihaba:fix/fish-builtin-commands

Conversation

@naokihaba

Copy link
Copy Markdown
Collaborator

Context

When a user defines a fish function with the name of a built-in, env.fish calls the user function instead of the built-in. With a user count function, vp env use reports success, but the Node.js version does not change.

The fish documentation for function warns about this case. It says that a function with the name of a built-in often causes problems "in scripts written by others". env.fish is such a script.

This PR adds builtin to each built-in that env.fish calls: count, math, contains, complete, commandline, and source. builtin skips functions and runs only the built-in. #3123 did the same for Nushell with the % sigil.

This PR does not change the vp completion. clap_complete registers it with bare complete and commandline, so env.fish cannot protect it. fish's own completions also call bare commandline.

# fish 4.9.3, vp built from 09961cfa5
# $R is a temporary VP_HOME. A line that starts with > is a command. [exit N] is the exit status of the command above it.

$ VP_HOME=$R VP_SELF_SETUP_NO_MODIFY_PATH=1 ./target/debug/vp env setup --refresh
[exit 0]
$ sed 's/builtin //g' $R/env.fish > $R/env-old.fish
$ diff $R/env-old.fish $R/env.fish | grep -c '^>'
14

## env-old.fish
> function count; echo 0; end
[exit 0]
> source env-old.fish
[exit 0]
> set -gx VP_NODE_VERSION 18.20.0
[exit 0]
> vp env use 20.20.2
Installing Node.js v20.20.2...
Using Node.js v20.20.2 (resolved from 20.20.2)
[exit 0]
> echo VP_NODE_VERSION=$VP_NODE_VERSION
VP_NODE_VERSION=18.20.0
[exit 0]
> node --version
v18.20.0
[exit 0]

## env.fish
> function count; echo 0; end
[exit 0]
> source env.fish
[exit 0]
> set -gx VP_NODE_VERSION 18.20.0
[exit 0]
> vp env use 20.20.2
Using Node.js v20.20.2 (resolved from 20.20.2)
[exit 0]
> echo VP_NODE_VERSION=$VP_NODE_VERSION
VP_NODE_VERSION=20.20.2
[exit 0]
> node --version
v20.20.2
[exit 0]

User functions named like fish built-ins replaced them in env.fish.
A user count function made vp env use report success without setting
VP_NODE_VERSION.

Closes voidzero-dev#3128
@naokihaba naokihaba self-assigned this Nov 4, 2026
@naokihaba

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-04T15:04:02.507618Z 09961cf Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 09961cfa54

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@naokihaba
naokihaba marked this pull request as ready for review November 4, 2026 15:41
@naokihaba
naokihaba requested review from fengmk2 and nekomoyi and removed request for nekomoyi November 4, 2026 15:41
@naokihaba

Copy link
Copy Markdown
Collaborator Author

Maybe we should wait for #3354 to be merged first and then do a final check on this PR just to be safe.

@naokihaba

Copy link
Copy Markdown
Collaborator Author

I merged main into this branch to get #3354, and then checked commit aa317daba on macOS with fish 4.9.3.

All 3 command_env_fish snapshot cases pass: setup, use, and shadowed_builtins. The 2 unit tests from #3354 also pass: test_parse_task_completion_lines and test_sanitize_task_current_prefix.

I also ran a manual check with the debug vp two times. The first run had no user functions. The second run had user functions that shadow count, math, contains, and source, as in #3128. The two runs gave the same result:

  • env.fish loads without errors.
  • vp env use and vp -C . env use set VP_NODE_VERSION, and vp env use --help does not change it.
  • The vpr completion does not show the comment keys // and # Scripts for docs #.
  • Each vpr completion candidate shows its task command as the description.
  • The input test\:u matches test:unit.
  • env.fish does not replace the user's count function.
$ builtin source <tmp>/env.fish
  -> status=0
$ vp env use 20.20.2 --no-install
Using Node.js v20.20.2 (resolved from 20.20.2)
  -> status=0
  VP_NODE_VERSION=20.20.2
$ vp env use --help >/dev/null
  -> status=0
  VP_NODE_VERSION=20.20.2 (expected: unchanged)
$ vp -C . env use 22.23.4 --no-install
Using Node.js v22.23.4 (resolved from 22.23.4)
  -> status=0
  VP_NODE_VERSION=22.23.4
$ complete -C 'vpr '
  build      vite build
  test:e2e   playwright test
  test:unit  vitest run
$ complete -C 'vpr test\:u'
  test:unit  vitest run
$ count a b c
  0

@fengmk2
fengmk2 merged commit fc9d5ba into voidzero-dev:main Nov 5, 2026
78 checks passed
@fengmk2 fengmk2 mentioned this pull request Nov 9, 2026
fengmk2 added a commit that referenced this pull request Nov 9, 2026
Vite+ 1.5.1 checks managed package-manager downloads against the
integrity hash in `packageManager`, restores interactive input in `vp
run` tasks, fixes `vp migrate` config merges, and adds a reference page
for each package command.

### Features

- Vite+ checks a downloaded pnpm, Yarn 2+, or bun against the integrity
hash in the project's `packageManager` field instead of the hash that
the registry reports, and rejects a download that does not match.
Mirrors and private registries that serve the same package still pass.
Each pinned version gets its own cache directory, so a project with a
pinned package manager downloads it once more after the upgrade.
Unpinned installs keep their current location
([#3400](#3400)), by
@fengmk2 and @arkmarta.
- Upgrade the bundled Vite and Rolldown
([#3390](#3390)), by
@voidzero-guard[bot] and @fengmk2:
- `vite@8.3.5` to `vite@8.3.7`. A pnpm install no longer turns every
cached build into a cache miss, because Vite tells Vite Task to ignore
`node_modules/.modules.yaml`. It also fixes named imports from Node.js
built-ins and reloads in bundled dev mode, subpath imports (`#`) in the
dependency optimizer, SSR builds with `build.ssr: true`, and chunks
shared with workers.
- `rolldown@1.2.16` to `rolldown@1.2.18`, with module source maps that
keep only the sources and names that they trace.
- `@voidzero-dev/vite-plus-core` requires `postcss@^8.5.32`, as the
bundled Vite does.

### Fixes & Enhancements

- Scripts that `vp run` starts get a blocking stdin again when the `run`
block of `vite.config.ts` is not statically analyzable (for example, a
task command held in a constant), so interactive prompts such as `vp
update --interactive` wait for input instead of failing with `EAGAIN`
([#3361](#3361)), by
@everton-dgn.
- `vp migrate` changes only the `return` statements of a `defineConfig`
callback, so functions inside the config, such as Rolldown
`codeSplitting.groups[].name` callbacks, keep their return values and
the build no longer fails. When a callback return cannot receive the
merged settings, migration keeps the standalone config files and asks
for a manual merge. Pack and task cache migration also recognize configs
wrapped in parentheses, `as`, `satisfies`, `<T>`, or `!`
([#3325](#3325),
[#3372](#3372)), by
@jong-kyung.
- `vp create react-router` passes `--no-git-init` to
`create-react-router`, so the generator's initial commit no longer stops
the Vite+ setup when no Git identity is configured
([#3363](#3363)), by
@chbaefront.
- `env.fish` calls fish built-ins through `builtin`, so `vp env use`
changes the Node.js version even when a user function has the name of a
built-in such as `count`
([#3353](#3353)), by
@naokihaba.
- Shell completion suggests full command names before aliases, so `vp
i<Tab>` offers `install` and `vp up<Tab>` offers `update`. An alias
stays available when no full name matches
([#3337](#3337)), by
@nekomoyi.
- Completion for `vp run` and `vpr` skips comment keys such as `"# docs
#"` in `package.json` scripts, matches task names that contain `:`, and
shows each task's command as its description in Zsh and Fish
([#3354](#3354)), by
@nekomoyi.
- `vp pm dist-tag rm` works with Yarn Berry, because Vite+ passes
`remove` to `yarn npm tag`
([#3358](#3358)), by
@jong-kyung.
- A package-manager version that resolves through a dist-tag, such as
`pnpm@latest` in `vp env use`, must be a valid semver version. Vite+
rejects any other registry reply with an error, including a version with
surrounding whitespace
([#3395](#3395)), by
@fengmk2 and @arkmarta.

### Docs

- Add a Package Management section to the guide, with a reference page
for each of the 38 package commands that lists its options,
package-manager support, version requirements, and npm fallbacks. Help
output for package commands and the old package management and install
URLs point to the new pages
([docs](https://viteplus.dev/guide/package-management/))
([#3105](#3105)), by
@jong-kyung.
- Show the README logo that matches the GitHub theme, so the logo stays
visible after a theme change
([#3350](#3350)), by
@fengmk2.

### Chore

- Build Linux native bindings against the napi-cross glibc 2.17 sysroot
with `@napi-rs/cli@3.10.12`, let the linker reject unresolved symbols,
and run Linux CI on `ubuntu-latest` again. Let the dependency upgrade
workflow change workflow files
([#3349](#3349),
[#3384](#3384)), by
@fengmk2.
- Refine contributor guidance: `AGENTS.md` separates the `vite-plus`
package from the global `vp` CLI and replaces `CLAUDE.md`, and the
Node.js version RFCs describe `.nvmrc` support
([#3388](#3388),
[#3383](#3383)), by
@liangmiQwQ and @hyunbinseo.
- Resolve the docs theme aliases from `import.meta.dirname`, so the docs
dev server no longer warns about `__dirname`
([#3379](#3379)), by
@liangmiQwQ.
- Fold the `.node-version` parse tests into one table
([#3355](#3355)), by
@Brooooooklyn.

### Bundled Versions

| Tool | Version | Source | Changelog |
| --------------- | ---------- |
----------------------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------------------------------------------------
|
| vite | `8.3.7` |
[`5def936`](vitejs/vite@5def936)
| [8.3.6](https://github.com/vitejs/vite/releases/tag/v8.3.6),
[8.3.7](https://github.com/vitejs/vite/releases/tag/v8.3.7) |
| rolldown | `1.2.18` |
[`f9a49d6`](rolldown/rolldown@f9a49d6)
| [1.2.18](https://github.com/rolldown/rolldown/releases/tag/v1.2.18) |
| oxc-node | `1.0.1` |
[`7ff14c3`](oxc-project/oxc-node@7ff14c3)
| unchanged |
| tsdown | `0.23.4` | [npm](https://npmx.dev/package/tsdown/v/0.23.4) |
unchanged |
| vitest | `5.1.0` | [npm](https://npmx.dev/package/vitest/v/5.1.0) |
unchanged |
| oxlint | `1.91.0` | [npm](https://npmx.dev/package/oxlint/v/1.91.0) |
unchanged |
| oxlint-tsgolint | `7.0.2005` |
[npm](https://npmx.dev/package/oxlint-tsgolint/v/7.0.2005) | unchanged |
| oxfmt | `0.76.0` | [npm](https://npmx.dev/package/oxfmt/v/0.76.0) |
unchanged |

### Upgrade

```bash
vp upgrade
```

### New Contributors

@chbaefront, @everton-dgn

**Full Changelog**:
v1.5.0...v1.5.1

---

Merging this PR will trigger the release workflow.

---------

Co-authored-by: voidzero-guard[bot] <278573678+voidzero-guard[bot]@users.noreply.github.com>
Co-authored-by: MK (fengmk2) <fengmk2@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

User fish functions named like built-ins break the vp wrapper and vpr completion in env.fish

3 participants