On macOS 14 and newer, `/usr/libexec/path_helper` supports setting a
`PATH_HELPER_ROOT` environment variable.
With this set, `path_helper` checks `$PATH_HELPER_ROOT/etc/paths` and
`$PATH_HELPER_ROOT/etc/paths.d` in the same way it checks `/etc/paths`
and `/etc/paths.d`.
We can use this to simplify management of the user's `PATH` variable
when they do `brew shellenv`. In particular, if their system supports
it, we delegate setting the `PATH` environment variable to `path_helper`
instead of our own code. We also write a default `etc/paths` file if one
is not already present.
This is nicer because it simplifies management of the user's `PATH`
variable. For example, if a user wants a keg-only formula to be in their
`PATH`, they can simply add the necessary path to `/etc/paths` or
`/etc/paths.d` without having to do something like `brew link --force`
or adding to `PATH` themselves.
When `/usr/libexec/path_helper` is not available, we just fall back to
the existing code.
This is yet another approach to f3a5a3c449cf004aee662966e6c8dd2ebe122c0f
which got merged in over the weekend. It is much simpler than what we've
got now with almost exactly the same performance characteristics. A great
combination of maintability and performance.
```console
$ hyperfine --parameter-list branch master,speed-up-loading-cask-and-formula-file-names_v4 --warmup 5 --setup 'git switch {branch}' 'brew cat gimp'
Benchmark 1: brew cat gimp (branch = master)
Time (mean ± σ): 1.459 s ± 0.012 s [User: 0.892 s, System: 0.536 s]
Range (min … max): 1.448 s … 1.483 s 10 runs
Benchmark 2: brew cat gimp (branch = speed-up-loading-cask-and-formula-file-names_v4)
Time (mean ± σ): 1.456 s ± 0.009 s [User: 0.889 s, System: 0.536 s]
Range (min … max): 1.445 s … 1.468 s 10 runs
Summary
brew cat gimp (branch = speed-up-loading-cask-and-formula-file-names_v4) ran
1.00 ± 0.01 times faster than brew cat gimp (branch = master)
```
`brew test-bot` can occasionally spend a long time doing nothing when
testing dependents.[^1] This is because it takes a long time to work out
that there is nothing to do.
To fix this, let's adjust `brew determine-test-runners` to pass on only
the list of formulae for which there is work to be done so that
`brew test-bot` doesn't need to waste time working this out.
[^1]: For example, it spends about 15 minutes doing nothing at https://github.com/Homebrew/homebrew-core/actions/runs/10500178069/job/29133091332?pr=180185
These are slow because of some Pathname related reasons so it's been
changed up to use `Dir.glob` instead and that makes a large difference.
```
$ hyperfine --parameter-list branch master,speed-up-loading-cask-and-formula-file-names,speed-up-loading-cask-and-formula-file-names_v2 --warmup 5 --setup 'git switch {branch}' 'brew cat gimp'
Benchmark 1: brew cat gimp (branch = master)
Time (mean ± σ): 2.150 s ± 0.014 s [User: 1.369 s, System: 0.745 s]
Range (min … max): 2.126 s … 2.174 s 10 runs
Benchmark 2: brew cat gimp (branch = speed-up-loading-cask-and-formula-file-names)
Time (mean ± σ): 1.814 s ± 0.012 s [User: 1.068 s, System: 0.711 s]
Range (min … max): 1.797 s … 1.840 s 10 runs
Benchmark 3: brew cat gimp (branch = speed-up-loading-cask-and-formula-file-names_v2)
Time (mean ± σ): 1.489 s ± 0.009 s [User: 0.905 s, System: 0.550 s]
Range (min … max): 1.478 s … 1.503 s 10 runs
Summary
brew cat gimp (branch = speed-up-loading-cask-and-formula-file-names_v2) ran
1.22 ± 0.01 times faster than brew cat gimp (branch = speed-up-loading-cask-and-formula-file-names)
1.44 ± 0.01 times faster than brew cat gimp (branch = master)
```
A local `ruby` build failed while building extensions, with:
*** Following extensions are not compiled:
-test-/file:
Could not be configured. It will not be installed.
/tmp/ruby-20240824-893184-ehcnsa/ruby-3.3.4/lib/mkmf.rb:480: The compiler failed to generate an executable file.
You have to install development tools first.
Check ext/-test-/file/mkmf.log for more details.
-test-/symbol:
Could not be configured. It will not be installed.
/tmp/ruby-20240824-893184-ehcnsa/ruby-3.3.4/lib/mkmf.rb:480: The compiler failed to generate an executable file.
You have to install development tools first.
Check ext/-test-/symbol/mkmf.log for more details.
[...]
`mkmf.log` indicated that the compiler shim failed to load `pathname`:
LD_LIBRARY_PATH=.:../../.. "gcc-13 -o conftest -I../../../.ext/include/aarch64-linux -I../../.././include -I../../.././ext/-test-/file -I/home/linuxbrew/.linuxbrew/opt/libyaml/include -I/home/linuxbrew/.linuxbrew/opt/openssl@3/include -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wdeprecated-declarations -Wdiv-by-zero -Wduplicated-cond -Wimplicit-function-declaration -Wimplicit-int -Wpointer-arith -Wwrite-strings -Wold-style-definition -Wimplicit-fallthrough=0 -Wmissing-noreturn -Wno-cast-function-type -Wno-constant-logical-operand -Wno-long-long -Wno-missing-field-initializers -Wno-overlength-strings -Wno-packed-bitfield-compat -Wno-parentheses-equality -Wno-self-assign -Wno-tautological-compare -Wno-unused-parameter -Wno-unused-value -Wsuggest-attribute=format -Wsuggest-attribute=noreturn -Wunused-variable -Wmisleading-indentation -Wundef -fPIC conftest.c -L. -L../../.. -L/home/linuxbrew/.linuxbrew/opt/libyaml/lib -Wl,-rpath,/home/linuxbrew/.linuxbrew/opt/libyaml/lib -L/home/linuxbrew/.linuxbrew/opt/openssl@3/lib -Wl,-rpath,/home/linuxbrew/.linuxbrew/opt/openssl@3/lib -L. -fstack-protector-strong -L/home/linuxbrew/.linuxbrew/opt/libyaml/lib -Wl,-rpath,/home/linuxbrew/.linuxbrew/opt/libyaml/lib -L/home/linuxbrew/.linuxbrew/opt/openssl@3/lib -Wl,-rpath,/home/linuxbrew/.linuxbrew/opt/openssl@3/lib -rdynamic -Wl,-export-dynamic -Wl,--no-as-needed -Wl,-rpath,/home/linuxbrew/.linuxbrew/Cellar/ruby/3.3.4/lib -L/home/linuxbrew/.linuxbrew/Cellar/ruby/3.3.4/lib -lruby-static -lz -lrt -lrt -ldl -lcrypt -lm -lpthread -lm -lpthread -lc"
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/shims/linux/super/gcc-13:12:in `require': cannot load such file -- pathname (LoadError)
from /home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/shims/linux/super/gcc-13:12:in `<main>'
I believe this was due to `../../..` in `LD_LIBRARY_PATH` containing
`libruby.so`, causing the Ruby script to load the being-built Ruby
library instead of the system/portable one.
This is most noticeable when you have a large local tap and it ends
up taking a nontrivial percentage of the overall run time for simple
commands like `brew info gimp`. The improvement here is to just
create paths later on in the loop which copies what we already do
for formulae.
See b1ddb05
```console
$ hyperfine --parameter-list branch master,speed-up-cask-files-by-name --warmup 5 --setup 'git switch {branch}' 'brew info gimp'
Benchmark 1: brew info gimp (branch = master)
Time (mean ± σ): 2.737 s ± 0.010 s [User: 1.958 s, System: 0.732 s]
Range (min … max): 2.720 s … 2.748 s 10 runs
Benchmark 2: brew info gimp (branch = speed-up-cask-files-by-name)
Time (mean ± σ): 2.597 s ± 0.017 s [User: 1.828 s, System: 0.724 s]
Range (min … max): 2.577 s … 2.624 s 10 runs
Summary
brew info gimp (branch = speed-up-cask-files-by-name) ran
1.05 ± 0.01 times faster than brew info gimp (branch = master)
```
This doesn't count PRs from forks, so it only works correctly for
maintainers (and only if they use non-fork branches).
Let's fix that, and:
- simplify the logic by using `paginate_graphql`
- return early if it's impossible for them to have too many open PRs