Add more type signatures.

This commit is contained in:
Markus Reiter 2020-10-20 12:03:48 +02:00
parent c602090624
commit da9289eff0
237 changed files with 1223 additions and 98 deletions

View File

@ -297,15 +297,9 @@ Sorbet/ConstantsFromStrings:
Style/AccessModifierDeclarations:
Enabled: false
# don't group nicely documented or private attr_readers
# Conflicts with type signatures on `attr_*`s.
Style/AccessorGrouping:
Exclude:
- 'Homebrew/formula.rb'
- 'Homebrew/formulary.rb'
- 'Homebrew/migrator.rb'
- 'Homebrew/resource.rb'
- 'Homebrew/system_command.rb'
- 'Homebrew/tap.rb'
Enabled: false
# make rspec formatting more flexible
Style/BlockDelimiters:

View File

@ -8,6 +8,8 @@ require "json"
#
# @api private
class Bintray
extend T::Sig
include Context
API_URL = "https://api.bintray.com"
@ -15,6 +17,7 @@ class Bintray
class Error < RuntimeError
end
sig { returns(String) }
def inspect
"#<Bintray: org=#{@bintray_org}>"
end

View File

@ -7,6 +7,8 @@ module Cask
#
# @api private
class AbstractArtifact
extend T::Sig
include Comparable
extend Predicable
@ -132,6 +134,7 @@ module Cask
cask.config
end
sig { returns(String) }
def to_s
"#{summarize} (#{self.class.english_name})"
end

View File

