Merge pull request #20525 from Homebrew/utils_output
Move `o*` output methods to `Utils::Output`
This commit is contained in:
		
						commit
						3bbff84ff1
					
				@ -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
 | 
			
		||||
@ -105,14 +106,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|
 | 
			
		||||
@ -129,14 +130,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
 | 
			
		||||
@ -161,7 +164,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)
 | 
			
		||||
@ -199,7 +202,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)
 | 
			
		||||
@ -208,7 +211,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