Commit Graph
82 Commits
Author SHA1 Message Date
Mike McQuaid 204ea7e964 Make tests use public APIs and enable their cops
- Make every statically-poked method public and call it directly,
  keeping `public_send` only for dynamically-named public methods.
- Read and write state through public `attr_*` accessors instead of
  instance variable reflection.
- Enable `Homebrew/NoSendInTests` and
  `Homebrew/NoInstanceVariableAccessInTests` now the test suite is
  clean, so neither pattern creeps back in.
- Keep rare justified disables, e.g. `Module#remove_const` is
  private core Ruby and raw memoisation state has no accessor.
2026-07-27 08:11:46 +01:00
Anthony HollandandClaude Fable 5 3cd4b81833 cask/installer: remove Caskroom symlinks broken by uninstall
Cask renames leave an alias symlink in the Caskroom (today old token ->
new directory; an earlier migration era created the inverse
arrangement). Uninstall removed only broken symlinks named after the
cask's declared old_tokens, so any other arrangement - uninstalling by
the old token, or an alias left by the earlier era - left a dangling
symlink behind: brew list --cask still showed the name while
brew uninstall of it failed with "Cask ... is not installed". Scan the
Caskroom for broken symlinks pointing at the removed directory instead,
whichever of the linked names was uninstalled, and clean up on the
purge_caskroom_path force path too.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-21 13:08:19 +12:00
Mike McQuaid 4880cf92db Serialise cask language variations
- store deterministic language deltas in public and internal API data
- select URLs, checksums and artifacts without loading cask Ruby
- retain source fallback for older API data and legacy flight blocks
2026-07-17 15:36:14 +01:00
Mike McQuaid 71bfac209e Recover legacy Cask metadata
- preserve artifacts when receipts or metadata are missing
- share recovery between migration, upgrade and reinstall
- verify rewritten JSON before deleting legacy metadata
2026-07-16 17:56:15 +01:00
Mike McQuaid 055a22740c Preserve cask container metadata
- Retain nested paths and explicit types for API-backed downloads.
- Ensure queued staging extracts the declared nested container.
2026-07-14 15:05:44 +01:00
Mike McQuaid ed5180388b Pre-stage cask downloads
- Extract cask containers during queued fetches so installs spend less
  serial time in the staging phase.
- Keep receipt writing and artifact installation in the normal install
  path so installed state does not change early.
- Skip queued extraction when unpack dependencies are still missing so
  dependency installation ordering stays intact.
2026-07-10 09:32:40 +01:00
Gaál György 4d424622c1 cask: don't crash upgrade when staged version dir is missing
`Cask::Installer#backup` renamed the staged version directory to
`<version>.upgrading` for rollback safety, raising `Errno::ENOENT`
("No such file or directory @ rb_file_s_rename") and aborting the
whole `brew upgrade` when that directory was already gone — a common
state for `auto_updates` casks that self-updated out-of-band, or after
an interrupted `brew upgrade`/`brew cleanup`. Guard the rename so a
missing staged path is a no-op instead of a fatal error.

Closes #22998.

Signed-off-by: Gaál György <gb12335@gmail.com>
2026-07-07 10:47:32 +02:00
Mike McQuaid 9da6c488bb Store cask metadata as JSON
- Use a minimal post-install snapshot for supported casks.
- Read receipt-owned version and artifacts from `INSTALL_RECEIPT.json`.
- Leave uninstall flight block caskfiles as Ruby until ported.
2026-07-05 13:38:03 +01:00
Patrick Linnane 07d5146d9a Name the formula or cask in requirement error messages
Signed-off-by: Patrick Linnane <patrick@linnane.io>
2026-06-19 12:13:41 -07:00
Michael Cho 422b0c2b41 cask/installer: prepend cask name to macOS requirement error
Related to https://github.com/orgs/Homebrew/discussions/6913

This also aligns with style of formula message at:

https://github.com/Homebrew/brew/blob/2642c278b458e689a0ac0265f0b1d8f4ba82c68d/Library/Homebrew/formula_installer.rb#L718
2026-06-19 12:28:23 -04:00
Mike McQuaid 45bd89028b Use API cask metadata for fetch
- Avoid loading simple `homebrew/cask` entries when `brew fetch --cask`
  can resolve URL, version and checksum data from `CaskStruct`.