@ -15,6 +15,8 @@ module Cask
#
# @api private
class AbstractUninstall < AbstractArtifact
extend T::Sig
ORDERED_DIRECTIVES = [
:early_script,
:launchctl,
@ -53,6 +55,7 @@ module Cask
directives.to_h
end
sig { returns(String) }
def summarize
to_h.flat_map { |key, val| Array(val).map { |v| "#{key.inspect} => #{v.inspect}" } }.join(", ")
end
@ -128,6 +131,7 @@ module Cask
end
end
sig { returns(String) }
def automation_access_instructions
"Enable Automation Access for “Terminal > System Events” in " \
"“System Preferences > Security > Privacy > Automation” if you haven't already."

View File

@ -12,6 +12,9 @@ module Cask
#
# @api private
class Artifact < Moved
extend T::Sig
sig { returns(String) }
def self.english_name
"Generic Artifact"
end

View File

@ -9,6 +9,9 @@ module Cask
#
# @api private
class Mdimporter < Moved
extend T::Sig
sig { returns(String) }
def self.english_name
"Spotlight metadata importer"
end

View File

@ -9,6 +9,9 @@ module Cask
#
# @api private
class Moved < Relocated
extend T::Sig
sig { returns(String) }
def self.english_description
"#{english_name}s"
end

View File

@ -9,6 +9,9 @@ module Cask
#
# @api private
class Prefpane < Moved
extend T::Sig
sig { returns(String) }
def self.english_name
"Preference Pane"
end

View File

@ -9,6 +9,9 @@ module Cask
#
# @api private
class Qlplugin < Moved
extend T::Sig
sig { returns(String) }
def self.english_name
"QuickLook Plugin"
end

View File

@ -12,6 +12,8 @@ module Cask
#
# @api private
class Relocated < AbstractArtifact
extend T::Sig
def self.from_args(cask, *args)
source_string, target_hash = args
@ -49,6 +51,7 @@ module Cask
end
end
sig { returns(String) }
def summarize
target_string = @target_string.empty? ? "" : " -> #{@target_string}"
"#{@source_string}#{target_string}"

View File

@ -9,16 +9,20 @@ module Cask
#
# @api private
class StageOnly < AbstractArtifact
extend T::Sig
def self.from_args(cask, *args)
raise CaskInvalidError.new(cask.token, "'stage_only' takes only a single argument: true") if args != [true]
new(cask)
end
sig { returns(T::Array[T::Boolean]) }
def to_a
[true]
end
sig { returns(String) }
def summarize
"true"
end

View File

@ -9,10 +9,14 @@ module Cask
#
# @api private
class Suite < Moved
extend T::Sig
sig { returns(String) }
def self.english_name
"App Suite"
end
sig { returns(Symbol) }
def self.dirmethod
:appdir
end

View File

@ -9,10 +9,14 @@ module Cask
#
# @api private
class Symlinked < Relocated
extend T::Sig
sig { returns(String) }
def self.link_type_english_name
"Symlink"
end
sig { returns(String) }
def self.english_description
"#{english_name} #{link_type_english_name}s"
end

View File

@ -13,6 +13,8 @@ module Cask
#
# @api private
class Audit
extend T::Sig
extend Predicable
attr_reader :cask, :download
@ -117,6 +119,7 @@ module Cask
end
end
sig { returns(String) }
def summary
summary = ["audit for #{cask}: #{result}"]
@ -416,6 +419,7 @@ module Cask
core_tap.formula_names
end
sig { returns(String) }
def core_formula_url
"#{core_tap.default_remote}/blob/HEAD/Formula/#{cask.token}.rb"
end

View File

@ -12,6 +12,8 @@ module Cask
#
# @api private
class Cask
extend T::Sig
extend Enumerable
extend Forwardable
extend Searchable
@ -64,6 +66,7 @@ module Cask
define_method(method_name) { |&block| @dsl.send(method_name, &block) }
end
sig { returns(T::Array[[String, String]]) }
def timestamped_versions
Pathname.glob(metadata_timestamped_path(version: "*", timestamp: "*"))
.map { |p| p.relative_path_from(p.parent.parent) }
@ -89,6 +92,7 @@ module Cask
!versions.empty?
end
sig { returns(T.nilable(Time)) }
def install_time
_, time = timestamped_versions.last
return unless time

View File

@ -90,6 +90,8 @@ module Cask
# Loads a cask from a URI.
class FromURILoader < FromPathLoader
extend T::Sig
def self.can_load?(ref)
uri_regex = ::URI::DEFAULT_PARSER.make_regexp
return false unless ref.to_s.match?(Regexp.new("\\A#{uri_regex.source}\\Z", uri_regex.options))
@ -103,6 +105,7 @@ module Cask
attr_reader :url
sig { params(url: T.any(URI::Generic, String)).void }
def initialize(url)
@url = URI(url)
super Cache.path/File.basename(@url.path)
@ -177,10 +180,13 @@ module Cask
# Pseudo-loader which raises an error when trying to load the corresponding cask.
class NullLoader < FromPathLoader
extend T::Sig
def self.can_load?(*)
true
end
sig { params(ref: T.any(String, Pathname)).void }
def initialize(ref)
token = File.basename(ref, ".rb")
super CaskLoader.default_path(token)

View File

@ -38,6 +38,8 @@ module Cask
#
# @api private
class Cmd
extend T::Sig
include Context
ALIASES = {
@ -61,6 +63,7 @@ module Cask
Cmd::Upgrade => "brew upgrade --cask",
}.freeze
sig { returns(String) }
def self.description
max_command_length = Cmd.commands.map(&:length).max

View File

@ -7,18 +7,24 @@ module Cask
#
# @api private
class Cache < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
:cask
end
sig { returns(String) }
def self.description
"Display the file used to cache a <cask>."
end
sig { returns(String) }
def self.command_name
"--cache"
end
sig { void }
def run
casks.each do |cask|
puts self.class.cached_location(cask)

View File

@ -9,16 +9,22 @@ module Cask
#
# @api private
class AbstractCommand
extend T::Sig
extend T::Helpers
include Homebrew::Search
sig { returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
nil
end
sig { returns(T.nilable(Integer)) }
def self.max_named
nil
end
sig { returns(String) }
def self.banner_args
if min_named == :cask && max_named != 1
" <cask>"
@ -29,6 +35,7 @@ module Cask
end
end
sig { returns(String) }
def self.banner_headline
"`#{command_name}` [<options>]#{banner_args}"
end
@ -72,24 +79,29 @@ module Cask
end
end
sig { returns(String) }
def self.command_name
@command_name ||= name.sub(/^.*:/, "").gsub(/(.)([A-Z])/, '\1_\2').downcase
end
sig { returns(T::Boolean) }
def self.abstract?
name.split("::").last.match?(/^Abstract[^a-z]/)
end
sig { returns(T::Boolean) }
def self.visible?
true
end
sig { returns(String) }
def self.help
parser.generate_help_text
end
sig { returns(String) }
def self.short_description
description.split(".").first
description[/\A[^.]*\./]
end
def self.run(*args)

View File

@ -7,10 +7,14 @@ module Cask
#
# @api private
class AbstractInternalCommand < AbstractCommand
extend T::Sig
sig { returns(String) }
def self.command_name
super.sub(/^internal_/i, "_")
end
sig { returns(T::Boolean) }
def self.visible?
false
end

View File

@ -9,6 +9,9 @@ module Cask
#
# @api private
class Audit < AbstractCommand
extend T::Sig
sig { returns(String) }
def self.description
<<~EOS
Check <cask> for Homebrew coding style violations. This should be run before
@ -37,6 +40,7 @@ module Cask
end
end
sig { void }
def run
require "cask/auditor"

View File

@ -7,14 +7,19 @@ module Cask
#
# @api private
class Cat < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
:cask
end
sig { returns(String) }
def self.description
"Dump raw source of a <cask> to the standard output."
end
sig { void }
def run
casks.each do |cask|
if Homebrew::EnvConfig.bat?

View File

@ -7,14 +7,19 @@ module Cask
#
# @api private
class Create < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
:cask
end
sig { override.returns(T.nilable(Integer)) }
def self.max_named
1
end
sig { returns(String) }
def self.description
"Creates the given <cask> and opens it in an editor."
end
@ -25,6 +30,7 @@ module Cask
raise UsageError, "Only one cask can be created at a time."
end
sig { void }
def run
cask_token = args.named.first
cask_path = CaskLoader.path(cask_token)

View File

@ -7,14 +7,19 @@ module Cask
#
# @api private
class Doctor < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(Integer)) }
def self.max_named
0
end
sig { returns(String) }
def self.description
"Checks for configuration issues."
end
sig { void }
def run
require "diagnostic"

