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.
- Previously I thought that comments were fine to discourage people from
wasting their time trying to bump things that used `undef` that Sorbet
didn't support. But RuboCop is better at this since it'll complain if
the comments are unnecessary.
- Suggested in https://github.com/Homebrew/brew/pull/18018#issuecomment-2283369501.
- I've gone for a mixture of `rubocop:disable` for the files that can't
be `typed: strict` (use of undef, required before everything else, etc)
and `rubocop:todo` for everything else that should be tried to make
strictly typed. There's no functional difference between the two as
`rubocop:todo` is `rubocop:disable` with a different name.
- And I entirely disabled the cop for the docs/ directory since
`typed: strict` isn't going to gain us anything for some Markdown
linting config files.
- This means that now it's easier to track what needs to be done rather
than relying on checklists of files in our big Sorbet issue:
```shell
$ git grep 'typed: true # rubocop:todo Sorbet/StrictSigil' | wc -l
268
```
- And this is confirmed working for new files:
```shell
$ git status
On branch use-rubocop-for-sorbet-strict-sigils
Untracked files:
(use "git add <file>..." to include in what will be committed)
Library/Homebrew/bad.rb
Library/Homebrew/good.rb
nothing added to commit but untracked files present (use "git add" to track)
$ brew style
Offenses:
bad.rb:1:1: C: Sorbet/StrictSigil: Sorbet sigil should be at least strict got true.
^^^^^^^^^^^^^
1340 files inspected, 1 offense detected
```
Fish didn't support `$(...)` substitution until v3.4.0, but the command
didn't work with just parenthesis, so rewrite the test to prepend an
empty string if MANPATH is non-empty (to trigger a leading colon).
Only manipulate INFOPATH in Fish if Homebrew not in path already.
We were selectively requiring the tap.rb file in a few places for
performance reasons. The main method we were referencing was the
`Tap.cmd_directories` method which uses `Pathname` and the `TAP_DIRECTORY`
constant internally. `Tap.cmd_directories` is mostly used in the `Commands`
module and that is loaded very early on in the program so it made sense
to move that command to that module. To facilitate that I moved the
`TAP_DIRECTORY` constant to the top-level and renamed it to
`HOMEBREW_TAP_DIRECTORY`. It now lies in the tap_constants.rb file.
A nice bonus of this refactor is that it speeds up loading external
commands since the tap.rb file is no longer required by default in
those cases.
My experience recently playing around with our locking behaviour is
that, while mostly seamless and not seen by users, it's leaks
implementation details a bit too heavily.
As a result, the following improvements are in this commit:
- Ensure that, whenever possible, we tell the user the actual command
that is holding a given lock instead of the lock name (an internal
implementation detail)
- Make the locking error output a little more consistent and user
friendly
- Add a `DownloadLock` class to simplify locking downloads
- Add a `HOMEBREW_LOCK_CONTEXT` variable to allow adding additional
context for logging error messages
- Lock paths and leave deciding how this translates to lock names up
to the locking code itself
- Lock the Cellar/Caskroom paths explicitly rather than implicitly
Co-authored-by: Carlo Cabrera <30379873+carlocab@users.noreply.github.com>
This adds a new method to either move the `gh` formula to the front
of the formula list to be installed or checks that the `gh` formula
is already installed some other way.
The `Homebrew::CLI::NamedArgs` class often returns frozen arrays so this one cannot
be easily modified in-place here. We just overwrite it instead.
I also updated the `brew reinstall` command logic to match for consistency.
```console
$ brew upgrade gh --verbose --debug
...
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FromAPILoader): loading gh
/usr/local/Homebrew/Library/Homebrew/brew.rb (Formulary::FromAPILoader): loading gh
Error: can't modify frozen Array: [#<Formula gh (stable) /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/g/gh.rb>]
/usr/local/Homebrew/Library/Homebrew/cmd/upgrade.rb:139:in `delete'
/usr/local/Homebrew/Library/Homebrew/cmd/upgrade.rb:139:in `run'
/usr/local/Homebrew/Library/Homebrew/vendor/bundle/ruby/3.3.0/gems/sorbet-runtime-0.5.11481/lib/types/private/methods/call_validation.rb:270:in `bind_call'
/usr/local/Homebrew/Library/Homebrew/vendor/bundle/ruby/3.3.0/gems/sorbet-runtime-0.5.11481/lib/types/private/methods/call_validation.rb:270:in `validate_call'
/usr/local/Homebrew/Library/Homebrew/vendor/bundle/ruby/3.3.0/gems/sorbet-runtime-0.5.11481/lib/types/private/methods/_methods.rb:277:in `block in _on_method_added'
/usr/local/Homebrew/Library/Homebrew/brew.rb:95:in `<main>'
```