Files
brew/Library/Homebrew/cmd/readall.rb
T
Mike McQuaid d413e1630e Speed up brew style and brew readall
- `brew readall`: validate tap formulae and casks across forked
  workers (combination loop inside each worker so the `on_system`
  cache keeps its per-file locality) and syntax-check Ruby files
  in-process with `RubyVM::InstructionSequence.compile_file` and a
  `Warning` buffer instead of spawning `ruby -c -w` per file.
- `brew style`: run shellcheck+shfmt and actionlint on background
  threads with buffered output while RuboCop runs on the main
  thread, chunk shellcheck across CPU cores and pass `--parallel`
  to RuboCop with `--fix` (supported since RuboCop 1.41).
- Resolve linter executables before spawning threads so they
  cannot race to install formulae.
- `Readall.valid_aliases?`: use a single glob and `Set` lookup
  rather than one glob per alias.
- Fix an `end` indentation warning in `cask/cask.rb` that made
  `brew readall --syntax` fail.
- Hyperfine benchmarks (18-core Mac, mean of 2 runs, warm RuboCop
  cache for style runs, all exit codes 0):
  - `brew readall homebrew/core`: 34.36s -> 4.71s (7.3x faster)
  - `brew readall homebrew/cask`: 40.69s -> 5.17s (7.9x faster)
  - `brew style homebrew/core` (warm): 2.93s -> 2.20s
  - `brew style homebrew/cask` (warm): 2.37s -> 2.18s
  - `brew style` on Homebrew/brew itself: 13.2s -> 7.8s
  - `brew readall --syntax`: 18.2s -> 0.5s
- Tap style runs are RuboCop-bound so barely change; the larger
  style win is on Homebrew/brew where all four linters run. CI
  runners with fewer cores should expect roughly 3-4x on readall.
2026-08-04 15:13:59 +01:00

74 lines
2.6 KiB
Ruby

# typed: strict
# frozen_string_literal: true
require "abstract_command"
require "readall"
require "env_config"
module Homebrew
module Cmd
class ReadallCmd < AbstractCommand
cmd_args do
description <<~EOS
Import all items from the specified <tap>, or from all installed taps if none is provided.
This can be useful for debugging issues across all items when making
significant changes to `formula.rb`, testing the performance of loading
all items or checking if any current formulae/casks have Ruby issues.
EOS
flag "--os=",
description: "Read using the given operating system. (Pass `all` to simulate all operating systems.)"
flag "--arch=",
description: "Read using the given CPU architecture. (Pass `all` to simulate all architectures.)"
switch "--aliases",
description: "Verify any alias symlinks in each tap."
switch "--syntax",
description: "Syntax-check all of Homebrew's Ruby files (if no <tap> is passed)."
switch "--eval-all",
description: "Evaluate all available formulae and casks, whether installed or not.",
env: :eval_all,
odeprecated: true
switch "--no-simulate",
description: "Don't simulate other system configurations when checking formulae and casks."
named_args :tap
end
sig { override.void }
def run
Homebrew.with_no_api_env do
if args.syntax? && args.no_named?
scan_files = "#{HOMEBREW_LIBRARY_PATH}/**/*.rb"
ruby_files = Dir.glob(scan_files).grep_v(%r{/(vendor)/}).map { Pathname(it) }
Homebrew.failed = true unless Readall.valid_ruby_syntax?(ruby_files)
end
options = {
aliases: args.aliases?,
no_simulate: args.no_simulate?,
}
options[:os_arch_combinations] = args.os_arch_combinations if args.os || args.arch
eval_all = args.eval_all?
eval_all ||= args.no_named? && Homebrew::EnvConfig.tap_trust_configured?
taps = if args.no_named?
unless eval_all
raise UsageError,
"`brew readall` needs a tap, `HOMEBREW_REQUIRE_TAP_TRUST=1` or " \
"`HOMEBREW_NO_REQUIRE_TAP_TRUST=1` set!"
end
Tap.installed
else
args.named.to_installed_taps
end
taps.each do |tap|
Homebrew.failed = true unless Readall.valid_tap?(tap, **options)
end
end
end
end
end
end