I'm on macOS Catalina, but I don't believe the version matters here as the issue would likely apply only to those that are using Homebrew. I've had the following issue for a long time and was finally fed up to the point that I began to search for the culprit. This may help someone, so I'd like to update the documentation located at https://asdf-vm.com/#/core-manage-asdf-vm?id=install, but the guide doesn't describe how this can be done
I'm using bash, but I think this, too, applies to Fish and Zsh users -- anyone using Homebrew
Issue
It takes a good couple of seconds before my shell prompt is loaded and ready for action. By process of deduction, I discovered that asking Hombrew to find the prefix for a given utility, asdf in this case, took anywhere from 2-3 seconds. This would be extremely bothersome for anyone using multiple tabs or even a terminal multiplexer. The documentation asks us to add the following to our .bash_profile:
. $(brew --prefix asdf)/asdf.sh
. $(brew --prefix asdf)/etc/bash_completion.d/asdf.bash
Solution
Easy - hard-code the Homebrew prefix in a local bash variable or environment variable:
BREW_PREFIX=/usr/local/opt
. $BREW_PREFIX/asdf/asdf.sh
. $BREW_PREFIX/asdf/etc/bash_completion.d/asdf.bash
Less easy - try to speed up Homebrew's prefix option and resolution upstream
I'm unfamiliar with how brew --prefix works, but given there's a command to find it is it possible it can change? If the asdf Homebrew package gets updated with a different install location and Brew updates all it's packages, then would this break people's systems?
I have Homebrew on one system, though I barely use brew and have not experienced this. Is brew --prefix affected by the number of packages installed with Homebrew?
A quick Google landed me here: https://stackoverflow.com/questions/24377639/can-i-change-homebrews-prefix Which references HOMEBREW_PREFIX during Homebrew installation. Is this value available in your shell after initializing Homebrew? Can it be used instead?
@jthegedus valid questions. I guess I wasn't as clear as I thought
$HOMEBREW_PREFIX is set by Homebrew and it appears that Homebrew provides a utility function to apply that prefix to any installed utility, like asdf via $(brew --prefix asdf), but as noted -- incredibly slow
It wasn't clear in my recommendation how I came up with what I have:
$ echo $(brew --prefix asdf)BREW_PREFIX and use it as the prefix for both a) asdf.sh and b) asdf.bash I'm more inclined to recommend this as an optimization in the docs than an explicit installation instructions.
asdf Homebrew package itself may change location across versions (an assumption, happy to be corrected)Is performing the command once like so much better:
ASDF_BREW_PREFIX=$(brew --prefix asdf)
. $ASDF_BREW_PREFIX/asdf/asdf.sh
. $ASDF_BREW_PREFIX/asdf/etc/bash_completion.d/asdf.bash
On the surface that should halve the time to init asdf, no?
@jthegedus I can see why. Having it as an optimization recommendation seems valid
I don't think it'll halve the time if you're still relying on Homebrew to generate that prefix (benchmarks below):
# test.sh (your suggestion)
#!/usr/local/bin/bash
ASDF_BREW_PREFIX=$(brew --prefix asdf)
. $ASDF_BREW_PREFIX/asdf.sh
. $ASDF_BREW_PREFIX/etc/bash_completion.d/asdf.bash
$ time ./test.sh
real 0m3.016s
user 0m1.293s
sys 0m0.952s
cost to generate the prefix:
$ time brew --prefix asdf
/usr/local/opt/asdf
real 0m1.946s
user 0m1.138s
sys 0m0.695s
when placed in a variable in test.sh/.bash_profile
$ time ./test.sh
real 0m0.243s
user 0m0.007s
sys 0m0.009s
@wulymammoth Thanks for providing more concrete data of each case. Are you able to confirm if this is a factor of the number of Homebrew packages on the system? Just for extra information in the docs update.
@jthegedus difficult to confirm, but it is certainly an issue and core maintainers seem to be aware of it, even so far as making an attempt to fix it, but gave up (only a week ago) -- https://github.com/Homebrew/brew/issues/8189#issuecomment-667639679
Just for reference, with respect to --prefix, the manual's description follows. My interpretation is that this is likely static, unless otherwise deliberately changed:
--prefix [formula]
Display Homebrew's install path. Default: /usr/local on macOS and /home/linuxbrew/.linuxbrew on Linux.
If formula is provided, display the location in the Cellar where formula is or would be installed.
Why not simply change the instructions to
echo -e "\n. $(brew --prefix asdf)/asdf.sh" >> ~/.bashrc
or so? The brew --prefix asdf part will be computed when writing to the settings file and not during startup, which will resolve this issue.
Important point: the asdf.sh path is consistent no matter the version of asdf, so it would work with any setup and would not break brew upgrade.
The only case where it would be an issue is if the user changes his Homebrew directory or if the person maintaining the Homebrew package for asdf decides to make a breaking change.
Overall, I think the benefits of a fast shell startup overweight the potential issues it could cause, which really seem to be unlikely enough.
@danhper fairly inline with my original recommendation, and I'd imagine those, like myself, that desire to modularize, will know to place the output elsewhere verses redirecting it
We moved away from _executing commands that modified shell configs_ to what _contents should be added to the config_ to allow users to manage their own configs as they are highly custom.
The only case where it would be an issue is if the user changes his Homebrew directory or if the person maintaining the Homebrew package for asdf decides to make a breaking change.
These cases are my concern. Especially since Homebrew updates it's packages whenever, if there was a breaking change with the asdf Homebrew package it would break for everyone at different times.
Going with the consensus 馃憤
@wulymammoth Appreciate the input and detail you went to with this, if you have other feedback for asdf we're always happy to receive it to discuss 馃槃
@jthegedus you bet! I just appreciate that this tool exists and recommend it a lot. Thanks for asking the right questions opening up the doors for me to probe deeper as well :)
Most helpful comment
Why not simply change the instructions to
or so? The
brew --prefix asdfpart will be computed when writing to the settings file and not during startup, which will resolve this issue.Important point: the
asdf.shpath is consistent no matter the version of asdf, so it would work with any setup and would not breakbrew upgrade.The only case where it would be an issue is if the user changes his Homebrew directory or if the person maintaining the Homebrew package for asdf decides to make a breaking change.
Overall, I think the benefits of a fast shell startup overweight the potential issues it could cause, which really seem to be unlikely enough.