Commit Graph
230 Commits
Author SHA1 Message Date
Mike McQuaid 4b375799df Tolerate missing bottle manifests in prefetches
- After #23381, homebrew-core CI fails installing dependencies on
  version-bump PRs: the bumped formula's stale bottle block derives
  its manifest URL from the new version, whose bottle has not been
  published yet, and `DownloadQueue#fetch` treats every bottle
  manifest failure as fatal.
- Before that change the default ask-mode plan fetched manifests
  synchronously via `Formula#fetch_bottle_tab`, which rescues
  download errors so dependency resolution falls back to a full
  install, and the installer's memoisation then kept the queue from
  retrying the download.
- Add `DownloadQueue#fetch(allow_failures:)`: failed downloads are
  still reported but neither raise nor mark the fetch or run as
  failed. Use it for the metadata-only drains (`fetch_formulae`'s
  bottle manifest waits, `brew install`'s ask-mode drain and
  `brew upgrade`'s tab prefetch), restoring the synchronous path's
  tolerance. Manifest failures in fetches that pour bottles remain
  fatal.
2026-08-03 14:25:47 +01:00
Mike McQuaid 284cd0ed4c Start install downloads before local-only checks
- `brew install` only started network transfers after preinstall
  checks and, in ask mode, fetched each bottle manifest serially
  while computing the dry-run plan.
- Enqueue bottle manifests on the shared download queue right after
  building formula installers in both ask and no-ask modes so
  transfers overlap preinstall checks and dependant scanning and
  manifests for multiple formulae download concurrently. Ask mode
  drains them under a `Downloading bottle manifests` heading before
  printing the plan; warm runs enqueue nothing and stay silent.
- Once downloads are confirmed (`--yes` installs, reinstall, upgrade
  and other `Install.fetch_formulae` callers), also enqueue the
  formula's own bottle in `FormulaInstaller#prelude_fetch`: the blob
  URL needs neither the manifest nor dependency resolution, so both
  transfer concurrently and staging joins the same queue cycle.
- Skip the `enqueue_fetch` requeue for bottles the prelude fetch
  already enqueued so a completed early download is not reported a
  second time.
- Give `DownloadQueue#fetch` `only:` and `heading:` so a heading is
  always printed before any queue output and never for empty fetches:
  dependency resolution inside `Install.fetch_formulae` waits on just
  the bottle manifests it needs (under `Downloading bottle manifests`)
  and the cask source pre-fetch on just its cask files, keeping other
  in-flight downloads queued and unreported so bottles only ever
  appear under the `Fetching downloads for:` heading, which now
  prints lazily from the fetch that reports them (`brew upgrade`
  enqueues before it knows that heading's contents). This replaces
  `Install.show_combined_fetch_downloads_heading`, `brew upgrade`'s
  manual manifest heading predicate and its dead
  `show_downloads_heading` plumbing.
- Instrument `Install.perform_preinstall_checks_once` as a
  `preinstall_checks` phase timing to keep the reordering visible.
- Archive-cold `brew install hello`: the first transfer starts at
  ~375ms instead of ~442ms, the bottle no longer waits for the
  manifest round trip (~672ms before, ~375ms now) and `--yes` wall
  time drops around 30%. Two-formula ask-mode installs drop one full
  manifest round trip (~1240ms to ~1030ms).
2026-08-03 08:54:24 +01:00
Mike McQuaid 55e268f8a0 install: isolate formula and cask fetch errors
- One malformed formula or cask (e.g. a bottle `root_url` that is an
  invalid URI) raised while enqueueing downloads and aborted the whole
  `brew upgrade` batch with an internal stack trace.
- Rescue anything raised by an individual formula's or cask's prelude
  and enqueue steps so the offending package is reported and skipped,
  the rest still proceed and the command exits nonzero.

Fixes https://github.com/Homebrew/brew/issues/23377.
2026-07-31 20:32:40 +01:00
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
Mike McQuaid 63628631c2 Respect ignored dependencies in ask plans 2026-07-23 11:23:14 +01:00
Sean Molenaar 9bb718d934 Add JSON output method for doctor 2026-07-17 09:56:14 +02:00
Harald Nordgren 2b741705ef Split and columnize dry-run dependency listings
Group `brew upgrade --dry-run` dependencies into separate "Would install"
and "Would upgrade" sections aligned with format_upgrade_summary, and read
the installed version from the kegs so unlinked upgrades still show
"old -> new".

Also stop the first dependency in the "Installing dependencies for" line
from rendering bolder than the rest.
2026-07-05 12:15:59 +02:00
Harald Nordgren ec61b24045 Revert "Merge pull request #22767 from HaraldNordgren/simplify-pretty-install-status-outdated" 2026-06-18 10:28:11 +02:00
Harald Nordgren 05167c9078 Drop redundant installed guard from pretty_install_status callers
`pretty_install_status` already gates the upgradable status on
`installed && outdated`, so callers passing
`outdated: installed && formula.outdated?` duplicated the guard.
Pass `outdated: formula.outdated?` directly and let the method
combine it with `installed`.
2026-06-17 09:59:35 +02:00
Harald Nordgren 5ae846fe2e Don't bold upgradable dependencies in install plans
The install dependency list is already a plain "would install" list,
so bolding the upgradable entries made them stand out inconsistently
from the fresh installs. Add a `bold:` option to `pretty_upgradable`
and `pretty_install_status` (defaulting to `true` to preserve `brew
info` styling) and pass `bold: false` from the install plans.
2026-06-16 23:57:40 +02:00
Harald Nordgren 191b5834a3 Annotate upgradable dependencies in install plans
Show installed-but-outdated dependencies with the upgradable status
already used by `brew info`, so the install dependency list signals
an upgrade rather than looking like a fresh install.
2026-06-16 17:57:00 +02:00
Mike McQuaid a40d2df7f5 Start install downloads earlier
- Start formula prelude fetches before dependant checks when no prompt can block.
- Share idempotent prelude-fetch queueing across install, reinstall and upgrade.
- Reuse the early queue later to avoid changing pour/link behaviour.
2026-06-12 19:16:03 +01:00
Mike McQuaid 717fc4b630 Refine tap trust warnings
- keep `brew doctor` visibility while moving install-time hints to
  non-fatal preinstall diagnostics
- document why explicit trust matters before the default changes in
  Homebrew 6.0.0 or 5.2.0
- clean untrusted hosted-runner taps before test-bot setup so unrelated
  runner state does not fail `brew doctor`
2026-06-01 19:27:28 +01:00
Mike McQuaidandPatrick Linnane e0d818bbbd Make bundle cleanup ask before removal
- Prevent `brew bundle install --cleanup` from removing packages unless
  ask mode or an explicit force cleanup path is used.
- Share the ask confirmation helper with install, upgrade and bundle
  cleanup flows so prompts behave consistently.
- Keep generated help and completions aligned with the safer cleanup
  contract.

Signed-off-by: Patrick Linnane <patrick@linnane.io>
2026-05-29 09:55:41 -07:00
Mike McQuaidandGitHub 0cba9a27bd Merge pull request #22434 from Homebrew/fix-install-warning-annotations
Avoid install warning annotations
2026-05-28 08:58:30 +00:00
Mike McQuaid e49b5ca88d Accept one-key ask confirmations
- Allow `brew --ask` prompts to proceed from `y` or `Y`.
- Abort from `n` or `N` without waiting for a newline.
- Treat Escape, Ctrl-D and Ctrl-C as quiet cancellation.
- Reprompt after other keys so users choose explicitly.
2026-05-28 09:35:26 +01:00
Mike McQuaid 9f7daa134e Avoid install warning annotations
- Keep idempotent `brew install` warnings visible in CI logs.
- Avoid noisy GitHub Actions annotations for harmless installs.
- Preserve annotation behaviour for other `opoo` callers.
2026-05-28 08:54:37 +01:00
Mike McQuaidandGitHub 0defe2a748 Merge pull request #22399 from Homebrew/cask-dry-run-dependencies
install: avoid cask dry-run keg reads
2026-05-24 15:16:14 +00:00
Mike McQuaid 6111bbd6b0 install: avoid cask dry-run keg reads
- avoid installed tab reads for pending cask formula deps
- keep cask ask-mode plans from failing on absent kegs
2026-05-23 19:03:53 +01: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 3c7a62aa4d Default ask mode for developers
- Set `HOMEBREW_ASK` before Ruby starts so `EnvConfig.ask?`
  can stay generated.
- Let `HOMEBREW_NO_ASK` suppress environment defaults while
  keeping explicit `--ask` authoritative.
- Document and enforce TTY-only confirmation prompts so
  non-interactive runs keep moving.
2026-05-22 17:30:47 +01:00
Mike McQuaid 49a29117ed Align ask dry-run prompts
- Use dry-run-style `--ask` plans for install and reinstall commands.
- Make single-package operations proceed without a prompt e.g. if you
  `brew install foo` and there's no dependencies or dependents to install:
  just install without the prompt.
- Keep prompting when dependencies or dependents change the plan.
2026-05-20 15:28:12 +01:00
Mike McQuaid 4621504438 Add ask dependency plans and cask support
- Reuse dry-run upgrade planning for `--ask` so users see
  the same package list before choosing whether to continue.
- Suppress dependency and dependent dry-run sections when they
  duplicate the final `outdated packages` summary.
- Include available formula bottle download sizes inline in the
  dry-run package list.
- Keep `--ask` prompts default-no and ahead of downloads.
2026-05-16 10:39:34 +01:00
Sanket Kalekar 916f6a1711 tab: remove installed_as_dependency, use installed_on_request as source of truth
Replace all uses of installed_as_dependency with !installed_on_request.
Stop storing installed_as_dependency in new Tabs for both formulae and casks.
installed_on_request is now the single source of truth.

Fixes #21751
2026-04-27 09:19:24 +00:00
Douglas Eichelberger 3016643418 formula: use Pathname#empty? instead of children.empty? to check for installation
`Pathname#children.empty?` reads all directory entries into a Ruby Array
just to check whether any exist. `Pathname#empty?` (backed by
`Dir.empty?`) stops at the first entry, avoiding the full enumeration.

Microbenchmark (100,000 iterations, 11-entry Cellar keg directory):
  dir.children.empty? : 3084ms
  dir.empty?          : 2136ms (~1.44x faster)

`Formula#latest_version_installed?` and the prefix-installed check in
install.rb are called for every formula when commands like
`brew deps --installed` enumerate installed formulae, so the savings
compound across the full set.
2026-04-03 07:46:40 -07:00
Mike McQuaidandGitHub 4018153a23 Revert "Revert "Link versioned keg-only formulae by default"" 2026-03-07 07:07:33 +00:00
Steve Peters 9cb36f8569 Revert "Link versioned keg-only formulae by default"
This reverts commit f383ae2516
due to regressions in linking non-keg-only dependencies of
installed formulae.
2026-03-06 14:54:59 -08:00
Mike McQuaid f383ae2516 Link versioned keg-only formulae by default
Link `@` versioned or `-full` formulae by default if their unversioned
or unfull siblings are not installed.
2026-03-06 18:56:01 +00:00
Mike McQuaid c25ed8f088 Cleanup Download Queue
- cleanup various cases conditional on the download queue to always
  use it, now it's default and has been for a while
- ensure that both casks and formulae are fetched at the same time
  when possible to maximise concurrency
- generally DRY up the relevant download queue code
2026-03-01 13:59:20 +00:00
Douglas Eichelberger b95d9cef17 formatter: move formatting methods from kernel
Move `disk_usage_readable_size_unit`, `disk_usage_readable`,
`number_readable`, and `redact_secrets` from `extend/kernel.rb` to
`utils/formatter.rb` as class methods. These methods are formatting
utilities that fit better in the Formatter module.

Update all call sites and move corresponding specs to formatter_spec.rb.
2026-01-25 09:08:57 -08:00
Michael Cho 9c44782fbf Remove unused inherited_options
inherited_options feature was originally added to support cascading
`option :univeral` back in 793d6de6c3.

This is now dead code given `:universal` support was removed.
2025-12-06 13:20:59 -05:00
f3966cc91e install: apply Copilot fix
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-03 20:57:03 -05:00
Michael Cho 0fbb71700a install: typed: strict 2025-12-03 20:05:54 -05:00
botantony 06ad6161f8 download_queue: move exit 1 to the relevant cmd/* files
Signed-off-by: botantony <antonsm21@gmail.com>
2025-11-19 17:41:18 +01:00
Mike McQuaid 07091cfbea Simplify pluralisation of common words
Formulae, dependencies, tries are all used in multiple places so let's
simplify them
2025-09-12 09:02:43 +01:00
Mike McQuaid a1f112f3fe Move o* output methods to Utils::Output
This reduces the surface area of our `Kernel` monkeypatch and removes
the need to `include Kernel` in a bunch of modules.

While we're here, also move `Kernel#require?` to `Homebrew` and fully
scope the calls to it.
2025-08-20 19:20:19 +01:00
Eric Knibbe 827480f06b messages/comments: wording fixes 2025-08-16 00:57:59 -04:00
Mike McQuaid ec56bbf289 Improve extend/* Sorbet typing 2025-07-31 17:31:27 +01:00
ebb71682ab Improve error message for tap conflicts in brew install
Co-authored-by: MikeMcQuaid <125011+MikeMcQuaid@users.noreply.github.com>
Co-authored-by: carlocab <30379873+carlocab@users.noreply.github.com>
2025-07-25 09:39:19 +01:00
Mike McQuaidandCarlo Cabrera e10d4c43c2 Optionally use DownloadQueue for reinstall, upgrade.
Follow up on `DownloadQueue` for download concurrency on `brew fetch`
and `brew install` to also add support for `brew reinstall` and
`brew upgrade`.

This required a fair bit of refactoring to make this work so I've also
made `install.rb`, `reinstall.rb` and `upgrade.rb` `typed: strict` to
add some extra guardrails from Sorbet here.

Co-authored-by: Carlo Cabrera <github@carlo.cab>
2025-07-24 15:41:03 +01:00
Bo Anderson b2ffe7b060 Fix handling of formula install blocks 2025-07-23 21:19:22 +01:00
Mike McQuaidandCarlo Cabrera 5cc6722372 Optionally use DownloadQueue for brew install
Allowing using `HOMEBREW_DOWNLOAD_CONCURRENCY` to use the
`DownloadQueue` for `brew install` by downloading and extracting
bottles in parallel.

This requires some fixes in e.g. `Dependency` and `FormulaInstaller`
to be able to front-load all downloads and handle parallelisation of
bottle pouring.

Behaviour without `HOMEBREW_DOWNLOAD_CONCURRENCY` set should be
unchanged.

Attestations are not handled for now and the UI should be improved
before we roll this out to users.

Post-install upgrades are not yet parallelised.

Co-authored-by: Carlo Cabrera <github@carlo.cab>
2025-07-18 15:00:23 +01:00
4513a43d53 Fix RuboCop failures.
Co-authored-by: Patrick Linnane <patrick@linnane.io>
Co-authored-by: Carlo Cabrera <github@carlo.cab>
Co-authored-by: Thierry Moisan <thierry.moisan@gmail.com>
Co-authored-by: Mike McQuaid <mike@mikemcquaid.com>
2025-07-14 19:12:38 +01:00
Carlo CabreraandGitHub 57024a9f2d Merge pull request #20195 from tyuwags/ask-option-refactoring
Ask option refactoring
2025-07-03 12:28:46 +00:00
Issy LongandGitHub c7af63488d Be more explicit that we want the formula name 2025-07-03 11:29:50 +01:00
Issy Long 5310c5e730 Fix "undefined method 'name' for an instance of FormulaInstaller"
- Because `name` is not a method on `FormulaInstaller`, instead
  `formula` shows the name.
- Fixes issue 20199.

Before:

```
$ brew install -n hello
Error: undefined method 'name' for an instance of FormulaInstaller
Warning: Removed Sorbet lines from backtrace!
Rerun with `--verbose` to see the original backtrace
/opt/homebrew/Library/Homebrew/install.rb:330:in 'Array#map'
/opt/homebrew/Library/Homebrew/install.rb:330:in 'Homebrew::Install.install_formulae'
```

After:

```
$ brew install -n hello
==> Would install 1 formula:
hello
```
2025-07-01 22:25:22 +01:00
thibhero c7f7ab5631 duplicate in ask_formulae 2025-06-29 23:29:18 -04:00
thibhero e731b572f3 correcting rescue to use installer and not formula 2025-06-27 03:50:26 -04:00
thibhero 9e131d0794 correcting error of installation dependency
resolves #20181
2025-06-26 19:12:39 -04:00
bcc7f0f796 Update Library/Homebrew/install.rb
Co-authored-by: Bo Anderson <mail@boanderson.me>
2025-06-20 11:10:18 -04:00