- Reuse that API-backed download construction for internal-API casks
  during installer download enqueueing.
- Keep source-backed cask loading for language-specific casks and other
  caskfile-only install paths.
2026-06-12 12:36:46 +01:00
Mike McQuaidandGitHub 2287e42256 Merge pull request #22615 from Homebrew/deflake-bzip2-cask-installer-test
Deflake bzip2 cask installer test
2026-06-09 12:32:45 +00:00
Issy Long 75ed51f24e sorbet: String vs Pathname fixes in tests
- Ensure `join` is called on a Pathname of `config.appdir`, because
  `config.appdir` is typed in `cask/config.rbi` as a String, but in the
  real method sig can be either a String or a Pathname.

- `Formulary.cache.delete` can take a String or a Pathname, but Sorbet
  only sees the String type, so call `to_s` on the argument passed to
  it.
2026-06-09 11:05:46 +01:00
Mike McQuaid 62b43ef2c7 Deflake bzip2 cask installer test
- Stub the `bzip2` formula fetch/install dispatched by the bzip2
  container's unpack strategy, so the test no longer pours a real
  bottle whose GitHub Packages manifest fetch flaked with
  `Couldn't find manifest matching bottle checksum`
- Keep `UnpackStrategy::Bzip2#dependencies` intact and force the
  dependency to resolve as missing so the container-driven
  dependency-resolution path stays covered deterministically
2026-06-09 09:32:09 +01:00
Mike McQuaid f03bb2bd9e Pin tap allow/forbid/trust lists to remotes
- `HOMEBREW_ALLOWED_TAPS`, `HOMEBREW_FORBIDDEN_TAPS` and `trust.json`
  matched taps by `user/repository` name only, which `brew tap
  user/repository <url>` trivially spoofed by pointing that name at an
  arbitrary remote
- match a `user/repository` name only against a tap on its default
  GitHub remote; a tap with a custom remote must now be referenced by
  its remote URL, so non-GitHub taps are listed and trusted by URL
- evaluate the allow/forbid gate against the requested clone remote so
  the bypass is caught before cloning
- gate the implicit official-tap exemption behind `implicitly_official?`
  so an official-named tap is only auto-allowed/trusted when its content
  comes from the API or it uses an official (or `HOMEBREW_CORE_GIT_REMOTE`)
  remote, not when pointed at an untrusted custom remote
- refuse per-item trust for custom-remote taps; trust the whole tap by
  URL instead
2026-06-08 19:27:19 +01:00
Issy LongandBo Anderson 46d728bad9 tests: Use RSpec's described_class now Sorbet understands it
- Since https://github.com/sorbet/sorbet/commit/d9d4b57b3fde3907d739ed85d340e64f75f2a7b8
  Sorbet types `described_class` more correctly than assuming `T.untyped`.
- Switched back via having Copilot CLI (GPT 5.3 Codex) write me a
  script to change all of the `klass` references into full class names,
  and then running RuboCop's autocorrector having removed the `explicit`
  style. The explicit style was deemed too verbose in
  0c1321f1b1, hence why we went with
  `let(:klass)`.
- This is much less verbose than the full class name, while preserving
  Sorbet typing of the tests fully.
2026-06-07 00:37:41 +01:00
Mike McQuaidandGitHub 9303785ff7 Merge pull request #22394 from Homebrew/cask-shared-download-queue
Share cask upgrade download queues
2026-05-24 15:08:35 +00:00
Mike McQuaid a30a58024c Share cask upgrade download queues
- Avoid splitting cask source fetches from combined upgrade fetches
- Keep language-specific caskfiles on a prefetch queue only when needed
- Hide `Downloading Cask files` unless that queue will fetch new files
2026-05-23 12:53:46 +01:00
Mike McQuaid 85a29bacee Speed up slow specs
- Reduce slow command specs because repeated `brew` subprocesses were
  dominating the profile more than the tested Homebrew behaviour.
- Preserve coverage by moving option and error branches into direct
  command-object specs where a full process adds no useful signal.
- Keep shell-specific coverage by folding Bash command checks into one
  subprocess harness for each affected Bash path.
- Combine formula and cask happy paths in `fetch`, `outdated` and
  `upgrade`, so one process still checks both package types.
- Keep `cmd/install` source, bottle, keg-only and `--HEAD` coverage,
  with `--HEAD` separate because the option applies to the whole call.
