Skip to content

feat(env): apply initial use during env --use-on-cd#207

Open
Dargon789 wants to merge 6 commits intoDargon789:revert-118-revert-115-Dargon789-patch-9from
Schniz:master
Open

feat(env): apply initial use during env --use-on-cd#207
Dargon789 wants to merge 6 commits intoDargon789:revert-118-revert-115-Dargon789-patch-9from
Schniz:master

Conversation

@Dargon789
Copy link
Copy Markdown
Owner

@Dargon789 Dargon789 commented Apr 5, 2026

feat(env): apply initial use during env --use-on-cd (https://github.com/Schniz/fnm/pull/1516[)](https://github.com/Dargon789/fnm/commit/10c68cb6630be811799afdccf212a399e08bef99)

@Schniz
Schniz authored on Mar 6

Summary by Sourcery

Apply initial Node version when using fnm env --use-on-cd, improve shell hooks and installer guidance, and add support for the x64-glibc-217 architecture.

New Features:

  • Apply the directory-specific Node version immediately during fnm env --use-on-cd instead of requiring an extra fnm use call.
  • Add support for the x64-glibc-217 architecture via the --arch x64-glibc-217 flag in fnm env.

Bug Fixes:

  • Make Windows CMD --use-on-cd hooks robust for paths with spaces and drive changes.
  • Ensure zsh --use-on-cd hook de-duplicates existing hooks on re-source.
  • Avoid premature fnm use execution on shell init for fish, bash, and PowerShell hooks.

Enhancements:

  • Route informational fnm use output to stderr when invoked internally by fnm env to keep stdout clean for shell evaluation.
  • Allow cloning of configuration and directories structs to support internal reuse with modified multishell paths.
  • Adjust PATH handling for multishell shells so the correct Node path is available during internal use execution.

Build:

  • Update crate and npm package versions to 1.39.0 and add changelog and changeset entries for the new release.

CI:

  • Fix ARM installer CI by specifying matching Docker platforms for arm64 and armv7 images.

Documentation:

  • Recommend passing explicit --shell flags to fnm env in docs and installer output for better performance and reliability, and document updated usage examples for each shell.

Tests:

  • Add end-to-end tests for immediate version switching on env --use-on-cd and for re-sourcing behavior, plus unit tests for zsh and Windows CMD hook generation.

Chores:

  • Normalize YAML and shell quoting in CI and installer scripts for consistency.

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
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Apr 5, 2026

Reviewer's Guide

Implements eager application of the initial Node version during fnm env --use-on-cd, refines shell hooks and installer behavior for use-on-cd across shells (including Windows CMD and zsh), adds support for the x64-glibc-217 architecture, and updates docs, tests, CI, and versioning for the 1.39.0 release.

Sequence diagram for fnm env --use-on-cd eager initial use

sequenceDiagram
    actor User
    participant Shell
    participant FnM_env as FnM_env_command
    participant UseCmd as Use_command

    User->>Shell: start shell session
    Shell->>FnM_env: run fnm env --use-on-cd --shell <shell>
    FnM_env->>FnM_env: compute multishell_path
    FnM_env->>FnM_env: set_path_for_multishell(multishell_path)
    FnM_env->>FnM_env: config_with_multishell = config.clone().with_multishell_path(multishell_path)
    FnM_env->>FnM_env: construct Use{version=None, install_if_missing=false, silent_if_unchanged=true, info_to_stderr=true}
    FnM_env->>FnM_env: determine should_force_stderr_color
    alt should_force_stderr_color
        FnM_env->>FnM_env: colored::control::set_override(true)
    end
    FnM_env->>UseCmd: apply(config_with_multishell)
    Note over UseCmd: Reads version file in current directory
    UseCmd-->>FnM_env: Result (ignored on error)
    alt should_force_stderr_color
        FnM_env->>FnM_env: colored::control::unset_override()
    end
    FnM_env-->>Shell: shell.use_on_cd(config) script
    Shell->>Shell: install cd hook using returned script
    Shell-->>User: environment ready, directory version already active
Loading

Class diagram for updated Use, FnmConfig, Directories, and Arch

classDiagram
    class Command{
        <<interface>>
        +apply(config: FnmConfig) Result
    }

    class Use{
        +Option~UserVersionReader~ version
        +bool install_if_missing
        +bool silent_if_unchanged
        +bool info_to_stderr
        +apply(config: FnmConfig) Result
    }

    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 Directories{
        <<struct>>
        <<Clone>>
        +cache_dir() PathBuf
        +node_dist_mirror_dir() PathBuf
    }

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

    Use ..|> Command
    FnmConfig o-- Directories
    FnmConfig .. Arch
    Use ..> FnmConfig
Loading

File-Level Changes

Change Details Files
Apply the initial Node version directly during fnm env --use-on-cd instead of requiring an immediate extra fnm use subprocess from the shell hook.
  • Introduce set_path_for_multishell to prepend the multishell bin directory to PATH at runtime, handling Windows vs non-Windows paths.
  • Clone FnmConfig and add a with_multishell_path builder so fnm env can construct a config that matches the multishell instance it is emitting.
  • Instantiate and invoke an internal Use command (with version: None, install_if_missing: false, silent_if_unchanged: true, info_to_stderr: true) from Env when use_on_cd is enabled.
  • Detect when stderr (but not stdout) is a terminal and temporarily force colored output for the internal use call, then restore the color override afterward.
  • Add e2e tests to ensure that the current directory’s .node-version is respected immediately after fnm env --use-on-cd and that sourcing env twice still works.
src/commands/env.rs
src/commands/use.rs
src/config.rs
e2e/use-on-cd.test.ts
Improve robustness and correctness of shell integration for --use-on-cd, especially for zsh, fish, bash, PowerShell, and Windows CMD.
  • In zsh, ensure re-sourcing the env output doesn’t duplicate the hook by calling add-zsh-hook -D chpwd _fnm_autoload_hook before re-adding the hook, with a unit test verifying the removal call is present.
  • In fish, remove the eager _fnm_autoload_hook call from the generated hook so it only runs on actual directory changes.
  • In bash, remove the immediate __fnm_use_if_file_found call from the hook to avoid extra work on shell startup; only the cd alias remains.
  • In PowerShell, stop calling Set-FnmOnLoad eagerly so version switching occurs lazily on directory changes.
  • Update cd.cmd to use cd /d %* so drive-letter changes are handled correctly on Windows CMD, and add quoting for the doskey cd macro path (doskey cd="{path}" $*) so paths with spaces work; cover this with a unit test for WindowsCmd::use_on_cd.
  • Add tests for zsh and Windows CMD use_on_cd output to assert the correct hook and quoting behavior.
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
Refine fnm use behavior and configuration plumbing to support the new env flow and clarify user messaging.
  • Extend the Use command with an internal info_to_stderr flag (skipped by clap) to optionally route informational output to stderr instead of stdout.
  • Adjust Use::apply to choose between outln!(..., Info, ...) and outln!(..., Error, ...) depending on info_to_stderr, so that internal invocations from fnm env don’t interfere with env output.
  • Initialize info_to_stderr to false for existing install and use_installed_version call sites to preserve current behavior.
  • Clarify the interactive missing-version prompt by prefixing it with fnm, changing the message to fnm can't find an installed Node version matching ....
  • Make FnmConfig and Directories implement Clone so configuration can be copied when computing multishell-specific configs, and add FnmConfig::with_multishell_path to set the multishell path in a builder-style fashion.
src/commands/use.rs
src/commands/install.rs
src/config.rs
src/directories.rs
Update installer scripts, documentation, and CLI help to prefer explicit --shell flags and improve CI coverage for ARM.
  • Change the installer shell setup snippets to call fnm env --shell <shell> (zsh, fish, bash) instead of relying on automatic shell detection (fnm env).
  • Update CLI help text and docs (README.md, docs/commands.md) to show examples using explicit --shell flags for better performance and fewer runtime detections.
  • Fix GitHub Actions installation-script workflow to test ARM images with the correct --platform setting and to use the newer matrix structure with include entries for ARM64 and ARMv7.
  • Normalize quoting, whitespace, and job name strings in the installation-script workflow YAML.
  • Add changeset entries describing the installer explicit-shell change and the CI ARM platform fix.
.ci/install.sh
src/cli.rs
README.md
docs/commands.md
.github/workflows/installation_script.yml
.changeset/cuddly-cars-ring.md
Add support for the x64-glibc-217 architecture and bump the project version to 1.39.0 with associated release notes.
  • Extend the Arch enum with a new X64Glibc217 variant, wire it into as_str and FromStr so it maps to/from the string value x64-glibc-217.
  • Add a changeset documenting support for --arch x64-glibc-217 in fnm env.
  • Bump crate and npm package versions from 1.38.1 to 1.39.0 in Cargo.toml and package.json.
  • Update CHANGELOG.md with the 1.39.0 entry, including this PR and related feature and patch entries.
src/arch.rs
Cargo.toml
package.json
CHANGELOG.md
.changeset/brave-timers-move.md
.changeset/fair-carrots-greet.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
Copy link
Copy Markdown

snyk-io bot commented Apr 5, 2026

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 update

@mergify
Copy link
Copy Markdown

mergify bot commented Apr 5, 2026

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]

