Merge branch 'master' of https://github.com/Homebrew/brew
This commit is contained in:
commit
87ff28431f
1
.github/workflows/tests.yml
vendored
1
.github/workflows/tests.yml
vendored
@ -6,7 +6,6 @@ on:
|
||||
env:
|
||||
HOMEBREW_DEVELOPER: 1
|
||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||
HOMEBREW_GITHUB_ACTIONS_BIG_SUR_TESTING: 1 # TODO: remove when Big Sur is released.
|
||||
jobs:
|
||||
tests:
|
||||
if: github.repository == 'Homebrew/brew'
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@ -24,6 +24,7 @@
|
||||
# Ignore Bundler files
|
||||
**/.bundle/bin
|
||||
**/.bundle/cache
|
||||
**/vendor/bundle/ruby/*/bundler.lock
|
||||
**/vendor/bundle/ruby/*/bin
|
||||
**/vendor/bundle/ruby/*/build_info/
|
||||
**/vendor/bundle/ruby/*/cache
|
||||
@ -127,6 +128,7 @@
|
||||
**/vendor/bundle/ruby/*/gems/rspec-mocks-*/
|
||||
**/vendor/bundle/ruby/*/gems/rspec-retry-*/
|
||||
**/vendor/bundle/ruby/*/gems/rspec-support-*/
|
||||
**/vendor/bundle/ruby/*/gems/rspec-sorbet-*/
|
||||
**/vendor/bundle/ruby/*/gems/rspec-wait-*/
|
||||
**/vendor/bundle/ruby/*/gems/rubocop-1*/
|
||||
**/vendor/bundle/ruby/*/gems/rubocop-ast-*/
|
||||
|
||||
@ -18,6 +18,7 @@ AllCops:
|
||||
- 'Homebrew/sorbet/rbi/gems/**/*.rbi'
|
||||
- 'Homebrew/sorbet/rbi/hidden-definitions/**/*.rbi'
|
||||
- 'Homebrew/sorbet/rbi/todo.rbi'
|
||||
- 'Homebrew/sorbet/rbi/upstream.rbi'
|
||||
- 'Homebrew/bin/*'
|
||||
- 'Homebrew/vendor/**/*'
|
||||
|
||||
@ -69,7 +70,7 @@ Naming/HeredocDelimiterNaming:
|
||||
|
||||
Naming/MethodName:
|
||||
IgnoredPatterns:
|
||||
- '\AHEAD\?\Z'
|
||||
- '\A(fetch_)?HEAD\?\Z'
|
||||
|
||||
# Allow dashes in filenames.
|
||||
Naming/FileName:
|
||||
@ -108,7 +109,9 @@ Style/HashTransformValues:
|
||||
# Allow for license expressions
|
||||
Style/HashAsLastArrayItem:
|
||||
Exclude:
|
||||
- 'Taps/*/*/{Formula/,}*.rb'
|
||||
- 'Taps/*/*/*.rb'
|
||||
- '/**/Formula/*.rb'
|
||||
- '**/Formula/*.rb'
|
||||
|
||||
# Enabled now LineLength is lowish.
|
||||
Style/IfUnlessModifier:
|
||||
@ -118,6 +121,8 @@ Style/IfUnlessModifier:
|
||||
Style/NumericLiterals:
|
||||
MinDigits: 7
|
||||
Strict: true
|
||||
Exclude:
|
||||
- '**/Brewfile'
|
||||
|
||||
# Zero-prefixed octal literals are widely used and understood.
|
||||
Style/NumericLiteralPrefix:
|
||||
@ -161,11 +166,17 @@ Performance/CaseWhenSplat:
|
||||
Performance/Caller:
|
||||
Enabled: false
|
||||
|
||||
# Makes code less readable for minor performance increases.
|
||||
Performance/MethodObjectAsBlock:
|
||||
Enabled: false
|
||||
|
||||
# Don't allow cops to be disabled in casks and formulae.
|
||||
Style/DisableCopsWithinSourceCodeDirective:
|
||||
Enabled: true
|
||||
Include:
|
||||
- 'Taps/*/*/{Formula/,Casks/,}*.rb'
|
||||
- 'Taps/*/*/*.rb'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
|
||||
# make our hashes consistent
|
||||
Layout/HashAlignment:
|
||||
@ -175,7 +186,9 @@ Layout/HashAlignment:
|
||||
# `system` is a special case and aligns on second argument, so allow this for formulae.
|
||||
Layout/ArgumentAlignment:
|
||||
Exclude:
|
||||
- 'Taps/*/*/{Formula/,}*.rb'
|
||||
- 'Taps/*/*/*.rb'
|
||||
- '/**/Formula/*.rb'
|
||||
- '**/Formula/*.rb'
|
||||
|
||||
# this is a bit less "floaty"
|
||||
Layout/CaseIndentation:
|
||||
@ -197,6 +210,12 @@ Layout/RescueEnsureAlignment:
|
||||
Lint/AmbiguousBlockAssociation:
|
||||
Enabled: false
|
||||
|
||||
Lint/DuplicateBranch:
|
||||
Exclude:
|
||||
- 'Taps/*/*/*.rb'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
|
||||
# needed for lazy_object magic
|
||||
Naming/MemoizedInstanceVariableName:
|
||||
Exclude:
|
||||
@ -206,7 +225,9 @@ Naming/MemoizedInstanceVariableName:
|
||||
# TODO: fix these as `ruby -w` complains about them.
|
||||
Lint/AmbiguousRegexpLiteral:
|
||||
Exclude:
|
||||
- 'Taps/*/*/{Formula/,}*.rb'
|
||||
- 'Taps/*/*/*.rb'
|
||||
- '/**/Formula/*.rb'
|
||||
- '**/Formula/*.rb'
|
||||
|
||||
# useful for metaprogramming in RSpec
|
||||
Lint/ConstantDefinitionInBlock:
|
||||
@ -216,30 +237,46 @@ Lint/ConstantDefinitionInBlock:
|
||||
# so many of these in formulae and can't be autocorrected
|
||||
Lint/ParenthesesAsGroupedExpression:
|
||||
Exclude:
|
||||
- 'Taps/*/*/{Formula/,}*.rb'
|
||||
- 'Taps/*/*/*.rb'
|
||||
- '/**/Formula/*.rb'
|
||||
- '**/Formula/*.rb'
|
||||
|
||||
# Most metrics don't make sense to apply for casks/formulae/taps.
|
||||
Metrics/AbcSize:
|
||||
Exclude:
|
||||
- 'Taps/**/*'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
Metrics/BlockLength:
|
||||
Exclude:
|
||||
- 'Taps/**/*'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
Metrics/ClassLength:
|
||||
Exclude:
|
||||
- 'Taps/**/*'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
Metrics/CyclomaticComplexity:
|
||||
Exclude:
|
||||
- 'Taps/**/*'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
Metrics/MethodLength:
|
||||
Exclude:
|
||||
- 'Taps/**/*'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
Metrics/ModuleLength:
|
||||
Exclude:
|
||||
- 'Taps/**/*'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
Metrics/PerceivedComplexity:
|
||||
Exclude:
|
||||
- 'Taps/**/*'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
|
||||
# allow those that are standard
|
||||
# TODO: try to remove some of these
|
||||
@ -280,7 +317,9 @@ Layout/LineLength:
|
||||
|
||||
Sorbet/FalseSigil:
|
||||
Exclude:
|
||||
- 'Taps/**/*.rb'
|
||||
- 'Taps/**/*'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
- 'Homebrew/test/**/Casks/**/*.rb'
|
||||
|
||||
Sorbet/StrictSigil:
|
||||
@ -297,15 +336,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:
|
||||
@ -322,6 +355,8 @@ Style/ClassVars:
|
||||
Style/Documentation:
|
||||
Exclude:
|
||||
- 'Taps/**/*'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
- '**/*.rbi'
|
||||
|
||||
Style/DocumentationMethod:
|
||||
@ -332,9 +367,12 @@ Style/DocumentationMethod:
|
||||
Style/FrozenStringLiteralComment:
|
||||
EnforcedStyle: always
|
||||
Exclude:
|
||||
- 'Taps/*/*/{Formula,Casks,}/*.rb'
|
||||
- 'Taps/*/*/*.rb'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
- 'Homebrew/test/**/Casks/**/*.rb'
|
||||
- '**/*.rbi'
|
||||
- '**/Brewfile'
|
||||
|
||||
# TODO: remove this when possible.
|
||||
Style/GlobalVars:
|
||||
@ -344,7 +382,9 @@ Style/GlobalVars:
|
||||
# potential for errors in formulae too high with this
|
||||
Style/GuardClause:
|
||||
Exclude:
|
||||
- 'Taps/*/*/{Formula/,Casks/,}*.rb'
|
||||
- 'Taps/*/*/*.rb'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
|
||||
# avoid hash rockets where possible
|
||||
Style/HashSyntax:
|
||||
@ -353,7 +393,9 @@ Style/HashSyntax:
|
||||
# so many of these in formulae and can't be autocorrected
|
||||
Style/StringConcatenation:
|
||||
Exclude:
|
||||
- 'Taps/*/*/{Formula/,Casks/,}*.rb'
|
||||
- 'Taps/*/*/*.rb'
|
||||
- '/**/{Formula,Casks}/*.rb'
|
||||
- '**/{Formula,Casks}/*.rb'
|
||||
|
||||
# ruby style guide favorite
|
||||
Style/StringLiterals:
|
||||
|
||||
@ -10,6 +10,7 @@ gem "ronn", require: false
|
||||
gem "rspec", require: false
|
||||
gem "rspec-its", require: false
|
||||
gem "rspec-retry", require: false
|
||||
gem "rspec-sorbet", require: false
|
||||
gem "rspec-wait", require: false
|
||||
gem "rubocop", require: false
|
||||
gem "simplecov", require: false
|
||||
|
||||
@ -44,7 +44,7 @@ GEM
|
||||
method_source (1.0.0)
|
||||
mime-types (3.3.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2020.0512)
|
||||
mime-types-data (3.2020.1104)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.14.2)
|
||||
mustache (1.1.1)
|
||||
@ -95,39 +95,42 @@ GEM
|
||||
rspec-support (~> 3.10.0)
|
||||
rspec-retry (0.6.2)
|
||||
rspec-core (> 3.3)
|
||||
rspec-sorbet (1.7.0)
|
||||
sorbet
|
||||
sorbet-runtime
|
||||
rspec-support (3.10.0)
|
||||
rspec-wait (0.0.9)
|
||||
rspec (>= 3, < 4)
|
||||
rubocop (1.2.0)
|
||||
rubocop (1.3.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.7.1.5)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8)
|
||||
rexml
|
||||
rubocop-ast (>= 1.0.1)
|
||||
rubocop-ast (>= 1.1.1)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 2.0)
|
||||
rubocop-ast (1.1.1)
|
||||
parser (>= 2.7.1.5)
|
||||
rubocop-performance (1.8.1)
|
||||
rubocop (>= 0.87.0)
|
||||
rubocop-performance (1.9.0)
|
||||
rubocop (>= 0.90.0, < 2.0)
|
||||
rubocop-ast (>= 0.4.0)
|
||||
rubocop-rspec (2.0.0)
|
||||
rubocop (~> 1.0)
|
||||
rubocop-ast (>= 1.1.0)
|
||||
rubocop-sorbet (0.5.1)
|
||||
rubocop
|
||||
ruby-macho (2.2.0)
|
||||
ruby-macho (2.5.0)
|
||||
ruby-progressbar (1.10.1)
|
||||
simplecov (0.19.1)
|
||||
docile (~> 1.1)
|
||||
simplecov-html (~> 0.11)
|
||||
simplecov-html (0.12.3)
|
||||
sorbet (0.5.6042)
|
||||
sorbet-static (= 0.5.6042)
|
||||
sorbet-runtime (0.5.6040)
|
||||
sorbet (0.5.6076)
|
||||
sorbet-static (= 0.5.6076)
|
||||
sorbet-runtime (0.5.6076)
|
||||
sorbet-runtime-stub (0.2.0)
|
||||
sorbet-static (0.5.6042-universal-darwin-14)
|
||||
sorbet-static (0.5.6076-universal-darwin-14)
|
||||
spoom (1.0.4)
|
||||
colorize
|
||||
sorbet (~> 0.5.5)
|
||||
@ -142,14 +145,14 @@ GEM
|
||||
thor (>= 0.19.2)
|
||||
thor (1.0.1)
|
||||
thread_safe (0.3.6)
|
||||
tzinfo (1.2.7)
|
||||
tzinfo (1.2.8)
|
||||
thread_safe (~> 0.1)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.7)
|
||||
unicode-display_width (1.7.0)
|
||||
webrobots (0.1.2)
|
||||
zeitwerk (2.4.0)
|
||||
zeitwerk (2.4.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
@ -167,6 +170,7 @@ DEPENDENCIES
|
||||
rspec
|
||||
rspec-its
|
||||
rspec-retry
|
||||
rspec-sorbet
|
||||
rspec-wait
|
||||
rubocop
|
||||
rubocop-performance
|
||||
|
||||
@ -67,13 +67,9 @@ class PATH
|
||||
|
||||
sig { params(other: T.untyped).returns(T::Boolean) }
|
||||
def ==(other)
|
||||
if other.respond_to?(:to_ary) && to_ary == other.to_ary
|
||||
true
|
||||
elsif other.respond_to?(:to_str) && to_str == other.to_str
|
||||
true
|
||||
else
|
||||
(other.respond_to?(:to_ary) && to_ary == other.to_ary) ||
|
||||
(other.respond_to?(:to_str) && to_str == other.to_str) ||
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
|
||||
@ -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
|
||||
|
||||
@ -164,7 +164,7 @@ rescue BuildError => e
|
||||
if e.formula.head? || e.formula.deprecated? || e.formula.disabled?
|
||||
$stderr.puts <<~EOS
|
||||
Please create pull requests instead of asking for help on Homebrew's GitHub,
|
||||
Discourse, Twitter or any other official channels.
|
||||
Twitter or any other official channels.
|
||||
EOS
|
||||
end
|
||||
|
||||
|
||||
@ -53,11 +53,7 @@ class Build
|
||||
def expand_reqs
|
||||
formula.recursive_requirements do |dependent, req|
|
||||
build = effective_build_options_for(dependent)
|
||||
if req.prune_from_option?(build)
|
||||
Requirement.prune
|
||||
elsif req.prune_if_build_and_not_dependent?(dependent, formula)
|
||||
Requirement.prune
|
||||
elsif req.test?
|
||||
if req.prune_from_option?(build) || req.prune_if_build_and_not_dependent?(dependent, formula) || req.test?
|
||||
Requirement.prune
|
||||
end
|
||||
end
|
||||
@ -66,14 +62,12 @@ class Build
|
||||
def expand_deps
|
||||
formula.recursive_dependencies do |dependent, dep|
|
||||
build = effective_build_options_for(dependent)
|
||||
if dep.prune_from_option?(build)
|
||||
Dependency.prune
|
||||
elsif dep.prune_if_build_and_not_dependent?(dependent, formula)
|
||||
if dep.prune_from_option?(build) ||
|
||||
dep.prune_if_build_and_not_dependent?(dependent, formula) ||
|
||||
(dep.test? && !dep.build?)
|
||||
Dependency.prune
|
||||
elsif dep.build?
|
||||
Dependency.keep_but_prune_recursive_deps
|
||||
elsif dep.test?
|
||||
Dependency.prune
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,34 +1,44 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Settings for the build environment.
|
||||
#
|
||||
# @api private
|
||||
class BuildEnvironment
|
||||
extend T::Sig
|
||||
|
||||
sig { params(settings: Symbol).void }
|
||||
def initialize(*settings)
|
||||
@settings = Set.new(*settings)
|
||||
@settings = Set.new(settings)
|
||||
end
|
||||
|
||||
sig { params(args: T::Enumerable[Symbol]).returns(T.self_type) }
|
||||
def merge(*args)
|
||||
@settings.merge(*args)
|
||||
self
|
||||
end
|
||||
|
||||
sig { params(o: Symbol).returns(T.self_type) }
|
||||
def <<(o)
|
||||
@settings << o
|
||||
self
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def std?
|
||||
@settings.include? :std
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def userpaths?
|
||||
@settings.include? :userpaths
|
||||
end
|
||||
|
||||
# DSL for specifying build environment settings.
|
||||
module DSL
|
||||
extend T::Sig
|
||||
|
||||
sig { params(settings: Symbol).returns(BuildEnvironment) }
|
||||
def env(*settings)
|
||||
@env ||= BuildEnvironment.new
|
||||
@env.merge(settings)
|
||||
@ -50,16 +60,18 @@ class BuildEnvironment
|
||||
].freeze
|
||||
private_constant :KEYS
|
||||
|
||||
sig { params(env: T.untyped).returns(T::Array[String]) }
|
||||
def self.keys(env)
|
||||
KEYS & env.keys
|
||||
end
|
||||
|
||||
sig { params(env: T.untyped, f: IO).void }
|
||||
def self.dump(env, f = $stdout)
|
||||
keys = self.keys(env)
|
||||
keys -= %w[CC CXX OBJC OBJCXX] if env["CC"] == env["HOMEBREW_CC"]
|
||||
|
||||
keys.each do |key|
|
||||
value = env[key]
|
||||
value = env.fetch(key)
|
||||
s = +"#{key}: #{value}"
|
||||
case key
|
||||
when "CC", "CXX", "LD"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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."
|
||||
|
||||
@ -12,6 +12,9 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
class Artifact < Moved
|
||||
extend T::Sig
|
||||
|
||||
sig { returns(String) }
|
||||
def self.english_name
|
||||
"Generic Artifact"
|
||||
end
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -9,6 +9,9 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
class Prefpane < Moved
|
||||
extend T::Sig
|
||||
|
||||
sig { returns(String) }
|
||||
def self.english_name
|
||||
"Preference Pane"
|
||||
end
|
||||
|
||||
@ -9,6 +9,9 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
class Qlplugin < Moved
|
||||
extend T::Sig
|
||||
|
||||
sig { returns(String) }
|
||||
def self.english_name
|
||||
"QuickLook Plugin"
|
||||
end
|
||||
|
||||
@ -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}"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -6,9 +6,10 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
module Cache
|
||||
module_function
|
||||
extend T::Sig
|
||||
|
||||
def path
|
||||
sig { returns(Pathname) }
|
||||
def self.path
|
||||
@path ||= HOMEBREW_CACHE/"Cask"
|
||||
end
|
||||
end
|
||||
|
||||
@ -12,6 +12,8 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
class Cask
|
||||
extend T::Sig
|
||||
|
||||
extend Enumerable
|
||||
extend Forwardable
|
||||
extend Searchable
|
||||
@ -20,7 +22,7 @@ module Cask
|
||||
attr_reader :token, :sourcefile_path, :config, :default_config
|
||||
|
||||
def self.each(&block)
|
||||
return to_enum unless block_given?
|
||||
return to_enum unless block
|
||||
|
||||
Tap.flat_map(&:cask_files).each do |f|
|
||||
block.call CaskLoader::FromTapPathLoader.new(f).load(config: nil)
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/user"
|
||||
@ -8,13 +8,15 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
module Caskroom
|
||||
module_function
|
||||
extend T::Sig
|
||||
|
||||
def path
|
||||
sig { returns(Pathname) }
|
||||
def self.path
|
||||
@path ||= HOMEBREW_PREFIX.join("Caskroom")
|
||||
end
|
||||
|
||||
def ensure_caskroom_exists
|
||||
sig { void }
|
||||
def self.ensure_caskroom_exists
|
||||
return if path.exist?
|
||||
|
||||
sudo = !path.parent.writable?
|
||||
@ -30,7 +32,8 @@ module Cask
|
||||
SystemCommand.run("/usr/bin/chgrp", args: ["admin", path], sudo: sudo)
|
||||
end
|
||||
|
||||
def casks(config: nil)
|
||||
sig { params(config: T.nilable(Config)).returns(T::Array[Cask]) }
|
||||
def self.casks(config: nil)
|
||||
return [] unless path.exist?
|
||||
|
||||
Pathname.glob(path.join("*")).sort.select(&:directory?).map do |path|
|
||||
|
||||
@ -38,6 +38,8 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
class Cmd
|
||||
extend T::Sig
|
||||
|
||||
include Context
|
||||
|
||||
ALIASES = {
|
||||
@ -61,11 +63,13 @@ module Cask
|
||||
Cmd::Upgrade => "brew upgrade --cask",
|
||||
}.freeze
|
||||
|
||||
sig { returns(String) }
|
||||
def self.description
|
||||
max_command_length = Cmd.commands.map(&:length).max
|
||||
|
||||
command_lines = Cmd.command_classes
|
||||
.select(&:visible?)
|
||||
.reject { |command| DEPRECATED_COMMANDS.key?(command) }
|
||||
.map do |klass|
|
||||
" - #{"`#{klass.command_name}`".ljust(max_command_length + 2)} #{klass.short_description}\n"
|
||||
end
|
||||
@ -75,14 +79,13 @@ module Cask
|
||||
|
||||
Commands:
|
||||
#{command_lines.join}
|
||||
|
||||
See also: `man brew`
|
||||
EOS
|
||||
end
|
||||
|
||||
def self.parser(&block)
|
||||
Homebrew::CLI::Parser.new do
|
||||
if block_given?
|
||||
if block
|
||||
instance_eval(&block)
|
||||
else
|
||||
usage_banner <<~EOS
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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,13 +35,14 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def self.banner_headline
|
||||
"`#{command_name}` [<options>]#{banner_args}"
|
||||
end
|
||||
|
||||
OPTIONS = [
|
||||
[:switch, "--[no-]binaries", {
|
||||
description: "Disable/enable linking of helper executables. Default: enabled",
|
||||
description: "Disable/enable linking of helper executables (default: enabled).",
|
||||
env: :cask_opts_binaries,
|
||||
}],
|
||||
[:switch, "--require-sha", {
|
||||
@ -43,7 +50,7 @@ module Cask
|
||||
env: :cask_opts_require_sha,
|
||||
}],
|
||||
[:switch, "--[no-]quarantine", {
|
||||
description: "Disable/enable quarantining of downloads. Default: enabled",
|
||||
description: "Disable/enable quarantining of downloads (default: enabled).",
|
||||
env: :cask_opts_quarantine,
|
||||
}],
|
||||
].freeze
|
||||
@ -61,7 +68,7 @@ module Cask
|
||||
Cmd.parser do
|
||||
usage_banner banner
|
||||
|
||||
instance_eval(&block) if block_given?
|
||||
instance_eval(&block) if block
|
||||
|
||||
OPTIONS.each do |option|
|
||||
send(*option)
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,57 +40,84 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def run
|
||||
require "cask/auditor"
|
||||
|
||||
Homebrew.auditing = true
|
||||
|
||||
options = {
|
||||
audit_download: args.download?,
|
||||
audit_appcast: args.appcast?,
|
||||
audit_online: args.online?,
|
||||
audit_strict: args.strict?,
|
||||
audit_new_cask: args.new_cask?,
|
||||
audit_token_conflicts: args.token_conflicts?,
|
||||
quarantine: args.quarantine?,
|
||||
language: args.language,
|
||||
}.compact
|
||||
|
||||
options[:quarantine] = true if options[:quarantine].nil?
|
||||
|
||||
casks = args.named.flat_map do |name|
|
||||
if File.exist?(name)
|
||||
name
|
||||
elsif name.count("/") == 1
|
||||
Tap.fetch(name).cask_files
|
||||
else
|
||||
name
|
||||
end
|
||||
next name if File.exist?(name)
|
||||
next Tap.fetch(name).cask_files if name.count("/") == 1
|
||||
|
||||
name
|
||||
end
|
||||
casks = casks.map { |c| CaskLoader.load(c, config: Config.from_args(args)) }
|
||||
casks = Cask.to_a if casks.empty?
|
||||
|
||||
failed_casks = casks.reject do |cask|
|
||||
odebug "Auditing Cask #{cask}"
|
||||
result = Auditor.audit(cask, **options)
|
||||
results = self.class.audit_casks(
|
||||
*casks,
|
||||
download: args.download?,
|
||||
appcast: args.appcast?,
|
||||
online: args.online?,
|
||||
strict: args.strict?,
|
||||
new_cask: args.new_cask?,
|
||||
token_conflicts: args.token_conflicts?,
|
||||
quarantine: args.quarantine?,
|
||||
language: args.language,
|
||||
)
|
||||
|
||||
if ENV["GITHUB_ACTIONS"]
|
||||
cask_path = cask.sourcefile_path
|
||||
annotations = (result[:warnings].map { |w| [:warning, w] } + result[:errors].map { |e| [:error, e] })
|
||||
.map { |type, message| GitHub::Actions::Annotation.new(type, message, file: cask_path) }
|
||||
|
||||
annotations.each do |annotation|
|
||||
puts annotation if annotation.relevant?
|
||||
end
|
||||
end
|
||||
|
||||
result[:errors].empty?
|
||||
end
|
||||
self.class.print_annotations(results)
|
||||
|
||||
failed_casks = results.reject { |_, result| result[:errors].empty? }.map(&:first)
|
||||
return if failed_casks.empty?
|
||||
|
||||
raise CaskError, "audit failed for casks: #{failed_casks.join(" ")}"
|
||||
end
|
||||
|
||||
def self.audit_casks(
|
||||
*casks,
|
||||
download: nil,
|
||||
appcast: nil,
|
||||
online: nil,
|
||||
strict: nil,
|
||||
new_cask: nil,
|
||||
token_conflicts: nil,
|
||||
quarantine: nil,
|
||||
language: nil
|
||||
)
|
||||
options = {
|
||||
audit_download: download,
|
||||
audit_appcast: appcast,
|
||||
audit_online: online,
|
||||
audit_strict: strict,
|
||||
audit_new_cask: new_cask,
|
||||
audit_token_conflicts: token_conflicts,
|
||||
quarantine: quarantine,
|
||||
language: language,
|
||||
}.compact
|
||||
|
||||
options[:quarantine] = true if options[:quarantine].nil?
|
||||
|
||||
Homebrew.auditing = true
|
||||
|
||||
require "cask/auditor"
|
||||
|
||||
casks.map do |cask|
|
||||
odebug "Auditing Cask #{cask}"
|
||||
[cask, Auditor.audit(cask, **options)]
|
||||
end.to_h
|
||||
end
|
||||
|
||||
def self.print_annotations(results)
|
||||
return unless ENV["GITHUB_ACTIONS"]
|
||||
|
||||
results.each do |cask, result|
|
||||
cask_path = cask.sourcefile_path
|
||||
annotations = (result[:warnings].map { |w| [:warning, w] } + result[:errors].map { |e| [:error, e] })
|
||||
.map { |type, message| GitHub::Actions::Annotation.new(type, message, file: cask_path) }
|
||||
|
||||
annotations.each do |annotation|
|
||||
puts annotation if annotation.relevant?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -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?
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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))
|
||||
|
||||
@ -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
|
||||
@ -30,10 +34,11 @@ module Cask
|
||||
send(*option)
|
||||
end
|
||||
|
||||
instance_eval(&block) if block_given?
|
||||
instance_eval(&block) if block
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def run
|
||||
self.class.install_casks(
|
||||
*casks,
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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}"
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
@ -23,6 +26,7 @@ module Cask
|
||||
}],
|
||||
].freeze
|
||||
|
||||
sig { returns(Homebrew::CLI::Parser) }
|
||||
def self.parser
|
||||
super do
|
||||
switch "--force",
|
||||
@ -36,6 +40,7 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def run
|
||||
verbose = ($stdout.tty? || args.verbose?) && !args.quiet?
|
||||
self.class.upgrade_casks(
|
||||
@ -52,6 +57,20 @@ module Cask
|
||||
)
|
||||
end
|
||||
|
||||
sig do
|
||||
params(
|
||||
casks: Cask,
|
||||
args: Homebrew::CLI::Args,
|
||||
force: T.nilable(T::Boolean),
|
||||
greedy: T.nilable(T::Boolean),
|
||||
dry_run: T.nilable(T::Boolean),
|
||||
skip_cask_deps: T.nilable(T::Boolean),
|
||||
verbose: T.nilable(T::Boolean),
|
||||
binaries: T.nilable(T::Boolean),
|
||||
quarantine: T.nilable(T::Boolean),
|
||||
require_sha: T.nilable(T::Boolean),
|
||||
).void
|
||||
end
|
||||
def self.upgrade_casks(
|
||||
*casks,
|
||||
args:,
|
||||
@ -81,7 +100,9 @@ module Cask
|
||||
|
||||
return if outdated_casks.empty?
|
||||
|
||||
ohai "Casks with `auto_updates` or `version :latest` will not be upgraded" if casks.empty? && !greedy
|
||||
if casks.empty? && !greedy
|
||||
ohai "Casks with `auto_updates` or `version :latest` will not be upgraded; pass `--greedy` to upgrade them."
|
||||
end
|
||||
|
||||
verb = dry_run ? "Would upgrade" : "Upgrading"
|
||||
oh1 "#{verb} #{outdated_casks.count} #{"outdated package".pluralize(outdated_casks.count)}:"
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -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)/
|
||||
|
||||
@ -125,7 +125,7 @@ module Cask
|
||||
def language(*args, default: false, &block)
|
||||
if args.empty?
|
||||
language_eval
|
||||
elsif block_given?
|
||||
elsif block
|
||||
@language_blocks ||= {}
|
||||
@language_blocks[args] = block
|
||||
|
||||
@ -248,7 +248,7 @@ module Cask
|
||||
|
||||
def caveats(*strings, &block)
|
||||
@caveats ||= DSL::Caveats.new(cask)
|
||||
if block_given?
|
||||
if block
|
||||
@caveats.eval_caveats(&block)
|
||||
elsif strings.any?
|
||||
strings.each do |string|
|
||||
|
||||
@ -64,7 +64,7 @@ module Cask
|
||||
MacOSRequirement.new([version.to_sym], comparator: comparator)
|
||||
elsif /^\s*(?<comparator><|>|[=<>]=)\s*(?<version>\S+)\s*$/ =~ args.first
|
||||
MacOSRequirement.new([version], comparator: comparator)
|
||||
else
|
||||
else # rubocop:disable Lint/DuplicateBranch
|
||||
MacOSRequirement.new([args.first], comparator: "==")
|
||||
end
|
||||
rescue MacOSVersionError => e
|
||||
|
||||
@ -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?
|
||||
|
||||
|
||||
@ -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."
|
||||
|
||||
|
||||
@ -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?
|
||||
@ -368,15 +371,19 @@ module Cask
|
||||
force: false,
|
||||
).install
|
||||
else
|
||||
FormulaInstaller.new(cask_or_formula, verbose: verbose?).yield_self do |fi|
|
||||
fi.installed_as_dependency = true
|
||||
fi.installed_on_request = false
|
||||
fi.show_header = true
|
||||
fi.prelude
|
||||
fi.fetch
|
||||
fi.install
|
||||
fi.finish
|
||||
end
|
||||
fi = FormulaInstaller.new(
|
||||
cask_or_formula,
|
||||
**{
|
||||
show_header: true,
|
||||
installed_as_dependency: true,
|
||||
installed_on_request: false,
|
||||
verbose: verbose?,
|
||||
}.compact,
|
||||
)
|
||||
fi.prelude
|
||||
fi.fetch
|
||||
fi.install
|
||||
fi.finish
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -8,19 +8,25 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
class Pkg
|
||||
extend T::Sig
|
||||
|
||||
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|
|
||||
new(package_id.chomp, command)
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
attr_reader :package_id
|
||||
|
||||
sig { params(package_id: String, command: T.class_of(SystemCommand)).void }
|
||||
def initialize(package_id, command = SystemCommand)
|
||||
@package_id = package_id
|
||||
@command = command
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def uninstall
|
||||
unless pkgutil_bom_files.empty?
|
||||
odebug "Deleting pkg files"
|
||||
@ -65,23 +71,28 @@ module Cask
|
||||
forget
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def forget
|
||||
odebug "Unregistering pkg receipt (aka forgetting)"
|
||||
@command.run!("/usr/sbin/pkgutil", args: ["--forget", package_id], sudo: true)
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Pathname]) }
|
||||
def pkgutil_bom_files
|
||||
@pkgutil_bom_files ||= pkgutil_bom_all.select(&:file?) - pkgutil_bom_specials
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Pathname]) }
|
||||
def pkgutil_bom_specials
|
||||
@pkgutil_bom_specials ||= pkgutil_bom_all.select(&method(:special?))
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Pathname]) }
|
||||
def pkgutil_bom_dirs
|
||||
@pkgutil_bom_dirs ||= pkgutil_bom_all.select(&:directory?) - pkgutil_bom_specials
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Pathname]) }
|
||||
def pkgutil_bom_all
|
||||
@pkgutil_bom_all ||= @command.run!("/usr/sbin/pkgutil", args: ["--files", package_id])
|
||||
.stdout
|
||||
@ -90,6 +101,7 @@ module Cask
|
||||
.reject(&MacOS.public_method(:undeletable?))
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def root
|
||||
@root ||= Pathname.new(info.fetch("volume")).join(info.fetch("install-location"))
|
||||
end
|
||||
@ -101,10 +113,12 @@ module Cask
|
||||
|
||||
private
|
||||
|
||||
sig { params(path: Pathname).returns(T::Boolean) }
|
||||
def special?(path)
|
||||
path.symlink? || path.chardev? || path.blockdev?
|
||||
end
|
||||
|
||||
sig { params(path: Pathname).void }
|
||||
def rmdir(path)
|
||||
return unless path.children.empty?
|
||||
|
||||
@ -115,7 +129,8 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
def with_full_permissions(path)
|
||||
sig { params(path: Pathname, _block: T.proc.void).void }
|
||||
def with_full_permissions(path, &_block)
|
||||
original_mode = (path.stat.mode % 01000).to_s(8)
|
||||
original_flags = @command.run!("/usr/bin/stat", args: ["-f", "%Of", "--", path]).stdout.chomp
|
||||
|
||||
@ -128,10 +143,12 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(paths: T::Array[Pathname]).returns(T::Array[Pathname]) }
|
||||
def deepest_path_first(paths)
|
||||
paths.sort_by { |path| -path.to_s.split(File::SEPARATOR).count }
|
||||
end
|
||||
|
||||
sig { params(dir: Pathname).void }
|
||||
def clean_ds_store(dir)
|
||||
return unless (ds_store = dir.join(".DS_Store")).exist?
|
||||
|
||||
@ -140,12 +157,14 @@ module Cask
|
||||
|
||||
# Some packages leave broken symlinks around; we clean them out before
|
||||
# attempting to `rmdir` to prevent extra cruft from accumulating.
|
||||
sig { params(dir: Pathname).void }
|
||||
def clean_broken_symlinks(dir)
|
||||
dir.children.select(&method(:broken_symlink?)).each do |path|
|
||||
@command.run!("/bin/rm", args: ["--", path], sudo: true)
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(path: Pathname).returns(T::Boolean) }
|
||||
def broken_symlink?(path)
|
||||
path.symlink? && !path.exist?
|
||||
end
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "utils/user"
|
||||
@ -8,25 +8,35 @@ module Cask
|
||||
#
|
||||
# @api private
|
||||
module Staged
|
||||
extend T::Sig
|
||||
|
||||
# FIXME: Enable cop again when https://github.com/sorbet/sorbet/issues/3532 is fixed.
|
||||
# rubocop:disable Style/MutableConstant
|
||||
Paths = T.type_alias { T.any(String, Pathname, T::Array[T.any(String, Pathname)]) }
|
||||
# rubocop:enable Style/MutableConstant
|
||||
|
||||
sig { params(paths: Paths, permissions_str: String).void }
|
||||
def set_permissions(paths, permissions_str)
|
||||
full_paths = remove_nonexistent(paths)
|
||||
return if full_paths.empty?
|
||||
|
||||
@command.run!("/bin/chmod", args: ["-R", "--", permissions_str] + full_paths,
|
||||
@command.run!("/bin/chmod", args: ["-R", "--", permissions_str, *full_paths],
|
||||
sudo: false)
|
||||
end
|
||||
|
||||
def set_ownership(paths, user: User.current, group: "staff")
|
||||
sig { params(paths: Paths, user: T.any(String, User), group: String).void }
|
||||
def set_ownership(paths, user: T.must(User.current), group: "staff")
|
||||
full_paths = remove_nonexistent(paths)
|
||||
return if full_paths.empty?
|
||||
|
||||
ohai "Changing ownership of paths required by #{@cask}; your password may be necessary"
|
||||
@command.run!("/usr/sbin/chown", args: ["-R", "--", "#{user}:#{group}"] + full_paths,
|
||||
@command.run!("/usr/sbin/chown", args: ["-R", "--", "#{user}:#{group}", *full_paths],
|
||||
sudo: true)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
sig { params(paths: Paths).returns(T::Array[Pathname]) }
|
||||
def remove_nonexistent(paths)
|
||||
Array(paths).map { |p| Pathname(p).expand_path }.select(&:exist?)
|
||||
end
|
||||
|
||||
7
Library/Homebrew/cask/staged.rbi
Normal file
7
Library/Homebrew/cask/staged.rbi
Normal file
@ -0,0 +1,7 @@
|
||||
# typed: strict
|
||||
|
||||
module Cask
|
||||
module Staged
|
||||
include Kernel
|
||||
end
|
||||
end
|
||||
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "tsort"
|
||||
@ -8,7 +8,11 @@ module Cask
|
||||
class TopologicalHash < Hash
|
||||
include TSort
|
||||
|
||||
alias tsort_each_node each_key
|
||||
private
|
||||
|
||||
def tsort_each_node(&block)
|
||||
each_key(&block)
|
||||
end
|
||||
|
||||
def tsort_each_child(node, &block)
|
||||
fetch(node).each(&block)
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -76,6 +76,12 @@ class Cleaner
|
||||
path.text_executable? || path.executable?
|
||||
end
|
||||
|
||||
# Both these files are completely unnecessary to package and cause
|
||||
# pointless conflicts with other formulae. They are removed by Debian,
|
||||
# Arch & MacPorts amongst other packagers as well. The files are
|
||||
# created as part of installing any Perl module.
|
||||
PERL_BASENAMES = Set.new(%w[perllocal.pod .packlist]).freeze
|
||||
|
||||
# Clean a top-level (bin, sbin, lib) directory, recursively, by fixing file
|
||||
# permissions and removing .la files, unless the files (or parent
|
||||
# directories) are protected by skip_clean.
|
||||
@ -93,18 +99,10 @@ class Cleaner
|
||||
|
||||
next if path.directory?
|
||||
|
||||
if path.extname == ".la"
|
||||
if path.extname == ".la" || PERL_BASENAMES.include?(path.basename.to_s)
|
||||
path.unlink
|
||||
elsif path.symlink?
|
||||
# Skip it.
|
||||
elsif path.basename.to_s == "perllocal.pod"
|
||||
# Both this file & the .packlist one below are completely unnecessary
|
||||
# to package & causes pointless conflict with other formulae. They are
|
||||
# removed by Debian, Arch & MacPorts amongst other packagers as well.
|
||||
# The files are created as part of installing any Perl module.
|
||||
path.unlink
|
||||
elsif path.basename.to_s == ".packlist" # Hidden file, not file extension!
|
||||
path.unlink
|
||||
else
|
||||
# Set permissions for executables and non-executables
|
||||
perms = if executable_path?(path)
|
||||
|
||||
@ -168,6 +168,7 @@ module Homebrew
|
||||
return false if Homebrew::EnvConfig.no_install_cleanup?
|
||||
|
||||
unless PERIODIC_CLEAN_FILE.exist?
|
||||
HOMEBREW_CACHE.mkpath
|
||||
FileUtils.touch PERIODIC_CLEAN_FILE
|
||||
return false
|
||||
end
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -21,7 +24,7 @@ module Homebrew
|
||||
|
||||
# Can set these because they will be overwritten by freeze_named_args!
|
||||
# (whereas other values below will only be overwritten if passed).
|
||||
self[:named_args] = NamedArgs.new(parent: self)
|
||||
self[:named] = NamedArgs.new(parent: self)
|
||||
self[:remaining] = []
|
||||
end
|
||||
|
||||
@ -30,7 +33,7 @@ module Homebrew
|
||||
end
|
||||
|
||||
def freeze_named_args!(named_args)
|
||||
self[:named_args] = NamedArgs.new(
|
||||
self[:named] = NamedArgs.new(
|
||||
*named_args.freeze,
|
||||
override_spec: spec(nil),
|
||||
force_bottle: force_bottle?,
|
||||
@ -50,8 +53,9 @@ module Homebrew
|
||||
@flags_only = cli_args.select { |a| a.start_with?("--") }.freeze
|
||||
end
|
||||
|
||||
sig { returns(NamedArgs) }
|
||||
def named
|
||||
named_args
|
||||
self[:named]
|
||||
end
|
||||
|
||||
def no_named?
|
||||
@ -131,6 +135,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
|
||||
|
||||
@ -3,27 +3,62 @@
|
||||
module Homebrew
|
||||
module CLI
|
||||
class Args < OpenStruct
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def devel?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def HEAD?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def include_test?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def build_bottle?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def build_universal?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def build_from_source?; end
|
||||
|
||||
def named_args; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def force_bottle?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def debug?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def quiet?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def verbose?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def fetch_HEAD?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def cask?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def dry_run?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def skip_cask_deps?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def greedy?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def force?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def ignore_pinned?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def display_times?; end
|
||||
|
||||
sig { returns(T.nilable(T::Boolean)) }
|
||||
def formula?; end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -6,6 +6,7 @@ require "delegate"
|
||||
require "cask/cask_loader"
|
||||
require "cli/args"
|
||||
require "formulary"
|
||||
require "keg"
|
||||
require "missing_formula"
|
||||
|
||||
module Homebrew
|
||||
@ -13,7 +14,9 @@ module Homebrew
|
||||
# Helper class for loading formulae/casks from named arguments.
|
||||
#
|
||||
# @api private
|
||||
class NamedArgs < SimpleDelegator
|
||||
class NamedArgs < Array
|
||||
extend T::Sig
|
||||
|
||||
def initialize(*args, parent: Args.new, override_spec: nil, force_bottle: false, flags: [])
|
||||
@args = args
|
||||
@override_spec = override_spec
|
||||
@ -39,9 +42,9 @@ module Homebrew
|
||||
end
|
||||
end
|
||||
|
||||
def to_formulae_to_casks(method: nil, only: nil)
|
||||
def to_formulae_to_casks(only: nil, method: nil)
|
||||
@to_formulae_to_casks ||= {}
|
||||
@to_formulae_to_casks[[method, only]] = to_formulae_and_casks(method: method, only: only)
|
||||
@to_formulae_to_casks[[method, only]] = to_formulae_and_casks(only: only, method: method)
|
||||
.partition { |o| o.is_a?(Formula) }
|
||||
.map(&:freeze).freeze
|
||||
end
|
||||
@ -62,14 +65,16 @@ module Homebrew
|
||||
when nil, :factory
|
||||
Formulary.factory(name, *spec, force_bottle: @force_bottle, flags: @flags)
|
||||
when :resolve
|
||||
Formulary.resolve(name, spec: spec, force_bottle: @force_bottle, flags: @flags)
|
||||
resolve_formula(name)
|
||||
when :keg
|
||||
resolve_keg(name)
|
||||
else
|
||||
raise
|
||||
end
|
||||
|
||||
warn_if_cask_conflicts(name, "formula") unless only == :formula
|
||||
return formula
|
||||
rescue FormulaUnavailableError => e
|
||||
rescue NoSuchKegError, FormulaUnavailableError => e
|
||||
raise e if only == :formula
|
||||
end
|
||||
end
|
||||
@ -97,24 +102,22 @@ module Homebrew
|
||||
end
|
||||
|
||||
def to_resolved_formulae_to_casks(only: nil)
|
||||
to_formulae_to_casks(method: :resolve, only: only)
|
||||
to_formulae_to_casks(only: only, method: :resolve)
|
||||
end
|
||||
|
||||
# Convert named arguments to {Tap}, {Formula} or {Cask} objects.
|
||||
# Convert named arguments to {Formula} or {Cask} objects.
|
||||
# If both a formula and cask exist with the same name, returns the
|
||||
# formula and prints a warning unless `only` is specified.
|
||||
def to_objects(only: nil, method: nil)
|
||||
@to_objects ||= {}
|
||||
@to_objects[only] ||= downcased_unique_named.flat_map do |name|
|
||||
next Tap.fetch(name) if only == :tap || (only.nil? && name.count("/") == 1 && !name.start_with?("./", "/"))
|
||||
|
||||
@to_objects[only] ||= downcased_unique_named.map do |name|
|
||||
load_formula_or_cask(name, only: only, method: method)
|
||||
end.uniq.freeze
|
||||
end
|
||||
private :to_objects
|
||||
|
||||
def to_formulae_paths
|
||||
to_paths(only: :formulae)
|
||||
to_paths(only: :formula)
|
||||
end
|
||||
|
||||
# Keep existing paths and try to convert others to tap, formula or cask paths.
|
||||
@ -125,11 +128,11 @@ module Homebrew
|
||||
@to_paths[only] ||= downcased_unique_named.flat_map do |name|
|
||||
if File.exist?(name)
|
||||
Pathname(name)
|
||||
elsif name.count("/") == 1
|
||||
elsif name.count("/") == 1 && !name.start_with?("./", "/")
|
||||
Tap.fetch(name).path
|
||||
else
|
||||
next Formulary.path(name) if only == :formulae
|
||||
next Cask::CaskLoader.path(name) if only == :casks
|
||||
next Formulary.path(name) if only == :formula
|
||||
next Cask::CaskLoader.path(name) if only == :cask
|
||||
|
||||
formula_path = Formulary.path(name)
|
||||
cask_path = Cask::CaskLoader.path(name)
|
||||
@ -144,44 +147,33 @@ module Homebrew
|
||||
end.uniq.freeze
|
||||
end
|
||||
|
||||
sig { returns(T::Array[Keg]) }
|
||||
def to_kegs
|
||||
@to_kegs ||= downcased_unique_named.map do |name|
|
||||
resolve_keg name
|
||||
@to_kegs ||= begin
|
||||
to_formulae_and_casks(only: :formula, method: :keg).freeze
|
||||
rescue NoSuchKegError => e
|
||||
if (reason = Homebrew::MissingFormula.suggest_command(name, "uninstall"))
|
||||
if (reason = Homebrew::MissingFormula.suggest_command(e.name, "uninstall"))
|
||||
$stderr.puts reason
|
||||
end
|
||||
raise e
|
||||
end.freeze
|
||||
end
|
||||
|
||||
def to_kegs_to_casks
|
||||
@to_kegs_to_casks ||= begin
|
||||
kegs = []
|
||||
casks = []
|
||||
|
||||
downcased_unique_named.each do |name|
|
||||
kegs << resolve_keg(name)
|
||||
|
||||
warn_if_cask_conflicts(name, "keg")
|
||||
rescue NoSuchKegError, FormulaUnavailableError
|
||||
begin
|
||||
casks << Cask::CaskLoader.load(name, config: Cask::Config.from_args(@parent))
|
||||
rescue Cask::CaskUnavailableError
|
||||
raise "No installed keg or cask with the name \"#{name}\""
|
||||
end
|
||||
end
|
||||
|
||||
[kegs.freeze, casks.freeze].freeze
|
||||
end
|
||||
end
|
||||
|
||||
sig { params(only: T.nilable(Symbol)).returns([T::Array[Keg], T::Array[Cask::Cask]]) }
|
||||
def to_kegs_to_casks(only: nil)
|
||||
@to_kegs_to_casks ||= to_formulae_and_casks(only: only, method: :keg)
|
||||
.partition { |o| o.is_a?(Keg) }
|
||||
.map(&:freeze).freeze
|
||||
end
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def homebrew_tap_cask_names
|
||||
downcased_unique_named.grep(HOMEBREW_CASK_TAP_CASK_REGEX)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def downcased_unique_named
|
||||
# Only lowercase names, not paths, bottle filenames or URLs
|
||||
map do |arg|
|
||||
|
||||
@ -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)
|
||||
@ -31,78 +33,82 @@ module Homebrew
|
||||
def self.global_cask_options
|
||||
[
|
||||
[:flag, "--appdir=", {
|
||||
description: "Target location for Applications. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:appdir]}`",
|
||||
description: "Target location for Applications " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:appdir]}`).",
|
||||
}],
|
||||
[:flag, "--colorpickerdir=", {
|
||||
description: "Target location for Color Pickers. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:colorpickerdir]}`",
|
||||
description: "Target location for Color Pickers " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:colorpickerdir]}`).",
|
||||
}],
|
||||
[:flag, "--prefpanedir=", {
|
||||
description: "Target location for Preference Panes. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:prefpanedir]}`",
|
||||
description: "Target location for Preference Panes " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:prefpanedir]}`).",
|
||||
}],
|
||||
[:flag, "--qlplugindir=", {
|
||||
description: "Target location for QuickLook Plugins. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:qlplugindir]}`",
|
||||
description: "Target location for QuickLook Plugins " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:qlplugindir]}`).",
|
||||
}],
|
||||
[:flag, "--mdimporterdir=", {
|
||||
description: "Target location for Spotlight Plugins. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:mdimporterdir]}`",
|
||||
description: "Target location for Spotlight Plugins " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:mdimporterdir]}`).",
|
||||
}],
|
||||
[:flag, "--dictionarydir=", {
|
||||
description: "Target location for Dictionaries. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:dictionarydir]}`",
|
||||
description: "Target location for Dictionaries " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:dictionarydir]}`).",
|
||||
}],
|
||||
[:flag, "--fontdir=", {
|
||||
description: "Target location for Fonts. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:fontdir]}`",
|
||||
description: "Target location for Fonts " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:fontdir]}`).",
|
||||
}],
|
||||
[:flag, "--servicedir=", {
|
||||
description: "Target location for Services. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:servicedir]}`",
|
||||
description: "Target location for Services " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:servicedir]}`).",
|
||||
}],
|
||||
[:flag, "--input_methoddir=", {
|
||||
description: "Target location for Input Methods. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:input_methoddir]}`",
|
||||
description: "Target location for Input Methods " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:input_methoddir]}`).",
|
||||
}],
|
||||
[:flag, "--internet_plugindir=", {
|
||||
description: "Target location for Internet Plugins. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:internet_plugindir]}`",
|
||||
description: "Target location for Internet Plugins " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:internet_plugindir]}`).",
|
||||
}],
|
||||
[:flag, "--audio_unit_plugindir=", {
|
||||
description: "Target location for Audio Unit Plugins. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:audio_unit_plugindir]}`",
|
||||
description: "Target location for Audio Unit Plugins " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:audio_unit_plugindir]}`).",
|
||||
}],
|
||||
[:flag, "--vst_plugindir=", {
|
||||
description: "Target location for VST Plugins. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:vst_plugindir]}`",
|
||||
description: "Target location for VST Plugins " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:vst_plugindir]}`).",
|
||||
}],
|
||||
[:flag, "--vst3_plugindir=", {
|
||||
description: "Target location for VST3 Plugins. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:vst3_plugindir]}`",
|
||||
description: "Target location for VST3 Plugins " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:vst3_plugindir]}`).",
|
||||
}],
|
||||
[:flag, "--screen_saverdir=", {
|
||||
description: "Target location for Screen Savers. " \
|
||||
"Default: `#{Cask::Config::DEFAULT_DIRS[:screen_saverdir]}`",
|
||||
description: "Target location for Screen Savers " \
|
||||
"(default: `#{Cask::Config::DEFAULT_DIRS[:screen_saverdir]}`).",
|
||||
}],
|
||||
[:comma_array, "--language", {
|
||||
description: "Set language of the Cask to install. The first matching " \
|
||||
"language is used, otherwise the default language on the Cask. " \
|
||||
"The default value is the `language of your system`",
|
||||
description: "Comma-separated list of language codes to prefer for cask installation. " \
|
||||
"The first matching language is used, otherwise it reverts to the cask's " \
|
||||
"default language. The default value is the language of your system.",
|
||||
}],
|
||||
]
|
||||
end
|
||||
|
||||
sig { returns(T::Array[[String, String, String]]) }
|
||||
def self.global_options
|
||||
[
|
||||
["-d", "--debug", "Display any debugging information."],
|
||||
["-q", "--quiet", "Suppress any warnings."],
|
||||
["-q", "--quiet", "Make some output more quiet."],
|
||||
["-v", "--verbose", "Make some output more verbose."],
|
||||
["-h", "--help", "Show this message."],
|
||||
]
|
||||
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
|
||||
|
||||
@ -130,7 +136,7 @@ module Homebrew
|
||||
switch short, long, description: desc, env: option_to_name(long), method: :on_tail
|
||||
end
|
||||
|
||||
instance_eval(&block) if block_given?
|
||||
instance_eval(&block) if block
|
||||
end
|
||||
|
||||
def switch(*names, description: nil, env: nil, required_for: nil, depends_on: nil, method: :on)
|
||||
@ -170,7 +176,7 @@ module Homebrew
|
||||
|
||||
def usage_banner_text
|
||||
@parser.banner
|
||||
.gsub(/^ - (`[^`]+`)\s+/, "\n- \\1 \n ") # Format `cask` subcommands as MarkDown list.
|
||||
.gsub(/^ - (`[^`]+`)\s+/, "\n- \\1:\n <br>") # Format `cask` subcommands as Markdown list.
|
||||
end
|
||||
|
||||
def comma_array(name, description: nil)
|
||||
@ -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
|
||||
|
||||
@ -6,14 +6,17 @@ 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
|
||||
`--cache` [<options>] [<formula|cask>]
|
||||
`--cache` [<options>] [<formula>|<cask>]
|
||||
|
||||
Display Homebrew's download cache. See also `HOMEBREW_CACHE`.
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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
|
||||
@ -44,11 +47,10 @@ module Homebrew
|
||||
Utils::Shell.from_path(args.shell)
|
||||
end
|
||||
|
||||
env_keys = BuildEnvironment.keys(ENV)
|
||||
if shell.nil?
|
||||
BuildEnvironment.dump ENV
|
||||
else
|
||||
env_keys.each do |key|
|
||||
BuildEnvironment.keys(ENV).each do |key|
|
||||
puts Utils::Shell.export_value(key, ENV[key], shell)
|
||||
end
|
||||
end
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -14,6 +17,7 @@ module Homebrew
|
||||
Print the version numbers of Homebrew, Homebrew/homebrew-core and Homebrew/homebrew-cask
|
||||
(if tapped) to standard output.
|
||||
EOS
|
||||
|
||||
max_named 0
|
||||
end
|
||||
end
|
||||
|
||||
@ -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
|
||||
@ -17,12 +20,13 @@ module Homebrew
|
||||
`brew analytics` [`state`]:
|
||||
Display the current state of Homebrew's analytics.
|
||||
|
||||
`brew analytics` [`on`|`off`]:
|
||||
`brew analytics` (`on`|`off`):
|
||||
Turn Homebrew's analytics on or off respectively.
|
||||
|
||||
`brew analytics regenerate-uuid`:
|
||||
Regenerate the UUID used for Homebrew's analytics.
|
||||
EOS
|
||||
|
||||
max_named 1
|
||||
end
|
||||
end
|
||||
|
||||
@ -17,7 +17,8 @@ module Homebrew
|
||||
EOS
|
||||
switch "-n", "--dry-run",
|
||||
description: "List what would be uninstalled, but do not actually uninstall anything."
|
||||
named 0
|
||||
|
||||
max_named 0
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -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]
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -87,20 +90,23 @@ module Homebrew
|
||||
raise FormulaOrCaskUnspecifiedError if args.no_named?
|
||||
|
||||
exec_browser(*args.named.to_formulae_and_casks.map { |f| github_info(f) })
|
||||
elsif args.no_named?
|
||||
print_statistics
|
||||
else
|
||||
print_info(args: args)
|
||||
end
|
||||
end
|
||||
|
||||
def print_statistics
|
||||
return unless HOMEBREW_CELLAR.exist?
|
||||
|
||||
count = Formula.racks.length
|
||||
puts "#{count} #{"keg".pluralize(count)}, #{HOMEBREW_CELLAR.dup.abv}"
|
||||
end
|
||||
|
||||
def print_analytics(args:)
|
||||
if args.no_named?
|
||||
if args.analytics?
|
||||
Utils::Analytics.output(args: args)
|
||||
elsif HOMEBREW_CELLAR.exist?
|
||||
count = Formula.racks.length
|
||||
puts "#{count} #{"keg".pluralize(count)}, #{HOMEBREW_CELLAR.dup.abv}"
|
||||
end
|
||||
|
||||
Utils::Analytics.output(args: args)
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@ -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
|
||||
@ -82,7 +85,6 @@ module Homebrew
|
||||
}],
|
||||
[:switch, "--keep-tmp", {
|
||||
description: "Retain the temporary files created during installation.",
|
||||
|
||||
}],
|
||||
[:switch, "--build-bottle", {
|
||||
description: "Prepare the formula for eventual bottling during installation, skipping any " \
|
||||
@ -122,7 +124,6 @@ module Homebrew
|
||||
|
||||
conflicts "--ignore-dependencies", "--only-dependencies"
|
||||
conflicts "--build-from-source", "--build-bottle", "--force-bottle"
|
||||
|
||||
min_named :formula_or_cask
|
||||
end
|
||||
end
|
||||
@ -203,7 +204,7 @@ module Homebrew
|
||||
EOS
|
||||
elsif args.only_dependencies?
|
||||
installed_formulae << f
|
||||
else
|
||||
elsif !args.quiet?
|
||||
opoo <<~EOS
|
||||
#{f.full_name} #{f.pkg_version} is already installed and up-to-date
|
||||
To reinstall #{f.pkg_version}, run `brew reinstall #{f.name}`
|
||||
@ -223,11 +224,14 @@ module Homebrew
|
||||
msg = "#{f.full_name} #{installed_version} is already installed"
|
||||
linked_not_equals_installed = f.linked_version != installed_version
|
||||
if f.linked? && linked_not_equals_installed
|
||||
msg = <<~EOS
|
||||
#{msg}
|
||||
The currently linked version is #{f.linked_version}
|
||||
You can use `brew switch #{f} #{installed_version}` to link this version.
|
||||
EOS
|
||||
msg = if args.quiet?
|
||||
nil
|
||||
else
|
||||
<<~EOS
|
||||
#{msg}
|
||||
The currently linked version is #{f.linked_version}
|
||||
EOS
|
||||
end
|
||||
elsif !f.linked? || f.keg_only?
|
||||
msg = <<~EOS
|
||||
#{msg}, it's just not linked
|
||||
@ -237,10 +241,14 @@ module Homebrew
|
||||
msg = nil
|
||||
installed_formulae << f
|
||||
else
|
||||
msg = <<~EOS
|
||||
#{msg} and up-to-date
|
||||
To reinstall #{f.pkg_version}, run `brew reinstall #{f.name}`
|
||||
EOS
|
||||
msg = if args.quiet?
|
||||
nil
|
||||
else
|
||||
<<~EOS
|
||||
#{msg} and up-to-date
|
||||
To reinstall #{f.pkg_version}, run `brew reinstall #{f.name}`
|
||||
EOS
|
||||
end
|
||||
end
|
||||
opoo msg if msg
|
||||
elsif !f.any_version_installed? && old_formula = f.old_installed_formulae.first
|
||||
@ -250,8 +258,10 @@ module Homebrew
|
||||
#{msg}, it's just not linked.
|
||||
You can use `brew link #{old_formula.full_name}` to link this version.
|
||||
EOS
|
||||
elsif args.quiet?
|
||||
msg = nil
|
||||
end
|
||||
opoo msg
|
||||
opoo msg if msg
|
||||
elsif f.migration_needed? && !args.force?
|
||||
# Check if the formula we try to install is the same as installed
|
||||
# but not migrated one. If --force is passed then install anyway.
|
||||
@ -288,7 +298,7 @@ module Homebrew
|
||||
Cleanup.install_formula_clean!(f)
|
||||
end
|
||||
|
||||
Upgrade.check_installed_dependents(args: args)
|
||||
Upgrade.check_installed_dependents(installed_formulae, args: args)
|
||||
|
||||
Homebrew.messages.display_messages(display_times: args.display_times?)
|
||||
rescue FormulaUnreadableError, FormulaClassUnavailableError,
|
||||
@ -347,21 +357,28 @@ module Homebrew
|
||||
f.print_tap_action
|
||||
build_options = f.build
|
||||
|
||||
fi = FormulaInstaller.new(f, force_bottle: args.force_bottle?,
|
||||
include_test_formulae: args.include_test_formulae,
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
debug: args.debug?, quiet: args.quiet?, verbose: args.verbose?)
|
||||
fi.options = build_options.used_options
|
||||
fi.env = args.env
|
||||
fi.force = args.force?
|
||||
fi.keep_tmp = args.keep_tmp?
|
||||
fi.ignore_deps = args.ignore_dependencies?
|
||||
fi.only_deps = args.only_dependencies?
|
||||
fi.build_bottle = args.build_bottle?
|
||||
fi.bottle_arch = args.bottle_arch
|
||||
fi.interactive = args.interactive?
|
||||
fi.git = args.git?
|
||||
fi.cc = args.cc
|
||||
fi = FormulaInstaller.new(
|
||||
f,
|
||||
**{
|
||||
options: build_options.used_options,
|
||||
build_bottle: args.build_bottle?,
|
||||
force_bottle: args.force_bottle?,
|
||||
bottle_arch: args.bottle_arch,
|
||||
ignore_deps: args.ignore_dependencies?,
|
||||
only_deps: args.only_dependencies?,
|
||||
include_test_formulae: args.include_test_formulae,
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
env: args.env,
|
||||
cc: args.cc,
|
||||
git: args.git?,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
verbose: args.verbose?,
|
||||
}.compact,
|
||||
)
|
||||
fi.prelude
|
||||
fi.fetch
|
||||
fi.install
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -7,19 +7,22 @@ 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
|
||||
`list`, `ls` [<options>] [<formula|cask>]
|
||||
`list`, `ls` [<options>] [<formula>|<cask>]
|
||||
|
||||
List all installed formulae or casks
|
||||
List all installed formulae and casks.
|
||||
|
||||
If <formula> is provided, summarise the paths within its current keg.
|
||||
EOS
|
||||
switch "--formula", "--formulae",
|
||||
description: "List only formulae. `This is the default action on non TTY.`"
|
||||
description: "List only formulae. This is the default when output is not to a terminal."
|
||||
switch "--cask", "--casks",
|
||||
description: "List only casks, or <cask> if provided."
|
||||
switch "--unbrewed",
|
||||
|
||||
@ -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
|
||||
@ -25,8 +28,9 @@ module Homebrew
|
||||
description: "Print only one commit."
|
||||
flag "-n", "--max-count=",
|
||||
description: "Print only a specified number of commits."
|
||||
max_named 1
|
||||
|
||||
conflicts "-1", "--max-count"
|
||||
max_named 1
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -23,9 +26,9 @@ module Homebrew
|
||||
switch "-v", "--verbose",
|
||||
description: "Include detailed version information."
|
||||
switch "--formula",
|
||||
description: "Only output outdated formulae."
|
||||
description: "List only outdated formulae."
|
||||
switch "--cask",
|
||||
description: "Only output outdated casks."
|
||||
description: "List only outdated casks."
|
||||
flag "--json",
|
||||
description: "Print output in JSON format. There are two versions: v1 and v2. " \
|
||||
"v1 is deprecated and is currently the default if no version is specified. " \
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -25,7 +28,7 @@ module Homebrew
|
||||
|
||||
args.named.to_resolved_formulae.each do |f|
|
||||
ohai "Postinstalling #{f}"
|
||||
fi = FormulaInstaller.new(f, debug: args.debug?, quiet: args.quiet?, verbose: args.verbose?)
|
||||
fi = FormulaInstaller.new(f, **{ debug: args.debug?, quiet: args.quiet?, verbose: args.verbose? }.compact)
|
||||
fi.post_install
|
||||
end
|
||||
end
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
@ -42,8 +45,8 @@ module Homebrew
|
||||
}],
|
||||
[:switch, "-i", "--interactive", {
|
||||
description: "Download and patch <formula>, then open a shell. This allows the user to " \
|
||||
"run `./configure --help` and otherwise determine how to turn the software " \
|
||||
"package into a Homebrew package.",
|
||||
"run `./configure --help` and otherwise determine how to turn the software " \
|
||||
"package into a Homebrew package.",
|
||||
}],
|
||||
[:switch, "--force-bottle", {
|
||||
description: "Install from a bottle if it exists for the current or newest version of " \
|
||||
@ -72,7 +75,6 @@ module Homebrew
|
||||
cask_options
|
||||
|
||||
conflicts "--build-from-source", "--force-bottle"
|
||||
|
||||
min_named :formula_or_cask
|
||||
end
|
||||
end
|
||||
@ -100,7 +102,7 @@ module Homebrew
|
||||
Cleanup.install_formula_clean!(f)
|
||||
end
|
||||
|
||||
Upgrade.check_installed_dependents(args: args)
|
||||
Upgrade.check_installed_dependents(formulae, args: args)
|
||||
|
||||
if casks.any?
|
||||
Cask::Cmd::Reinstall.reinstall_casks(
|
||||
|
||||
@ -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
|
||||
@ -47,7 +50,7 @@ module Homebrew
|
||||
description: "Search for formulae with a description matching <text> and casks with "\
|
||||
"a name matching <text>."
|
||||
switch "--pull-request",
|
||||
description: "Search for GitHub pull requests for <text>."
|
||||
description: "Search for GitHub pull requests containing <text>."
|
||||
|
||||
package_manager_switches = PACKAGE_MANAGERS.keys.map { |name| "--#{name}" }
|
||||
package_manager_switches.each do |s|
|
||||
|
||||
@ -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
|
||||
|
||||
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