View File

@ -7,14 +7,19 @@ module Cask
#
# @api private
class Edit < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
:cask
end
sig { override.returns(T.nilable(Integer)) }
def self.max_named
1
end
sig { returns(String) }
def self.description
"Open the given <cask> for editing."
end
@ -25,6 +30,7 @@ module Cask
raise UsageError, "Only one cask can be edited at a time."
end
sig { void }
def run
exec_editor cask_path
rescue CaskUnavailableError => e

View File

@ -7,6 +7,9 @@ module Cask
#
# @api private
class Fetch < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
:cask
end
@ -18,10 +21,12 @@ module Cask
end
end
sig { returns(String) }
def self.description
"Downloads remote application files to local cache."
end
sig { void }
def run
require "cask/download"
require "cask/installer"

View File

@ -7,14 +7,19 @@ module Cask
#
# @api private
class Help < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(Integer)) }
def self.max_named
1
end
sig { returns(String) }
def self.description
"Print help for `cask` commands."
end
sig { void }
def run
if args.named.empty?
puts Cmd.parser.generate_help_text

View File

@ -7,10 +7,14 @@ module Cask
#
# @api private
class Home < AbstractCommand
extend T::Sig
sig { returns(String) }
def self.description
"Opens the homepage of the given <cask>. If no cask is given, opens the Homebrew homepage."
end
sig { void }
def run
if casks.none?
odebug "Opening project homepage"

View File

@ -9,10 +9,14 @@ module Cask
#
# @api private
class Info < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
:cask
end
sig { returns(String) }
def self.description
"Displays information about the given <cask>."
end
@ -42,6 +46,7 @@ module Cask
end
end
sig { void }
def run
if args.json == "v1"
puts JSON.generate(args.named.to_casks.map(&:to_h))

View File