- Stub expensive `svn`, DMG mount and signal-wait paths so the specs
  cover Homebrew decisions without invoking slow external work.
- Restore `brew extract` monkey patches when specs run in-process, so
  dependency and formula requirement caches do not leak across examples.
- Document the integration-test limit in `AGENTS.md` so future command
  specs bias towards fast in-process coverage.
2026-05-23 08:14:00 +01:00
Issy LongandMike McQuaid 0c1321f1b1 tests: Prefer let(:klass) { Foo } over described_class
- The "explicit" setting on the `RSpec/DescribedClass` cop is still
  enabled, because `described_class` is bad for Sorbet typing, but
  instead of applying its autocorrections to specify the full class name
  everywhere that `described_class` was used, use
  `let(:klass) { Foo }` so that the repetition per-test isn't massive in
  tests that use it a lot (say, >5 times).

- Changes made with Copilot CLI, agent mode, Claude Opus 4.7.
2026-05-22 14:32:42 +01:00
Patrick LinnaneandMike McQuaid 2c151eacd7 cask: run forbidden checks before download
Signed-off-by: Patrick Linnane <patrick@linnane.io>
2026-05-13 09:09:34 +01:00
Mike McQuaid 7472e3191c Add Linux OS dependencies
- Support `depends_on :linux` for casks and formulae.
- Fast-path support checks for Linux-only software.
- Document the Linux-only dependency semantics.
- Cover Linux-only and conflicting OS guard paths.
2026-05-10 09:25:52 +01:00
Mike McQuaid c9e3d4a222 Reject unsupported API casks earlier
- stop `gimp` on Linux before source reloads fail
- avoid queued downloads for unsupported API-backed casks
- cover `fetch` and `enqueue_downloads` with regression tests
2026-04-23 19:54:21 +01:00
Issy Long f3fb592638 sorbet: Make tests typed: false
- Now that we've enabled `--experimental-rspec-mode` [1], let's start
  using Sorbet in tests at its basic `typed: false` level for now.
- This will ease the migration to `typed: true` of any or all tests we
  want to do in the future.

