-
Notifications
You must be signed in to change notification settings - Fork 631
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to disable direnv automatic loading of environments in the current shell? #550
Comments
A In a project, I currently offer a way to enter a combined nix environment so that the user can load his ide (vscode) from this environment and work on multiple projects (this environment can be optionally loaded via direnv). However, when a terminal is opened in some of these folders, direnv breaks the combined environment / needlessly takes time to load an environment that is already available through the combined nix env. In this particular case, I would like to be able to deny / prevent direnv from automatically loading the environment but only for the projects that are part of the combined environment. That is so that the user can still get the advantages of direnv for any other projects. |
Note that you can implement these things yourself in your ${DIRENV_DISABLE:+exit} This will basically treat any current (Note: if you want to re-enable .envrc loading for the current directory, you may have to explicitly |
@pjeby : Thanks for this trick, it is indeed working fine, and a nice think to know. However, I feel like this should be shipped with direnv by default. This works fine for me, however, as this is some custom local direnv lib, I cannot assume it will be the case for my teammates, contributors so I cannot rely on this, say for example if I want to implement for example a nix shell hook that will prevent direnv from loading when I explicitly entered the nix env from via nix instead of direnv. It will only work for me but not my teammate, unless I can force them to install my lib. |
I'm confused. If you want to disable direnv in a shell whose environment you control, why not just redefine or unset the hook function for that shell? As long as you do so before the first prompt is reached in that shell, that would disable it. In the case of e.g. bash, setting |
Sorry for the confusion. Just coming back to the following previous example: #550 (comment). In this previous example, I only want to disable a select set of direnv directory whose environments are already merged in the top level combined environment. The lib above trick would effectively allow me to do this were it possible to make it available to my coworkers (for example through an env specifiying common libs). Outside of this example, I certainly do not want to completely prevent my teammate's bashrc from being executed as this encode some of his personal preferences. |
Then can't you write the .envrc files to not do expensive things if they're "already merged"? This discussion is still way too abstract for me, as it's unclear who owns what files. (Also, I didn't say not to run .bashrc; I was just noting that as long as you can run code after .bashrc but before a prompt, you can disable direnv by removing it from (Also, to be clear, I am not arguing against having the ability to disable direnv; just trying to suggest possible workarounds in the meantime.) |
@pjeby: I'm in the context of the Now assuming the following simplified tree where .
├── shell.nix
├── .envrc
├── subdep1
│ ├──shell.nix
│ └── .envrc
└── subdep2
├──shell.nix
└── .envrc Dev is doing: $ cd mytoplevelproject
# direnv loading ./.envrc
$ launch-my-ide Now, when inside the ide (which does have a shell), or when directly in the shell, $ cd ./subdep1
# Dir env does not load `.envrc, and ideally does not report an error when .envrc is now allowed.
$ cd -
$ cd ./subdep2
# Dir env does not load `.envrc`, and ideally does not report an error when .envrc is now allowed. Indeed those are really nice workaround going well beyond my personal shell internals experience 😉. Will keep those in my toolbox and take some time to decant this new knowledge to see if I can effectively apply it as a workaround. |
A more general use case for this is when you have things that you want to run in multiple directories, but temporarily don't want the current environment overridden by .envrc when using cd. While it's certainly possible to write a shell script that doesn't hook direnv, or use an alternate shell rc file, this can be burdensome if you just want to do something like: export DIRENV_DISABLE=1
for dir in some_glob*; do
cd "$dir"
:
done
unset DIRENV_DISABLE to execute some set of commands without triggering direnv for the lifetime of the loop. I'm actually trying to do something along those lines myself, and ran across this feature request. I would really love to have a way to temporarily unload or disable direnv from the shell, without having to load a completely different shell configuration to do so. |
Is there is specific version I need to use for this. I am on
I exported the variable, but direnv still seems to be doing the load and unload part.
|
@nikhilkalige This isn't actually a current feature. My example was essentially pseudo-code based on other comments earlier in the thread. As of today, there is no obvious facility for temporarily (or permanently) unhooking direnv execution other than starting a new shell without direnv loaded, or deleting all its related functions from your current shell. One comment provided a potential Bash-centric solution for ignoring .envrc files when triggered, but I personally couldn't get it to work in either Bash or Fish (the latter being my preferred shell). Your mileage may vary. |
What I usually do if I want to disable direnv in a single bash shell (for testing): Look at |
I haven't tried this yet, but will test it. If it can be Fish-ified (considering global, universal, et al. variables), then I think this is a reasonable thing to do. Thanks for the suggestion; I'll let you know if it works for me. |
Basically
It's only almost 5K chars, which means I would be very upset loosing all functionality I use by its mean.
(most probably
Hope this helps. |
@todd-a-jacobs For fish, I think it's:
Both for the bash and fish solution, the commands are entered in the current shell. To restore direnv, exit and re-create a new shell. This is a solution for temporary testing, not a generic solution. |
@zimbatm Does this actually restore the environment first, or does it simply (as seems to me) erase the functions from the environment? It's serviceable either way, but if the latter then one has to be careful to restore the desired environment before disabling the functions, or you may still end up with a polluted environment. Restoring direnv should be as simple as calling |
Time is limited for everybody, unfortunately. If somebody wants to tackle this problem in a PR, I'm happy to review it. Maybe start with a prototype so we can agree on the design before making the whole thing. |
+1 |
I have run into this problem as well. I've solved this with the following little shell function for zsh, if anyone might find it useful: source $(direnv hook zsh)
direnv-toggle() {
if [ -z "${DIRENV_DISABLE:-}" ]; then
unset -f _direnv_hook
export DIRENV_DISABLE=1
else
unset DIRENV_DISABLE
source $(direnv_hook_zsh)
fi
} Would be great if direnv would respect the DIRENV_DISABLE environment variable out of the box though. I mean, I DO want the polluted environment (eg. set the environment with |
I cannot find any environment variable for doing this. I know that I can specifically deny a specific env from loading but that implies mutations of the configuration which I do not want to change my direnv configuration.
I would have expected something like:
I tried something like this in my
~/.bashrc
:however, I cannot disable it temporarily as follow:
I feel that there should be 2 possibilities:
DIRENV_DISABLE
to disable to whole hook (no printing that the env is denied and that one can allow it) and another var such asDIRENV_DENY_ALL
which would have the same effect as if all env were denied.The text was updated successfully, but these errors were encountered: