- Ignore intentional bootstrap constant reassignments, RBI declarations
and OS-specific method overrides.
- Allow valid names unavailable to the project-only index.
- Retain absolute core constants where inherited lookup can make the
indexed autocorrection unsafe.
Also updates rubocop-sorbet (0.13.2 -> 0.14.0) and json (2.21.1 ->
2.21.2), which rubocop depends on.
Two suppressions can go away thanks to bug fixes in this release:
- rubocop/rubocop#15438 and rubocop/rubocop#15442 stop
`Style/ArrayIntersect` firing when the `include?` receiver in a block
is not an array literal, so the cop is re-enabled. It still cannot
guarantee the *outer* receiver is an `Array`, and in
`cask/artifact/abstract_uninstall.rb` that receiver is the `Enumerator`
from `Pathname#each_filename`, which has no `intersect?`. Convert with
`to_a` there rather than taking the autocorrect verbatim.
- rubocop/rubocop#15452 fixes the `Layout/HashAlignment` false positive on
multi-line hash keys, so the two `delegate` disable comments in
`formula.rb` are dead and removed.
One suppression is added: rubocop/rubocop#15493 makes
`Style/IfUnlessModifier` respect `Layout/LineLength`'s exemptions rather
than its `Max`. Several of our exemption patterns are unescaped regexes
(`"#{version."` matches `#{version}`, `#{version_text}` and
`#{version_info[...]}`), so the cop demanded modifier form for statements
that then ran to 179 characters. Disable the cop. Reported upstream as
rubocop/rubocop#15531.
rubocop-sorbet 0.14.0 widens `Sorbet/SetterReturnType` to cover setters
taking splat and keyword arguments, so several `depends_on` and ENV
setters switch to `.void`. Under `HOMEBREW_SORBET_RUNTIME` a `.void`
method returns the sentinel `T::Private::Types::Void::VOID`, which breaks
the two callers that consumed a setter's return value. Sorbet does not
catch either statically:
- `DependsOn#load` stored the result of `send(:"#{key}=", ...)` into the
delegated hash, so the whole `depends_on` stanza became `VOID`. Read the
value back through the matching reader instead.
- `Superenv#cc=` assigned `super` to `HOMEBREW_CC`, raising `TypeError:
no implicit conversion of Module into String`. Assign from `val`.
Drop `extend/ENV/shared.rbi`, which existed to widen `[]=` to accept
`Pathname` and `PATH`. Without it `[]=` resolves to Sorbet's own
`ENVClass#[]=`, which takes `T.nilable(String)`, so the ENV assignments
convert explicitly with `to_s`/`&.to_s`. Both `Pathname` and `PATH`
define `to_str`, so Ruby was already converting implicitly and behaviour
is unchanged.
The remaining changes are new offenses in this release:
- `Lint/UselessAssignment` (rubocop/rubocop#12269) catches the
`root_url = root_url =` workaround in `dev-cmd/tap-new.rb`. The Ruby
`assigned but unused variable` warning it silenced no longer fires on
our vendored Ruby, so drop it.
- `Style/RedundantParentheses` (rubocop/rubocop#15472) and
`Layout/MultilineMethodCallIndentation` autocorrections.
The redundant `T.let` on `GitHub::API::ERRORS` is also dropped.
Claude-Session: https://claude.ai/code/session_01AdSQcU5MmY4VWiFdfrPeu2
A crate cargo reports as installed from a local origin is still dumped
as a registry crate, but without warning about the origin that could
not be expressed, which is noise for anyone who is content with the
crate they have.
Neither a local path nor a file:// URL resolves on another machine, so
both are rejected when the Brewfile is parsed. A crate cargo reports as
installed from one is dumped as a registry crate rather than dropped,
with a warning naming the origin that could not be expressed.
Formula install-step paths now serialise only a base that was explicitly
specified. RuboCop prevents relative official-tap paths from relying on the
current working directory.
Run structured-only API post-installs from the current JSON data so old
formula snapshots embedded in bottles cannot restore the removed default.
Keep using bottle snapshots for formulae that still have Ruby hooks.
Two forms were accepted at parse time that `cargo install` cannot act
on, so the failure surfaced later and less clearly.
`--git` takes a URL and rejects an scp-style remote outright, naming
the `ssh://` form to use instead, so require a scheme rather than also
accepting anything ending in `.git`.
Only a `branch`, `tag` or `rev` query is restored as a `cargo install`
flag. Any other query was accepted and then silently dropped, which
left the installed origin unequal to the `Brewfile` entry and so made
`brew bundle check` report the crate missing on every run.
`cargo "name"` could only install from crates.io. Accept a `source:`
option naming a git URL or a local path, mirroring the `uv` extension,
and install with `cargo install --git` or `cargo install --path`.
`cargo install --list` reports the origin of anything not installed
from a registry, so dumped Brewfiles round-trip. The resolved commit is
dropped, since a dumped entry has to compare equal to a hand-written
one, while a branch, tag or revision chosen at install time is carried
in the URL query and restored with `--branch`, `--tag` or `--rev`.
- Reject relative formula step paths without an explicit base.
- Autocorrect paths that previously relied on the temporary `var`
compatibility default.
- Keep absolute paths and install-time path tokens unchanged.
- Align casks with formulae: platform support comes from
`depends_on :macos`/`:linux`/`macos:` data rather than generation
heuristics guessing intent from `os` stanzas, Linux checksums or
`on_linux` blocks.
- `Cask#to_hash_with_variations` now emits variations for every
valid OS/arch tag whenever `on_system` blocks exist, matching
`Formula#to_hash_with_variations`; the Linux-specific gate and its
`sha256_set_for_linux?` and `on_linux_blocks_exist?` tracking are
removed. macOS-only casks publish truthful Linux variations, e.g.
a `null` `sha256`, instead of omitting them.
- `Cask::Installer` gains a first-class unsupported-system error:
API-loaded casks with no activatable artifact for the running
system fail with "This cask is not available on macOS/Linux."
instead of installing nothing. Audited casks always declare an
activatable artifact for the systems they support, so missing
artifacts in API data mean the system is unsupported. Source
loads keep working for unaudited casks, e.g. naked containers.
- A sweep of the full homebrew/cask generation pipeline (all casks,
both Linux tags, including internal per-tag payloads) confirmed
no cask needs new `depends_on` annotations and nothing regresses.
A few spots were calling send on methods that are already public
(stable, head, deps.build/required/recommended/optional, and
SimulateSystem's os check), so there was no real need for the
private-method backdoor. Switching to public_send makes that clear
and keeps Ruby's privacy checks in place if that ever changes.