[1]: https://github.com/Homebrew/brew/pull/21742
2026-03-29 16:37:52 +01:00
8484bfc0d1 Add HOMEBREW_FORBIDDEN_CASK_ARTIFACTS feature implementation
Co-authored-by: MikeMcQuaid <125011+MikeMcQuaid@users.noreply.github.com>
Co-authored-by: p-linnane <105994585+p-linnane@users.noreply.github.com>
2025-10-06 17:21:42 +01:00
Bevan Kay 9a60526c47 test/cask: speed up tests 2025-08-19 00:11:51 +10:00
Bevan Kay 9cb2b65319 cask/dsl/rename: add new rename dsl 2025-08-12 23:24:20 +10:00
Mike McQuaid bafc57cfe1 Add Cask install/upgrade/reinstall support for download queue
This will allow installing/upgrading/reinstalling casks and all their
dependencies in parallel.
2025-07-30 08:18:35 +01:00
Mike McQuaid 94416e82f0 Add new odeprecated, odisabled, remove disabled code.
Prepare the usual deprecation cycle for Homebrew 4.4.0.
2024-09-24 10:15:34 +01:00
Mike McQuaid 7abc6f4349 cask/installer: improve *_FORBIDDEN_* env handling.
- Improve the error message when a cask or formula is forbidden by an
  environment variable (fixes #17880)
- Move the `forbidden_tap_check` and `forbidden_cask_and_formula_check`
  methods to the top of the `install` method, so that they are checked
  before the main cask is downloaded.
2024-07-27 16:13:51 +01:00
Carlo Cabrera be29afa5f7 Fix brew style 2024-05-06 15:26:29 +01:00
Carlo Cabrera 3b794fc6e8 formula_installer, cask/installer: add tests for HOMEBREW_ALLOWED_TAPS 2024-05-06 15:22:48 +01:00
Carlo Cabrera 34387bfc8a cask/installer: update to match formula_installer 2024-05-05 14:00:02 +01:00
Mike McQuaidandBo Anderson 1474806527 Add more HOMEBREW_FORBIDDEN_* configuration
We already had `HOMEBREW_FORBIDDEN_LICENSES` but this commit adds
`HOMEBREW_FORBIDDEN_CASKS`, `HOMEBREW_FORBIDDEN_FORMULAE` and
`HOMEBREW_FORBIDDEN_TAPS` for also forbidding those.

Relatedly, add `HOMEBREW_FORBIDDEN_OWNER` and
`HOMEBREW_FORBIDDEN_OWNER_CONTACT` to allow customising these
messages.

There were no existing tests for `HOMEBREW_FORBIDDEN_LICENSES` so have
added more tests for all of these checks.

Co-authored-by: Bo Anderson <mail@boanderson.me>
2024-04-08 16:38:32 +01:00
Douglas EichelbergerandMike McQuaid 26eda5a303 git grep -l '^describe' | xargs gsed -i 's|^describe|RSpec.describe|g' 2024-02-19 13:57:27 +00:00
apainintheneck c9dea04bd4 cmd/install: upgrade already installed casks
Previously, the behavior was to warn users that a cask was already
installed and then skip modifying the installed version. This is
different to how we handled things with formulas. For them we would
upgrade any already installed formulas. This just brings casks in line
with what we already do with formulas.

Changes:
- cmd/install: Upgrade already installed casks if HOMEBREW_NO_INSTALL_UPGRADE
  is not set
- env_config: Update wording of HOMEBREW_NO_INSTALL_UPGRADE to include casks
- remove error that was only used to alert about already installed casks

Note:
- The upgrade command for casks defaults to --greedy when you pass named casks
  to the command which means that this will always default to that behavior
  since you must specify the name of the cask when installing.
2023-07-23 18:50:39 -07:00
Markus Reiter a3231a03fa Implement cask renames. 2023-05-12 21:17:30 +02:00
Markus Reiter df620ad3ba Make manual installers easier to open. 2023-05-08 08:25:32 +02:00
Bo Anderson 44f058edb5 Refactor formula, cask and Ruby source downloads to use shared code 2023-04-27 23:23:07 +01:00
Douglas Eichelberger 9075cbae62 brew style --fix 2023-04-21 09:58:50 -07:00
Douglas Eichelberger ac1e6ded9a git grep -l '# typed: false' | xargs gsed -i 's|# typed: false||g' 2023-04-21 09:57:47 -07:00
Issy Long 3a83b5492c rubocop: Clean up Style/BlockDelimiters excludes and autofix offenses
- The defaults of using "do ... end" for multi-line blocks everywhere is
  good, better than switching everything to braces everywhere.
2023-03-08 23:54:22 +00:00
hyuraku 122b24e9ff repair zap spec 2023-03-06 22:27:54 +09:00
hyuraku e0416e0f65 add zap option spec to cask_installer spec 2023-03-06 22:27:53 +09:00
apainintheneck c19017c6bd Make Cask#to_h work without the API
Set metadata when we load casks from the source API.

Set `@tap_git_head` manually.

Also, allow `auto_update` to receive false.
This is only done for consistency.

Stop double printing the `kext` caveat.

Handle Array elements correctly when substituting
path elements in artifacts. This affected how the
Uninstall Signal keys were evaluated (they are
represented as arrays of arrays).
2023-02-28 19:36:20 -08:00
apainintheneck 9af04fdf38 Add installer tests 2023-02-26 11:26:44 -08:00
Douglas Eichelberger 585098a9b9 Resolve cask/installer_spec violation 2023-01-22 17:09:55 -08:00
apainintheneck b85f407e95 Only upgrade :latest casks when --greedy and the cask has been updated
A sha256 hash of the previous download is stored and compared with
new downloads before updating :latest casks. This prevents unnecessary
reinstalls when the cask hasn't been updated.

Move download path to cask from installer to prevent unnecessary
redownloads of casks.
2022-05-17 16:15:05 -07:00
xxyzz 1b877273d8 Don't print Cask installed error message when --quiet is used 2022-05-11 11:03:20 +08:00
apainintheneck 0dd3764041 Allow casks with outdated caskfiles to be reinstalled
The problem occurred when calling `brew reinstall` on a cask
with an out of date caskfile.

To solve the problem Cask::Installer#uninstall_existing_cask has been changed to
catch a possible CaskInvalidError when trying to load outdated
caskfiles using Cask::CaskLoader#load.
2022-05-02 23:39:18 -07:00