@mergify
Copy link
Copy Markdown

mergify bot commented Apr 5, 2026

⚠️ The sha of the head commit of this PR conflicts with #199. Mergify cannot evaluate rules on this PR. Once #199 is merged or closed, Mergify will resume processing this PR. ⚠️

@Dargon789
Copy link
Copy Markdown
Owner Author

bfb1860

@Dargon789 Dargon789 enabled auto-merge (squash) April 5, 2026 14:37
@Dargon789
Copy link
Copy Markdown
Owner Author

@Mergifyio refresh

@Dargon789
Copy link
Copy Markdown
Owner Author

@Mergifyio rebase

@mergify
Copy link
Copy Markdown

mergify bot commented Apr 5, 2026

refresh

✅ Pull request refreshed

@mergify
Copy link
Copy Markdown

mergify bot commented Apr 5, 2026

rebase

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

Details
  • -conflict [📌 rebase requirement]
  • -closed [📌 rebase requirement]
  • queue-position = -1 [📌 rebase requirement]
  • any of:
    • #commits-behind > 0 [📌 rebase requirement]
    • -linear-history [📌 rebase requirement]

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • In set_path_for_multishell, the unsafe block around std::env::set_var is unnecessary since set_var is safe; you can drop the unsafe to simplify the function.
  • When prepending path_for_node to PATH in set_path_for_multishell, consider skipping insertion if that path is already present to avoid unbounded PATH growth when fnm env --use-on-cd is evaluated multiple times.
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 since `set_var` is safe; you can drop the `unsafe` to simplify the function.
- When prepending `path_for_node` to `PATH` in `set_path_for_multishell`, consider skipping insertion if that path is already present to avoid unbounded PATH growth when `fnm env --use-on-cd` is evaluated multiple times.