@ -7,10 +7,14 @@ module Cask
#
# @api private
class Install < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
:cask
end
sig { returns(String) }
def self.description
"Installs the given <cask>."
end
@ -34,6 +38,7 @@ module Cask
end
end
sig { void }
def run
self.class.install_casks(
*casks,

View File

@ -7,14 +7,19 @@ module Cask
#
# @api private
class InternalHelp < AbstractInternalCommand
extend T::Sig
sig { override.returns(T.nilable(Integer)) }
def self.max_named
0
end
sig { returns(String) }
def self.description
"Print help for unstable internal-use commands."
end
sig { void }
def run
max_command_len = Cmd.commands.map(&:length).max
puts "Unstable Internal-use Commands:\n\n"

View File

@ -9,6 +9,8 @@ module Cask
#
# @api private
class InternalStanza < AbstractInternalCommand
extend T::Sig
# Syntax
#
# brew cask _stanza <stanza_name> [ --quiet ] [ --table | --yaml ] [ <cask_token> ... ]
@ -24,14 +26,17 @@ module Cask
(DSL::ORDINARY_ARTIFACT_CLASSES.map(&:dsl_key) +
DSL::ARTIFACT_BLOCK_CLASSES.map(&:dsl_key)).freeze
sig { override.returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
1
end
sig { returns(String) }
def self.banner_args
" <stanza_name> [<cask>]"
end
sig { returns(String) }
def self.description
<<~EOS
Extract and render a specific stanza for the given <cask>.
@ -80,6 +85,7 @@ module Cask
EOS
end
sig { void }
def run
if ARTIFACTS.include?(stanza)
artifact_name = stanza

View File

@ -9,6 +9,9 @@ module Cask
#
# @api private
class List < AbstractCommand
extend T::Sig
sig { returns(String) }
def self.description
"Lists installed casks or the casks provided in the arguments."
end
@ -26,6 +29,7 @@ module Cask
end
end
sig { void }
def run
self.class.list_casks(
*casks,

View File

@ -7,6 +7,9 @@ module Cask
#
# @api private
class Outdated < AbstractCommand
extend T::Sig
sig { returns(String) }
def self.description
"List the outdated installed casks."
end
@ -20,6 +23,7 @@ module Cask
end
end
sig { void }
def run
outdated_casks = casks(alternative: -> { Caskroom.casks(config: Config.from_args(args)) }).select do |cask|
odebug "Checking update info of Cask #{cask}"

View File

@ -7,10 +7,14 @@ module Cask
#
# @api private
class Reinstall < Install
extend T::Sig
sig { returns(String) }
def self.description
"Reinstalls the given <cask>."
end
sig { void }
def run
self.class.reinstall_casks(
*casks,

View File

@ -10,6 +10,9 @@ module Cask
#
# @api private
class Style < AbstractCommand
extend T::Sig
sig { returns(String) }
def self.description
"Checks style of the given <cask> using RuboCop."
end
@ -21,6 +24,7 @@ module Cask
end
end
sig { void }
def run
success = Homebrew::Style.check_style_and_print(
cask_paths,

View File

@ -7,10 +7,14 @@ module Cask
#
# @api private
class Uninstall < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
:cask
end
sig { returns(String) }
def self.description
"Uninstalls the given <cask>."
end
@ -23,6 +27,7 @@ module Cask
end
end
sig { void }
def run
self.class.uninstall_casks(
*casks,

View File

@ -10,6 +10,9 @@ module Cask
#
# @api private
class Upgrade < AbstractCommand
extend T::Sig
sig { returns(String) }
def self.description
"Upgrades all outdated casks or the specified casks."
end
@ -36,6 +39,7 @@ module Cask
end
end
sig { void }
def run
verbose = ($stdout.tty? || args.verbose?) && !args.quiet?
self.class.upgrade_casks(

View File

@ -7,10 +7,14 @@ module Cask
#
# @api private
class Zap < AbstractCommand
extend T::Sig
sig { override.returns(T.nilable(T.any(Integer, Symbol))) }
def self.min_named
:cask
end
sig { returns(String) }
def self.description
<<~EOS
Zaps all files associated with the given <cask>. Implicitly also performs all actions associated with `uninstall`.
@ -26,6 +30,7 @@ module Cask
end
end
sig { void }
def run
require "cask/installer"

View File

@ -1,4 +1,4 @@
# typed: true
# typed: strict
# frozen_string_literal: true
module Cask
@ -6,6 +6,9 @@ module Cask
#
# @api private
module Denylist
extend T::Sig
sig { params(name: String).returns(T.nilable(String)) }
def self.reason(name)
case name
when /^adobe-(after|illustrator|indesign|photoshop|premiere)/

View File

@ -7,6 +7,8 @@ module Cask
#
# @api private
class Version < ::String
extend T::Sig
DIVIDERS = {
"." => :dots,
"-" => :hyphens,
@ -62,6 +64,7 @@ module Cask
attr_reader :raw_version
sig { params(raw_version: T.nilable(T.any(String, Symbol))).void }
def initialize(raw_version)
@raw_version = raw_version
super(raw_version.to_s)
@ -73,6 +76,7 @@ module Cask
raw_version.scan(INVALID_CHARACTERS)
end
sig { returns(T::Boolean) }
def unstable?
return false if latest?
@ -84,6 +88,7 @@ module Cask
false
end
sig { returns(T::Boolean) }
def latest?
to_s == "latest"
end
@ -134,6 +139,7 @@ module Cask
private
sig { returns(T.self_type) }
def version
return self if empty? || latest?

View File

@ -11,12 +11,15 @@ module Cask
#
# @api private
class MultipleCaskErrors < CaskError
extend T::Sig
def initialize(errors)
super()
@errors = errors
end
sig { returns(String) }
def to_s
<<~EOS
Problems with multiple casks:
@ -29,12 +32,18 @@ module Cask
#
# @api private
class AbstractCaskErrorWithToken < CaskError
attr_reader :token, :reason
extend T::Sig
sig { returns(String) }
attr_reader :token
sig { returns(String) }
attr_reader :reason
def initialize(token, reason = nil)
super()
@token = token
@token = token.to_s
@reason = reason.to_s
end
end
@ -43,6 +52,9 @@ module Cask
#
# @api private
class CaskNotInstalledError < AbstractCaskErrorWithToken
extend T::Sig
sig { returns(String) }
def to_s
"Cask '#{token}' is not installed."
end
@ -52,6 +64,8 @@ module Cask
#
# @api private
class CaskConflictError < AbstractCaskErrorWithToken
extend T::Sig
attr_reader :conflicting_cask
def initialize(token, conflicting_cask)
@ -59,6 +73,7 @@ module Cask
@conflicting_cask = conflicting_cask
end
sig { returns(String) }
def to_s
"Cask '#{token}' conflicts with '#{conflicting_cask}'."
end
@ -68,6 +83,9 @@ module Cask
#
# @api private
class CaskUnavailableError < AbstractCaskErrorWithToken
extend T::Sig
sig { returns(String) }
def to_s
"Cask '#{token}' is unavailable#{reason.empty? ? "." : ": #{reason}"}"
end
@ -77,6 +95,9 @@ module Cask
#
# @api private
class CaskUnreadableError < CaskUnavailableError
extend T::Sig
sig { returns(String) }
def to_s
"Cask '#{token}' is unreadable#{reason.empty? ? "." : ": #{reason}"}"
end
@ -86,6 +107,9 @@ module Cask
#
# @api private
class CaskAlreadyCreatedError < AbstractCaskErrorWithToken
extend T::Sig
sig { returns(String) }
def to_s
%Q(Cask '#{token}' already exists. Run #{Formatter.identifier("brew cask edit #{token}")} to edit it.)
end
@ -95,6 +119,9 @@ module Cask
#
# @api private
class CaskAlreadyInstalledError < AbstractCaskErrorWithToken
extend T::Sig
sig { returns(String) }
def to_s
<<~EOS
Cask '#{token}' is already installed.
@ -109,6 +136,9 @@ module Cask
#
# @api private
class CaskX11DependencyError < AbstractCaskErrorWithToken
extend T::Sig
sig { returns(String) }
def to_s
<<~EOS
Cask '#{token}' requires XQuartz/X11, which can be installed using Homebrew Cask by running:
@ -124,6 +154,9 @@ module Cask
#
# @api private
class CaskCyclicDependencyError < AbstractCaskErrorWithToken
extend T::Sig
sig { returns(String) }
def to_s
"Cask '#{token}' includes cyclic dependencies on other Casks#{reason.empty? ? "." : ": #{reason}"}"
end
@ -133,6 +166,9 @@ module Cask
#
# @api private
class CaskSelfReferencingDependencyError < CaskCyclicDependencyError
extend T::Sig
sig { returns(String) }
def to_s
"Cask '#{token}' depends on itself."
end
@ -142,6 +178,9 @@ module Cask
#
# @api private
class CaskUnspecifiedError < CaskError
extend T::Sig
sig { returns(String) }
def to_s
"This command requires a Cask token."
end
@ -151,6 +190,9 @@ module Cask
#
# @api private
class CaskInvalidError < AbstractCaskErrorWithToken
extend T::Sig
sig { returns(String) }
def to_s
"Cask '#{token}' definition is invalid#{reason.empty? ? "." : ": #{reason}"}"
end
@ -182,6 +224,9 @@ module Cask
#
# @api private
class CaskSha256MissingError < CaskSha256Error
extend T::Sig
sig { returns(String) }
def to_s
<<~EOS
Cask '#{token}' requires a checksum:
@ -194,6 +239,8 @@ module Cask
#
# @api private
class CaskSha256MismatchError < CaskSha256Error
extend T::Sig
attr_reader :path
def initialize(token, expected, actual, path)
@ -201,6 +248,7 @@ module Cask
@path = path
end
sig { returns(String) }
def to_s
<<~EOS
Checksum for Cask '#{token}' does not match.
@ -218,6 +266,9 @@ module Cask
#
# @api private
class CaskNoShasumError < CaskSha256Error
extend T::Sig
sig { returns(String) }
def to_s
<<~EOS
Cask '#{token}' does not have a sha256 checksum defined and was not installed.
@ -230,6 +281,8 @@ module Cask
#
# @api private
class CaskQuarantineError < CaskError
extend T::Sig
attr_reader :path, :reason
def initialize(path, reason)
@ -239,6 +292,7 @@ module Cask
@reason = reason
end
sig { returns(String) }
def to_s
s = +"Failed to quarantine #{path}."
@ -256,6 +310,9 @@ module Cask
#
# @api private
class CaskQuarantinePropagationError < CaskQuarantineError
extend T::Sig
sig { returns(String) }
def to_s
s = +"Failed to quarantine one or more files within #{path}."
@ -273,6 +330,9 @@ module Cask
#
# @api private
class CaskQuarantineReleaseError < CaskQuarantineError
extend T::Sig
sig { returns(String) }
def to_s
s = +"Failed to release #{path} from quarantine."

View File

@ -18,6 +18,8 @@ module Cask
#
# @api private
class Installer
extend T::Sig
extend Predicable
# TODO: it is unwise for Cask::Staged to be a module, when we are
# dealing with both staged and unstaged casks here. This should
@ -142,6 +144,7 @@ module Cask
Installer.new(installed_cask, binaries: binaries?, verbose: verbose?, force: true, upgrade: upgrade?).uninstall
end
sig { returns(String) }
def summary
s = +""
s << "#{Homebrew::EnvConfig.install_badge} " unless Homebrew::EnvConfig.no_emoji?

View File

@ -9,6 +9,8 @@ module Cask
#
# @api private
module Quarantine
extend T::Sig
module_function
QUARANTINE_ATTRIBUTE = "com.apple.quarantine"
@ -25,6 +27,7 @@ module Cask
end
private :xattr
sig { returns(Symbol) }
def check_quarantine_support
odebug "Checking quarantine support"

View File

@ -13,6 +13,8 @@ module Cask
#
# @api private
module Utils
extend T::Sig
def self.gain_permissions_remove(path, command: SystemCommand)
if path.respond_to?(:rmtree) && path.exist?
gain_permissions(path, ["-R"], command) do |p|
@ -72,10 +74,12 @@ module Cask
end
end
sig { params(path: Pathname).returns(T::Boolean) }
def self.path_occupied?(path)
File.exist?(path) || File.symlink?(path)
path.exist? || path.symlink?
end
sig { returns(String) }
def self.error_message_with_suggestions
<<~EOS
Follow the instructions here:

View File

@ -7,11 +7,14 @@ require "ostruct"
module Homebrew
module CLI
class Args < OpenStruct
extend T::Sig
attr_reader :options_only, :flags_only
# undefine tap to allow --tap argument
undef tap
sig { void }
def initialize
super()
@ -131,6 +134,7 @@ module Homebrew
flag_with_value.delete_prefix(arg_prefix)
end
sig { returns(Context::ContextStruct) }
def context
Context::ContextStruct.new(debug: debug?, quiet: quiet?, verbose: verbose?)
end

View File

@ -14,6 +14,8 @@ OPTION_DESC_WIDTH = 43
module Homebrew
module CLI
class Parser
extend T::Sig
attr_reader :processed_options, :hide_from_man_page
def self.from_cmd_path(cmd_path)
@ -94,6 +96,7 @@ module Homebrew
]
end
sig { returns(T::Array[[String, String, String]]) }
def self.global_options
[
["-d", "--debug", "Display any debugging information."],
@ -103,6 +106,9 @@ module Homebrew
]
end
# FIXME: Block should be `T.nilable(T.proc.bind(Parser).void)`.
# See https://github.com/sorbet/sorbet/issues/498.
sig { params(block: T.proc.bind(Parser).void).void.checked(:never) }
def initialize(&block)
@parser = OptionParser.new
@ -331,6 +337,7 @@ module Homebrew
end
end
sig { void }
def formula_options
@formula_options = true
end
@ -367,6 +374,7 @@ module Homebrew
end
end
sig { void }
def hide_from_man_page!
@hide_from_man_page = true
end
@ -454,20 +462,24 @@ module Homebrew
end
def check_named_args(args)
min_exception = case @min_named_type
when :cask
Cask::CaskUnspecifiedError
when :formula
FormulaUnspecifiedError
when :formula_or_cask
FormulaOrCaskUnspecifiedError
when :keg
KegUnspecifiedError
else
MinNamedArgumentsError.new(@min_named_args)
exception = if @min_named_args && args.size < @min_named_args
case @min_named_type
when :cask
Cask::CaskUnspecifiedError
when :formula
FormulaUnspecifiedError
when :formula_or_cask
FormulaOrCaskUnspecifiedError
when :keg
KegUnspecifiedError
else
MinNamedArgumentsError.new(@min_named_args)
end
elsif @max_named_args && args.size > @max_named_args
MaxNamedArgumentsError.new(@max_named_args)
end
raise min_exception if @min_named_args && args.size < @min_named_args
raise MaxNamedArgumentsError, @max_named_args if @max_named_args && args.size > @max_named_args
raise exception if exception
end
def process_option(*args)
@ -535,6 +547,9 @@ module Homebrew
end
class MaxNamedArgumentsError < UsageError
extend T::Sig
sig { params(maximum: Integer).void }
def initialize(maximum)
super case maximum
when 0
@ -546,6 +561,9 @@ module Homebrew
end
class MinNamedArgumentsError < UsageError
extend T::Sig
sig { params(minimum: Integer).void }
def initialize(minimum)
super "This command requires at least #{minimum} named #{"argument".pluralize(minimum)}."
end

View File

@ -6,10 +6,13 @@ require "cli/parser"
require "cask/download"
module Homebrew
extend T::Sig
extend Fetch
module_function
sig { returns(CLI::Parser) }
def __cache_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -1,9 +1,12 @@
# typed: false
# typed: strict
# frozen_string_literal: true
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def __caskroom_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
@ -17,6 +20,7 @@ module Homebrew
end
end
sig { void }
def __caskroom
args = __caskroom_args.parse

View File

@ -7,8 +7,11 @@ require "utils/shell"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def __env_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -4,8 +4,11 @@
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def __prefix_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -4,8 +4,11 @@
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def __repository_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -4,8 +4,11 @@
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def __version_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -4,8 +4,11 @@
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def analytics_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -5,8 +5,11 @@ require "cleanup"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def cleanup_args
Homebrew::CLI::Parser.new do
days = Homebrew::EnvConfig::ENVS[:HOMEBREW_CLEANUP_MAX_AGE_DAYS][:default]

View File

@ -4,8 +4,11 @@
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def commands_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -5,8 +5,11 @@ require "system_config"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def config_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -8,10 +8,13 @@ require "cask/caskroom"
require "dependencies_helpers"
module Homebrew
extend T::Sig
extend DependenciesHelpers
module_function
sig { returns(CLI::Parser) }
def deps_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -7,10 +7,13 @@ require "description_cache_store"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
extend Search
sig { returns(CLI::Parser) }
def desc_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -6,8 +6,11 @@ require "cli/parser"
require "cask/caskroom"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def doctor_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -6,10 +6,13 @@ require "fetch"
require "cli/parser"
module Homebrew
extend T::Sig
extend Fetch
module_function
sig { returns(CLI::Parser) }
def fetch_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -9,10 +9,13 @@ require "socket"
require "cli/parser"
module Homebrew
extend T::Sig
extend Install
module_function
sig { returns(CLI::Parser) }
def gist_logs_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -4,8 +4,11 @@
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def home_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -13,12 +13,15 @@ require "utils/spdx"
require "deprecate_disable"
module Homebrew
extend T::Sig
module_function
VALID_DAYS = %w[30 90 365].freeze
VALID_FORMULA_CATEGORIES = %w[install install-on-request build-error].freeze
VALID_CATEGORIES = (VALID_FORMULA_CATEGORIES + %w[cask-install os-version]).freeze
sig { returns(CLI::Parser) }
def info_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -14,10 +14,13 @@ require "cli/parser"
require "upgrade"
module Homebrew
extend T::Sig
extend Search
module_function
sig { returns(CLI::Parser) }
def install_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -5,8 +5,11 @@ require "formula"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def leaves_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -7,8 +7,11 @@ require "cli/parser"
require "unlink"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def link_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -7,8 +7,11 @@ require "cli/parser"
require "cask/cmd"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def list_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -5,8 +5,11 @@ require "formula"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def log_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -5,8 +5,11 @@ require "migrator"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def migrate_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -7,8 +7,11 @@ require "diagnostic"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def missing_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -7,8 +7,11 @@ require "cli/parser"
require "commands"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def options_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -8,8 +8,11 @@ require "cask/cmd"
require "cask/caskroom"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def outdated_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -5,8 +5,11 @@ require "formula"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def pin_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -6,8 +6,11 @@ require "formula_installer"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def postinstall_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -5,8 +5,11 @@ require "readall"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def readall_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -14,8 +14,11 @@ require "cask/macos"
require "upgrade"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def reinstall_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -8,6 +8,8 @@ require "cli/parser"
require "search"
module Homebrew
extend T::Sig
module_function
extend Search
@ -25,6 +27,7 @@ module Homebrew
},
}.freeze
sig { returns(CLI::Parser) }
def search_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -6,8 +6,11 @@ require "keg"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def switch_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -4,8 +4,11 @@
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def tap_info_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -4,8 +4,11 @@
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def tap_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -11,8 +11,11 @@ require "cask/cask_loader"
require "uninstall"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def uninstall_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -6,8 +6,11 @@ require "cli/parser"
require "unlink"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def unlink_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -5,8 +5,11 @@ require "formula"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def unpin_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -4,8 +4,11 @@
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def untap_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -10,6 +10,8 @@ require "description_cache_store"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
def update_preinstall_header(args:)
@ -19,6 +21,7 @@ module Homebrew
end
end
sig { returns(CLI::Parser) }
def update_report_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS
@ -413,10 +416,13 @@ class Reporter
end
class ReporterHub
extend T::Sig
extend Forwardable
attr_reader :reporters
sig { void }
def initialize
@hash = {}
@reporters = []

View File

@ -10,8 +10,11 @@ require "cask/utils"
require "cask/macos"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def upgrade_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -11,10 +11,13 @@ require "cask/caskroom"
require "dependencies_helpers"
module Homebrew
extend T::Sig
extend DependenciesHelpers
module_function
sig { returns(CLI::Parser) }
def uses_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -4,28 +4,36 @@
raise "HOMEBREW_BREW_FILE was not exported! Please call bin/brew directly!" unless ENV["HOMEBREW_BREW_FILE"]
# Path to `bin/brew` main executable in `HOMEBREW_PREFIX`
HOMEBREW_BREW_FILE = Pathname.new(ENV["HOMEBREW_BREW_FILE"]).freeze
HOMEBREW_BREW_FILE = Pathname(ENV["HOMEBREW_BREW_FILE"]).freeze
class MissingEnvironmentVariables < RuntimeError; end
def get_env_or_raise(env)
raise MissingEnvironmentVariables, "#{env} was not exported!" unless ENV[env]
# Helper module for getting environment variables which must be set.
#
# @api private
module EnvVar
extend T::Sig
ENV[env]
sig { params(env: String).returns(String) }
def self.[](env)
raise MissingEnvironmentVariables, "#{env} was not exported!" unless ENV[env]
ENV.fetch(env)
end
end
require "extend/git_repository"
# Where we link under
HOMEBREW_PREFIX = Pathname.new(get_env_or_raise("HOMEBREW_PREFIX")).freeze
HOMEBREW_PREFIX = Pathname(EnvVar["HOMEBREW_PREFIX"]).freeze
# Where `.git` is found
HOMEBREW_REPOSITORY = Pathname.new(get_env_or_raise("HOMEBREW_REPOSITORY"))
.extend(GitRepositoryExtension)
.freeze
HOMEBREW_REPOSITORY = Pathname(EnvVar["HOMEBREW_REPOSITORY"])
.extend(GitRepositoryExtension)
.freeze
# Where we store most of Homebrew, taps, and various metadata
HOMEBREW_LIBRARY = Pathname.new(get_env_or_raise("HOMEBREW_LIBRARY")).freeze
HOMEBREW_LIBRARY = Pathname(EnvVar["HOMEBREW_LIBRARY"]).freeze
# Where shim scripts for various build and SCM tools are stored
HOMEBREW_SHIMS_PATH = (HOMEBREW_LIBRARY/"Homebrew/shims").freeze
@ -43,19 +51,19 @@ HOMEBREW_PINNED_KEGS = (HOMEBREW_PREFIX/"var/homebrew/pinned").freeze
HOMEBREW_LOCKS = (HOMEBREW_PREFIX/"var/homebrew/locks").freeze
# Where we store built products
HOMEBREW_CELLAR = Pathname.new(get_env_or_raise("HOMEBREW_CELLAR")).freeze
HOMEBREW_CELLAR = Pathname(EnvVar["HOMEBREW_CELLAR"]).freeze
# Where downloads (bottles, source tarballs, etc.) are cached
HOMEBREW_CACHE = Pathname.new(get_env_or_raise("HOMEBREW_CACHE")).freeze
HOMEBREW_CACHE = Pathname(EnvVar["HOMEBREW_CACHE"]).freeze
# Where brews installed via URL are cached
HOMEBREW_CACHE_FORMULA = (HOMEBREW_CACHE/"Formula").freeze
# Where build, postinstall, and test logs of formulae are written to
HOMEBREW_LOGS = Pathname.new(get_env_or_raise("HOMEBREW_LOGS")).expand_path.freeze
HOMEBREW_LOGS = Pathname(EnvVar["HOMEBREW_LOGS"]).expand_path.freeze
# Must use `/tmp` instead of `TMPDIR` because long paths break Unix domain sockets
HOMEBREW_TEMP = Pathname.new(get_env_or_raise("HOMEBREW_TEMP")).yield_self do |tmp|
HOMEBREW_TEMP = Pathname(EnvVar["HOMEBREW_TEMP"]).yield_self do |tmp|
tmp.mkpath unless tmp.exist?
tmp.realpath
end.freeze

View File

@ -5,6 +5,8 @@ require "compilers"
# Combination of C++ standard library and compiler.
class CxxStdlib
extend T::Sig
include CompilerConstants
# Error for when a formula's dependency was built with a different C++ standard library.
@ -72,6 +74,7 @@ class CxxStdlib
type.to_s.gsub(/cxx$/, "c++")
end
sig { returns(String) }
def inspect
"#<#{self.class.name}: #{compiler} #{type}>"
end

View File

@ -41,10 +41,13 @@ module Debrew
# Module for displaying a debugging menu.
class Menu
extend T::Sig
Entry = Struct.new(:name, :action)
attr_accessor :prompt, :entries
sig { void }
def initialize
@entries = []
end

View File

@ -8,6 +8,8 @@ require "cask_dependent"
#
# @api private
class Dependencies < SimpleDelegator
extend T::Sig
def initialize(*args)
super(args)
end
@ -34,6 +36,7 @@ class Dependencies < SimpleDelegator
build + required + recommended
end
sig { returns(String) }
def inspect
"#<#{self.class.name}: #{to_a}>"
end
@ -43,6 +46,8 @@ end
#
# @api private
class Requirements < SimpleDelegator
extend T::Sig
def initialize(*args)
super(Set.new(args))
end
@ -59,6 +64,7 @@ class Requirements < SimpleDelegator
self
end
sig { returns(String) }
def inspect
"#<#{self.class.name}: {#{to_a.join(", ")}}>"
end

View File

@ -7,6 +7,8 @@ require "dependable"
#
# @api private
class Dependency
extend T::Sig
extend Forwardable
include Dependable
@ -64,6 +66,7 @@ class Dependency
env_proc&.call
end
sig { returns(String) }
def inspect
"#<#{self.class.name}: #{name.inspect} #{tags.inspect}>"
end
@ -78,6 +81,8 @@ class Dependency
end
class << self
extend T::Sig
# Expand the dependencies of each dependent recursively, optionally yielding
# `[dependent, dep]` pairs to allow callers to apply arbitrary filters to
# the list.
@ -126,16 +131,19 @@ class Dependency
end
# Prune a dependency and its dependencies recursively.
sig { void }
def prune
throw(:action, :prune)
end
# Prune a single dependency but do not prune its dependencies.
sig { void }
def skip
throw(:action, :skip)
end
# Keep a dependency, but prune its dependencies.
sig { void }
def keep_but_prune_recursive_deps
throw(:action, :keep_but_prune_recursive_deps)
end

View File

@ -18,10 +18,13 @@ require "extend/cachable"
# This class is used by `depends_on` in the formula DSL to turn dependency
# specifications into the proper kinds of dependencies and requirements.
class DependencyCollector
extend T::Sig
extend Cachable
attr_reader :deps, :requirements
sig { void }
def initialize
@deps = Dependencies.new
@requirements = Requirements.new

View File

@ -18,8 +18,11 @@ require "cli/parser"
require "json"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def audit_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -40,8 +40,11 @@ EOS
MAXIMUM_STRING_MATCHES = 100
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def bottle_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -6,8 +6,11 @@ require "cli/parser"
require "utils/tar"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def bump_cask_pr_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -7,8 +7,11 @@ require "utils/pypi"
require "utils/tar"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def bump_formula_pr_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -5,8 +5,11 @@ require "formula"
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def bump_revision_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

View File

@ -4,8 +4,11 @@
require "cli/parser"
module Homebrew
extend T::Sig
module_function
sig { returns(CLI::Parser) }
def bump_args
Homebrew::CLI::Parser.new do
usage_banner <<~EOS

Some files were not shown because too many files have changed in this diff Show More