Repository navigation
fix: re-assert Hermit env after shell startup files - #631
Merged
Merged
Conversation
Hermit can activate before the user's startup files run: zsh hooks may live in /etc/zshrc, fish hooks run from conf.d before config.fish, and a child bash inherits Hermit's variables without its functions. Those files can then override the environment (eg. RVM prepending to PATH). zsh already re-asserted PATH at the first prompt, but only for bin and HERMIT_PREPEND_PATH, so it moved bin ahead of package PATH entries and the final order differed from a fresh activation. It also ignored every other variable. Add `hermit env --reassert-from-ops`, which reverts and then re-applies HERMIT_ENV_OPS. Reverting first makes values set by startup files the ones deactivation restores. zsh and fish run it once at the first prompt. Bash re-activates at the prompt when it inherited an environment but lacks deactivate-hermit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hermit can activate an environment before the user's own startup files run, and those files can then override it. For example, RVM prepending to
PATHshadows Hermit's tools. This happens in three ways:/etc/zshrc, which runs before~/.zshrc.conf.d/hermit.fish, which fish runs before laterconf.dsnippets and beforeconfig.fish..bashrcruns. The child also has nodeactivate-hermit.zsh already had a one-shot first-prompt hook (#594), but it rebuilt the front of
PATHfrom onlyHERMIT_PREPEND_PATHandbin. That movedbinahead of packagePATHentries and the link farm. So a freshly activated shell ended up with a differentPATHorder from one re-activated byupdate_hermit_env. The hook also ignored every variable other thanPATH.The approach:
hermit env --reassert-from-ops=OPSrevertsHERMIT_ENV_OPSagainst the current environment and then applies it again. It has none of the activation side effects, such as triggers, channel update checks or link farm creation. Because the ops are idempotent, this restores every Hermit-managed variable in activation order. Reverting first means values set by startup files become what deactivation restores.reassert_hermit_envinactivate.tmpl.sh) and fish (activate.tmpl.fish) run it once at the first prompt. Their deactivation removes the hook.restore_hermit_envahead ofchange_hermit_envinPROMPT_COMMAND. It fires only when an environment is inherited butdeactivate-hermitis missing. It then reverts the inherited ops and re-sourcesactivate-hermit. Bash hooks already activate at the prompt, after startup files, so bash needs no separate first-prompt step.Tradeoff: each new zsh and fish shell now starts one Hermit process at its first prompt. The old zsh hook was pure shell.
Known gap: a child fish shell has the same inherited-functions problem as bash did. This PR does not fix it.
Tests:
ZshReassertsPackageEnvironmentAtFirstPromptandTestFishReassertsEnvironmentAtFirstPromptcheck that a packagePATHentry and a non-PATHvariable are re-asserted after simulated startup changes. They check the full HermitPATHprefix order, and that deactivation restores the startup values.BashChildShellRestoresEnvironmentAtPromptcovers the bash child shell under both bash and zsh parents.🤖 Generated with Claude Code