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.
This commit is contained in:
parent
fc85e051aa
commit
a1f112f3fe
@ -74,6 +74,7 @@ Style/Documentation:
|
||||
- resource.rb
|
||||
- startup/config.rb
|
||||
- utils/inreplace.rb
|
||||
- utils/output.rb
|
||||
- utils/shebang.rb
|
||||
- utils/string_inreplace_extension.rb
|
||||
- version.rb
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
require "cli/parser"
|
||||
require "shell_command"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Subclass this to implement a `brew` command. This is preferred to declaring a named function in the `Homebrew`
|
||||
@ -19,6 +20,7 @@ module Homebrew
|
||||
# @api public
|
||||
class AbstractCommand
|
||||
extend T::Helpers
|
||||
include Utils::Output::Mixin
|
||||
|
||||
abstract!
|
||||
|
||||
|
@ -2,10 +2,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "fileutils"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Aliases
|
||||
class Alias
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
sig { returns(String) }
|
||||
attr_accessor :name
|
||||
|
||||
|
@ -2,9 +2,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "aliases/alias"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Aliases
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
RESERVED = T.let((
|
||||
Commands.internal_commands +
|
||||
Commands.internal_developer_commands +
|
||||
|
@ -6,10 +6,13 @@ require "api/cask"
|
||||
require "api/formula"
|
||||
require "api/internal"
|
||||
require "base64"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Helper functions for using Homebrew's formulae.brew.sh API.
|
||||
module API
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
extend Cachable
|
||||
|
||||
HOMEBREW_CACHE_API = T.let((HOMEBREW_CACHE/"api").freeze, Pathname)
|
||||
|
@ -7,10 +7,12 @@ require "utils/popen"
|
||||
require "utils/github/api"
|
||||
require "exceptions"
|
||||
require "system_command"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Attestation
|
||||
extend SystemCommand::Mixin
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
# @api private
|
||||
HOMEBREW_CORE_REPO = "Homebrew/homebrew-core"
|
||||
|
@ -16,6 +16,7 @@ end
|
||||
std_trap = trap("INT") { exit! 130 } # no backtrace thanks
|
||||
|
||||
require_relative "global"
|
||||
require "utils/output"
|
||||
|
||||
begin
|
||||
trap("INT", std_trap) # restore default CTRL-C handler
|
||||
@ -115,14 +116,14 @@ begin
|
||||
converted_cmd = cmd.downcase.tr("-", "_")
|
||||
case_error = "undefined method `#{converted_cmd}' for module Homebrew"
|
||||
private_method_error = "private method `#{converted_cmd}' called for module Homebrew"
|
||||
odie "Unknown command: brew #{cmd}" if [case_error, private_method_error].include?(e.message)
|
||||
Utils::Output.odie "Unknown command: brew #{cmd}" if [case_error, private_method_error].include?(e.message)
|
||||
|
||||
raise
|
||||
end
|
||||
end
|
||||
elsif (path = Commands.external_ruby_cmd_path(cmd))
|
||||
Homebrew.running_command = cmd
|
||||
require?(path)
|
||||
Homebrew.require?(path)
|
||||
exit Homebrew.failed? ? 1 : 0
|
||||
elsif Commands.external_cmd_path(cmd)
|
||||
%w[CACHE LIBRARY_PATH].each do |env|
|
||||
@ -139,14 +140,16 @@ begin
|
||||
possible_tap.installed? ||
|
||||
(blocked_tap = Tap.untapped_official_taps.include?(possible_tap.name))
|
||||
if blocked_tap
|
||||
onoe <<~EOS
|
||||
Utils::Output.onoe <<~EOS
|
||||
`brew #{cmd}` is unavailable because #{possible_tap.name} was manually untapped.
|
||||
Run `brew tap #{possible_tap.name}` to reenable `brew #{cmd}`.
|
||||
EOS
|
||||
end
|
||||
# Check for cask explicitly because it's very common in old guides
|
||||
odie "`brew cask` is no longer a `brew` command. Use `brew <command> --cask` instead." if cmd == "cask"
|
||||
odie "Unknown command: brew #{cmd}"
|
||||
if cmd == "cask"
|
||||
Utils::Output.odie "`brew cask` is no longer a `brew` command. Use `brew <command> --cask` instead."
|
||||
end
|
||||
Utils::Output.odie "Unknown command: brew #{cmd}"
|
||||
end
|
||||
|
||||
# Unset HOMEBREW_HELP to avoid confusing the tap
|
||||
@ -171,7 +174,7 @@ rescue UsageError => e
|
||||
require "help"
|
||||
Homebrew::Help.help cmd, remaining_args: args&.remaining || [], usage_error: e.message
|
||||
rescue SystemExit => e
|
||||
onoe "Kernel.exit" if args&.debug? && !e.success?
|
||||
Utils::Output.onoe "Kernel.exit" if args&.debug? && !e.success?
|
||||
if args&.debug? || ARGV.include?("--debug")
|
||||
require "utils/backtrace"
|
||||
$stderr.puts Utils::Backtrace.clean(e)
|
||||
@ -209,7 +212,7 @@ rescue BuildError => e
|
||||
rescue RuntimeError, SystemCallError => e
|
||||
raise if e.message.empty?
|
||||
|
||||
onoe e
|
||||
Utils::Output.onoe e
|
||||
if args&.debug? || ARGV.include?("--debug")
|
||||
require "utils/backtrace"
|
||||
$stderr.puts Utils::Backtrace.clean(e)
|
||||
@ -218,7 +221,7 @@ rescue RuntimeError, SystemCallError => e
|
||||
exit 1
|
||||
# Catch any other types of exceptions.
|
||||
rescue Exception => e # rubocop:disable Lint/RescueException
|
||||
onoe e
|
||||
Utils::Output.onoe e
|
||||
|
||||
method_deprecated_error = e.is_a?(MethodDeprecatedError)
|
||||
require "utils/backtrace"
|
||||
|
@ -16,9 +16,12 @@ require "fcntl"
|
||||
require "utils/socket"
|
||||
require "cmd/install"
|
||||
require "json/add/exception"
|
||||
require "utils/output"
|
||||
|
||||
# A formula build.
|
||||
class Build
|
||||
include Utils::Output::Mixin
|
||||
|
||||
attr_reader :formula, :deps, :reqs, :args
|
||||
|
||||
def initialize(formula, options, args:)
|
||||
|
@ -6,11 +6,14 @@ require "exceptions"
|
||||
require "extend/ENV"
|
||||
require "utils"
|
||||
require "PATH"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Bundle
|
||||
module Commands
|
||||
module Exec
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
PATH_LIKE_ENV_REGEX = /.+#{File::PATH_SEPARATOR}/
|
||||
|
||||
sig {
|
||||
|
@ -3,11 +3,14 @@
|
||||
|
||||
require "json"
|
||||
require "tsort"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Bundle
|
||||
# TODO: refactor into multiple modules
|
||||
module FormulaDumper
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
def self.reset!
|
||||
require "bundle/brew_services"
|
||||
|
||||
|
@ -1,9 +1,13 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Bundle
|
||||
module Remover
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
def self.remove(*args, type:, global:, file:)
|
||||
require "bundle/brewfile"
|
||||
require "bundle/dumper"
|
||||
|
@ -1,9 +1,13 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Bundle
|
||||
module WhalebrewDumper
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
sig { void }
|
||||
def self.reset!
|
||||
@images = T.let(nil, T.nilable(T::Array[String]))
|
||||
|
@ -1,9 +1,13 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Bundle
|
||||
module WhalebrewInstaller
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
def self.reset!
|
||||
@installed_images = nil
|
||||
end
|
||||
|
@ -2,16 +2,19 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "extend/object/deep_dup"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
# Abstract superclass for all artifacts.
|
||||
class AbstractArtifact
|
||||
extend T::Helpers
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
abstract!
|
||||
|
||||
include Comparable
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
def self.english_name
|
||||
@english_name ||= T.must(name).sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1 \2')
|
||||
|
@ -14,12 +14,14 @@ require "formula_name_cask_token_auditor"
|
||||
require "utils/curl"
|
||||
require "utils/git"
|
||||
require "utils/shared_audits"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
# Audit a cask for various problems.
|
||||
class Audit
|
||||
include SystemCommand::Mixin
|
||||
include ::Utils::Curl
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
Error = T.type_alias do
|
||||
{
|
||||
|
@ -2,10 +2,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/audit"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
# Helper class for auditing all available languages of a cask.
|
||||
class Auditor
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
# TODO: use argument forwarding (...) when Sorbet supports it in strict mode
|
||||
sig {
|
||||
params(
|
||||
|
@ -8,6 +8,7 @@ require "cask/dsl"
|
||||
require "cask/metadata"
|
||||
require "cask/tab"
|
||||
require "utils/bottles"
|
||||
require "utils/output"
|
||||
require "api_hashable"
|
||||
|
||||
module Cask
|
||||
@ -15,6 +16,7 @@ module Cask
|
||||
class Cask
|
||||
extend Forwardable
|
||||
extend APIHashable
|
||||
extend ::Utils::Output::Mixin
|
||||
include Metadata
|
||||
|
||||
# The token of this {Cask}.
|
||||
|
@ -5,6 +5,7 @@ require "cask/cache"
|
||||
require "cask/cask"
|
||||
require "uri"
|
||||
require "utils/curl"
|
||||
require "utils/output"
|
||||
require "extend/hash/keys"
|
||||
require "api"
|
||||
|
||||
@ -12,12 +13,14 @@ module Cask
|
||||
# Loads a cask from various sources.
|
||||
module CaskLoader
|
||||
extend Context
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
ALLOWED_URL_SCHEMES = %w[file].freeze
|
||||
private_constant :ALLOWED_URL_SCHEMES
|
||||
|
||||
module ILoader
|
||||
extend T::Helpers
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
interface!
|
||||
|
||||
|
@ -2,12 +2,15 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/user"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
# Helper functions for interacting with the `Caskroom` directory.
|
||||
#
|
||||
# @api internal
|
||||
module Caskroom
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def self.path
|
||||
@path ||= T.let(HOMEBREW_PREFIX/"Caskroom", T.nilable(Pathname))
|
||||
|
@ -5,6 +5,7 @@ require "autobump_constants"
|
||||
require "locale"
|
||||
require "lazy_object"
|
||||
require "livecheck"
|
||||
require "utils/output"
|
||||
|
||||
require "cask/artifact"
|
||||
require "cask/artifact_set"
|
||||
@ -32,6 +33,8 @@ require "on_system"
|
||||
module Cask
|
||||
# Class representing the domain-specific language used for casks.
|
||||
class DSL
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
ORDINARY_ARTIFACT_CLASSES = [
|
||||
Artifact::Installer,
|
||||
Artifact::App,
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
require "delegate"
|
||||
require "extend/hash/keys"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
class DSL
|
||||
@ -23,7 +24,7 @@ module Cask
|
||||
options.assert_valid_keys(*VALID_KEYS, *ODEPRECATED_KEYS)
|
||||
|
||||
options.keys.intersection(ODEPRECATED_KEYS).each do |key|
|
||||
Kernel.odeprecated "conflicts_with #{key}:"
|
||||
::Utils::Output.odeprecated "conflicts_with #{key}:"
|
||||
end
|
||||
|
||||
conflicts = options.transform_values { |v| Set.new(Kernel.Array(v)) }
|
||||
|
@ -3,9 +3,12 @@
|
||||
|
||||
require "json"
|
||||
require "cmd/info"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
class Info
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
sig { params(cask: Cask).returns(String) }
|
||||
def self.get_info(cask)
|
||||
require "cask/installer"
|
||||
|
@ -5,6 +5,7 @@ require "formula_installer"
|
||||
require "unpack_strategy"
|
||||
require "utils/topological_hash"
|
||||
require "utils/analytics"
|
||||
require "utils/output"
|
||||
|
||||
require "cask/config"
|
||||
require "cask/download"
|
||||
@ -15,6 +16,9 @@ require "cask/tab"
|
||||
module Cask
|
||||
# Installer for a {Cask}.
|
||||
class Installer
|
||||
extend ::Utils::Output::Mixin
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
sig {
|
||||
params(
|
||||
cask: ::Cask::Cask, command: T::Class[SystemCommand], force: T::Boolean, adopt: T::Boolean,
|
||||
|
@ -2,9 +2,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/artifact/relocated"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
class List
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
sig { params(casks: Cask, one: T::Boolean, full_name: T::Boolean, versions: T::Boolean).void }
|
||||
def self.list_casks(*casks, one: false, full_name: false, versions: false)
|
||||
output = if casks.any?
|
||||
|
@ -1,10 +1,13 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
# Helper module for reading and writing cask metadata.
|
||||
module Metadata
|
||||
extend T::Helpers
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
METADATA_SUBDIR = ".metadata"
|
||||
TIMESTAMP_FORMAT = "%Y%m%d%H%M%S.%L"
|
||||
|
@ -3,9 +3,12 @@
|
||||
|
||||
require "cask/cask_loader"
|
||||
require "utils/inreplace"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
class Migrator
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
sig { returns(Cask) }
|
||||
attr_reader :old_cask, :new_cask
|
||||
|
||||
|
@ -2,10 +2,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/macos"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
# Helper class for uninstalling `.pkg` installers.
|
||||
class Pkg
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
sig { params(regexp: String, command: T.class_of(SystemCommand)).returns(T::Array[Pkg]) }
|
||||
def self.all_matching(regexp, command)
|
||||
command.run("/usr/sbin/pkgutil", args: ["--pkgs=#{regexp}"]).stdout.split("\n").map do |package_id|
|
||||
|
@ -4,11 +4,13 @@
|
||||
require "development_tools"
|
||||
require "cask/exceptions"
|
||||
require "system_command"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
# Helper module for quarantining files.
|
||||
module Quarantine
|
||||
extend SystemCommand::Mixin
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
QUARANTINE_ATTRIBUTE = "com.apple.quarantine"
|
||||
|
||||
|
@ -1,8 +1,12 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
class Reinstall
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
sig {
|
||||
params(
|
||||
casks: ::Cask::Cask, verbose: T::Boolean, force: T::Boolean, skip_cask_deps: T::Boolean, binaries: T::Boolean,
|
||||
|
@ -2,10 +2,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/user"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
# Helper functions for staged casks.
|
||||
module Staged
|
||||
include ::Utils::Output::Mixin
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { ::Cask::DSL::Base }
|
||||
|
@ -1,8 +1,12 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
class Uninstall
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
sig { params(casks: ::Cask::Cask, binaries: T::Boolean, force: T::Boolean, verbose: T::Boolean).void }
|
||||
def self.uninstall_casks(*casks, binaries: false, force: false, verbose: false)
|
||||
require "cask/installer"
|
||||
|
@ -3,9 +3,12 @@
|
||||
|
||||
require "env_config"
|
||||
require "cask/config"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
class Upgrade
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
sig {
|
||||
params(
|
||||
casks: Cask,
|
||||
|
@ -3,10 +3,13 @@
|
||||
|
||||
require "utils/user"
|
||||
require "open3"
|
||||
require "utils/output"
|
||||
|
||||
module Cask
|
||||
# Helper functions for various cask operations.
|
||||
module Utils
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
BUG_REPORTS_URL = "https://github.com/Homebrew/homebrew-cask#reporting-bugs"
|
||||
|
||||
def self.gain_permissions_mkpath(path, command: SystemCommand)
|
||||
|
@ -1,6 +1,8 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
# Cleans a newly installed keg.
|
||||
# By default:
|
||||
#
|
||||
@ -13,6 +15,7 @@
|
||||
# * removes unresolved symlinks
|
||||
class Cleaner
|
||||
include Context
|
||||
include Utils::Output::Mixin
|
||||
|
||||
# Create a cleaner for the given formula.
|
||||
sig { params(formula: Formula).void }
|
||||
|
@ -2,6 +2,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/bottles"
|
||||
require "utils/output"
|
||||
|
||||
require "formula"
|
||||
require "cask/cask_loader"
|
||||
@ -9,6 +10,9 @@ require "cask/cask_loader"
|
||||
module Homebrew
|
||||
# Helper class for cleaning up the Homebrew cache.
|
||||
class Cleanup
|
||||
extend Utils::Output::Mixin
|
||||
include Utils::Output::Mixin
|
||||
|
||||
CLEANUP_DEFAULT_DAYS = Homebrew::EnvConfig.cleanup_periodic_full_days.to_i.freeze
|
||||
GH_ACTIONS_ARTIFACT_CLEANUP_DAYS = 3
|
||||
private_constant :CLEANUP_DEFAULT_DAYS, :GH_ACTIONS_ARTIFACT_CLEANUP_DAYS
|
||||
|
@ -2,11 +2,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/args"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module CLI
|
||||
# Helper class for loading formulae/casks from named arguments.
|
||||
class NamedArgs < Array
|
||||
include Utils::Output::Mixin
|
||||
extend T::Generic
|
||||
|
||||
Elem = type_member(:out) { { fixed: String } }
|
||||
|
@ -10,10 +10,13 @@ require "commands"
|
||||
require "optparse"
|
||||
require "utils/tty"
|
||||
require "utils/formatter"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module CLI
|
||||
class Parser
|
||||
include Utils::Output::Mixin
|
||||
|
||||
ArgType = T.type_alias { T.any(NilClass, Symbol, T::Array[String], T::Array[Symbol]) }
|
||||
HIDDEN_DESC_PLACEHOLDER = "@@HIDDEN@@"
|
||||
SYMBOL_TO_USAGE_MAPPING = T.let({
|
||||
@ -40,7 +43,7 @@ module Homebrew
|
||||
cmd_name = cmd_args_method_name.to_s.delete_suffix("_args").tr("_", "-")
|
||||
|
||||
begin
|
||||
if require?(cmd_path)
|
||||
if Homebrew.require?(cmd_path)
|
||||
cmd = Homebrew::AbstractCommand.command(cmd_name)
|
||||
if cmd
|
||||
cmd.parser
|
||||
|
@ -425,6 +425,8 @@ end
|
||||
require "extend/os/cmd/update-report"
|
||||
|
||||
class Reporter
|
||||
include Utils::Output::Mixin
|
||||
|
||||
class ReporterRevisionUnsetError < RuntimeError
|
||||
sig { params(var_name: String).void }
|
||||
def initialize(var_name)
|
||||
@ -782,6 +784,8 @@ class Reporter
|
||||
end
|
||||
|
||||
class ReporterHub
|
||||
include Utils::Output::Mixin
|
||||
|
||||
sig { returns(T::Array[Reporter]) }
|
||||
attr_reader :reporters
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils"
|
||||
|
||||
# Helper functions for commands.
|
||||
module Commands
|
||||
HOMEBREW_CMD_PATH = (HOMEBREW_LIBRARY_PATH/"cmd").freeze
|
||||
@ -34,11 +36,11 @@ module Commands
|
||||
DESCRIPTION_SPLITTING_PATTERN = /\.(?>\s|$)/
|
||||
|
||||
def self.valid_internal_cmd?(cmd)
|
||||
require?(HOMEBREW_CMD_PATH/cmd)
|
||||
Homebrew.require?(HOMEBREW_CMD_PATH/cmd)
|
||||
end
|
||||
|
||||
def self.valid_internal_dev_cmd?(cmd)
|
||||
require?(HOMEBREW_DEV_CMD_PATH/cmd)
|
||||
Homebrew.require?(HOMEBREW_DEV_CMD_PATH/cmd)
|
||||
end
|
||||
|
||||
def self.valid_ruby_cmd?(cmd)
|
||||
@ -76,7 +78,7 @@ module Commands
|
||||
# Ruby commands which can be `require`d without being run.
|
||||
def self.external_ruby_v2_cmd_path(cmd)
|
||||
path = which("#{cmd}.rb", tap_cmd_directories)
|
||||
path if require?(path)
|
||||
path if Homebrew.require?(path)
|
||||
end
|
||||
|
||||
# Ruby commands which are run by being `require`d.
|
||||
|
@ -8,6 +8,8 @@ require "erb"
|
||||
module Homebrew
|
||||
# Helper functions for generating shell completions.
|
||||
module Completions
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
Variables = Struct.new(
|
||||
:aliases,
|
||||
:builtin_command_descriptions,
|
||||
|
@ -8,6 +8,7 @@ require "formulary"
|
||||
require "version"
|
||||
require "development_tools"
|
||||
require "utils/shell"
|
||||
require "utils/output"
|
||||
require "system_config"
|
||||
require "cask/caskroom"
|
||||
require "cask/quarantine"
|
||||
@ -16,6 +17,8 @@ require "system_command"
|
||||
module Homebrew
|
||||
# Module containing diagnostic checks.
|
||||
module Diagnostic
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
sig {
|
||||
params(formulae: T::Array[Formula], hide: T::Array[String], _block: T.nilable(
|
||||
T.proc.params(formula_name: String, missing_dependencies: T::Array[Formula]).void,
|
||||
|
@ -6,9 +6,12 @@ require "concurrent/promises"
|
||||
require "concurrent/executors"
|
||||
require "retryable_download"
|
||||
require "resource"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
class DownloadQueue
|
||||
include Utils::Output::Mixin
|
||||
|
||||
sig { params(retries: Integer, force: T::Boolean, pour: T::Boolean).void }
|
||||
def initialize(retries: 1, force: false, pour: false)
|
||||
@concurrency = T.let(EnvConfig.download_concurrency, Integer)
|
||||
|
@ -7,6 +7,7 @@ require "unpack_strategy"
|
||||
require "lazy_object"
|
||||
require "lock_file"
|
||||
require "system_command"
|
||||
require "utils/output"
|
||||
|
||||
# Need to define this before requiring Mechanize to avoid:
|
||||
# uninitialized constant Mechanize
|
||||
@ -27,6 +28,7 @@ class AbstractDownloadStrategy
|
||||
include FileUtils
|
||||
include Context
|
||||
include SystemCommand::Mixin
|
||||
include Utils::Output::Mixin
|
||||
|
||||
abstract!
|
||||
|
||||
|
@ -4,9 +4,11 @@
|
||||
require "url"
|
||||
require "checksum"
|
||||
require "download_strategy"
|
||||
require "utils/output"
|
||||
|
||||
module Downloadable
|
||||
include Context
|
||||
include Utils::Output::Mixin
|
||||
extend T::Helpers
|
||||
|
||||
abstract!
|
||||
|
@ -1,11 +1,16 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Helper module for querying Homebrew-specific environment variables.
|
||||
#
|
||||
# @api internal
|
||||
module EnvConfig
|
||||
include Utils::Output::Mixin
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
module_function
|
||||
|
||||
ENVS = T.let({
|
||||
|
@ -1,6 +1,8 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
# Raised when a command is used wrong.
|
||||
#
|
||||
# @api internal
|
||||
@ -463,6 +465,8 @@ end
|
||||
|
||||
# Raised when an error occurs during a formula build.
|
||||
class BuildError < RuntimeError
|
||||
include Utils::Output::Mixin
|
||||
|
||||
attr_reader :cmd, :args, :env
|
||||
attr_accessor :formula, :options
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
require "extend/ENV/shared"
|
||||
require "development_tools"
|
||||
require "utils/output"
|
||||
|
||||
# ### Why `superenv`?
|
||||
#
|
||||
@ -16,6 +17,7 @@ require "development_tools"
|
||||
# 8. Build-system agnostic configuration of the toolchain
|
||||
module Superenv
|
||||
include SharedEnvExtension
|
||||
include Utils::Output::Mixin
|
||||
|
||||
attr_accessor :keg_only_deps, :deps, :run_time_deps
|
||||
|
||||
|
@ -1,9 +1,7 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Contains shorthand Homebrew utility methods like `ohai`, `opoo`, `odisabled`.
|
||||
# TODO: move these out of `Kernel` into `Homebrew::GlobalMethods` and add
|
||||
# necessary Sorbet and global Kernel inclusions.
|
||||
require "utils/output"
|
||||
|
||||
module Kernel
|
||||
sig { params(env: T.nilable(String)).returns(T::Boolean) }
|
||||
@ -14,279 +12,6 @@ module Kernel
|
||||
end
|
||||
private :superenv?
|
||||
|
||||
sig { params(path: T.nilable(T.any(String, Pathname))).returns(T::Boolean) }
|
||||
def require?(path)
|
||||
return false if path.nil?
|
||||
|
||||
if defined?(Warnings)
|
||||
# Work around require warning when done repeatedly:
|
||||
# https://bugs.ruby-lang.org/issues/21091
|
||||
Warnings.ignore(/already initialized constant/, /previous definition of/) do
|
||||
require path.to_s
|
||||
end
|
||||
else
|
||||
require path.to_s
|
||||
end
|
||||
true
|
||||
rescue LoadError
|
||||
false
|
||||
end
|
||||
|
||||
sig { params(title: String).returns(String) }
|
||||
def ohai_title(title)
|
||||
verbose = if respond_to?(:verbose?)
|
||||
T.unsafe(self).verbose?
|
||||
else
|
||||
Context.current.verbose?
|
||||
end
|
||||
|
||||
title = Tty.truncate(title.to_s) if $stdout.tty? && !verbose
|
||||
Formatter.headline(title, color: :blue)
|
||||
end
|
||||
|
||||
sig { params(title: T.any(String, Exception), sput: T.anything).void }
|
||||
def ohai(title, *sput)
|
||||
puts ohai_title(title.to_s)
|
||||
puts sput
|
||||
end
|
||||
|
||||
sig { params(title: T.any(String, Exception), sput: T.anything, always_display: T::Boolean).void }
|
||||
def odebug(title, *sput, always_display: false)
|
||||
debug = if respond_to?(:debug)
|
||||
T.unsafe(self).debug?
|
||||
else
|
||||
Context.current.debug?
|
||||
end
|
||||
|
||||
return if !debug && !always_display
|
||||
|
||||
$stderr.puts Formatter.headline(title.to_s, color: :magenta)
|
||||
$stderr.puts sput unless sput.empty?
|
||||
end
|
||||
|
||||
sig { params(title: String, truncate: T.any(Symbol, T::Boolean)).returns(String) }
|
||||
def oh1_title(title, truncate: :auto)
|
||||
verbose = if respond_to?(:verbose?)
|
||||
T.unsafe(self).verbose?
|
||||
else
|
||||
Context.current.verbose?
|
||||
end
|
||||
|
||||
title = Tty.truncate(title.to_s) if $stdout.tty? && !verbose && truncate == :auto
|
||||
Formatter.headline(title, color: :green)
|
||||
end
|
||||
|
||||
sig { params(title: String, truncate: T.any(Symbol, T::Boolean)).void }
|
||||
def oh1(title, truncate: :auto)
|
||||
puts oh1_title(title, truncate:)
|
||||
end
|
||||
|
||||
# Print a warning message.
|
||||
#
|
||||
# @api public
|
||||
sig { params(message: T.any(String, Exception)).void }
|
||||
def opoo(message)
|
||||
require "utils/github/actions"
|
||||
return if GitHub::Actions.puts_annotation_if_env_set!(:warning, message.to_s)
|
||||
|
||||
require "utils/formatter"
|
||||
|
||||
Tty.with($stderr) do |stderr|
|
||||
stderr.puts Formatter.warning(message, label: "Warning")
|
||||
end
|
||||
end
|
||||
|
||||
# Print a warning message only if not running in GitHub Actions.
|
||||
#
|
||||
# @api public
|
||||
sig { params(message: T.any(String, Exception)).void }
|
||||
def opoo_outside_github_actions(message)
|
||||
require "utils/github/actions"
|
||||
return if GitHub::Actions.env_set?
|
||||
|
||||
opoo(message)
|
||||
end
|
||||
|
||||
# Print an error message.
|
||||
#
|
||||
# @api public
|
||||
sig { params(message: T.any(String, Exception)).void }
|
||||
def onoe(message)
|
||||
require "utils/github/actions"
|
||||
return if GitHub::Actions.puts_annotation_if_env_set!(:error, message.to_s)
|
||||
|
||||
require "utils/formatter"
|
||||
|
||||
Tty.with($stderr) do |stderr|
|
||||
stderr.puts Formatter.error(message, label: "Error")
|
||||
end
|
||||
end
|
||||
|
||||
# Print an error message and fail at the end of the program.
|
||||
#
|
||||
# @api public
|
||||
sig { params(error: T.any(String, Exception)).void }
|
||||
def ofail(error)
|
||||
onoe error
|
||||
Homebrew.failed = true
|
||||
end
|
||||
|
||||
# Print an error message and fail immediately.
|
||||
#
|
||||
# @api public
|
||||
sig { params(error: T.any(String, Exception)).returns(T.noreturn) }
|
||||
def odie(error)
|
||||
onoe error
|
||||
exit 1
|
||||
end
|
||||
|
||||
# Output a deprecation warning/error message.
|
||||
sig {
|
||||
params(method: String, replacement: T.nilable(T.any(String, Symbol)), disable: T::Boolean,
|
||||
disable_on: T.nilable(Time), disable_for_developers: T::Boolean, caller: T::Array[String]).void
|
||||
}
|
||||
def odeprecated(method, replacement = nil,
|
||||
disable: false,
|
||||
disable_on: nil,
|
||||
disable_for_developers: true,
|
||||
caller: send(:caller))
|
||||
replacement_message = if replacement
|
||||
"Use #{replacement} instead."
|
||||
else
|
||||
"There is no replacement."
|
||||
end
|
||||
|
||||
unless disable_on.nil?
|
||||
if disable_on > Time.now
|
||||
will_be_disabled_message = " and will be disabled on #{disable_on.strftime("%Y-%m-%d")}"
|
||||
else
|
||||
disable = true
|
||||
end
|
||||
end
|
||||
|
||||
verb = if disable
|
||||
"disabled"
|
||||
else
|
||||
"deprecated#{will_be_disabled_message}"
|
||||
end
|
||||
|
||||
# Try to show the most relevant location in message, i.e. (if applicable):
|
||||
# - Location in a formula.
|
||||
# - Location of caller of deprecated method (if all else fails).
|
||||
backtrace = caller
|
||||
|
||||
# Don't throw deprecations at all for cached, .brew or .metadata files.
|
||||
return if backtrace.any? do |line|
|
||||
next true if line.include?(HOMEBREW_CACHE.to_s)
|
||||
next true if line.include?("/.brew/")
|
||||
next true if line.include?("/.metadata/")
|
||||
|
||||
next false unless line.match?(HOMEBREW_TAP_PATH_REGEX)
|
||||
|
||||
path = Pathname(line.split(":", 2).first)
|
||||
next false unless path.file?
|
||||
next false unless path.readable?
|
||||
|
||||
formula_contents = path.read
|
||||
formula_contents.include?(" deprecate! ") || formula_contents.include?(" disable! ")
|
||||
end
|
||||
|
||||
tap_message = T.let(nil, T.nilable(String))
|
||||
|
||||
backtrace.each do |line|
|
||||
next unless (match = line.match(HOMEBREW_TAP_PATH_REGEX))
|
||||
|
||||
require "tap"
|
||||
|
||||
tap = Tap.fetch(match[:user], match[:repository])
|
||||
tap_message = "\nPlease report this issue to the #{tap.full_name} tap"
|
||||
tap_message += " (not Homebrew/* repositories)" unless tap.official?
|
||||
tap_message += ", or even better, submit a PR to fix it" if replacement
|
||||
tap_message << ":\n #{line.sub(/^(.*:\d+):.*$/, '\1')}\n\n"
|
||||
break
|
||||
end
|
||||
file, line, = backtrace.first.split(":")
|
||||
line = line.to_i if line.present?
|
||||
|
||||
message = "Calling #{method} is #{verb}! #{replacement_message}"
|
||||
message << tap_message if tap_message
|
||||
message.freeze
|
||||
|
||||
disable = true if disable_for_developers && Homebrew::EnvConfig.developer?
|
||||
if disable || Homebrew.raise_deprecation_exceptions?
|
||||
require "utils/github/actions"
|
||||
GitHub::Actions.puts_annotation_if_env_set!(:error, message, file:, line:)
|
||||
exception = MethodDeprecatedError.new(message)
|
||||
exception.set_backtrace(backtrace)
|
||||
raise exception
|
||||
elsif !Homebrew.auditing?
|
||||
opoo message
|
||||
end
|
||||
end
|
||||
|
||||
sig {
|
||||
params(method: String, replacement: T.nilable(T.any(String, Symbol)),
|
||||
disable_on: T.nilable(Time), disable_for_developers: T::Boolean, caller: T::Array[String]).void
|
||||
}
|
||||
def odisabled(method, replacement = nil,
|
||||
disable_on: nil,
|
||||
disable_for_developers: true,
|
||||
caller: send(:caller))
|
||||
# This odeprecated should stick around indefinitely.
|
||||
odeprecated(method, replacement, disable: true, disable_on:, disable_for_developers:, caller:)
|
||||
end
|
||||
|
||||
sig { params(string: String).returns(String) }
|
||||
def pretty_installed(string)
|
||||
if !$stdout.tty?
|
||||
string
|
||||
elsif Homebrew::EnvConfig.no_emoji?
|
||||
Formatter.success("#{Tty.bold}#{string} (installed)#{Tty.reset}")
|
||||
else
|
||||
"#{Tty.bold}#{string} #{Formatter.success("✔")}#{Tty.reset}"
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(string: String).returns(String) }
|
||||
def pretty_outdated(string)
|
||||
if !$stdout.tty?
|
||||
string
|
||||
elsif Homebrew::EnvConfig.no_emoji?
|
||||
Formatter.error("#{Tty.bold}#{string} (outdated)#{Tty.reset}")
|
||||
else
|
||||
"#{Tty.bold}#{string} #{Formatter.warning("⚠")}#{Tty.reset}"
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(string: String).returns(String) }
|
||||
def pretty_uninstalled(string)
|
||||
if !$stdout.tty?
|
||||
string
|
||||
elsif Homebrew::EnvConfig.no_emoji?
|
||||
Formatter.error("#{Tty.bold}#{string} (uninstalled)#{Tty.reset}")
|
||||
else
|
||||
"#{Tty.bold}#{string} #{Formatter.error("✘")}#{Tty.reset}"
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(seconds: T.nilable(T.any(Integer, Float))).returns(String) }
|
||||
def pretty_duration(seconds)
|
||||
seconds = seconds.to_i
|
||||
res = +""
|
||||
|
||||
if seconds > 59
|
||||
minutes = seconds / 60
|
||||
seconds %= 60
|
||||
res = +Utils.pluralize("minute", minutes, include_count: true)
|
||||
return res.freeze if seconds.zero?
|
||||
|
||||
res << " "
|
||||
end
|
||||
|
||||
res << Utils.pluralize("second", seconds, include_count: true)
|
||||
res.freeze
|
||||
end
|
||||
|
||||
sig { params(formula: T.nilable(Formula)).void }
|
||||
def interactive_shell(formula = nil)
|
||||
unless formula.nil?
|
||||
@ -368,7 +93,7 @@ module Kernel
|
||||
editor ||= "vim"
|
||||
|
||||
unless silent
|
||||
opoo <<~EOS
|
||||
Utils::Output.opoo <<~EOS
|
||||
Using #{editor} because no editor was set in the environment.
|
||||
This may change in the future, so we recommend setting `$EDITOR`
|
||||
or `$HOMEBREW_EDITOR` to your preferred text editor.
|
||||
|
@ -1,6 +1,8 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module OS
|
||||
module Linux
|
||||
module Install
|
||||
@ -108,7 +110,7 @@ module OS
|
||||
::Kernel.system HOMEBREW_PREFIX/"opt/glibc/sbin/ldconfig"
|
||||
end
|
||||
else
|
||||
::Kernel.odie "#{HOMEBREW_PREFIX}/lib does not exist!" unless (HOMEBREW_PREFIX/"lib").readable?
|
||||
Utils::Output.odie "#{HOMEBREW_PREFIX}/lib does not exist!" unless (HOMEBREW_PREFIX/"lib").readable?
|
||||
end
|
||||
|
||||
GCC_RUNTIME_LIBS.each do |library|
|
||||
|
@ -1,11 +1,14 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module OS
|
||||
module Mac
|
||||
module Readall
|
||||
module ClassMethods
|
||||
extend T::Helpers
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
requires_ancestor { Kernel }
|
||||
|
||||
|
@ -4,12 +4,14 @@
|
||||
require "system_command"
|
||||
require "extend/pathname/disk_usage_extension"
|
||||
require "extend/pathname/observer_pathname_extension"
|
||||
require "utils/output"
|
||||
|
||||
# Homebrew extends Ruby's `Pathname` to make our code more readable.
|
||||
# @see https://ruby-doc.org/stdlib-2.6.3/libdoc/pathname/rdoc/Pathname.html Ruby's Pathname API
|
||||
class Pathname
|
||||
include SystemCommand::Mixin
|
||||
include DiskUsageExtension
|
||||
include Utils::Output::Mixin
|
||||
|
||||
# Moves a file from the original location to the {Pathname}'s.
|
||||
#
|
||||
|
@ -2,8 +2,11 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "time"
|
||||
require "utils/output"
|
||||
|
||||
class Time
|
||||
include Utils::Output::Mixin
|
||||
|
||||
# Backwards compatibility for formulae that used this ActiveSupport extension
|
||||
sig { returns(String) }
|
||||
def rfc3339
|
||||
|
@ -41,6 +41,7 @@ require "utils/spdx"
|
||||
require "on_system"
|
||||
require "api"
|
||||
require "api_hashable"
|
||||
require "utils/output"
|
||||
|
||||
# A formula provides instructions and metadata for Homebrew to install a piece
|
||||
# of software. Every Homebrew formula is a {Formula}.
|
||||
@ -75,6 +76,7 @@ class Formula
|
||||
include FileUtils
|
||||
include Utils::Shebang
|
||||
include Utils::Shell
|
||||
include Utils::Output::Mixin
|
||||
include Context
|
||||
include OnSystem::MacOSAndLinux
|
||||
include Homebrew::Livecheck::Constants
|
||||
@ -82,6 +84,7 @@ class Formula
|
||||
extend Cachable
|
||||
extend APIHashable
|
||||
extend T::Helpers
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
abstract!
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Helper functions available in formula `test` blocks.
|
||||
module Assertions
|
||||
include Context
|
||||
include ::Utils::Output::Mixin
|
||||
extend T::Helpers
|
||||
|
||||
requires_ancestor { Kernel }
|
||||
|
@ -6,12 +6,14 @@ require "formula_versions"
|
||||
require "formula_name_cask_token_auditor"
|
||||
require "resource_auditor"
|
||||
require "utils/shared_audits"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Auditor for checking common violations in {Formula}e.
|
||||
class FormulaAuditor
|
||||
include FormulaCellarChecks
|
||||
include Utils::Curl
|
||||
include Utils::Output::Mixin
|
||||
|
||||
attr_reader :formula, :text, :problems, :new_formula_problems
|
||||
|
||||
|
@ -4,10 +4,13 @@
|
||||
require "digest"
|
||||
require "erb"
|
||||
require "utils/github"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Class for generating a formula from a template.
|
||||
class FormulaCreator
|
||||
include Utils::Output::Mixin
|
||||
|
||||
sig { returns(String) }
|
||||
attr_accessor :name
|
||||
|
||||
|
@ -24,10 +24,12 @@ require "service"
|
||||
require "attestation"
|
||||
require "sbom"
|
||||
require "utils/fork"
|
||||
require "utils/output"
|
||||
|
||||
# Installer for a formula.
|
||||
class FormulaInstaller
|
||||
include FormulaCellarChecks
|
||||
include Utils::Output::Mixin
|
||||
|
||||
ETC_VAR_DIRS = T.let([HOMEBREW_PREFIX/"etc", HOMEBREW_PREFIX/"var"].freeze, T::Array[Pathname])
|
||||
|
||||
|
@ -2,12 +2,14 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "formula"
|
||||
require "utils/output"
|
||||
|
||||
# Helper class for traversing a formula's previous versions.
|
||||
#
|
||||
# @api internal
|
||||
class FormulaVersions
|
||||
include Context
|
||||
include Utils::Output::Mixin
|
||||
|
||||
IGNORED_EXCEPTIONS = [
|
||||
ArgumentError, NameError, SyntaxError, TypeError,
|
||||
|
@ -6,6 +6,7 @@ require "cachable"
|
||||
require "tab"
|
||||
require "utils"
|
||||
require "utils/bottles"
|
||||
require "utils/output"
|
||||
require "service"
|
||||
require "utils/curl"
|
||||
require "deprecate_disable"
|
||||
@ -18,6 +19,8 @@ require "tap"
|
||||
module Formulary
|
||||
extend Context
|
||||
extend Cachable
|
||||
extend Utils::Output::Mixin
|
||||
include Utils::Output::Mixin
|
||||
|
||||
ALLOWED_URL_SCHEMES = %w[file].freeze
|
||||
private_constant :ALLOWED_URL_SCHEMES
|
||||
@ -559,6 +562,7 @@ module Formulary
|
||||
# Subclasses implement loaders for particular sources of formulae.
|
||||
class FormulaLoader
|
||||
include Context
|
||||
include Utils::Output::Mixin
|
||||
|
||||
# The formula's name.
|
||||
sig { returns(String) }
|
||||
@ -609,6 +613,8 @@ module Formulary
|
||||
|
||||
# Loads a formula from a bottle.
|
||||
class FromBottleLoader < FormulaLoader
|
||||
include Utils::Output::Mixin
|
||||
|
||||
sig {
|
||||
params(ref: T.any(String, Pathname, URI::Generic), from: T.nilable(Symbol), warn: T::Boolean)
|
||||
.returns(T.nilable(T.attached_class))
|
||||
|
@ -1,5 +0,0 @@
|
||||
# typed: strict
|
||||
|
||||
module Formulary
|
||||
include Kernel
|
||||
end
|
@ -3,6 +3,7 @@
|
||||
|
||||
require "utils/curl"
|
||||
require "utils/gzip"
|
||||
require "utils/output"
|
||||
require "json"
|
||||
require "zlib"
|
||||
require "extend/hash/keys"
|
||||
@ -12,6 +13,7 @@ require "system_command"
|
||||
class GitHubPackages
|
||||
include Context
|
||||
include SystemCommand::Mixin
|
||||
include Utils::Output::Mixin
|
||||
|
||||
URL_DOMAIN = "ghcr.io"
|
||||
URL_PREFIX = "https://#{URL_DOMAIN}/v2/".freeze
|
||||
|
@ -2,11 +2,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/github"
|
||||
require "utils/output"
|
||||
require "json"
|
||||
|
||||
# GitHub Releases client.
|
||||
class GitHubReleases
|
||||
include Context
|
||||
include Utils::Output::Mixin
|
||||
|
||||
URL_REGEX = %r{https://github\.com/([\w-]+)/([\w-]+)?/releases/download/(.+)}
|
||||
|
||||
|
@ -3,10 +3,13 @@
|
||||
|
||||
require "cli/parser"
|
||||
require "commands"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Helper module for printing help output.
|
||||
module Help
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
sig {
|
||||
params(
|
||||
cmd: T.nilable(String),
|
||||
|
@ -7,10 +7,13 @@ require "hardware"
|
||||
require "development_tools"
|
||||
require "upgrade"
|
||||
require "download_queue"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Helper module for performing (pre-)install checks.
|
||||
module Install
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
class << self
|
||||
sig { params(all_fatal: T::Boolean).void }
|
||||
def perform_preinstall_checks_once(all_fatal: false)
|
||||
|
@ -5,10 +5,12 @@ require "keg_relocate"
|
||||
require "language/python"
|
||||
require "lock_file"
|
||||
require "cachable"
|
||||
require "utils/output"
|
||||
|
||||
# Installation prefix of a formula.
|
||||
class Keg
|
||||
extend Cachable
|
||||
include Utils::Output::Mixin
|
||||
|
||||
# Error for when a keg is already linked.
|
||||
class AlreadyLinkedError < RuntimeError
|
||||
|
@ -1,11 +1,15 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
module Language
|
||||
# Helper functions for Node formulae.
|
||||
#
|
||||
# @api public
|
||||
module Node
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
sig { returns(String) }
|
||||
def self.npm_cache_config
|
||||
"cache=#{HOMEBREW_CACHE}/npm_cache"
|
||||
|
@ -5,9 +5,12 @@ require "keg"
|
||||
require "formula"
|
||||
require "linkage_cache_store"
|
||||
require "fiddle"
|
||||
require "utils/output"
|
||||
|
||||
# Check for broken/missing linkage in a formula's keg.
|
||||
class LinkageChecker
|
||||
include Utils::Output::Mixin
|
||||
|
||||
attr_reader :undeclared_deps, :keg, :formula, :store
|
||||
|
||||
def initialize(keg, formula = nil, cache_db:, rebuild_cache: false)
|
||||
|
@ -7,12 +7,15 @@ require "livecheck/livecheck_version"
|
||||
require "livecheck/skip_conditions"
|
||||
require "livecheck/strategy"
|
||||
require "addressable"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# The {Livecheck} module consists of methods used by the `brew livecheck`
|
||||
# command. These methods print the requested livecheck information
|
||||
# for formulae.
|
||||
module Livecheck
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
NO_CURRENT_VERSION_MSG = "Unable to identify current version"
|
||||
NO_VERSIONS_MSG = "Unable to get versions"
|
||||
|
||||
|
@ -2,9 +2,12 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "fcntl"
|
||||
require "utils/output"
|
||||
|
||||
# A lock file to prevent multiple Homebrew processes from modifying the same path.
|
||||
class LockFile
|
||||
include Utils::Output::Mixin
|
||||
|
||||
class OpenFileChangedOnDisk < RuntimeError; end
|
||||
private_constant :OpenFileChangedOnDisk
|
||||
|
||||
|
@ -1,9 +1,13 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
# A {Messages} object collects messages that may need to be displayed together
|
||||
# at the end of a multi-step `brew` command run.
|
||||
class Messages
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
sig { returns(T::Array[{ package: String, caveats: T.any(String, Caveats) }]) }
|
||||
attr_reader :caveats
|
||||
|
||||
|
@ -4,10 +4,13 @@
|
||||
require "lock_file"
|
||||
require "keg"
|
||||
require "tab"
|
||||
require "utils/output"
|
||||
|
||||
# Helper class for migrating a formula from an old to a new name.
|
||||
class Migrator
|
||||
extend Utils::Output::Mixin
|
||||
include Context
|
||||
include Utils::Output::Mixin
|
||||
|
||||
# Error for when a migration is necessary.
|
||||
class MigrationNeededError < RuntimeError
|
||||
|
@ -2,10 +2,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "formulary"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Helper module for checking if there is a reason a formula is missing.
|
||||
module MissingFormula
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
class << self
|
||||
sig { params(name: String, silent: T::Boolean, show_info: T::Boolean).returns(T.nilable(String)) }
|
||||
def reason(name, silent: false, show_info: false)
|
||||
|
@ -1,10 +1,14 @@
|
||||
# typed: strict
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
# Performs {Formula#mktemp}'s functionality and tracks the results.
|
||||
# Each instance is only intended to be used once.
|
||||
# Can also be used to create a temporary directory with the brew instance's group.
|
||||
class Mktemp
|
||||
include Utils::Output::Mixin
|
||||
|
||||
# Path to the tmpdir used in this run
|
||||
sig { returns(T.nilable(Pathname)) }
|
||||
attr_reader :tmpdir
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
require "resource"
|
||||
require "erb"
|
||||
require "utils/output"
|
||||
|
||||
# Helper module for creating patches.
|
||||
module Patch
|
||||
@ -96,6 +97,8 @@ end
|
||||
|
||||
# A file containing a patch.
|
||||
class ExternalPatch
|
||||
include Utils::Output::Mixin
|
||||
|
||||
extend Forwardable
|
||||
|
||||
attr_reader :resource, :strip
|
||||
|
@ -4,11 +4,13 @@
|
||||
require "formula"
|
||||
require "cask/cask_loader"
|
||||
require "system_command"
|
||||
require "utils/output"
|
||||
|
||||
# Helper module for validating syntax in taps.
|
||||
module Readall
|
||||
extend Cachable
|
||||
extend SystemCommand::Mixin
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
# TODO: remove this once the `MacOS` module is undefined on Linux
|
||||
MACOS_MODULE_REGEX = /\b(MacOS|OS::Mac)(\.|::)\b/
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
require "development_tools"
|
||||
require "messages"
|
||||
require "utils/output"
|
||||
|
||||
# Needed to handle circular require dependency.
|
||||
# rubocop:disable Lint/EmptyClass
|
||||
@ -11,6 +12,8 @@ class FormulaInstaller; end
|
||||
|
||||
module Homebrew
|
||||
module Reinstall
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
class InstallationContext < T::Struct
|
||||
const :formula_installer, ::FormulaInstaller
|
||||
const :keg, T.nilable(Keg)
|
||||
|
@ -5,12 +5,14 @@ require "dependable"
|
||||
require "dependency"
|
||||
require "dependencies"
|
||||
require "build_environment"
|
||||
require "utils/output"
|
||||
|
||||
# A base class for non-formula requirements needed by formulae.
|
||||
# A fatal requirement is one that will fail the build if it is not present.
|
||||
# By default, requirements are non-fatal.
|
||||
class Requirement
|
||||
include Dependable
|
||||
include Utils::Output::Mixin
|
||||
extend Cachable
|
||||
extend T::Helpers
|
||||
|
||||
|
@ -5,6 +5,7 @@ require "downloadable"
|
||||
require "mktemp"
|
||||
require "livecheck"
|
||||
require "on_system"
|
||||
require "utils/output"
|
||||
|
||||
# Resource is the fundamental representation of an external resource. The
|
||||
# primary formula download, along with other declared resources, are instances
|
||||
@ -13,6 +14,7 @@ class Resource
|
||||
include Downloadable
|
||||
include FileUtils
|
||||
include OnSystem::MacOSAndLinux
|
||||
include Utils::Output::Mixin
|
||||
|
||||
attr_reader :source_modified_time, :patches, :owner
|
||||
attr_writer :checksum
|
||||
|
@ -3,10 +3,12 @@
|
||||
|
||||
require "bottle"
|
||||
require "api/json_download"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
class RetryableDownload
|
||||
include Downloadable
|
||||
include Utils::Output::Mixin
|
||||
|
||||
sig { override.returns(T.any(NilClass, String, URL)) }
|
||||
def url = downloadable.url
|
||||
|
@ -6,9 +6,12 @@ require "io/console"
|
||||
require "pty"
|
||||
require "tempfile"
|
||||
require "utils/fork"
|
||||
require "utils/output"
|
||||
|
||||
# Helper class for running a sub-process inside of a sandboxed environment.
|
||||
class Sandbox
|
||||
include Utils::Output::Mixin
|
||||
|
||||
SANDBOX_EXEC = "/usr/bin/sandbox-exec"
|
||||
|
||||
# This is defined in the macOS SDK but Ruby unfortunately does not expose it.
|
||||
|
@ -6,9 +6,12 @@ require "json"
|
||||
require "development_tools"
|
||||
require "cachable"
|
||||
require "utils/curl"
|
||||
require "utils/output"
|
||||
|
||||
# Rather than calling `new` directly, use one of the class methods like {SBOM.create}.
|
||||
class SBOM
|
||||
include Utils::Output::Mixin
|
||||
|
||||
FILENAME = "sbom.spdx.json"
|
||||
SCHEMA_FILE = (HOMEBREW_LIBRARY_PATH/"data/schemas/sbom.json").freeze
|
||||
|
||||
@ -87,7 +90,7 @@ class SBOM
|
||||
|
||||
sig { params(bottling: T::Boolean).returns(T::Array[T::Hash[String, T.untyped]]) }
|
||||
def schema_validation_errors(bottling: false)
|
||||
unless require? "json_schemer"
|
||||
unless Homebrew.require? "json_schemer"
|
||||
error_message = "Need json_schemer to validate SBOM, run `brew install-bundler-gems --add-groups=bottle`!"
|
||||
odie error_message if ENV["HOMEBREW_ENFORCE_SBOM"]
|
||||
return []
|
||||
|
@ -2,10 +2,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "description_cache_store"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Helper module for searching formulae or casks.
|
||||
module Search
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
def self.query_regexp(query)
|
||||
if (m = query.match(%r{^/(.*)/$}))
|
||||
Regexp.new(m[1])
|
||||
|
@ -3,11 +3,13 @@
|
||||
|
||||
require "services/formula_wrapper"
|
||||
require "fileutils"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Services
|
||||
module Cli
|
||||
extend FileUtils
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
sig { returns(T.nilable(String)) }
|
||||
def self.sudo_service_user
|
||||
|
@ -3,11 +3,14 @@
|
||||
|
||||
require "services/cli"
|
||||
require "services/formulae"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Services
|
||||
module Commands
|
||||
module List
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
TRIGGERS = [nil, "list", "ls"].freeze
|
||||
|
||||
sig { params(json: T::Boolean).void }
|
||||
|
@ -1,11 +1,15 @@
|
||||
# typed: true # rubocop:todo Sorbet/StrictSigil
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
# Wrapper for a formula to handle service-related stuff like parsing and
|
||||
# generating the service/plist files.
|
||||
module Homebrew
|
||||
module Services
|
||||
class FormulaWrapper
|
||||
include Utils::Output::Mixin
|
||||
|
||||
# Access the `Formula` instance.
|
||||
sig { returns(Formula) }
|
||||
attr_reader :formula
|
||||
|
@ -2,10 +2,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "system/systemctl"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
module Services
|
||||
module System
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
LAUNCHCTL_DOMAIN_ACTION_NOT_SUPPORTED = T.let(125, Integer)
|
||||
|
||||
# Path to launchctl binary.
|
||||
|
@ -4,10 +4,12 @@
|
||||
require "shellwords"
|
||||
require "source_location"
|
||||
require "system_command"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Helper module for running RuboCop.
|
||||
module Style
|
||||
extend Utils::Output::Mixin
|
||||
extend SystemCommand::Mixin
|
||||
|
||||
# Checks style for a list of files, printing simple RuboCop output.
|
||||
|
@ -8,6 +8,7 @@ require "uri"
|
||||
require "context"
|
||||
require "readline_nonblock"
|
||||
require "utils/timer"
|
||||
require "utils/output"
|
||||
|
||||
# Class for running sub-processes and capturing their output and exit status.
|
||||
#
|
||||
@ -380,6 +381,7 @@ class SystemCommand
|
||||
# Result containing the output and exit status of a finished sub-process.
|
||||
class Result
|
||||
include Context
|
||||
include Utils::Output::Mixin
|
||||
|
||||
attr_accessor :command, :status, :exit_status
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
require "api"
|
||||
require "commands"
|
||||
require "settings"
|
||||
require "utils/output"
|
||||
|
||||
# A {Tap} is used to encapsulate Homebrew formulae, casks and custom commands.
|
||||
# Usually, it's synced with a remote Git repository. And it's likely
|
||||
@ -13,6 +14,8 @@ require "settings"
|
||||
# repository name without the leading `homebrew-`.
|
||||
class Tap
|
||||
extend Cachable
|
||||
extend Utils::Output::Mixin
|
||||
include Utils::Output::Mixin
|
||||
|
||||
HOMEBREW_TAP_CASK_RENAMES_FILE = "cask_renames.json"
|
||||
private_constant :HOMEBREW_TAP_CASK_RENAMES_FILE
|
||||
|
@ -103,7 +103,6 @@ RSpec.describe Homebrew::Bundle::Dsl do
|
||||
end
|
||||
|
||||
it ".sanitize_cask_name" do
|
||||
allow_any_instance_of(Object).to receive(:opoo)
|
||||
expect(described_class.send(:sanitize_cask_name, "homebrew/cask-versions/adoptopenjdk8")).to eql("adoptopenjdk8")
|
||||
expect(described_class.send(:sanitize_cask_name, "adoptopenjdk8")).to eql("adoptopenjdk8")
|
||||
end
|
||||
|
@ -22,9 +22,7 @@ RSpec.describe Cask::DSL, :cask, :no_api do
|
||||
it "prints an error that it has encountered an unexpected method" do
|
||||
expected = Regexp.compile(<<~EOS.lines.map(&:chomp).join)
|
||||
(?m)
|
||||
Error:
|
||||
.*
|
||||
Unexpected method 'future_feature' called on Cask unexpected-method-cask\\.
|
||||
Error: Unexpected method 'future_feature' called on Cask unexpected-method-cask\\.
|
||||
.*
|
||||
https://github.com/Homebrew/homebrew-cask#reporting-bugs
|
||||
EOS
|
||||
|
@ -3,92 +3,6 @@
|
||||
RSpec.describe Kernel do
|
||||
let(:dir) { mktmpdir }
|
||||
|
||||
def esc(code)
|
||||
/(\e\[\d+m)*\e\[#{code}m/
|
||||
end
|
||||
|
||||
describe "#ofail" do
|
||||
it "sets Homebrew.failed to true" do
|
||||
expect do
|
||||
ofail "foo"
|
||||
end.to output("Error: foo\n").to_stderr
|
||||
|
||||
expect(Homebrew).to have_failed
|
||||
end
|
||||
end
|
||||
|
||||
describe "#odie" do
|
||||
it "exits with 1" do
|
||||
expect do
|
||||
odie "foo"
|
||||
end.to output("Error: foo\n").to_stderr.and raise_error SystemExit
|
||||
end
|
||||
end
|
||||
|
||||
describe "#pretty_installed" do
|
||||
subject(:pretty_installed_output) { pretty_installed("foo") }
|
||||
|
||||
context "when $stdout is a TTY" do
|
||||
before { allow($stdout).to receive(:tty?).and_return(true) }
|
||||
|
||||
context "with HOMEBREW_NO_EMOJI unset" do
|
||||
it "returns a string with a colored checkmark" do
|
||||
expect(pretty_installed_output)
|
||||
.to match(/#{esc 1}foo #{esc 32}✔#{esc 0}/)
|
||||
end
|
||||
end
|
||||
|
||||
context "with HOMEBREW_NO_EMOJI set" do
|
||||
before { ENV["HOMEBREW_NO_EMOJI"] = "1" }
|
||||
|
||||
it "returns a string with colored info" do
|
||||
expect(pretty_installed_output)
|
||||
.to match(/#{esc 1}foo \(installed\)#{esc 0}/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when $stdout is not a TTY" do
|
||||
before { allow($stdout).to receive(:tty?).and_return(false) }
|
||||
|
||||
it "returns plain text" do
|
||||
expect(pretty_installed_output).to eq("foo")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#pretty_uninstalled" do
|
||||
subject(:pretty_uninstalled_output) { pretty_uninstalled("foo") }
|
||||
|
||||
context "when $stdout is a TTY" do
|
||||
before { allow($stdout).to receive(:tty?).and_return(true) }
|
||||
|
||||
context "with HOMEBREW_NO_EMOJI unset" do
|
||||
it "returns a string with a colored checkmark" do
|
||||
expect(pretty_uninstalled_output)
|
||||
.to match(/#{esc 1}foo #{esc 31}✘#{esc 0}/)
|
||||
end
|
||||
end
|
||||
|
||||
context "with HOMEBREW_NO_EMOJI set" do
|
||||
before { ENV["HOMEBREW_NO_EMOJI"] = "1" }
|
||||
|
||||
it "returns a string with colored info" do
|
||||
expect(pretty_uninstalled_output)
|
||||
.to match(/#{esc 1}foo \(uninstalled\)#{esc 0}/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when $stdout is not a TTY" do
|
||||
before { allow($stdout).to receive(:tty?).and_return(false) }
|
||||
|
||||
it "returns plain text" do
|
||||
expect(pretty_uninstalled_output).to eq("foo")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#interactive_shell" do
|
||||
let(:shell) { dir/"myshell" }
|
||||
|
||||
@ -155,16 +69,6 @@ RSpec.describe Kernel do
|
||||
expect(which_editor).to eq("vemate -w")
|
||||
end
|
||||
|
||||
describe "#pretty_duration" do
|
||||
it "converts seconds to a human-readable string" do
|
||||
expect(pretty_duration(1)).to eq("1 second")
|
||||
expect(pretty_duration(2.5)).to eq("2 seconds")
|
||||
expect(pretty_duration(42)).to eq("42 seconds")
|
||||
expect(pretty_duration(240)).to eq("4 minutes")
|
||||
expect(pretty_duration(252.45)).to eq("4 minutes 12 seconds")
|
||||
end
|
||||
end
|
||||
|
||||
specify "#disk_usage_readable" do
|
||||
expect(disk_usage_readable(1)).to eq("1B")
|
||||
expect(disk_usage_readable(1000)).to eq("1000B")
|
||||
@ -198,22 +102,6 @@ RSpec.describe Kernel do
|
||||
expect(s).to eq(("x" * (n - glue.length)) + glue)
|
||||
end
|
||||
|
||||
describe "#odeprecated" do
|
||||
it "raises a MethodDeprecatedError when `disable` is true" do
|
||||
ENV.delete("HOMEBREW_DEVELOPER")
|
||||
expect do
|
||||
odeprecated(
|
||||
"method", "replacement",
|
||||
caller: ["#{HOMEBREW_LIBRARY}/Taps/playbrew/homebrew-play/"],
|
||||
disable: true
|
||||
)
|
||||
end.to raise_error(
|
||||
MethodDeprecatedError,
|
||||
%r{method.*replacement.*playbrew/homebrew-play.*/Taps/playbrew/homebrew-play/}m,
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "#with_env" do
|
||||
it "sets environment variables within the block" do
|
||||
expect(ENV.fetch("PATH")).not_to eq("/bin")
|
||||
|
@ -2,6 +2,7 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/parser"
|
||||
require "utils/output"
|
||||
|
||||
UNDEFINED_CONSTANTS = %w[
|
||||
AbstractDownloadStrategy
|
||||
@ -74,7 +75,7 @@ parser.parse
|
||||
|
||||
UNDEFINED_CONSTANTS.each do |constant_name|
|
||||
Object.const_get(constant_name)
|
||||
ofail "#{constant_name} should not be defined at startup"
|
||||
Utils::Output.ofail "#{constant_name} should not be defined at startup"
|
||||
rescue NameError
|
||||
# We expect this to error as it should not be defined.
|
||||
end
|
||||
|
@ -22,6 +22,9 @@ RSpec.describe Tap do
|
||||
path.mkpath
|
||||
(path/"audit_exceptions").mkpath
|
||||
(path/"style_exceptions").mkpath
|
||||
|
||||
# requiring utils/output in tap.rb should be enough but it's not for no apparent reason.
|
||||
$stderr.extend(Utils::Output::Mixin)
|
||||
end
|
||||
|
||||
def setup_tap_files
|
||||
|
117
Library/Homebrew/test/utils/output_spec.rb
Normal file
117
Library/Homebrew/test/utils/output_spec.rb
Normal file
@ -0,0 +1,117 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/output"
|
||||
|
||||
RSpec.describe Utils::Output do
|
||||
def esc(code)
|
||||
/(\e\[\d+m)*\e\[#{code}m/
|
||||
end
|
||||
|
||||
describe "#pretty_installed" do
|
||||
subject(:pretty_installed_output) { described_class.pretty_installed("foo") }
|
||||
|
||||
context "when $stdout is a TTY" do
|
||||
before { allow($stdout).to receive(:tty?).and_return(true) }
|
||||
|
||||
context "with HOMEBREW_NO_EMOJI unset" do
|
||||
it "returns a string with a colored checkmark" do
|
||||
expect(pretty_installed_output)
|
||||
.to match(/#{esc 1}foo #{esc 32}✔#{esc 0}/)
|
||||
end
|
||||
end
|
||||
|
||||
context "with HOMEBREW_NO_EMOJI set" do
|
||||
before { ENV["HOMEBREW_NO_EMOJI"] = "1" }
|
||||
|
||||
it "returns a string with colored info" do
|
||||
expect(pretty_installed_output)
|
||||
.to match(/#{esc 1}foo \(installed\)#{esc 0}/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when $stdout is not a TTY" do
|
||||
before { allow($stdout).to receive(:tty?).and_return(false) }
|
||||
|
||||
it "returns plain text" do
|
||||
expect(pretty_installed_output).to eq("foo")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#pretty_uninstalled" do
|
||||
subject(:pretty_uninstalled_output) { described_class.pretty_uninstalled("foo") }
|
||||
|
||||
context "when $stdout is a TTY" do
|
||||
before { allow($stdout).to receive(:tty?).and_return(true) }
|
||||
|
||||
context "with HOMEBREW_NO_EMOJI unset" do
|
||||
it "returns a string with a colored checkmark" do
|
||||
expect(pretty_uninstalled_output)
|
||||
.to match(/#{esc 1}foo #{esc 31}✘#{esc 0}/)
|
||||
end
|
||||
end
|
||||
|
||||
context "with HOMEBREW_NO_EMOJI set" do
|
||||
before { ENV["HOMEBREW_NO_EMOJI"] = "1" }
|
||||
|
||||
it "returns a string with colored info" do
|
||||
expect(pretty_uninstalled_output)
|
||||
.to match(/#{esc 1}foo \(uninstalled\)#{esc 0}/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when $stdout is not a TTY" do
|
||||
before { allow($stdout).to receive(:tty?).and_return(false) }
|
||||
|
||||
it "returns plain text" do
|
||||
expect(pretty_uninstalled_output).to eq("foo")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#pretty_duration" do
|
||||
it "converts seconds to a human-readable string" do
|
||||
expect(described_class.pretty_duration(1)).to eq("1 second")
|
||||
expect(described_class.pretty_duration(2.5)).to eq("2 seconds")
|
||||
expect(described_class.pretty_duration(42)).to eq("42 seconds")
|
||||
expect(described_class.pretty_duration(240)).to eq("4 minutes")
|
||||
expect(described_class.pretty_duration(252.45)).to eq("4 minutes 12 seconds")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#ofail" do
|
||||
it "sets Homebrew.failed to true" do
|
||||
expect do
|
||||
described_class.ofail "foo"
|
||||
end.to output("Error: foo\n").to_stderr
|
||||
|
||||
expect(Homebrew).to have_failed
|
||||
end
|
||||
end
|
||||
|
||||
describe "#odie" do
|
||||
it "exits with 1" do
|
||||
expect do
|
||||
described_class.odie "foo"
|
||||
end.to output("Error: foo\n").to_stderr.and raise_error SystemExit
|
||||
end
|
||||
end
|
||||
|
||||
describe "#odeprecated" do
|
||||
it "raises a MethodDeprecatedError when `disable` is true" do
|
||||
ENV.delete("HOMEBREW_DEVELOPER")
|
||||
expect do
|
||||
described_class.odeprecated(
|
||||
"method", "replacement",
|
||||
caller: ["#{HOMEBREW_LIBRARY}/Taps/playbrew/homebrew-play/"],
|
||||
disable: true
|
||||
)
|
||||
end.to raise_error(
|
||||
MethodDeprecatedError,
|
||||
%r{method.*replacement.*playbrew/homebrew-play.*/Taps/playbrew/homebrew-play/}m,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
@ -2,10 +2,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "installed_dependents"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Helper module for uninstalling kegs.
|
||||
module Uninstall
|
||||
extend ::Utils::Output::Mixin
|
||||
|
||||
def self.uninstall_kegs(kegs_by_rack, casks: [], force: false, ignore_dependencies: false, named_args: [])
|
||||
handle_unsatisfied_dependents(kegs_by_rack,
|
||||
casks:,
|
||||
@ -122,6 +125,8 @@ module Homebrew
|
||||
end
|
||||
|
||||
class DependentsMessage
|
||||
include ::Utils::Output::Mixin
|
||||
|
||||
attr_reader :reqs, :deps, :named_args
|
||||
|
||||
def initialize(requireds, dependents, named_args: [])
|
||||
|
@ -3,11 +3,14 @@
|
||||
|
||||
require "mktemp"
|
||||
require "system_command"
|
||||
require "utils/output"
|
||||
|
||||
# Module containing all available strategies for unpacking archives.
|
||||
module UnpackStrategy
|
||||
extend T::Helpers
|
||||
extend Utils::Output::Mixin
|
||||
include SystemCommand::Mixin
|
||||
include Utils::Output::Mixin
|
||||
|
||||
abstract!
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
require "tempfile"
|
||||
require "system_command"
|
||||
require "utils/output"
|
||||
|
||||
module UnpackStrategy
|
||||
# Strategy for unpacking disk images.
|
||||
@ -12,6 +13,7 @@ module UnpackStrategy
|
||||
|
||||
# Helper module for listing the contents of a volume mounted from a disk image.
|
||||
module Bom
|
||||
extend Utils::Output::Mixin
|
||||
extend SystemCommand::Mixin
|
||||
|
||||
DMG_METADATA = T.let(Set.new([
|
||||
|
@ -5,12 +5,14 @@ require "bundle_version"
|
||||
require "cask/cask"
|
||||
require "cask/installer"
|
||||
require "system_command"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Check unversioned casks for updates by extracting their
|
||||
# contents and guessing the version from contained files.
|
||||
class UnversionedCaskChecker
|
||||
include SystemCommand::Mixin
|
||||
include Utils::Output::Mixin
|
||||
|
||||
sig { returns(Cask::Cask) }
|
||||
attr_reader :cask
|
||||
|
@ -7,10 +7,13 @@ require "development_tools"
|
||||
require "messages"
|
||||
require "cleanup"
|
||||
require "utils/topological_hash"
|
||||
require "utils/output"
|
||||
|
||||
module Homebrew
|
||||
# Helper functions for upgrading formulae.
|
||||
module Upgrade
|
||||
extend Utils::Output::Mixin
|
||||
|
||||
class Dependents < T::Struct
|
||||
const :upgradeable, T::Array[Formula]
|
||||
const :pinned, T::Array[Formula]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user