This is the pattern we've been adopting for a while and it's a bit
cleaner. Let's remove all of the existing usage of the existing pattern
to avoid confusion when adopting the new one.
- 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
```
Add support for providing more granular glob patterns via the
mismatched_binary_allowlist.json rather than an all-or-nothing option.
This allows catching any unwanted binaries in new releases.
The glob patterns are assumed to be relative to the formula's prefix.
Patterns are matched using fnmatch with flags for:
* `File::FNM_DOTMATCH` to allow matching all files with `**/*`
* `File::FNM_EXTGLOB` to behave like `Dir.glob` for `{a,b}`
* `File::FNM_PATHNAME` to allow restricting `*` across directories
The original file format of `["<formula>"]` should behave similar to
`{"<formula>": "**/*"}`.
Also some changes to add type signature.
Signed-off-by: Michael Cho <michael@michaelcho.dev>
The main thing is that this DSL allows us to provide an
interface that can be serialized to the JSON API.
Changes:
- Homebrew::Service
- Adds `#service_name` and `#plist_name` methods
- Each is now included in the `#serialize` method as well
- Eval block on instantiation
- Before we lazy evaluated this but the cost is not significant
and it complicated the code a bunch. This only gets called
during install, when evaluating caveats and in the `brew service`
command. It skips this evaluation if the service block isn't there.
- Add `#command?` helper to avoid `#command.blank?` and `#command.present?`
- Formula
- `#service` now returns a service whenever it's called. This call is
hidden behind a call to `#service?` most of the time anyway so this
should be fine.
- `#plist_name` and `#service_name` now call the methods of the same name
on the service class. This should have already been in the service object
to begin with and keeping these methods here helps preserve backwards
compatibility with people who were overwriting these methods before.
- Caveats
- Prefer `service#command?`
- Add helpers for checking on service commands
- This duplicates some of the work in `brew services`. Maybe we should
merge that repo in at some point.
- Check for installed service at `#plist_name` or `#service_name`. I think
this should be used instead of `Keg#plist_installed?` which checked for any plist file.
We should think about deprecating `#plist_installed?` in the future.
- Stop using `ps aux | grep #{formula.plist_name}` to check for service files
because it was inaccurate (it always returns true on my machine) because the grep
process is started before the ps process.
- Note: The behavior is the same as it was before. This means that caveats
only show up for custom service files on install or if they're already installed.
Otherwise it won't show up in `brew info`. This is because it has to check
first if the service file has been installed.
- Utils::Service
- Add utils for evaluating if a service is installed and running. This duplicates
some of the work already found in `brew services`. We should seriously consider
merging `brew services` with the main brew repo in the future since it's already
tightly coupled to the code in the main repo.
- Formulary.load_formula_from_api
- Be more explicit about which types can be deserialized into run params since
it is now possible for run params to be nil.
- Update and add tests
- Change name of rubocop warning
- Disable linting on remaining offending lines
- Add todos to move lines with disabled linting
checks to extend/os in the future
Currently, if formula `foo` ships both universal and non-native
binaries and `foo` is on both allowlists, then `brew audit --strict`
errors out with an empty error message:
❯ brew audit --strict foo
foo:
*
Error: 1 problem in 1 formula detected
Let's fix this (admittedly obscure) corner case by returning early when
a formula is present on both allowlists.
This will make the error more informative by showing the architecture a
binary was built for along with the error message.
Before:
foo:
* Binaries built for an incompatible architecture were installed into foo's prefix.
The offending files are:
/usr/local/Cellar/foo/1.0/lib/libbar.dylib
/usr/local/Cellar/foo/1.0/lib/libfoo.dylib
/usr/local/Cellar/foo/1.0/lib/libincompatible.dylib
Unexpected universal binaries were found.
The offending files are:
/usr/local/Cellar/foo/1.0/lib/liball.dylib
/usr/local/Cellar/foo/1.0/lib/libuniversal.dylib
After:
foo:
* Binaries built for a non-native architecture were installed into foo's prefix.
The offending files are:
/usr/local/Cellar/foo/1.0/lib/libbar.dylib (i386)
/usr/local/Cellar/foo/1.0/lib/libfoo.dylib (arm64)
/usr/local/Cellar/foo/1.0/lib/libincompatible.dylib (universal)
Unexpected universal binaries were found.
The offending files are:
/usr/local/Cellar/foo/1.0/lib/liball.dylib
/usr/local/Cellar/foo/1.0/lib/libuniversal.dylib