## Individual Comments

### Comment 1
<location path="src/cli.rs" line_range="30" />
<code_context>
     /// should be evaluated by your shell to create a fnm-ready environment.
     ///
     /// Each shell has its own syntax of evaluating a dynamic expression.
-    /// For example, evaluating fnm on Bash and Zsh would look like `eval "$(fnm env)"`.
-    /// In Fish, evaluating would look like `fnm env | source`
+    /// For example, evaluating fnm on Bash and Zsh would look like `eval "$(fnm env --shell bash)"`.
+    /// In Fish, evaluating would look like `fnm env --shell fish | source`
     #[clap(name = "env", bin_name = "env")]
</code_context>
<issue_to_address>
**suggestion:** The example now uses `--shell bash` for both Bash and Zsh, which might be misleading for Zsh users.

Because `fnm env` accepts an explicit `--shell` value, Zsh users may reasonably expect to use `--shell zsh`. Showing `--shell bash` for Zsh as well can be confusing, even if it works. Please either add separate examples for Bash and Zsh or clarify in the text which `--shell` value each shell should use.
</issue_to_address>

### Comment 2
<location path=".changeset/brave-timers-move.md" line_range="5" />
<code_context>
+"fnm": patch
+---
+
+support `x64-glibc-217` arch by adding a `--arch x64-glibc-217` to fnm env
</code_context>
<issue_to_address>
**suggestion (typo):** Tighten up the grammar by adding an article before "arch" and adjusting the wording around the flag.

Consider rephrasing to: "Support the `x64-glibc-217` arch by adding `--arch x64-glibc-217` to `fnm env`." This fixes the missing article, removes the extra "a" before the flag, and formats command and flag names consistently with backticks.
</issue_to_address>

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.

Copy link
Copy Markdown

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

Choose a reason for hiding this comment

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

Code Review

This PR updates fnm to v1.39.0, introducing x64-glibc-217 support and optimizing shell startup by applying the initial Node version during 'fnm env' to eliminate extra subprocesses. It also improves shell setup scripts and fixes hook issues in Zsh and Windows CMD. Feedback recommends replacing 'unsafe' environment modifications in 'src/commands/env.rs' with a 'skip_path_check' flag in the 'Use' command to safely suppress PATH validation during internal calls.

@mergify
Copy link
Copy Markdown

mergify bot commented Apr 13, 2026

⚠️ The sha of the head commit of this PR conflicts with #199. Mergify cannot evaluate rules on this PR. Once #199 is merged or closed, Mergify will resume processing this PR. ⚠️

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.

3 participants