Skip to content

feat(env): apply initial use during env --use-on-cd (Schniz#1516) #183

Merged
Dargon789 merged 6 commits into
Dargon789:masterfrom
Schniz:master
Mar 13, 2026
Merged

feat(env): apply initial use during env --use-on-cd (Schniz#1516) #183
Dargon789 merged 6 commits into
Dargon789:masterfrom
Schniz:master

Conversation

@Dargon789

@Dargon789 Dargon789 commented Mar 13, 2026

Copy link
Copy Markdown
Owner

Summary by Sourcery

Apply the initial Node version when generating fnm env --use-on-cd to reduce shell startup overhead and improve hook behavior across shells, while adding new architecture support and updating installer, docs, and tests for the new behavior.

New Features:

  • Apply the current directory’s Node version during fnm env --use-on-cd, eliminating the need for an immediate extra fnm use subprocess on shell startup.
  • Support the x64-glibc-217 architecture via the --arch x64-glibc-217 option in fnm env.

Bug Fixes:

  • Ensure the zsh --use-on-cd hook is de-duplicated on re-sourcing the shell configuration.
  • Fix Windows CMD --use-on-cd behavior by quoting the cd macro path, handling paths with spaces, and switching drives with cd /d.
  • Correct ARM installer CI to run Docker images with the appropriate --platform setting.

Enhancements:

  • Route internal informational output from fnm use through stderr when invoked by fnm env to avoid interfering with env output.
  • Clone support on configuration and directory structs to allow safe reuse when wiring env and use behavior.
  • Clarify the interactive fnm use missing-version prompt by prefixing it with fnm so users can see which tool is requesting installation.
  • Prefer explicit --shell flags in generated shell setup and installer scripts to avoid runtime shell inference and speed up startup.
  • Refine fish, bash, and PowerShell --use-on-cd hooks so they no longer run the autoload hook immediately, relying instead on cd-triggered execution.

Build:

  • Update installation-script CI workflow quoting and add per-matrix Docker platform configuration for ARM tests.

CI:

  • Adjust the installation script workflow to use --platform with Docker for ARM images and normalize YAML quoting/style.

Documentation:

  • Document the recommendation to pass explicit --shell flags to fnm env in README and command docs, and fix minor README formatting issues.
  • Update changelog and package metadata for the 1.39.0 release, including notes on env --use-on-cd improvements and new CLI features.

Tests:

  • Add end-to-end tests validating that env --use-on-cd immediately honors the current directory version and still works after sourcing env multiple times.
  • Add unit tests to ensure the zsh hook de-duplicates existing hooks and the Windows CMD use-on-cd macro correctly quotes paths with spaces.

Chores:

  • Bump crate and npm package versions to 1.39.0.
  • Add changeset entries describing the new x64-glibc-217 arch support, installer shell flag preference, and the clarified missing-version prompt.

Schniz and others added 6 commits March 5, 2026 15:47
* fix(zsh): dedupe use-on-cd hook on re-source

* fix(wincmd): support spaces and drive switches in use-on-cd

* test(e2e): cover use-on-cd after re-sourcing env

* chore: add changeset for use-on-cd shell fixes
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: support x64-glibc-217

* add changeset

---------

Co-authored-by: Gal Schlezinger <gal@spitfire.co.il>
* fix(use): clarify interactive install prompt source

* chore: add changeset for prompt clarification
* perf(install): pin shell in generated env setup

* ci: pin docker platform for ARM installer tests

* chore: add changeset for installer shell update
@vercel

vercel Bot commented Mar 13, 2026

Copy link
Copy Markdown

@Schniz is attempting to deploy a commit to the Foundry development Team on Vercel.

A member of the Team first needs to authorize it.

@sourcery-ai

sourcery-ai Bot commented Mar 13, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implements immediate application of the current directory’s Node version when using fnm env --use-on-cd, improves shell hooks (especially zsh and Windows CMD), prefers explicit shell selection for fnm env, adds support for the x64-glibc-217 architecture, and updates CI, docs, tests, and versioning to 1.39.0.

Sequence diagram for fnm env --use-on-cd initial version application

sequenceDiagram
    actor User
    participant Shell
    participant EnvCommand
    participant UseCommand
    participant VersionFiles

    User->>Shell: run fnm env --use-on-cd --shell bash
    Shell->>EnvCommand: execute Env with use_on_cd=true
    EnvCommand->>EnvCommand: set_path_for_multishell(multishell_path)
    EnvCommand->>EnvCommand: config_with_multishell = config.clone().with_multishell_path(multishell_path)
    EnvCommand->>UseCommand: apply(config_with_multishell)
    UseCommand->>VersionFiles: read .node-version in current directory
    VersionFiles-->>UseCommand: desired Node version
    UseCommand->>UseCommand: switch Node version for multishell
    UseCommand-->>EnvCommand: Ok(()) or Error(ignored)
    EnvCommand->>Shell: print shell.use_on_cd(config) script
    Shell-->>User: evaluates env output, hook installed and initial version already active
Loading

Sequence diagram for zsh use-on-cd hook de-duplication

sequenceDiagram
    participant ZshShell
    participant EnvCommand

    ZshShell->>EnvCommand: fnm env --use-on-cd --shell zsh
    EnvCommand-->>ZshShell: script with add-zsh-hook -D chpwd _fnm_autoload_hook
    ZshShell->>ZshShell: evaluate script, remove existing _fnm_autoload_hook
    ZshShell->>ZshShell: add-zsh-hook chpwd _fnm_autoload_hook

    ZshShell->>EnvCommand: fnm env --use-on-cd --shell zsh (sourced again)
    EnvCommand-->>ZshShell: same script
    ZshShell->>ZshShell: add-zsh-hook -D chpwd _fnm_autoload_hook (de-duplicate)
    ZshShell->>ZshShell: add-zsh-hook chpwd _fnm_autoload_hook (single active hook)
Loading

Updated class diagram for Use, FnmConfig, Arch, and Directories

classDiagram
    class Use {
        +Option~UserVersion~ version
        +bool install_if_missing
        +bool silent_if_unchanged
        +bool info_to_stderr
        +apply(config: FnmConfig) Result~(), Error~
    }

    class FnmConfig {
        +Url node_dist_mirror
        +Option~PathBuf~ base_dir
        +Option~PathBuf~ multishell_path
        +with_base_dir(base_dir: Option~PathBuf~) FnmConfig
        +with_multishell_path(multishell_path: PathBuf) FnmConfig
    }

    class Arch {
        <<enum>>
        X86
        X64
        X64Musl
        X64Glibc217
        Arm64
        Armv7l
        Ppc64le
        Aarch64AppleDarwin
        +as_str() &str
        +from_str(s: &str) Result~Arch, Error~
    }

    class Directories {
        <<struct>>
        +cache_dir: PathBuf
        +data_dir: PathBuf
        +config_dir: PathBuf
        +new() Directories
    }

    Use --> FnmConfig : uses
    FnmConfig --> Directories : contains
    FnmConfig --> Arch : uses for downloads
Loading

File-Level Changes

Change Details Files
Apply initial fnm use behavior inside fnm env --use-on-cd to avoid an extra subprocess at shell startup.
  • Add set_path_for_multishell helper to prepend the multishell bin directory to PATH before running Use logic
  • Clone FnmConfig and add a with_multishell_path builder to pass the multishell path into the internal Use command
  • Construct a Use command with install_if_missing=false, silent_if_unchanged=true, and new info_to_stderr=true flag for internal use by env
  • Force colored output on stderr when stdout is not a terminal but stderr is, and restore the color override after running use
  • Silently ignore errors from the internal use call so env behaves gracefully when no version file exists
src/commands/env.rs
src/config.rs
Extend the Use command to distinguish between user-facing info and env-internal info and tweak its messaging.
  • Add info_to_stderr field on Use and mark it with #[clap(skip)] so it is not exposed as a CLI flag
  • Change Use::apply to emit info either as Info or Error log level depending on info_to_stderr
  • Update all internal constructors of Use (install and use-installed-version paths) to set info_to_stderr=false
  • Clarify interactive missing-version error message by prefixing it with fnm
src/commands/use.rs
src/commands/install.rs
.changeset/fair-carrots-greet.md
Improve and harden shell hooks for --use-on-cd, particularly for zsh, fish, bash, PowerShell, and Windows CMD.
  • Update zsh hook to de-duplicate _fnm_autoload_hook by first calling add-zsh-hook -D chpwd _fnm_autoload_hook and add a test verifying this
  • Remove eager _fnm_autoload_hook invocation from fish, bash, and PowerShell hooks so they only trigger on directory change
  • Change Windows CMD cd.cmd to cd /d %* so drive changes work, and quote cd doskey macro path to support spaces
  • Add tests ensuring the Windows CMD hook quotes paths correctly and that the zsh hook removal call is present
src/shell/zsh.rs
src/shell/fish.rs
src/shell/bash.rs
src/shell/powershell.rs
src/shell/windows_cmd/mod.rs
src/shell/windows_cmd/cd.cmd
Add new behavior tests to validate immediate use-on-cd behavior and repeated env sourcing.
  • Add e2e test asserting that fnm env --use-on-cd immediately uses the current directory’s .node-version on env setup
  • Add e2e test ensuring that sourcing fnm env --use-on-cd twice still correctly switches versions on cd into a subdirectory
e2e/use-on-cd.test.ts
Prefer explicit --shell flags with fnm env and adjust installer script, CLI help, and docs accordingly.
  • Change installer script to call fnm env --shell zsh, fnm env --shell fish, and fnm env --shell bash instead of relying on shell inference
  • Update CLI help text, commands docs, and README examples to recommend fnm env --shell <shell>
  • Document the new recommendation with a tip explaining that explicit shell avoids runtime detection overhead
  • Record this behavior change in a changeset entry
.ci/install.sh
src/cli.rs
docs/commands.md
README.md
.changeset/cuddly-cars-ring.md
Support the x64-glibc-217 architecture and expose it via --arch.
  • Extend Arch enum with X64Glibc217 variant and map it to x64-glibc-217 in display and parsing logic
  • Add a changeset describing support for --arch x64-glibc-217 in fnm env
src/arch.rs
.changeset/brave-timers-move.md
Update CI installation workflow to correctly test ARM images and tidy YAML formatting/quoting.
  • Switch ARM installation workflow matrix to use include entries with an explicit docker_platform field
  • Pass --platform ${{ matrix.docker_platform }} to Docker run invocations
  • Normalize YAML spacing and quoting for script arguments and job names
.github/workflows/installation_script.yml
Versioning and structural tweaks to support cloning of configuration and directories and release metadata.
  • Derive Clone for FnmConfig and Directories so configs can be cloned when passing modified variants
  • Bump crate and npm package versions from 1.38.1 to 1.39.0 and add 1.39.0 release notes to the changelog
  • Remove obsolete changeset files now captured in the CHANGELOG
src/config.rs
src/directories.rs
Cargo.toml
package.json
CHANGELOG.md
.changeset/grumpy-dingos-turn.md
.changeset/odd-mayflies-poke.md
.changeset/twelve-badgers-happen.md

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@snyk-io

snyk-io Bot commented Mar 13, 2026

Copy link
Copy Markdown

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@Dargon789

Copy link
Copy Markdown
Owner Author

@Mergifyio refresh

1 similar comment
@Dargon789

Copy link
Copy Markdown
Owner Author

@Mergifyio refresh

@Dargon789

Copy link
Copy Markdown
Owner Author

@Mergifyio update

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the fnm Node.js version manager by optimizing the env --use-on-cd feature for faster shell startup and improved robustness across various shell environments. It also introduces support for a new architecture, refines user prompts, and updates internal dependencies, contributing to a more performant and reliable experience.

Highlights

  • Performance Optimization: Reduced shell startup overhead for env --use-on-cd by applying the initial Node.js version directly during fnm env execution, eliminating an extra subprocess call.
  • Shell Hook Robustness: Improved use-on-cd shell hooks for zsh (de-duplication on re-source) and Windows CMD (handling paths with spaces and drive changes).
  • User Experience: Updated shell setup scripts and documentation to recommend explicit --shell flags for fnm env for better performance and reliability, and clarified the interactive fnm use missing-version prompt.
  • Architecture Support: Added support for the x64-glibc-217 architecture.
  • Dependency Updates: Bumped fnm to version 1.39.0 and updated the Rust toolchain to 1.88.
Changelog
  • .changeset/brave-timers-move.md
    • support x64-glibc-217 arch by adding a --arch x64-glibc-217 to fnm env
  • .changeset/cuddly-cars-ring.md
    • prefer explicit shell flags in installer-generated shell setup and fix ARM installer CI platform selection
  • .changeset/fair-carrots-greet.md
    • Clarify the interactive fnm use missing-version prompt by prefixing the message with fnm so it is obvious which tool is asking to install Node.
  • CHANGELOG.md
    • Updated to version 1.39.0, including minor changes for env --use-on-cd optimization and install --use flag, and patch changes for fnm default behavior, use-on-cd hook robustness, and Rust toolchain update.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/installation_script.yml
Activity
  • This is a new pull request, no activity has been recorded yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@mergify

mergify Bot commented Mar 13, 2026

Copy link
Copy Markdown

refresh

☑️ Command refresh ignored because it is already running from a previous command.

@mergify

mergify Bot commented Mar 13, 2026

Copy link
Copy Markdown

refresh

✅ Pull request refreshed

@mergify

mergify Bot commented Mar 13, 2026

Copy link
Copy Markdown

update

☑️ Nothing to do, the required conditions are not met

Details
  • -conflict [📌 update requirement]
  • #commits-behind > 0 [📌 update requirement]
  • -closed [📌 update requirement]
  • queue-position = -1 [📌 update requirement]

@vercel

vercel Bot commented Mar 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
fnm Ready Ready Preview, Comment Mar 13, 2026 0:17am

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In set_path_for_multishell, the unsafe block around std::env::set_var is unnecessary and could be removed to avoid implying special invariants where none are required.
  • set_path_for_multishell always unconditionally prepends the multishell path to PATH; if this function is ever called more than once in a process, it will grow duplicate entries, so consider checking for and avoiding re-adding an existing entry.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `set_path_for_multishell`, the `unsafe` block around `std::env::set_var` is unnecessary and could be removed to avoid implying special invariants where none are required.
- `set_path_for_multishell` always unconditionally prepends the multishell path to `PATH`; if this function is ever called more than once in a process, it will grow duplicate entries, so consider checking for and avoiding re-adding an existing entry.

Fix all in Cursor


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a significant performance optimization for fnm env --use-on-cd by applying the initial Node.js version directly within the env command, which avoids spawning an extra fnm use subprocess. The changes also include support for the x64-glibc-217 architecture, several fixes for shell hooks in zsh and Windows CMD to improve robustness, and corresponding updates to documentation and tests. Overall, the changes are well-structured and beneficial. However, I have a significant concern regarding the use of an unsafe block to modify the PATH environment variable, as this is not thread-safe and could lead to undefined behavior in a multi-threaded context. I've left a specific comment detailing this issue and suggesting a safer alternative.

Comment thread src/commands/env.rs
@Dargon789 Dargon789 enabled auto-merge (squash) March 13, 2026 12:22
@Dargon789 Dargon789 merged commit b09eb83 into Dargon789:master Mar 13, 2026
6 of 9 checks passed
@Dargon789

Copy link
Copy Markdown
Owner Author

@Mergifyio refresh

@mergify

mergify Bot commented Mar 13, 2026

Copy link
Copy Markdown

refresh

✅ Pull request refreshed

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.

e2e Linux tests using static binary artifact

3 participants