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.
This pull request improves integration with both Anaconda and its anorexic sibling Miniconda, fixing #377 and making Babun Python users squeal with kiddish glee. (You're out there. I know you are.)
What's the Problem, Bro?
Read issue #377 first, bro. High-level synopsis + fuzzy details = eureka moment.
No, Really. What's the Problem?
pact
-installed packages take precedence overconda
-installed packages under Babun's defaultbash
andoh-my-zsh
environments. That's a problem, effectively nullifying Anaconda and Miniconda out of the box.So. Like, What's Your Solution?
First, a real-world example. The
pact
-managed path/usr/bin
precedes theconda
-managed path/cygdrive/c/Miniconda3
under default installations of both Babun and Miniconda3:Ideally, Miniconda3 users want that to instead resemble:
To effect that, this pull request adds a new user-configurable
${PRIORITIZE_CONDA_PACKAGES}
boolean. When manually uncommented in~/.babunrc
, this boolean instructs Babun startup to juggle the${PATH}
such thatconda
-installed packages take precedence overpact
-installed packages. For end user sanity, this boolean is disabled by default in/usr/local/etc/babun.rc
. For portability, this boolean has been implemented at the plugin level and exhaustively tested as working under bothbash
andoh-my-zsh
.What Could Possibly Go Wrong?
Plenty:
bash
has no analogue tozsh
's standard${path}
list.zsh
implicitly splits the colon-delimited${PATH}
string into the${path}
list, each item of which is a directory in${PATH}
(in the same order). Changes to one are immediately reflected in the other, trivializing${PATH}
juggling.bash
has nothing like that. Inbash
,${PATH}
juggling requires:${PATH}
on colons into a${path}
-like list. (Hint: it sucks.)${PATH}
. (Yup! This sucks, too.)oh-my-zsh
's default~/.zshrc
prepends${PATH}
with/usr/local/bin
after all Babun startup scripts and plugins have been run. Like/usr/bin
,/usr/local/bin
is apact
-managed path containing copies ofpact
-installed packages – includingpython
. Since this happens after Babun has had its say, the default~/.zshrc
overrides any attempt by Babun to prepend${PATH}
with aconda
-managed path containingconda
-installed packages – again, includingpython
. (This is me ineffectually shaking my broken keyboard at the sky.)bash
process forked specifically for that plugin. That's usually what we want. We don't want plugins of dubious reliability taking down the entire Babun startup (e.g., due to some external command returning non-zero exit status underset -e
strictness). That would be terrible, right? On occasion, however, we do actually need to source a plugin in the current shell process – and we swear we'll be careful about it! This is that occasion.We've already addressed how we perform
${PATH}
juggling inbash
. It's not pretty, but it works. Let's address the latter two.Default
.zshrc
It's critical that Babun be able to safely modify
${PATH}
, both for this pull request and any future plugins requiring such modification. Babun shouldn't have to worry about the default~/.zshrc
maliciously undo-ing its hard work.Here's what the default
~/.zshrc
does:Prepending
${PATH}
by/usr/local/bin
here is pointless. As examples above illustrate, Babun already prepends${PATH}
by/usr/local/bin
. Why do it twice? Don't! So, the prior statement is reducible without loss of generality to:This pull request patches the latter statement into the default
~/.zshrc
on installation. (O.K., technically/usr/local/etc/babun/home/.zshrc
is patched on installation. But you know what we mean, man.) Since the default~/.bashrc
suffers no similar issue, we're done here.Plugin Isolation
While Babun plugins cannot modify the current shell environment, Babun does provides two shell scripts commonly sourced on both
bash
andzsh
startup:/usr/local/etc/babun.rc
, which is sourced before~/.babunrc
, which optionally redefines the${PRIORITIZE_CONDA_PACKAGES}
boolean upon which our${PATH}
juggling depends. It follows that/usr/local/etc/babun.rc
cannot perform such juggling. (Q.E.D., and stuff.)/usr/local/etc/babun.start
, a high-level wrapper around thebabun-core/plugins/start.sh
andbabun-core/tools/welcome.sh
scripts. Technically, our${PATH}
juggling could be embedded directly into this wrapper. Doing so would probably establish a bad precedent, however. It's a high-level wrapper. It's not supposed to contain low-level logic specific to optional external commands. Plugins exist for a reason. This is it.Since
babun.rc
is right out andbabun.start
should be, we're at an impasse. I'd hope we could all agree, though, that plugins should be able to modify the current shell environment when there absolutely exists no other way. (Let's just pretend we agree.) Under that assumption, this pull request adds support for a new type of plugin-specific script:start_sourced.sh
.Like
start.sh
scripts,start_sourced.sh
scripts are run at Babun startup. Unlikestart.sh
scripts,start_sourced.sh
scripts are sourced in the current shell process rather than run in a separatebash
process. Simple, right?The End, My Friend
Let's put it all together. Since plugins can now modify the current shell environment, we define a new
conda
plugin whosestart_sourced.sh
script tests whether the${PRIORITIZE_CONDA_PACKAGES}
boolean istrue
and, if so:${PATH}
for all Anaconda and Miniconda directories.${PATH}
in an order-preserving manner (i.e., preserving the internal order of all such directories and all other directories in${PATH}
).Yeah.