From 369fd3dcaf84b9c1b1df74f0e006358d8fe1be79 Mon Sep 17 00:00:00 2001 From: Ruoyu Zhong Date: Wed, 25 Sep 2024 01:50:43 +0800 Subject: [PATCH] Speed up `brew tap` for no arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This provides a >3x speedup for `brew tap` with no arguments (i.e., when listing taps). It also makes the completion significantly faster. $ hyperfine --warmup=3 --setup 'git checkout {branch}' --parameter-list branch master,brew-tap-speedup 'brew tap' Benchmark 1: brew tap (branch = master) Time (mean ± σ): 1.405 s ± 0.080 s [User: 0.561 s, System: 0.238 s] Range (min … max): 1.332 s … 1.549 s 10 runs Benchmark 2: brew tap (branch = brew-tap-speedup) Time (mean ± σ): 404.1 ms ± 124.8 ms [User: 107.9 ms, System: 200.7 ms] Range (min … max): 308.8 ms … 693.7 ms 10 runs Summary brew tap (branch = brew-tap-speedup) ran 3.48 ± 1.09 times faster than brew tap (branch = master) --- Library/Homebrew/brew.sh | 5 +++++ Library/Homebrew/tap.sh | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 Library/Homebrew/tap.sh diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index 877b33c868..25550839bb 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -172,6 +172,11 @@ case "$@" in source "${HOMEBREW_LIBRARY}/Homebrew/list.sh" homebrew-list "$@" && exit 0 ;; + # falls back to cmd/tap.rb on a non-zero return + tap*) + source "${HOMEBREW_LIBRARY}/Homebrew/tap.sh" + homebrew-tap "$@" && exit 0 + ;; # falls back to cmd/help.rb on a non-zero return help | --help | -h | --usage | "-?" | "") homebrew-help "$@" && exit 0 diff --git a/Library/Homebrew/tap.sh b/Library/Homebrew/tap.sh new file mode 100644 index 0000000000..97d581ef5b --- /dev/null +++ b/Library/Homebrew/tap.sh @@ -0,0 +1,41 @@ +# Does the quickest output of brew tap possible for no arguments. +# HOMEBREW_LIBRARY is set by bin/brew +# shellcheck disable=SC2154 + +normalise_tap_name() { + local dir="$1" + local user + local repo + + user="$(echo "${dir%%/*}" | tr '[:upper:]' '[:lower:]')" + repo="$(echo "${dir#*/}" | tr '[:upper:]' '[:lower:]')" + repo="${repo#@(home|linux)brew-}" + echo "${user}/${repo}" +} + +homebrew-tap() { + case "$1" in + # check we actually have tap and not e.g. tapsomething + tap) ;; + tap*) return 1 ;; + *) ;; + esac + + # Named args are handled by the Ruby code. + if [[ "$#" -gt 1 ]] + then + return 1 + fi + + local taplib="${HOMEBREW_LIBRARY}/Taps" + ( + shopt -s extglob + + for dir in "${taplib}"/*/* + do + [[ -d "${dir}" ]] || continue + dir="${dir#"${taplib}"/}" + normalise_tap_name "${dir}" + done | sort + ) +}