Skip to content

perf(shell): lazy-init version managers and cache op completion - #24

Merged
lgw4 merged 6 commits into
mainfrom
perf/shell-startup-optimizations
May 31, 2026
Merged

perf(shell): lazy-init version managers and cache op completion#24
lgw4 merged 6 commits into
mainfrom
perf/shell-startup-optimizations

Conversation

@lgw4

@lgw4 lgw4 commented May 31, 2026

Copy link
Copy Markdown
Owner

Summary

  • Lazy-init nodenv, rbenv, goenv in both bash and fish: the shell function for each manager is a lightweight placeholder that runs init on first explicit invocation, deferring all subprocess cost to when it's actually needed. *ENV_ROOT is set via default-value expansion (${RBENV_ROOT:-$HOME/.rbenv} in bash, set -q RBENV_ROOT; or set -x … in fish) so the variable always expands to a well-formed path. Shims are then added to PATH eagerly — but only when the shims directory exists — so managed runtimes resolve immediately without a subprocess and no bogus path entries are added on a fresh install before any versions have been installed.
  • Cache op completion fish to ~/.config/fish/completions/op.fish and regenerate only when the op binary is newer than the cache, eliminating a subprocess on every interactive fish shell start; output is written to a temp file and moved into place only on success to avoid leaving a broken cache if generation fails or is interrupted
  • Pass explicit shell name to brew shellenv (brew shellenv bash / brew shellenv fish) in both bash and fish configs; remove redundant Intel-Mac Homebrew fallback from bashrc

Test plan

  • Open a new bash shell and confirm node, ruby, and go resolve to the correct nodenv/rbenv/goenv-managed versions
  • Run nodenv version, rbenv version, and goenv version to confirm lazy init fires correctly on first use
  • Open a new fish shell and confirm the same for fish
  • Tab-complete an op subcommand and confirm completions work; verify ~/.config/fish/completions/op.fish was created
  • Confirm brew shellenv still sets HOMEBREW_PREFIX correctly in both shells

🤖 Generated with Claude Code

Defer nodenv, rbenv, and goenv shell initialization to first use in
both bash and fish. Shims remain on PATH eagerly so managed runtimes
resolve immediately without spawning a subprocess at startup. The shell
function for each manager is a placeholder that runs the real init on
first invocation.

Cache `op completion fish` output to disk and regenerate only when the
op binary is newer than the cached file, avoiding a subprocess on
every interactive shell start.

Also pass an explicit shell name to `brew shellenv` in bash and fish,
and remove the now-redundant Intel-Mac Homebrew fallback from bashrc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 31, 2026 04:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR improves shell startup performance by deferring version manager initialization and caching generated 1Password CLI fish completions while preserving runtime shim availability.

Changes:

  • Lazy-initializes nodenv, rbenv, and goenv in bash and fish while eagerly adding shims to PATH.
  • Caches op completion fish output under fish completions.
  • Passes explicit shell names to brew shellenv.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
private_dot_config/private_fish/private_conf.d/private_20-config-op.fish.tmpl Adds cached op fish completion generation.
private_dot_config/private_fish/private_conf.d/private_00-path-ruby.fish.tmpl Defers fish rbenv initialization until first use.
private_dot_config/private_fish/private_conf.d/private_00-path-node.fish.tmpl Defers fish nodenv initialization until first use.
private_dot_config/private_fish/private_conf.d/private_00-path-golang.fish.tmpl Defers fish goenv initialization until first use.
private_dot_config/private_fish/private_conf.d/private_00-path-base.fish.tmpl Calls brew shellenv with explicit fish shell.
private_dot_bashrc.d/private_tools/private_ruby.bash.tmpl Defers bash rbenv initialization until first use.
private_dot_bashrc.d/private_tools/private_node.bash.tmpl Defers bash nodenv initialization until first use.
private_dot_bashrc.d/private_tools/private_golang.bash.tmpl Defers bash goenv initialization until first use.
private_dot_bashrc Calls brew shellenv with explicit bash shell and changes Homebrew fallback handling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread private_dot_bashrc

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Comment thread private_dot_config/private_fish/private_conf.d/private_20-config-op.fish.tmpl Outdated
Comment thread private_dot_bashrc.d/private_tools/private_ruby.bash.tmpl Outdated
Comment thread private_dot_bashrc.d/private_tools/private_node.bash.tmpl Outdated
Avoid truncating the cached op.fish before generation succeeds.
Write to a mktemp file and mv into place only on success; clean up
the temp file on failure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.

Comment thread private_dot_bashrc.d/private_tools/private_ruby.bash.tmpl Outdated
Comment thread private_dot_bashrc.d/private_tools/private_node.bash.tmpl Outdated
Comment thread private_dot_bashrc.d/private_tools/private_golang.bash.tmpl Outdated
Comment thread private_dot_config/private_fish/private_conf.d/private_00-path-ruby.fish.tmpl Outdated
Comment thread private_dot_config/private_fish/private_conf.d/private_00-path-node.fish.tmpl Outdated
Comment thread private_dot_config/private_fish/private_conf.d/private_00-path-golang.fish.tmpl Outdated
When a version manager is installed via Homebrew without a user root
directory, *ENV_ROOT may be unset, causing "$NODENV_ROOT/shims" etc.
to expand to "/shims" and prepend a bogus entry to PATH. Guard the
fish_add_path/path_prepend call in all three version managers (bash
and fish) so shims are only added when the variable is set and the
directory exists.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

Replace the directory-existence check with an unconditional default:
  export RBENV_ROOT="${RBENV_ROOT:-$HOME/.rbenv}"   # bash
  set -q RBENV_ROOT; or set -x RBENV_ROOT $HOME/.rbenv  # fish

*ENV_ROOT is now always set to a well-formed path before the shims
entry is added to PATH, so the tool being Homebrew-installed without
an explicit root directory can no longer produce a bogus /shims entry.
The directory-existence guard introduced in the previous commit is
removed as it is no longer necessary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Comment thread private_dot_bashrc.d/private_tools/private_ruby.bash.tmpl Outdated
Comment thread private_dot_bashrc.d/private_tools/private_node.bash.tmpl Outdated
Comment thread private_dot_bashrc.d/private_tools/private_golang.bash.tmpl Outdated
*ENV_ROOT now always expands to a well-formed path, but the shims
directory itself may not exist when the tool is installed but no
versions have been installed yet. Add -d guards to path_prepend/
fish_add_path calls in all three version managers (bash and fish)
to match the pattern used for other conditional path entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.

@lgw4
lgw4 merged commit 79cc9f0 into main May 31, 2026
1 check passed
@lgw4
lgw4 deleted the perf/shell-startup-optimizations branch May 31, 2026 05:32
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.

2 participants