mirror of
https://github.com/Homebrew/brew.git
synced 2025-07-14 16:09:03 +08:00

- Homebrew Bundle referred to formulae as "brews". But it referred to casks as "casks" and taps as "taps". - Let's use the same terminology everywhere. - (I know that `brew "hello"` is the formula syntax in the Brewfile, so I'm not changing that (though would be up for it, in a backwards compatible manner), just making the code more consistent.)
157 lines
5.1 KiB
Ruby
157 lines
5.1 KiB
Ruby
# typed: true
|
|
# frozen_string_literal: true
|
|
|
|
module Homebrew
|
|
module Bundle
|
|
module Checker
|
|
class Base
|
|
# Implement these in any subclass
|
|
# PACKAGE_TYPE = :pkg
|
|
# PACKAGE_TYPE_NAME = "Package"
|
|
|
|
def exit_early_check(packages, no_upgrade:)
|
|
work_to_be_done = packages.find do |pkg|
|
|
!installed_and_up_to_date?(pkg, no_upgrade:)
|
|
end
|
|
|
|
Array(work_to_be_done)
|
|
end
|
|
|
|
def failure_reason(name, no_upgrade:)
|
|
reason = if no_upgrade && Bundle.upgrade_formulae.exclude?(name)
|
|
"needs to be installed."
|
|
else
|
|
"needs to be installed or updated."
|
|
end
|
|
"#{self.class.const_get(:PACKAGE_TYPE_NAME)} #{name} #{reason}"
|
|
end
|
|
|
|
def full_check(packages, no_upgrade:)
|
|
packages.reject { |pkg| installed_and_up_to_date?(pkg, no_upgrade:) }
|
|
.map { |pkg| failure_reason(pkg, no_upgrade:) }
|
|
end
|
|
|
|
def checkable_entries(all_entries)
|
|
require "bundle/skipper"
|
|
all_entries.select { |e| e.type == self.class.const_get(:PACKAGE_TYPE) }
|
|
.reject(&Bundle::Skipper.method(:skip?))
|
|
end
|
|
|
|
def format_checkable(entries)
|
|
checkable_entries(entries).map(&:name)
|
|
end
|
|
|
|
def installed_and_up_to_date?(_pkg, no_upgrade: false)
|
|
raise NotImplementedError
|
|
end
|
|
|
|
def find_actionable(entries, exit_on_first_error: false, no_upgrade: false, verbose: false)
|
|
requested = format_checkable entries
|
|
|
|
if exit_on_first_error
|
|
exit_early_check(requested, no_upgrade:)
|
|
else
|
|
full_check(requested, no_upgrade:)
|
|
end
|
|
end
|
|
end
|
|
|
|
CheckResult = Struct.new :work_to_be_done, :errors
|
|
|
|
CHECKS = {
|
|
taps_to_tap: "Taps",
|
|
casks_to_install: "Casks",
|
|
extensions_to_install: "VSCode Extensions",
|
|
apps_to_install: "Apps",
|
|
formulae_to_install: "Formulae",
|
|
formulae_to_start: "Services",
|
|
}.freeze
|
|
|
|
def self.check(global: false, file: nil, exit_on_first_error: false, no_upgrade: false, verbose: false)
|
|
require "bundle/brewfile"
|
|
@dsl ||= Brewfile.read(global:, file:)
|
|
|
|
check_method_names = CHECKS.keys
|
|
|
|
errors = []
|
|
enumerator = exit_on_first_error ? :find : :map
|
|
|
|
work_to_be_done = check_method_names.public_send(enumerator) do |check_method|
|
|
check_errors =
|
|
send(check_method, exit_on_first_error:, no_upgrade:, verbose:)
|
|
any_errors = check_errors.any?
|
|
errors.concat(check_errors) if any_errors
|
|
any_errors
|
|
end
|
|
|
|
work_to_be_done = Array(work_to_be_done).flatten.any?
|
|
|
|
CheckResult.new work_to_be_done, errors
|
|
end
|
|
|
|
def self.casks_to_install(exit_on_first_error: false, no_upgrade: false, verbose: false)
|
|
require "bundle/cask_checker"
|
|
Homebrew::Bundle::Checker::CaskChecker.new.find_actionable(
|
|
@dsl.entries,
|
|
exit_on_first_error:, no_upgrade:, verbose:,
|
|
)
|
|
end
|
|
|
|
def self.formulae_to_install(exit_on_first_error: false, no_upgrade: false, verbose: false)
|
|
require "bundle/brew_checker"
|
|
Homebrew::Bundle::Checker::BrewChecker.new.find_actionable(
|
|
@dsl.entries,
|
|
exit_on_first_error:, no_upgrade:, verbose:,
|
|
)
|
|
end
|
|
|
|
def self.taps_to_tap(exit_on_first_error: false, no_upgrade: false, verbose: false)
|
|
require "bundle/tap_checker"
|
|
Homebrew::Bundle::Checker::TapChecker.new.find_actionable(
|
|
@dsl.entries,
|
|
exit_on_first_error:, no_upgrade:, verbose:,
|
|
)
|
|
end
|
|
|
|
def self.apps_to_install(exit_on_first_error: false, no_upgrade: false, verbose: false)
|
|
require "bundle/mac_app_store_checker"
|
|
Homebrew::Bundle::Checker::MacAppStoreChecker.new.find_actionable(
|
|
@dsl.entries,
|
|
exit_on_first_error:, no_upgrade:, verbose:,
|
|
)
|
|
end
|
|
|
|
def self.extensions_to_install(exit_on_first_error: false, no_upgrade: false, verbose: false)
|
|
require "bundle/vscode_extension_checker"
|
|
Homebrew::Bundle::Checker::VscodeExtensionChecker.new.find_actionable(
|
|
@dsl.entries,
|
|
exit_on_first_error:, no_upgrade:, verbose:,
|
|
)
|
|
end
|
|
|
|
def self.formulae_to_start(exit_on_first_error: false, no_upgrade: false, verbose: false)
|
|
require "bundle/brew_service_checker"
|
|
Homebrew::Bundle::Checker::BrewServiceChecker.new.find_actionable(
|
|
@dsl.entries,
|
|
exit_on_first_error:, no_upgrade:, verbose:,
|
|
)
|
|
end
|
|
|
|
def self.reset!
|
|
require "bundle/cask_dumper"
|
|
require "bundle/formula_dumper"
|
|
require "bundle/mac_app_store_dumper"
|
|
require "bundle/tap_dumper"
|
|
require "bundle/brew_services"
|
|
|
|
@dsl = nil
|
|
Homebrew::Bundle::CaskDumper.reset!
|
|
Homebrew::Bundle::FormulaDumper.reset!
|
|
Homebrew::Bundle::MacAppStoreDumper.reset!
|
|
Homebrew::Bundle::TapDumper.reset!
|
|
Homebrew::Bundle::BrewServices.reset!
|
|
end
|
|
end
|
|
end
|
|
end
|