From 7073258a6acad940b028b7bd392d7bb439088a65 Mon Sep 17 00:00:00 2001 From: Mike McQuaid Date: Fri, 17 May 2024 11:59:40 +0900 Subject: [PATCH] Speed up `brew list` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similarly to have we have with other commands, use Bash to speed it up. Before: ``` $ hyperfine "brew list" Benchmark 1: brew list Time (mean ± σ): 559.9 ms ± 122.8 ms [User: 176.2 ms, System: 126.2 ms] Range (min … max): 503.2 ms … 907.3 ms 10 runs ``` After: ``` $ hyperfine "brew list" Benchmark 1: brew list Time (mean ± σ): 223.7 ms ± 31.9 ms [User: 35.0 ms, System: 53.4 ms] Range (min … max): 198.1 ms … 302.4 ms 10 ``` Petty after comparison because someone on Homebrew/discussions compared them: ``` $ hyperfine "brew list" "pip3 list" Benchmark 1: brew list Time (mean ± σ): 213.1 ms ± 22.8 ms [User: 34.2 ms, System: 49.2 ms] Range (min … max): 191.2 ms … 272.3 ms 13 runs Benchmark 2: pip3 list Time (mean ± σ): 271.7 ms ± 4.6 ms [User: 191.9 ms, System: 40.0 ms] Range (min … max): 264.7 ms … 281.4 ms 10 runs Summary brew list ran 1.28 ± 0.14 times faster than pip3 list ``` --- While we're here, also add the `HOMEBREW_CASKROOM` environment variable to make things a bit cleaner and use `--caskroom` in documentation. Co-authored-by: Carlo Cabrera <30379873+carlocab@users.noreply.github.com> --- Library/Homebrew/brew.sh | 10 +++- Library/Homebrew/list.sh | 77 ++++++++++++++++++++++++++++++ Library/Homebrew/startup/config.rb | 3 ++ docs/Common-Issues.md | 2 +- 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 Library/Homebrew/list.sh diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index 876220c8a6..747f6236e2 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -92,6 +92,8 @@ else HOMEBREW_CELLAR="${HOMEBREW_PREFIX}/Cellar" fi +HOMEBREW_CASKROOM="${HOMEBREW_PREFIX}/Caskroom" + HOMEBREW_CACHE="${HOMEBREW_CACHE:-${HOMEBREW_DEFAULT_CACHE}}" HOMEBREW_LOGS="${HOMEBREW_LOGS:-${HOMEBREW_DEFAULT_LOGS}}" HOMEBREW_TEMP="${HOMEBREW_TEMP:-${HOMEBREW_DEFAULT_TEMP}}" @@ -138,7 +140,7 @@ case "$@" in exit 0 ;; --caskroom) - echo "${HOMEBREW_PREFIX}/Caskroom" + echo "${HOMEBREW_CASKROOM}" exit 0 ;; --cache) @@ -155,6 +157,11 @@ case "$@" in source "${HOMEBREW_LIBRARY}/Homebrew/command_path.sh" homebrew-command-path "$@" && exit 0 ;; + # falls back to cmd/list.rb on a non-zero return + list*) + source "${HOMEBREW_LIBRARY}/Homebrew/list.sh" + homebrew-list "$@" && exit 0 + ;; esac ##### @@ -783,6 +790,7 @@ export HOMEBREW_LOGS export HOMEBREW_DEFAULT_TEMP export HOMEBREW_TEMP export HOMEBREW_CELLAR +export HOMEBREW_CASKROOM export HOMEBREW_SYSTEM export HOMEBREW_SYSTEM_CA_CERTIFICATES_TOO_OLD export HOMEBREW_CURL diff --git a/Library/Homebrew/list.sh b/Library/Homebrew/list.sh new file mode 100644 index 0000000000..563f375ba6 --- /dev/null +++ b/Library/Homebrew/list.sh @@ -0,0 +1,77 @@ +# does the quickest output of brew list possible for no named arguments. +# HOMEBREW_CELLAR, HOMEBREW_PREFIX are set by brew.sh +# shellcheck disable=SC2154 +homebrew-list() { + case "$1" in + # check we actually have list and not e.g. listsomething + list) ;; + list*) return 1 ;; + *) ;; + esac + + local ls_args=() + local formula="" + local cask="" + + for arg in "$@" + do + case "${arg}" in + # check for flags passed to ls + -1 | -l | -r | -t) ls_args+=("${arg}") ;; + --formula | --formulae) formula=1 ;; + --cask | --casks) cask=1 ;; + # reject all other flags + -* | *) return 1 ;; + esac + done + + local tty + if [[ -t 1 ]] + then + tty=1 + fi + + local error_string="LS_ERRORED" + if [[ -z "${cask}" && -d "${HOMEBREW_CELLAR}" ]] + then + if [[ -n "${tty}" && -z "${formula}" ]] + then + ohai "Formulae" + fi + + local formula_output + formula_output="$(ls "${ls_args[@]}" "${HOMEBREW_CELLAR}" || echo "${error_string}")" + if [[ "${formula_output}" == "${error_string}" ]] + then + exit 1 + elif [[ -n "${formula_output}" ]] + then + echo "${formula_output}" + fi + + if [[ -n "${tty}" && -z "${formula}" ]] + then + echo + fi + fi + + if [[ -z "${formula}" && -d "${HOMEBREW_CASKROOM}" ]] + then + if [[ -n "${tty}" && -z "${cask}" ]] + then + ohai "Casks" + fi + + local cask_output + cask_output="$(ls "${ls_args[@]}" "${HOMEBREW_CASKROOM}" || echo "${error_string}")" + if [[ "${cask_output}" == "${error_string}" ]] + then + exit 1 + elif [[ -n "${cask_output}" ]] + then + echo "${cask_output}" + fi + + return 0 + fi +} diff --git a/Library/Homebrew/startup/config.rb b/Library/Homebrew/startup/config.rb index 1251a8812a..7468b8a289 100644 --- a/Library/Homebrew/startup/config.rb +++ b/Library/Homebrew/startup/config.rb @@ -33,6 +33,9 @@ HOMEBREW_LOCKS = (HOMEBREW_PREFIX/"var/homebrew/locks").freeze # Where we store built products HOMEBREW_CELLAR = Pathname(ENV.fetch("HOMEBREW_CELLAR")).freeze +# Where we store Casks +HOMEBREW_CASKROOM = Pathname(ENV.fetch("HOMEBREW_CASKROOM")).freeze + # Where downloads (bottles, source tarballs, etc.) are cached HOMEBREW_CACHE = Pathname(ENV.fetch("HOMEBREW_CACHE")).freeze diff --git a/docs/Common-Issues.md b/docs/Common-Issues.md index f3d20aafda..a6ce961641 100644 --- a/docs/Common-Issues.md +++ b/docs/Common-Issues.md @@ -217,7 +217,7 @@ Help us by [submitting a fix](https://github.com/Homebrew/homebrew-cask/blob/HEA In this case, it’s likely your user account has no admin rights and therefore lacks permissions for writing to `/Applications`, which is the default install location. You can use [`--appdir`](https://github.com/Homebrew/homebrew-cask/blob/HEAD/USAGE.md#options) to choose where to install your applications. -If `--appdir` doesn’t fix the issue or you do have write permissions to `/Applications`, verify you’re the owner of the `Caskroom` directory by running `ls -dl "$(brew --prefix)/Caskroom"` and checking the third field. If you are not the owner, fix it with `sudo chown -R "$(whoami)" "$(brew --prefix)/Caskroom"`. If you are, the problem may lie in the app bundle itself. +If `--appdir` doesn’t fix the issue or you do have write permissions to `/Applications`, verify you’re the owner of the `Caskroom` directory by running `ls -dl "$(brew --caskroom)"` and checking the third field. If you are not the owner, fix it with `sudo chown -R "$(whoami)" "$(brew --caskroom)"`. If you are, the problem may lie in the app bundle itself. Some app bundles don’t have certain permissions that are necessary for us to move them to the appropriate location. You may check such permissions with `ls -ls '/path/to/application.app'`. If you see something like `dr-xr-xr-x` at the start of the output, that may be the cause. To fix it, we need to change the app bundle’s permission to allow us to move it, and then set it back to what it was (in case the developer set those permissions deliberately). See [litecoin.rb](https://github.com/Homebrew/homebrew-cask/blob/aa461148bbb5119af26b82cccf5003e2b4e50d95/Casks/l/litecoin.rb#L17-L27) for an example of such a cask.