Merge branch 'master' into add-service-block-to-formula-api
This commit is contained in:
commit
6ccf21c2c9
10
.github/workflows/tests.yml
vendored
10
.github/workflows/tests.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
|
||||
- name: Cache Bundler RubyGems
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
@ -73,7 +73,7 @@ jobs:
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
|
||||
- name: Cache Bundler RubyGems
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
@ -231,7 +231,7 @@ jobs:
|
||||
uses: Homebrew/actions/setup-homebrew@master
|
||||
|
||||
- name: Cache Bundler RubyGems
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
@ -276,7 +276,7 @@ jobs:
|
||||
HOMEBREW_NO_INSTALL_FROM_API: 1
|
||||
|
||||
- name: Cache Bundler RubyGems
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||
@ -289,7 +289,7 @@ jobs:
|
||||
run: mkdir tests
|
||||
|
||||
- name: Cache parallel tests log
|
||||
uses: actions/cache@v1
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: tests
|
||||
key: ${{ runner.os }}-${{ matrix.test-flags }}-parallel_runtime_rspec-${{ github.sha }}
|
||||
|
2
.github/workflows/triage.yml
vendored
2
.github/workflows/triage.yml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
steps:
|
||||
- name: Re-run this workflow
|
||||
if: github.event_name == 'schedule' || github.event.action == 'closed'
|
||||
uses: reitermarkus/rerun-workflow@1a15891377b6667377207cdd85b628b79ebd6f81
|
||||
uses: reitermarkus/rerun-workflow@7381e98aa2bc4464acef4b60ade8d1d1d90e6e65
|
||||
with:
|
||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||
continuous-label: waiting for feedback
|
||||
|
@ -28,6 +28,7 @@ gem "rubocop", require: false
|
||||
gem "rubocop-ast", require: false
|
||||
gem "simplecov", require: false
|
||||
gem "simplecov-cobertura", require: false
|
||||
gem "stackprof", require: false
|
||||
gem "warning", require: false
|
||||
|
||||
group :sorbet, optional: true do
|
||||
|
@ -188,6 +188,7 @@ GEM
|
||||
sorbet (>= 0.5.9204)
|
||||
sorbet-runtime (>= 0.5.9204)
|
||||
thor (>= 0.19.2)
|
||||
stackprof (0.2.24)
|
||||
tapioca (0.7.3)
|
||||
bundler (>= 1.17.3)
|
||||
pry (>= 0.12.2)
|
||||
@ -257,6 +258,7 @@ DEPENDENCIES
|
||||
sorbet-runtime
|
||||
sorbet-static-and-runtime
|
||||
spoom
|
||||
stackprof
|
||||
tapioca
|
||||
warning
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
# `HOMEBREW_STACKPROF` should be set via `brew prof --stackprof`, not manually.
|
||||
if ENV["HOMEBREW_STACKPROF"]
|
||||
require "rubygems"
|
||||
require "stackprof"
|
||||
@ -35,8 +36,8 @@ begin
|
||||
empty_argv = ARGV.empty?
|
||||
help_flag_list = %w[-h --help --usage -?]
|
||||
help_flag = !ENV["HOMEBREW_HELP"].nil?
|
||||
help_cmd_index = nil
|
||||
cmd = nil
|
||||
help_cmd_index = T.let(nil, T.nilable(Integer))
|
||||
cmd = T.let(nil, T.nilable(String))
|
||||
|
||||
ARGV.each_with_index do |arg, i|
|
||||
break if help_flag && cmd
|
||||
@ -64,7 +65,7 @@ begin
|
||||
path.prepend(HOMEBREW_SHIMS_PATH/"shared")
|
||||
homebrew_path.prepend(HOMEBREW_SHIMS_PATH/"shared")
|
||||
|
||||
ENV["PATH"] = path
|
||||
ENV["PATH"] = path.to_s
|
||||
|
||||
require "commands"
|
||||
require "settings"
|
||||
@ -76,7 +77,7 @@ begin
|
||||
homebrew_path.append(Tap.cmd_directories)
|
||||
|
||||
# External commands expect a normal PATH
|
||||
ENV["PATH"] = homebrew_path
|
||||
ENV["PATH"] = homebrew_path.to_s
|
||||
end
|
||||
|
||||
# Usage instructions should be displayed if and only if one of:
|
||||
|
@ -6,8 +6,6 @@ require "timeout"
|
||||
require "utils/user"
|
||||
require "cask/artifact/abstract_artifact"
|
||||
require "cask/pkg"
|
||||
require "extend/hash_validator"
|
||||
using HashValidator
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
@ -38,7 +36,7 @@ module Cask
|
||||
attr_reader :directives
|
||||
|
||||
def initialize(cask, directives)
|
||||
directives.assert_valid_keys!(*ORDERED_DIRECTIVES)
|
||||
directives.assert_valid_keys(*ORDERED_DIRECTIVES)
|
||||
|
||||
super(cask, **directives)
|
||||
directives[:signal] = Array(directives[:signal]).flatten.each_slice(2).to_a
|
||||
|
@ -3,9 +3,6 @@
|
||||
|
||||
require "cask/artifact/moved"
|
||||
|
||||
require "extend/hash_validator"
|
||||
using HashValidator
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
# Generic artifact corresponding to the `artifact` stanza.
|
||||
|
@ -3,9 +3,6 @@
|
||||
|
||||
require "cask/artifact/abstract_artifact"
|
||||
|
||||
require "extend/hash_validator"
|
||||
using HashValidator
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
# Artifact corresponding to the `installer` stanza.
|
||||
@ -67,7 +64,7 @@ module Cask
|
||||
)
|
||||
end
|
||||
|
||||
args.assert_valid_keys!(*VALID_KEYS)
|
||||
args.assert_valid_keys(*VALID_KEYS)
|
||||
new(cask, **args)
|
||||
end
|
||||
|
||||
|
@ -6,9 +6,6 @@ require "plist"
|
||||
require "utils/user"
|
||||
require "cask/artifact/abstract_artifact"
|
||||
|
||||
require "extend/hash_validator"
|
||||
using HashValidator
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
# Artifact corresponding to the `pkg` stanza.
|
||||
@ -18,7 +15,7 @@ module Cask
|
||||
attr_reader :path, :stanza_options
|
||||
|
||||
def self.from_args(cask, path, **stanza_options)
|
||||
stanza_options.assert_valid_keys!(:allow_untrusted, :choices)
|
||||
stanza_options.assert_valid_keys(:allow_untrusted, :choices)
|
||||
new(cask, path, **stanza_options)
|
||||
end
|
||||
|
||||
|
@ -3,9 +3,6 @@
|
||||
|
||||
require "cask/artifact/abstract_artifact"
|
||||
|
||||
require "extend/hash_validator"
|
||||
using HashValidator
|
||||
|
||||
module Cask
|
||||
module Artifact
|
||||
# Superclass for all artifacts which have a source and a target location.
|
||||
@ -20,7 +17,7 @@ module Cask
|
||||
if target_hash
|
||||
raise CaskInvalidError unless target_hash.respond_to?(:keys)
|
||||
|
||||
target_hash.assert_valid_keys!(:target)
|
||||
target_hash.assert_valid_keys(:target)
|
||||
end
|
||||
|
||||
target_hash ||= {}
|
||||
|
@ -20,9 +20,6 @@ module Cask
|
||||
extend APIHashable
|
||||
include Metadata
|
||||
|
||||
# TODO: can be removed when API JSON is regenerated with HOMEBREW_PREFIX_PLACEHOLDER.
|
||||
HOMEBREW_OLD_PREFIX_PLACEHOLDER = "$(brew --prefix)"
|
||||
|
||||
attr_reader :token, :sourcefile_path, :source, :config, :default_config, :loader
|
||||
attr_accessor :download, :allow_reassignment
|
||||
|
||||
|
@ -326,13 +326,10 @@ module Cask
|
||||
end
|
||||
|
||||
def from_h_string_gsubs(string, appdir)
|
||||
# TODO: HOMEBREW_OLD_PREFIX_PLACEHOLDER can be removed when API JSON is
|
||||
# regenerated with HOMEBREW_PREFIX_PLACEHOLDER.
|
||||
string.to_s
|
||||
.gsub(HOMEBREW_HOME_PLACEHOLDER, Dir.home)
|
||||
.gsub(HOMEBREW_PREFIX_PLACEHOLDER, HOMEBREW_PREFIX)
|
||||
.gsub(HOMEBREW_CASK_APPDIR_PLACEHOLDER, appdir)
|
||||
.gsub(Cask::HOMEBREW_OLD_PREFIX_PLACEHOLDER, HOMEBREW_PREFIX)
|
||||
end
|
||||
|
||||
def from_h_array_gsubs(array, appdir)
|
||||
|
@ -11,7 +11,6 @@ require "cask/config"
|
||||
|
||||
require "cask/cmd/abstract_command"
|
||||
require "cask/cmd/audit"
|
||||
require "cask/cmd/fetch"
|
||||
require "cask/cmd/install"
|
||||
require "cask/cmd/reinstall"
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Cask
|
||||
class Cmd
|
||||
# Cask implementation of the `brew fetch` command.
|
||||
#
|
||||
# @api private
|
||||
class Fetch < AbstractCommand
|
||||
extend T::Sig
|
||||
|
||||
def self.parser
|
||||
super do
|
||||
switch "--force",
|
||||
description: "Force redownloading even if files already exist in local cache."
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def run
|
||||
require "cask/download"
|
||||
require "cask/installer"
|
||||
|
||||
options = {
|
||||
quarantine: args.quarantine?,
|
||||
}.compact
|
||||
|
||||
options[:quarantine] = true if options[:quarantine].nil?
|
||||
|
||||
casks.each do |cask|
|
||||
puts Installer.caveats(cask)
|
||||
ohai "Downloading external files for Cask #{cask}"
|
||||
download = Download.new(cask, **options)
|
||||
download.clear_cache if args.force?
|
||||
downloaded_path = download.fetch
|
||||
ohai "Success! Downloaded to: #{downloaded_path}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -85,8 +85,7 @@ module Cask
|
||||
|
||||
if dry_run
|
||||
if (casks_to_install = casks.reject(&:installed?).presence)
|
||||
plural = ::Utils.pluralize("cask", casks_to_install.count)
|
||||
ohai "Would install #{casks_to_install.count} #{plural}:"
|
||||
ohai "Would install #{::Utils.pluralize("cask", casks_to_install.count, include_count: true)}:"
|
||||
puts casks_to_install.map(&:full_name).join(" ")
|
||||
end
|
||||
casks.each do |cask|
|
||||
@ -97,8 +96,8 @@ module Cask
|
||||
.map(&:name)
|
||||
next if dep_names.blank?
|
||||
|
||||
plural = ::Utils.pluralize("dependenc", dep_names.count, plural: "ies", singular: "y")
|
||||
ohai "Would install #{dep_names.count} #{plural} for #{cask.full_name}:"
|
||||
ohai "Would install #{::Utils.pluralize("dependenc", dep_names.count, plural: "ies", singular: "y",
|
||||
include_count: true)} for #{cask.full_name}:"
|
||||
puts dep_names.join(" ")
|
||||
end
|
||||
return
|
||||
|
@ -6,9 +6,6 @@ require "json"
|
||||
require "lazy_object"
|
||||
require "locale"
|
||||
|
||||
require "extend/hash_validator"
|
||||
using HashValidator
|
||||
|
||||
module Cask
|
||||
# Configuration for installing casks.
|
||||
#
|
||||
@ -110,8 +107,8 @@ module Cask
|
||||
return
|
||||
end
|
||||
|
||||
@env&.assert_valid_keys!(*self.class.defaults.keys)
|
||||
@explicit.assert_valid_keys!(*self.class.defaults.keys)
|
||||
@env&.assert_valid_keys(*self.class.defaults.keys)
|
||||
@explicit.assert_valid_keys(*self.class.defaults.keys)
|
||||
end
|
||||
|
||||
sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) }
|
||||
@ -169,10 +166,12 @@ module Cask
|
||||
|
||||
DEFAULT_DIRS.each_key do |dir|
|
||||
define_method(dir) do
|
||||
T.bind(self, Config)
|
||||
explicit.fetch(dir, env.fetch(dir, default.fetch(dir)))
|
||||
end
|
||||
|
||||
define_method(:"#{dir}=") do |path|
|
||||
T.bind(self, Config)
|
||||
explicit[dir] = Pathname(path).expand_path
|
||||
end
|
||||
end
|
||||
|
@ -339,6 +339,7 @@ module Cask
|
||||
|
||||
ORDINARY_ARTIFACT_CLASSES.each do |klass|
|
||||
define_method(klass.dsl_key) do |*args, **kwargs|
|
||||
T.bind(self, DSL)
|
||||
if [*artifacts.map(&:class), klass].include?(Artifact::StageOnly) &&
|
||||
(artifacts.map(&:class) & ACTIVATABLE_ARTIFACT_CLASSES).any?
|
||||
raise CaskInvalidError.new(cask, "'stage_only' must be the only activatable artifact.")
|
||||
@ -355,6 +356,7 @@ module Cask
|
||||
ARTIFACT_BLOCK_CLASSES.each do |klass|
|
||||
[klass.dsl_key, klass.uninstall_dsl_key].each do |dsl_key|
|
||||
define_method(dsl_key) do |&block|
|
||||
T.bind(self, DSL)
|
||||
artifacts.add(klass.new(cask, dsl_key => block))
|
||||
end
|
||||
end
|
||||
|
@ -1,11 +1,8 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "delegate"
|
||||
|
||||
require "extend/hash_validator"
|
||||
using HashValidator
|
||||
|
||||
module Cask
|
||||
class DSL
|
||||
# Class corresponding to the `conflicts_with` stanza.
|
||||
@ -22,16 +19,16 @@ module Cask
|
||||
].freeze
|
||||
|
||||
def initialize(**options)
|
||||
options.assert_valid_keys!(*VALID_KEYS)
|
||||
options.assert_valid_keys(*VALID_KEYS)
|
||||
|
||||
conflicts = options.transform_values { |v| Set.new(Array(v)) }
|
||||
conflicts = options.transform_values { |v| Set.new(Kernel.Array(v)) }
|
||||
conflicts.default = Set.new
|
||||
|
||||
super(conflicts)
|
||||
end
|
||||
|
||||
def to_json(generator)
|
||||
transform_values(&:to_a).to_json(generator)
|
||||
__getobj__.transform_values(&:to_a).to_json(generator)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "delegate"
|
||||
@ -38,7 +38,7 @@ module Cask
|
||||
pairs.each do |key, value|
|
||||
raise "invalid depends_on key: '#{key.inspect}'" unless VALID_KEYS.include?(key)
|
||||
|
||||
self[key] = send(:"#{key}=", *value)
|
||||
__getobj__[key] = send(:"#{key}=", *value)
|
||||
end
|
||||
end
|
||||
|
||||
@ -54,15 +54,18 @@ module Cask
|
||||
def macos=(*args)
|
||||
raise "Only a single 'depends_on macos' is allowed." if defined?(@macos)
|
||||
|
||||
# workaround for https://github.com/sorbet/sorbet/issues/6860
|
||||
first_arg = args.first&.to_s
|
||||
|
||||
begin
|
||||
@macos = if args.count > 1
|
||||
MacOSRequirement.new([args], comparator: "==")
|
||||
elsif MacOSVersions::SYMBOLS.key?(args.first)
|
||||
MacOSRequirement.new([args.first], comparator: "==")
|
||||
elsif /^\s*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/ =~ args.first
|
||||
MacOSRequirement.new([version.to_sym], comparator: comparator)
|
||||
elsif /^\s*(?<comparator><|>|[=<>]=)\s*(?<version>\S+)\s*$/ =~ args.first
|
||||
MacOSRequirement.new([version], comparator: comparator)
|
||||
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/.match(first_arg))
|
||||
MacOSRequirement.new([T.must(md[:version]).to_sym], comparator: md[:comparator])
|
||||
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*(?<version>\S+)\s*$/.match(first_arg))
|
||||
MacOSRequirement.new([md[:version]], comparator: md[:comparator])
|
||||
else # rubocop:disable Lint/DuplicateBranch
|
||||
MacOSRequirement.new([args.first], comparator: "==")
|
||||
end
|
||||
|
5
Library/Homebrew/cask/dsl/depends_on.rbi
Normal file
5
Library/Homebrew/cask/dsl/depends_on.rbi
Normal file
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
|
||||
class Cask::DSL::DependsOn
|
||||
include Kernel
|
||||
end
|
@ -32,6 +32,7 @@ module Cask
|
||||
def define_divider_deletion_method(divider)
|
||||
method_name = deletion_method_name(divider)
|
||||
define_method(method_name) do
|
||||
T.bind(self, Version)
|
||||
version { delete(divider) }
|
||||
end
|
||||
end
|
||||
@ -49,6 +50,7 @@ module Cask
|
||||
def define_divider_conversion_method(left_divider, right_divider)
|
||||
method_name = conversion_method_name(left_divider, right_divider)
|
||||
define_method(method_name) do
|
||||
T.bind(self, Version)
|
||||
version { gsub(left_divider, right_divider) }
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "formula_installer"
|
||||
@ -112,8 +112,9 @@ module Cask
|
||||
|
||||
install_artifacts
|
||||
|
||||
if @cask.tap&.should_report_analytics?
|
||||
::Utils::Analytics.report_event(:cask_install, @cask.token, on_request: true)
|
||||
if (tap = @cask.tap) && tap.should_report_analytics?
|
||||
::Utils::Analytics.report_event(:cask_install, package_name: @cask.token, tap_name: tap.name,
|
||||
on_request: true)
|
||||
end
|
||||
|
||||
purge_backed_up_versioned_files
|
||||
@ -241,7 +242,7 @@ module Cask
|
||||
save_download_sha if @cask.version.latest?
|
||||
rescue => e
|
||||
begin
|
||||
already_installed_artifacts.each do |artifact|
|
||||
already_installed_artifacts&.each do |artifact|
|
||||
if artifact.respond_to?(:uninstall_phase)
|
||||
odebug "Reverting installation of artifact of class #{artifact.class}"
|
||||
artifact.uninstall_phase(command: @command, verbose: verbose?, force: force?)
|
||||
@ -296,7 +297,7 @@ module Cask
|
||||
|
||||
graph = ::Utils::TopologicalHash.graph_package_dependencies(@cask)
|
||||
|
||||
raise CaskSelfReferencingDependencyError, cask.token if graph[@cask].include?(@cask)
|
||||
raise CaskSelfReferencingDependencyError, @cask.token if graph[@cask].include?(@cask)
|
||||
|
||||
::Utils::TopologicalHash.graph_package_dependencies(primary_container.dependencies, graph)
|
||||
|
||||
@ -454,7 +455,7 @@ module Cask
|
||||
artifacts = @cask.artifacts
|
||||
|
||||
odebug "Uninstalling artifacts"
|
||||
odebug "#{artifacts.length} #{::Utils.pluralize("artifact", artifacts.length)} defined", artifacts
|
||||
odebug "#{::Utils.pluralize("artifact", artifacts.length, include_count: true)} defined", artifacts
|
||||
|
||||
artifacts.each do |artifact|
|
||||
if artifact.respond_to?(:uninstall_phase)
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "development_tools"
|
||||
@ -11,29 +11,27 @@ module Cask
|
||||
module Quarantine
|
||||
extend T::Sig
|
||||
|
||||
module_function
|
||||
|
||||
QUARANTINE_ATTRIBUTE = "com.apple.quarantine"
|
||||
|
||||
QUARANTINE_SCRIPT = (HOMEBREW_LIBRARY_PATH/"cask/utils/quarantine.swift").freeze
|
||||
|
||||
def swift
|
||||
def self.swift
|
||||
@swift ||= DevelopmentTools.locate("swift")
|
||||
end
|
||||
private :swift
|
||||
private_class_method :swift
|
||||
|
||||
def xattr
|
||||
def self.xattr
|
||||
@xattr ||= DevelopmentTools.locate("xattr")
|
||||
end
|
||||
private :xattr
|
||||
private_class_method :xattr
|
||||
|
||||
def swift_target_args
|
||||
def self.swift_target_args
|
||||
["-target", "#{Hardware::CPU.arch}-apple-macosx#{MacOS.version}"]
|
||||
end
|
||||
private :swift_target_args
|
||||
private_class_method :swift_target_args
|
||||
|
||||
sig { returns(Symbol) }
|
||||
def check_quarantine_support
|
||||
def self.check_quarantine_support
|
||||
odebug "Checking quarantine support"
|
||||
|
||||
if !system_command(xattr, args: ["-h"], print_stderr: false).success?
|
||||
@ -58,13 +56,13 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
def available?
|
||||
def self.available?
|
||||
@status ||= check_quarantine_support
|
||||
|
||||
@status == :quarantine_available
|
||||
end
|
||||
|
||||
def detect(file)
|
||||
def self.detect(file)
|
||||
return if file.nil?
|
||||
|
||||
odebug "Verifying Gatekeeper status of #{file}"
|
||||
@ -76,13 +74,13 @@ module Cask
|
||||
quarantine_status
|
||||
end
|
||||
|
||||
def status(file)
|
||||
def self.status(file)
|
||||
system_command(xattr,
|
||||
args: ["-p", QUARANTINE_ATTRIBUTE, file],
|
||||
print_stderr: false).stdout.rstrip
|
||||
end
|
||||
|
||||
def toggle_no_translocation_bit(attribute)
|
||||
def self.toggle_no_translocation_bit(attribute)
|
||||
fields = attribute.split(";")
|
||||
|
||||
# Fields: status, epoch, download agent, event ID
|
||||
@ -94,7 +92,7 @@ module Cask
|
||||
fields.join(";")
|
||||
end
|
||||
|
||||
def release!(download_path: nil)
|
||||
def self.release!(download_path: nil)
|
||||
return unless detect(download_path)
|
||||
|
||||
odebug "Releasing #{download_path} from quarantine"
|
||||
@ -112,7 +110,7 @@ module Cask
|
||||
raise CaskQuarantineReleaseError.new(download_path, quarantiner.stderr)
|
||||
end
|
||||
|
||||
def cask!(cask: nil, download_path: nil, action: true)
|
||||
def self.cask!(cask: nil, download_path: nil, action: true)
|
||||
return if cask.nil? || download_path.nil?
|
||||
|
||||
return if detect(download_path)
|
||||
@ -139,7 +137,7 @@ module Cask
|
||||
end
|
||||
end
|
||||
|
||||
def propagate(from: nil, to: nil)
|
||||
def self.propagate(from: nil, to: nil)
|
||||
return if from.nil? || to.nil?
|
||||
|
||||
raise CaskError, "#{from} was not quarantined properly." unless detect(from)
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "env_config"
|
||||
@ -124,7 +124,9 @@ module Cask
|
||||
|
||||
return true if caught_exceptions.empty?
|
||||
raise MultipleCaskErrors, caught_exceptions if caught_exceptions.count > 1
|
||||
raise caught_exceptions.first if caught_exceptions.count == 1
|
||||
raise caught_exceptions.fetch(0) if caught_exceptions.count == 1
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def self.upgrade_cask(
|
||||
|
@ -94,7 +94,8 @@ class Caveats
|
||||
end
|
||||
end
|
||||
end
|
||||
s << "\n"
|
||||
s << "\n" unless s.end_with?("\n")
|
||||
s
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -124,7 +124,7 @@ module Homebrew
|
||||
return unless HOMEBREW_CELLAR.exist?
|
||||
|
||||
count = Formula.racks.length
|
||||
puts "#{count} #{Utils.pluralize("keg", count)}, #{HOMEBREW_CELLAR.dup.abv}"
|
||||
puts "#{Utils.pluralize("keg", count, include_count: true)}, #{HOMEBREW_CELLAR.dup.abv}"
|
||||
end
|
||||
|
||||
sig { params(args: CLI::Args).void }
|
||||
|
166
Library/Homebrew/cmd/postgresql-upgrade-database.rb
Executable file
166
Library/Homebrew/cmd/postgresql-upgrade-database.rb
Executable file
@ -0,0 +1,166 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cli/parser"
|
||||
require "formula"
|
||||
|
||||
module Homebrew
|
||||
module_function
|
||||
|
||||
sig { returns(CLI::Parser) }
|
||||
def postgresql_upgrade_database_args
|
||||
Homebrew::CLI::Parser.new do
|
||||
description <<~EOS
|
||||
Upgrades the database for the `postgresql` formula.
|
||||
EOS
|
||||
|
||||
named_args :none
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def postgresql_upgrade_database
|
||||
postgresql_upgrade_database_args.parse
|
||||
|
||||
name = "postgresql"
|
||||
pg = Formula[name]
|
||||
bin = pg.bin
|
||||
var = pg.var
|
||||
version = pg.version
|
||||
pg_version_file = var/"postgres/PG_VERSION"
|
||||
|
||||
pg_version_installed = version.to_s[/^\d+/]
|
||||
pg_version_data = pg_version_file.read.chomp
|
||||
if pg_version_installed == pg_version_data
|
||||
odie <<~EOS
|
||||
#{name} data already upgraded!
|
||||
EOS
|
||||
end
|
||||
|
||||
datadir = var/"postgres"
|
||||
old_datadir = var/"postgres.old"
|
||||
if old_datadir.exist?
|
||||
odie <<~EOS
|
||||
#{old_datadir} already exists!
|
||||
Remove it if you want to upgrade data automatically.
|
||||
EOS
|
||||
end
|
||||
|
||||
old_pg_name = "#{name}@#{pg_version_data}"
|
||||
old_pg_glob = "#{HOMEBREW_CELLAR}/#{old_pg_name}/#{pg_version_data}.*/bin"
|
||||
old_bin = Pathname.glob(old_pg_glob).first
|
||||
old_bin ||= begin
|
||||
Formula[old_pg_name]
|
||||
ohai "brew install #{old_pg_name}"
|
||||
system "brew", "install", old_pg_name
|
||||
Pathname.glob(old_pg_glob).first
|
||||
rescue FormulaUnavailableError
|
||||
nil
|
||||
end
|
||||
|
||||
odie "No #{name} #{pg_version_data}.* version installed!" unless old_bin
|
||||
|
||||
server_stopped = false
|
||||
moved_data = false
|
||||
initdb_run = false
|
||||
upgraded = false
|
||||
|
||||
begin
|
||||
# Following instructions from:
|
||||
# https://www.postgresql.org/docs/10/static/pgupgrade.html
|
||||
ohai "Upgrading #{name} data from #{pg_version_data} to #{pg_version_installed}..."
|
||||
services_json_output = Utils.popen_read("brew", "services", "info", "--all", "--json")
|
||||
services_json = JSON.parse(services_json_output)
|
||||
loaded_service_names = services_json.select { |sj| sj[:loaded] }.map { |sj| sj[:name] }
|
||||
if loaded_service_names.include?(name)
|
||||
system "brew", "services", "stop", name
|
||||
service_stopped = true
|
||||
elsif quiet_system "#{bin}/pg_ctl", "-D", datadir, "status"
|
||||
system "#{bin}/pg_ctl", "-D", datadir, "stop"
|
||||
server_stopped = true
|
||||
end
|
||||
|
||||
# Shut down old server if it is up via brew services
|
||||
system "brew", "services", "stop", old_pg_name if loaded_service_names.include?(old_pg_name)
|
||||
|
||||
# get 'lc_collate' from old DB"
|
||||
unless quiet_system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "status"
|
||||
system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "start"
|
||||
end
|
||||
|
||||
initdb_args = []
|
||||
locale_settings = %w[
|
||||
lc_collate
|
||||
lc_ctype
|
||||
lc_messages
|
||||
lc_monetary
|
||||
lc_numeric
|
||||
lc_time
|
||||
server_encoding
|
||||
]
|
||||
locale_settings.each do |setting|
|
||||
sql = "SELECT setting FROM pg_settings WHERE name LIKE '#{setting}';"
|
||||
value = Utils.popen_read("#{old_bin}/psql", "postgres", "-qtAX", "-U", ENV.fetch("USER"), "-c", sql).strip
|
||||
|
||||
next if value.empty?
|
||||
|
||||
initdb_args += if setting == "server_encoding"
|
||||
["-E #{value}"]
|
||||
else
|
||||
["--#{setting.tr("_", "-")}=#{value}"]
|
||||
end
|
||||
end
|
||||
|
||||
if quiet_system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "status"
|
||||
system "#{old_bin}/pg_ctl", "-w", "-D", datadir, "stop"
|
||||
end
|
||||
|
||||
ohai "Moving #{name} data from #{datadir} to #{old_datadir}..."
|
||||
FileUtils.mv datadir, old_datadir
|
||||
moved_data = true
|
||||
|
||||
(var/"postgres").mkpath
|
||||
ohai "Creating database..."
|
||||
safe_system "#{bin}/initdb", *initdb_args, "#{var}/postgres"
|
||||
initdb_run = true
|
||||
|
||||
ohai "Migrating and upgrading data..."
|
||||
(var/"log").cd do
|
||||
safe_system "#{bin}/pg_upgrade",
|
||||
"-r",
|
||||
"-b", old_bin,
|
||||
"-B", bin,
|
||||
"-d", old_datadir,
|
||||
"-D", datadir,
|
||||
"-j", Hardware::CPU.cores.to_s
|
||||
end
|
||||
upgraded = true
|
||||
|
||||
ohai "Upgraded #{name} data from #{pg_version_data} to #{pg_version_installed}!"
|
||||
ohai "Your #{name} #{pg_version_data} data remains at #{old_datadir}"
|
||||
ensure
|
||||
if upgraded
|
||||
if server_stopped
|
||||
safe_system "#{bin}/pg_ctl", "-D", datadir, "start"
|
||||
elsif service_stopped
|
||||
safe_system "brew", "services", "start", name
|
||||
end
|
||||
else
|
||||
onoe "Upgrading #{name} data from #{pg_version_data} to #{pg_version_installed} failed!"
|
||||
if initdb_run
|
||||
ohai "Removing empty #{name} initdb database..."
|
||||
FileUtils.rm_r datadir
|
||||
end
|
||||
if moved_data
|
||||
ohai "Moving #{name} data back from #{old_datadir} to #{datadir}..."
|
||||
FileUtils.mv old_datadir, datadir
|
||||
end
|
||||
if server_stopped
|
||||
system "#{bin}/pg_ctl", "-D", datadir, "start"
|
||||
elsif service_stopped
|
||||
system "brew", "services", "start", name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -57,10 +57,10 @@ module Homebrew
|
||||
command_count += tap.command_files.size
|
||||
private_count += 1 if tap.private?
|
||||
end
|
||||
info = "#{tap_count} #{Utils.pluralize("tap", tap_count)}"
|
||||
info = Utils.pluralize("tap", tap_count, include_count: true)
|
||||
info += ", #{private_count} private"
|
||||
info += ", #{formula_count} #{Utils.pluralize("formula", formula_count, plural: "e")}"
|
||||
info += ", #{command_count} #{Utils.pluralize("command", command_count)}"
|
||||
info += ", #{Utils.pluralize("formula", formula_count, plural: "e", include_count: true)}"
|
||||
info += ", #{Utils.pluralize("command", command_count, include_count: true)}"
|
||||
info += ", #{Tap::TAP_DIRECTORY.dup.abv}" if Tap::TAP_DIRECTORY.directory?
|
||||
puts info
|
||||
else
|
||||
|
@ -233,8 +233,7 @@ module Homebrew
|
||||
|
||||
unless updated_taps.empty?
|
||||
auto_update_header args: args
|
||||
noun = Utils.pluralize("tap", updated_taps.count)
|
||||
puts "Updated #{updated_taps.count} #{noun} (#{updated_taps.to_sentence})."
|
||||
puts "Updated #{Utils.pluralize("tap", updated_taps.count, include_count: true)} (#{updated_taps.to_sentence})."
|
||||
updated = true
|
||||
end
|
||||
|
||||
@ -656,12 +655,12 @@ class ReporterHub
|
||||
output_dump_formula_or_cask_report "Outdated Casks", outdated_casks
|
||||
elsif report_all
|
||||
if (changed_formulae = select_formula_or_cask(:M).count) && changed_formulae.positive?
|
||||
noun = Utils.pluralize("formula", changed_formulae, plural: "e")
|
||||
ohai "Modified Formulae", "Modified #{changed_formulae} #{noun}."
|
||||
ohai "Modified Formulae",
|
||||
"Modified #{Utils.pluralize("formula", changed_formulae, plural: "e", include_count: true)}."
|
||||
end
|
||||
|
||||
if (changed_casks = select_formula_or_cask(:MC).count) && changed_casks.positive?
|
||||
ohai "Modified Casks", "Modified #{changed_casks} #{Utils.pluralize("cask", changed_casks)}."
|
||||
ohai "Modified Casks", "Modified #{Utils.pluralize("cask", changed_casks, include_count: true)}."
|
||||
end
|
||||
else
|
||||
outdated_formulae = Formula.installed.select(&:outdated?).map(&:name)
|
||||
|
@ -12,6 +12,10 @@ git() {
|
||||
# HOMEBREW_LIBRARY is set by bin/brew
|
||||
# shellcheck disable=SC2154
|
||||
GIT_EXECUTABLE="$("${HOMEBREW_LIBRARY}/Homebrew/shims/shared/git" --homebrew=print-path)"
|
||||
if [[ -z "${GIT_EXECUTABLE}" ]]
|
||||
then
|
||||
odie "Can't find a working Git!"
|
||||
fi
|
||||
fi
|
||||
"${GIT_EXECUTABLE}" "$@"
|
||||
}
|
||||
|
@ -25,6 +25,10 @@ curl() {
|
||||
if [[ -z "${CURL_EXECUTABLE}" ]]
|
||||
then
|
||||
CURL_EXECUTABLE="$("${HOMEBREW_LIBRARY}/Homebrew/shims/shared/curl" --homebrew=print-path)"
|
||||
if [[ -z "${CURL_EXECUTABLE}" ]]
|
||||
then
|
||||
odie "Can't find a working Curl!"
|
||||
fi
|
||||
fi
|
||||
"${CURL_EXECUTABLE}" "$@"
|
||||
}
|
||||
@ -33,6 +37,10 @@ git() {
|
||||
if [[ -z "${GIT_EXECUTABLE}" ]]
|
||||
then
|
||||
GIT_EXECUTABLE="$("${HOMEBREW_LIBRARY}/Homebrew/shims/shared/git" --homebrew=print-path)"
|
||||
if [[ -z "${GIT_EXECUTABLE}" ]]
|
||||
then
|
||||
odie "Can't find a working Git!"
|
||||
fi
|
||||
fi
|
||||
"${GIT_EXECUTABLE}" "$@"
|
||||
}
|
||||
|
@ -275,22 +275,21 @@ module Homebrew
|
||||
if total_problems_count.positive?
|
||||
puts new_formula_problem_lines.map { |s| " #{s}" }
|
||||
|
||||
errors_summary = "#{total_problems_count} #{Utils.pluralize("problem", total_problems_count)}"
|
||||
errors_summary = Utils.pluralize("problem", total_problems_count, include_count: true)
|
||||
|
||||
error_sources = []
|
||||
if formula_count.positive?
|
||||
error_sources << "#{formula_count} #{Utils.pluralize("formula", formula_count, plural: "e")}"
|
||||
error_sources << Utils.pluralize("formula", formula_count, plural: "e", include_count: true)
|
||||
end
|
||||
error_sources << "#{cask_count} #{Utils.pluralize("cask", cask_count)}" if cask_count.positive?
|
||||
error_sources << "#{tap_count} #{Utils.pluralize("tap", tap_count)}" if tap_count.positive?
|
||||
error_sources << Utils.pluralize("cask", cask_count, include_count: true) if cask_count.positive?
|
||||
error_sources << Utils.pluralize("tap", tap_count, include_count: true) if tap_count.positive?
|
||||
|
||||
errors_summary += " in #{error_sources.to_sentence}" if error_sources.any?
|
||||
|
||||
errors_summary += " detected"
|
||||
|
||||
if corrected_problem_count.positive?
|
||||
noun = Utils.pluralize("problem", corrected_problem_count)
|
||||
errors_summary += ", #{corrected_problem_count} #{noun} corrected"
|
||||
errors_summary += ", #{Utils.pluralize("problem", corrected_problem_count, include_count: true)} corrected"
|
||||
end
|
||||
|
||||
ofail errors_summary
|
||||
|
@ -64,7 +64,8 @@ module Homebrew
|
||||
results[user] = scan_repositories(repos, user, args)
|
||||
grand_totals[user] = total(results[user])
|
||||
|
||||
puts "#{user} contributed #{grand_totals[user].values.sum} times #{time_period(args)}."
|
||||
puts "#{user} contributed #{Utils.pluralize("time", grand_totals[user].values.sum,
|
||||
include_count: true)} #{time_period(args)}."
|
||||
puts generate_csv(T.must(user), results[user], grand_totals[user]) if args.csv?
|
||||
return
|
||||
end
|
||||
@ -79,7 +80,8 @@ module Homebrew
|
||||
results[username] = scan_repositories(repos, username, args)
|
||||
grand_totals[username] = total(results[username])
|
||||
|
||||
puts "#{username} contributed #{grand_totals[username].values.sum} times #{time_period(args)}."
|
||||
puts "#{username} contributed #{Utils.pluralize("time", grand_totals[username].values.sum,
|
||||
include_count: true)} #{time_period(args)}."
|
||||
end
|
||||
|
||||
puts generate_maintainers_csv(grand_totals) if args.csv?
|
||||
|
@ -22,6 +22,8 @@ module Homebrew
|
||||
description: "Download the bottles but don't upload them."
|
||||
switch "--no-commit",
|
||||
description: "Do not generate a new commit before uploading."
|
||||
switch "--no-cherry-pick",
|
||||
description: "Do not cherry-pick commits from the pull request branch."
|
||||
switch "-n", "--dry-run",
|
||||
description: "Print what would be done rather than doing it."
|
||||
switch "--clean",
|
||||
@ -447,10 +449,16 @@ module Homebrew
|
||||
ohai "Fetching #{tap} pull request ##{pr}"
|
||||
Dir.mktmpdir pr do |dir|
|
||||
cd dir do
|
||||
original_commit = ENV["GITHUB_SHA"].presence || tap.path.git_head
|
||||
current_branch_head = ENV["GITHUB_SHA"] || tap.git_head
|
||||
original_commit = if args.no_cherry_pick?
|
||||
# TODO: Handle the case where `merge-base` returns multiple commits.
|
||||
Utils.safe_popen_read("git", "-C", tap.path, "merge-base", "origin/HEAD", current_branch_head).strip
|
||||
else
|
||||
current_branch_head
|
||||
end
|
||||
|
||||
unless args.no_commit?
|
||||
cherry_pick_pr!(user, repo, pr, path: tap.path, args: args)
|
||||
cherry_pick_pr!(user, repo, pr, path: tap.path, args: args) unless args.no_cherry_pick?
|
||||
if !args.no_autosquash? && !args.dry_run?
|
||||
autosquash!(original_commit, tap: tap,
|
||||
verbose: args.verbose?, resolve: args.resolve?, reason: args.message)
|
||||
|
@ -908,7 +908,7 @@ module Homebrew
|
||||
0
|
||||
end
|
||||
|
||||
"#{tap.path} (#{cask_count} #{Utils.pluralize("cask", cask_count)})"
|
||||
"#{tap.path} (#{Utils.pluralize("cask", cask_count, include_count: true)})"
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -491,10 +491,13 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy
|
||||
end
|
||||
end
|
||||
|
||||
filename = content_disposition.filename if filename.blank?
|
||||
next if filename.blank?
|
||||
|
||||
# Servers may include '/' in their Content-Disposition filename header. Take only the basename of this, because:
|
||||
# - Unpacking code assumes this is a single file - not something living in a subdirectory.
|
||||
# - Directory traversal attacks are possible without limiting this to just the basename.
|
||||
File.basename(filename || content_disposition.filename)
|
||||
File.basename(filename)
|
||||
end
|
||||
|
||||
filenames = lines.map(&parse_content_disposition).compact
|
||||
|
@ -1,8 +1,5 @@
|
||||
# typed: strict
|
||||
|
||||
module GitRepositoryExtension
|
||||
include Kernel
|
||||
|
||||
sig { params(args: T.any(String, Pathname)).returns(Pathname) }
|
||||
def join(*args); end
|
||||
requires_ancestor { Pathname }
|
||||
end
|
||||
|
@ -1,13 +0,0 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
module HashValidator
|
||||
refine Hash do
|
||||
def assert_valid_keys!(*valid_keys)
|
||||
unknown_keys = keys - valid_keys
|
||||
return if unknown_keys.empty?
|
||||
|
||||
raise ArgumentError, "invalid keys: #{unknown_keys.map(&:inspect).join(", ")}"
|
||||
end
|
||||
end
|
||||
end
|
@ -1,6 +0,0 @@
|
||||
# typed: strict
|
||||
|
||||
class Hash
|
||||
sig { params(valid_keys: T.untyped).void }
|
||||
def assert_valid_keys!(*valid_keys); end
|
||||
end
|
@ -199,13 +199,13 @@ module Kernel
|
||||
if seconds > 59
|
||||
minutes = seconds / 60
|
||||
seconds %= 60
|
||||
res = +"#{minutes} #{Utils.pluralize("minute", minutes)}"
|
||||
res = +Utils.pluralize("minute", minutes, include_count: true)
|
||||
return res.freeze if seconds.zero?
|
||||
|
||||
res << " "
|
||||
end
|
||||
|
||||
res << "#{seconds} #{Utils.pluralize("second", seconds)}"
|
||||
res << Utils.pluralize("second", seconds, include_count: true)
|
||||
res.freeze
|
||||
end
|
||||
|
||||
|
6
Library/Homebrew/extend/object.rbi
Normal file
6
Library/Homebrew/extend/object.rbi
Normal file
@ -0,0 +1,6 @@
|
||||
# typed: strict
|
||||
|
||||
class Object
|
||||
sig { returns(T::Boolean) }
|
||||
def present?; end
|
||||
end
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "simulate_system"
|
||||
@ -9,17 +9,15 @@ module OnSystem
|
||||
ARCH_OPTIONS = [:intel, :arm].freeze
|
||||
BASE_OS_OPTIONS = [:macos, :linux].freeze
|
||||
|
||||
module_function
|
||||
|
||||
sig { params(arch: Symbol).returns(T::Boolean) }
|
||||
def arch_condition_met?(arch)
|
||||
def self.arch_condition_met?(arch)
|
||||
raise ArgumentError, "Invalid arch condition: #{arch.inspect}" if ARCH_OPTIONS.exclude?(arch)
|
||||
|
||||
arch == Homebrew::SimulateSystem.current_arch
|
||||
end
|
||||
|
||||
sig { params(os_name: Symbol, or_condition: T.nilable(Symbol)).returns(T::Boolean) }
|
||||
def os_condition_met?(os_name, or_condition = nil)
|
||||
def self.os_condition_met?(os_name, or_condition = nil)
|
||||
return Homebrew::SimulateSystem.send("simulating_or_running_on_#{os_name}?") if BASE_OS_OPTIONS.include?(os_name)
|
||||
|
||||
raise ArgumentError, "Invalid OS condition: #{os_name.inspect}" unless MacOSVersions::SYMBOLS.key?(os_name)
|
||||
@ -46,17 +44,17 @@ module OnSystem
|
||||
end
|
||||
|
||||
sig { params(method_name: Symbol).returns(Symbol) }
|
||||
def condition_from_method_name(method_name)
|
||||
def self.condition_from_method_name(method_name)
|
||||
method_name.to_s.sub(/^on_/, "").to_sym
|
||||
end
|
||||
|
||||
sig { params(base: Class).void }
|
||||
def setup_arch_methods(base)
|
||||
def self.setup_arch_methods(base)
|
||||
ARCH_OPTIONS.each do |arch|
|
||||
base.define_method("on_#{arch}") do |&block|
|
||||
@on_system_blocks_exist = true
|
||||
|
||||
return unless OnSystem.arch_condition_met? OnSystem.condition_from_method_name(__method__)
|
||||
return unless OnSystem.arch_condition_met? OnSystem.condition_from_method_name(T.must(__method__))
|
||||
|
||||
@called_in_on_system_block = true
|
||||
result = block.call
|
||||
@ -75,12 +73,12 @@ module OnSystem
|
||||
end
|
||||
|
||||
sig { params(base: Class).void }
|
||||
def setup_base_os_methods(base)
|
||||
def self.setup_base_os_methods(base)
|
||||
BASE_OS_OPTIONS.each do |base_os|
|
||||
base.define_method("on_#{base_os}") do |&block|
|
||||
@on_system_blocks_exist = true
|
||||
|
||||
return unless OnSystem.os_condition_met? OnSystem.condition_from_method_name(__method__)
|
||||
return unless OnSystem.os_condition_met? OnSystem.condition_from_method_name(T.must(__method__))
|
||||
|
||||
@called_in_on_system_block = true
|
||||
result = block.call
|
||||
@ -118,12 +116,12 @@ module OnSystem
|
||||
end
|
||||
|
||||
sig { params(base: Class).void }
|
||||
def setup_macos_methods(base)
|
||||
def self.setup_macos_methods(base)
|
||||
MacOSVersions::SYMBOLS.each_key do |os_name|
|
||||
base.define_method("on_#{os_name}") do |or_condition = nil, &block|
|
||||
@on_system_blocks_exist = true
|
||||
|
||||
os_condition = OnSystem.condition_from_method_name __method__
|
||||
os_condition = OnSystem.condition_from_method_name T.must(__method__)
|
||||
return unless OnSystem.os_condition_met? os_condition, or_condition
|
||||
|
||||
@called_in_on_system_block = true
|
||||
|
@ -11,8 +11,6 @@ module UnpackStrategy
|
||||
include UnpackStrategy
|
||||
include SystemCommand::Mixin
|
||||
|
||||
using Magic
|
||||
|
||||
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
|
||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||
with_env(TZ: "UTC") do
|
||||
|
@ -1,9 +1,5 @@
|
||||
# typed: strict
|
||||
|
||||
module UnpackStrategy
|
||||
class Zip
|
||||
module MacOSZipExtension
|
||||
module UnpackStrategy::Zip::MacOSZipExtension
|
||||
include Kernel
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -343,14 +343,24 @@ class Pathname
|
||||
chmod saved_perms if saved_perms
|
||||
end
|
||||
|
||||
# @private
|
||||
def which_install_info
|
||||
@which_install_info ||=
|
||||
if File.executable?("/usr/bin/install-info")
|
||||
"/usr/bin/install-info"
|
||||
elsif Formula["texinfo"].any_version_installed?
|
||||
Formula["texinfo"].opt_bin/"install-info"
|
||||
end
|
||||
end
|
||||
|
||||
# @private
|
||||
def install_info
|
||||
quiet_system "/usr/bin/install-info", "--quiet", to_s, "#{dirname}/dir"
|
||||
quiet_system(which_install_info, "--quiet", to_s, "#{dirname}/dir")
|
||||
end
|
||||
|
||||
# @private
|
||||
def uninstall_info
|
||||
quiet_system "/usr/bin/install-info", "--delete", "--quiet", to_s, "#{dirname}/dir"
|
||||
quiet_system(which_install_info, "--delete", "--quiet", to_s, "#{dirname}/dir")
|
||||
end
|
||||
|
||||
# Writes an exec script in this folder for each target pathname.
|
||||
@ -456,6 +466,32 @@ class Pathname
|
||||
def rpaths
|
||||
[]
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def magic_number
|
||||
@magic_number ||= if directory?
|
||||
""
|
||||
else
|
||||
# Length of the longest regex (currently Tar).
|
||||
max_magic_number_length = 262
|
||||
# FIXME: The `T.let` is a workaround until we have https://github.com/sorbet/sorbet/pull/6865
|
||||
T.let(binread(max_magic_number_length), T.nilable(String)) || ""
|
||||
end
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def file_type
|
||||
@file_type ||= system_command("file", args: ["-b", self], print_stderr: false)
|
||||
.stdout.chomp
|
||||
end
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def zipinfo
|
||||
@zipinfo ||= system_command("zipinfo", args: ["-1", self], print_stderr: false)
|
||||
.stdout
|
||||
.encode(Encoding::UTF_8, invalid: :replace)
|
||||
.split("\n")
|
||||
end
|
||||
end
|
||||
|
||||
require "extend/os/pathname"
|
||||
|
@ -1,19 +1,9 @@
|
||||
# typed: strict
|
||||
|
||||
module DiskUsageExtension
|
||||
include Kernel
|
||||
|
||||
def exist?; end
|
||||
|
||||
def symlink?; end
|
||||
|
||||
def resolved_path; end
|
||||
requires_ancestor { Pathname }
|
||||
end
|
||||
|
||||
module ObserverPathnameExtension
|
||||
include Kernel
|
||||
|
||||
def dirname; end
|
||||
|
||||
def basename; end
|
||||
requires_ancestor { Pathname }
|
||||
end
|
||||
|
@ -466,6 +466,16 @@ module Homebrew
|
||||
"They must not be upgraded to version 7.11 or newer."
|
||||
end
|
||||
|
||||
def audit_keg_only_reason
|
||||
return unless @core_tap
|
||||
return unless formula.keg_only?
|
||||
|
||||
keg_only_message = text.to_s.match(/keg_only\s+["'](.*)["']/)&.captures&.first
|
||||
return unless keg_only_message&.include?("HOMEBREW_PREFIX")
|
||||
|
||||
problem "`keg_only` reason should not include `HOMEBREW_PREFIX` as it creates confusing `brew info` output."
|
||||
end
|
||||
|
||||
def audit_versioned_keg_only
|
||||
return unless @versioned_formula
|
||||
return unless @core_tap
|
||||
|
@ -414,9 +414,9 @@ class FormulaInstaller
|
||||
options = display_options(formula).join(" ")
|
||||
oh1 "Installing #{Formatter.identifier(formula.full_name)} #{options}".strip if show_header?
|
||||
|
||||
if formula.tap&.should_report_analytics?
|
||||
action = "#{formula.full_name} #{options}".strip
|
||||
Utils::Analytics.report_event(:formula_install, action, on_request: installed_on_request?)
|
||||
if (tap = formula.tap) && tap.should_report_analytics?
|
||||
Utils::Analytics.report_event(:formula_install, package_name: formula.name, tap_name: tap.name,
|
||||
on_request: installed_on_request?, options: options)
|
||||
end
|
||||
|
||||
self.class.attempted << formula
|
||||
|
@ -326,8 +326,8 @@ module Homebrew
|
||||
|
||||
if dry_run
|
||||
if (formulae_name_to_install = formulae_to_install.map(&:name))
|
||||
plural = Utils.pluralize("formula", formulae_name_to_install.count, plural: "e")
|
||||
ohai "Would install #{formulae_name_to_install.count} #{plural}:"
|
||||
ohai "Would install #{Utils.pluralize("formula", formulae_name_to_install.count,
|
||||
plural: "e", include_count: true)}:"
|
||||
puts formulae_name_to_install.join(" ")
|
||||
|
||||
formula_installers.each do |fi|
|
||||
@ -355,8 +355,8 @@ module Homebrew
|
||||
def print_dry_run_dependencies(formula, dependencies, &block)
|
||||
return if dependencies.empty?
|
||||
|
||||
plural = Utils.pluralize("dependenc", dependencies.count, plural: "ies", singular: "y")
|
||||
ohai "Would install #{dependencies.count} #{plural} for #{formula.name}:"
|
||||
ohai "Would install #{Utils.pluralize("dependenc", dependencies.count, plural: "ies", singular: "y",
|
||||
include_count: true)} for #{formula.name}:"
|
||||
formula_names = dependencies.map(&:first).map(&:to_formula).map(&block)
|
||||
puts formula_names.join(" ")
|
||||
end
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "keg_relocate"
|
||||
@ -524,8 +524,8 @@ class Keg
|
||||
end
|
||||
|
||||
def delete_pyc_files!
|
||||
find { |pn| pn.delete if PYC_EXTENSIONS.include?(pn.extname) }
|
||||
find { |pn| FileUtils.rm_rf pn if pn.basename.to_s == "__pycache__" }
|
||||
path.find { |pn| pn.delete if PYC_EXTENSIONS.include?(pn.extname) }
|
||||
path.find { |pn| FileUtils.rm_rf pn if pn.basename.to_s == "__pycache__" }
|
||||
end
|
||||
|
||||
def binary_executable_or_library_files
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Performs {Formula#mktemp}'s functionality, and tracks the results.
|
||||
@ -70,7 +70,7 @@ class Mktemp
|
||||
begin
|
||||
chown(nil, group_id, @tmpdir)
|
||||
rescue Errno::EPERM
|
||||
opoo "Failed setting group \"#{Etc.getgrgid(group_id).name}\" on #{@tmpdir}"
|
||||
opoo "Failed setting group \"#{T.must(Etc.getgrgid(group_id)).name}\" on #{@tmpdir}"
|
||||
end
|
||||
|
||||
begin
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
# A formula option.
|
||||
|
8
Library/Homebrew/options.rbi
Normal file
8
Library/Homebrew/options.rbi
Normal file
@ -0,0 +1,8 @@
|
||||
# typed: strict
|
||||
|
||||
class Options
|
||||
# This is a workaround to enable `alias to_ary to_a`
|
||||
# @see https://github.com/sorbet/sorbet/issues/2378#issuecomment-569474238
|
||||
sig { returns(T::Array[Option]) }
|
||||
def to_a; end
|
||||
end
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
# {Pathname} extension for dealing with ELF files.
|
||||
|
5
Library/Homebrew/os/linux/elf.rbi
Normal file
5
Library/Homebrew/os/linux/elf.rbi
Normal file
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
|
||||
module ELFShim
|
||||
requires_ancestor { Pathname }
|
||||
end
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "macho"
|
||||
|
5
Library/Homebrew/os/mac/mach.rbi
Normal file
5
Library/Homebrew/os/mac/mach.rbi
Normal file
@ -0,0 +1,5 @@
|
||||
# typed: strict
|
||||
|
||||
module MachOShim
|
||||
include Kernel
|
||||
end
|
@ -45,7 +45,7 @@ module OS
|
||||
sig { returns(T.self_type) }
|
||||
def strip_patch
|
||||
# Big Sur is 11.x but Catalina is 10.15.x.
|
||||
if major >= 11
|
||||
if T.must(major) >= 11
|
||||
self.class.new(major.to_s)
|
||||
else
|
||||
major_minor
|
||||
|
@ -1,10 +0,0 @@
|
||||
# typed: strict
|
||||
|
||||
module OS
|
||||
module Mac
|
||||
class Version
|
||||
sig { returns(Token) }
|
||||
def major; end
|
||||
end
|
||||
end
|
||||
end
|
@ -36,7 +36,15 @@ module RuboCop
|
||||
end
|
||||
|
||||
def toplevel_stanzas
|
||||
@toplevel_stanzas ||= stanzas.select(&:toplevel_stanza?)
|
||||
# If a `cask` block only contains one stanza, it is that stanza's direct parent,
|
||||
# otherwise stanzas are grouped in a block and `cask` is that block's parent.
|
||||
is_toplevel_stanza = if cask_body.begin_block?
|
||||
->(stanza) { stanza.parent_node.parent.cask_block? }
|
||||
else
|
||||
->(stanza) { stanza.parent_node.cask_block? }
|
||||
end
|
||||
|
||||
@toplevel_stanzas ||= stanzas.select(&is_toplevel_stanza)
|
||||
end
|
||||
|
||||
def sorted_toplevel_stanzas
|
||||
|
@ -52,10 +52,6 @@ module RuboCop
|
||||
stanza_group == other.stanza_group
|
||||
end
|
||||
|
||||
def toplevel_stanza?
|
||||
parent_node.cask_block? || parent_node.parent.cask_block?
|
||||
end
|
||||
|
||||
def ==(other)
|
||||
self.class == other.class && stanza_node == other.stanza_node
|
||||
end
|
||||
|
@ -17,6 +17,8 @@ module RuboCop
|
||||
def_node_matcher :cask_block?, "(block (send nil? :cask _) args ...)"
|
||||
def_node_matcher :arch_variable?, "(lvasgn _ (send nil? :on_arch_conditional ...))"
|
||||
|
||||
def_node_matcher :begin_block?, "(begin ...)"
|
||||
|
||||
def stanza?
|
||||
return true if arch_variable?
|
||||
|
||||
|
88
Library/Homebrew/sorbet/rbi/gems/stackprof@0.2.24.rbi
Normal file
88
Library/Homebrew/sorbet/rbi/gems/stackprof@0.2.24.rbi
Normal file
@ -0,0 +1,88 @@
|
||||
# typed: true
|
||||
|
||||
# DO NOT EDIT MANUALLY
|
||||
# This is an autogenerated file for types exported from the `stackprof` gem.
|
||||
# Please instead update this file by running `bin/tapioca gem stackprof`.
|
||||
|
||||
module StackProf
|
||||
class << self
|
||||
def results(*_arg0); end
|
||||
def run(*_arg0); end
|
||||
def running?; end
|
||||
def sample; end
|
||||
def start(*_arg0); end
|
||||
def stop; end
|
||||
def use_postponed_job!; end
|
||||
end
|
||||
end
|
||||
|
||||
class StackProf::Middleware
|
||||
def initialize(app, options = T.unsafe(nil)); end
|
||||
|
||||
def call(env); end
|
||||
|
||||
class << self
|
||||
def enabled; end
|
||||
def enabled=(_arg0); end
|
||||
def enabled?(env); end
|
||||
def interval; end
|
||||
def interval=(_arg0); end
|
||||
def metadata; end
|
||||
def metadata=(_arg0); end
|
||||
def mode; end
|
||||
def mode=(_arg0); end
|
||||
def path; end
|
||||
def path=(_arg0); end
|
||||
def raw; end
|
||||
def raw=(_arg0); end
|
||||
def save; end
|
||||
end
|
||||
end
|
||||
|
||||
class StackProf::Report
|
||||
def initialize(data); end
|
||||
|
||||
def +(other); end
|
||||
def add_lines(a, b); end
|
||||
def convert_to_d3_flame_graph_format(name, stacks, depth); end
|
||||
def data; end
|
||||
def files; end
|
||||
def flamegraph_row(f, x, y, weight, addr); end
|
||||
def flamegraph_stacks(raw); end
|
||||
def frames(sort_by_total = T.unsafe(nil)); end
|
||||
def max_samples; end
|
||||
def modeline; end
|
||||
def normalized_frames; end
|
||||
def overall_samples; end
|
||||
def print_alphabetical_flamegraph(f = T.unsafe(nil), skip_common = T.unsafe(nil)); end
|
||||
def print_callgrind(f = T.unsafe(nil)); end
|
||||
def print_d3_flamegraph(f = T.unsafe(nil), skip_common = T.unsafe(nil)); end
|
||||
def print_debug; end
|
||||
def print_dump(f = T.unsafe(nil)); end
|
||||
def print_file(filter, f = T.unsafe(nil)); end
|
||||
def print_files(sort_by_total = T.unsafe(nil), limit = T.unsafe(nil), f = T.unsafe(nil)); end
|
||||
def print_flamegraph(f, skip_common, alphabetical = T.unsafe(nil)); end
|
||||
def print_graphviz(options = T.unsafe(nil), f = T.unsafe(nil)); end
|
||||
def print_json(f = T.unsafe(nil)); end
|
||||
def print_method(name, f = T.unsafe(nil)); end
|
||||
def print_stackcollapse; end
|
||||
def print_text(sort_by_total = T.unsafe(nil), limit = T.unsafe(nil), select_files = T.unsafe(nil), reject_files = T.unsafe(nil), select_names = T.unsafe(nil), reject_names = T.unsafe(nil), f = T.unsafe(nil)); end
|
||||
def print_timeline_flamegraph(f = T.unsafe(nil), skip_common = T.unsafe(nil)); end
|
||||
def version; end
|
||||
def walk_method(name); end
|
||||
|
||||
private
|
||||
|
||||
def callers_for(addr); end
|
||||
def root_frames; end
|
||||
def source_display(f, file, lines, range = T.unsafe(nil)); end
|
||||
|
||||
class << self
|
||||
def from_file(file); end
|
||||
def from_json(json); end
|
||||
def parse_json(json); end
|
||||
end
|
||||
end
|
||||
|
||||
StackProf::Report::MARSHAL_SIGNATURE = T.let(T.unsafe(nil), String)
|
||||
StackProf::VERSION = T.let(T.unsafe(nil), String)
|
@ -6469,6 +6469,8 @@ end
|
||||
class RuboCop::AST::Node
|
||||
def arch_variable?(param0=T.unsafe(nil)); end
|
||||
|
||||
def begin_block?(param0=T.unsafe(nil)); end
|
||||
|
||||
def block_args(param0=T.unsafe(nil)); end
|
||||
|
||||
def block_body(param0=T.unsafe(nil)); end
|
||||
|
@ -4,7 +4,6 @@
|
||||
|
||||
# typed: false
|
||||
|
||||
module ::StackProf; end
|
||||
module T::InterfaceWrapper::Helpers; end
|
||||
module T::Private::Abstract::Hooks; end
|
||||
module T::Private::Methods::MethodHooks; end
|
||||
|
@ -1,23 +0,0 @@
|
||||
# typed: strict
|
||||
|
||||
# This file contains temporary definitions for fixes that have
|
||||
# been submitted upstream to https://github.com/sorbet/sorbet.
|
||||
|
||||
class Module
|
||||
# https://github.com/sorbet/sorbet/pull/3732
|
||||
sig do
|
||||
params(
|
||||
arg0: T.any(Symbol, String),
|
||||
arg1: T.any(Proc, Method, UnboundMethod)
|
||||
)
|
||||
.returns(Symbol)
|
||||
end
|
||||
sig do
|
||||
params(
|
||||
arg0: T.any(Symbol, String),
|
||||
blk: T.proc.bind(T.untyped).returns(T.untyped),
|
||||
)
|
||||
.returns(Symbol)
|
||||
end
|
||||
def define_method(arg0, arg1=T.unsafe(nil), &blk); end
|
||||
end
|
@ -7,7 +7,6 @@ require "shellwords"
|
||||
|
||||
require "extend/io"
|
||||
require "extend/predicable"
|
||||
require "extend/hash_validator"
|
||||
|
||||
require "extend/time"
|
||||
|
||||
|
@ -475,15 +475,15 @@ class Tap
|
||||
contents = []
|
||||
|
||||
if (command_count = command_files.count).positive?
|
||||
contents << "#{command_count} #{Utils.pluralize("command", command_count)}"
|
||||
contents << Utils.pluralize("command", command_count, include_count: true)
|
||||
end
|
||||
|
||||
if (cask_count = cask_files.count).positive?
|
||||
contents << "#{cask_count} #{Utils.pluralize("cask", cask_count)}"
|
||||
contents << Utils.pluralize("cask", cask_count, include_count: true)
|
||||
end
|
||||
|
||||
if (formula_count = formula_files.count).positive?
|
||||
contents << "#{formula_count} #{Utils.pluralize("formula", formula_count, plural: "e")}"
|
||||
contents << Utils.pluralize("formula", formula_count, plural: "e", include_count: true)
|
||||
end
|
||||
|
||||
contents
|
||||
|
@ -1,60 +0,0 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
describe Cask::Cmd::Fetch, :cask do
|
||||
let(:local_transmission) do
|
||||
Cask::CaskLoader.load(cask_path("local-transmission"))
|
||||
end
|
||||
|
||||
let(:local_caffeine) do
|
||||
Cask::CaskLoader.load(cask_path("local-caffeine"))
|
||||
end
|
||||
|
||||
it "allows downloading the installer of a Cask" do
|
||||
transmission_location = CurlDownloadStrategy.new(
|
||||
local_transmission.url.to_s, local_transmission.token, local_transmission.version,
|
||||
cache: Cask::Cache.path, **local_transmission.url.specs
|
||||
).cached_location
|
||||
caffeine_location = CurlDownloadStrategy.new(
|
||||
local_caffeine.url.to_s, local_caffeine.token, local_caffeine.version,
|
||||
cache: Cask::Cache.path, **local_caffeine.url.specs
|
||||
).cached_location
|
||||
|
||||
expect(transmission_location).not_to exist
|
||||
expect(caffeine_location).not_to exist
|
||||
|
||||
described_class.run("local-transmission", "local-caffeine")
|
||||
|
||||
expect(transmission_location).to exist
|
||||
expect(caffeine_location).to exist
|
||||
end
|
||||
|
||||
it "prevents double fetch (without nuking existing installation)" do
|
||||
cached_location = Cask::Download.new(local_transmission).fetch
|
||||
|
||||
old_ctime = File.stat(cached_location).ctime
|
||||
|
||||
described_class.run("local-transmission", "--no-quarantine")
|
||||
new_ctime = File.stat(cached_location).ctime
|
||||
|
||||
expect(old_ctime.to_i).to eq(new_ctime.to_i)
|
||||
end
|
||||
|
||||
it "allows double fetch with --force" do
|
||||
cached_location = Cask::Download.new(local_transmission).fetch
|
||||
|
||||
old_ctime = File.stat(cached_location).ctime
|
||||
sleep(1)
|
||||
|
||||
described_class.run("local-transmission", "--force", "--no-quarantine")
|
||||
new_ctime = File.stat(cached_location).ctime
|
||||
|
||||
expect(new_ctime.to_i).to be > old_ctime.to_i
|
||||
end
|
||||
|
||||
it "properly handles Casks that are not present" do
|
||||
expect do
|
||||
described_class.run("notacask")
|
||||
end.to raise_error(Cask::CaskUnavailableError)
|
||||
end
|
||||
end
|
@ -2,7 +2,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "cask/cmd/audit"
|
||||
require "cask/cmd/fetch"
|
||||
require "cask/cmd/install"
|
||||
require "cask/cask_loader"
|
||||
require "cask/download"
|
||||
@ -29,7 +28,8 @@ describe Cask::Quarantine, :cask do
|
||||
end
|
||||
|
||||
it "quarantines Cask fetches" do
|
||||
Cask::Cmd::Fetch.run("local-transmission")
|
||||
download = Cask::Download.new(Cask::CaskLoader.load("local-transmission"), quarantine: true)
|
||||
download.fetch
|
||||
local_transmission = Cask::CaskLoader.load(cask_path("local-transmission"))
|
||||
cached_location = Cask::Download.new(local_transmission).fetch
|
||||
|
||||
@ -50,7 +50,8 @@ describe Cask::Quarantine, :cask do
|
||||
end
|
||||
|
||||
it "quarantines Cask installs even if the fetch was not" do
|
||||
Cask::Cmd::Fetch.run("local-transmission", "--no-quarantine")
|
||||
download = Cask::Download.new(Cask::CaskLoader.load("local-transmission"), quarantine: false)
|
||||
download.fetch
|
||||
|
||||
Cask::Cmd::Install.run("local-transmission")
|
||||
|
||||
@ -144,7 +145,8 @@ describe Cask::Quarantine, :cask do
|
||||
end
|
||||
|
||||
it "does not quarantine Cask fetches" do
|
||||
Cask::Cmd::Fetch.run("local-transmission", "--no-quarantine")
|
||||
download = Cask::Download.new(Cask::CaskLoader.load("local-transmission"), quarantine: false)
|
||||
download.fetch
|
||||
local_transmission = Cask::CaskLoader.load(cask_path("local-transmission"))
|
||||
cached_location = Cask::Download.new(local_transmission).fetch
|
||||
|
||||
@ -165,7 +167,8 @@ describe Cask::Quarantine, :cask do
|
||||
end
|
||||
|
||||
it "does not quarantine Cask installs even if the fetch was" do
|
||||
Cask::Cmd::Fetch.run("local-transmission")
|
||||
download = Cask::Download.new(Cask::CaskLoader.load("local-transmission"), quarantine: true)
|
||||
download.fetch
|
||||
|
||||
Cask::Cmd::Install.run("local-transmission", "--no-quarantine")
|
||||
|
||||
|
@ -249,6 +249,32 @@ describe Caveats do
|
||||
expect(caveats).to include("#{f.opt_share}/pkgconfig")
|
||||
end
|
||||
end
|
||||
|
||||
context "when joining different caveat types together" do
|
||||
let(:f) do
|
||||
formula do
|
||||
url "foo-1.0"
|
||||
keg_only "some reason"
|
||||
|
||||
def caveats
|
||||
"something else"
|
||||
end
|
||||
|
||||
service do
|
||||
run [bin/"cmd"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:caveats) { described_class.new(f).caveats }
|
||||
|
||||
it "adds the correct amount of new lines to the output" do
|
||||
expect(caveats).to include("something else")
|
||||
expect(caveats).to include("keg-only")
|
||||
expect(caveats).to include("if you don't want/need a background service")
|
||||
expect(caveats.count("\n")).to eq(9)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "shell completions" do
|
||||
|
@ -6,7 +6,7 @@ require "formula_installer"
|
||||
|
||||
describe Utils::Analytics do
|
||||
before do
|
||||
described_class.clear_additional_tags_cache
|
||||
described_class.clear_cache
|
||||
end
|
||||
|
||||
describe "::label_google" do
|
||||
@ -45,64 +45,68 @@ describe Utils::Analytics do
|
||||
end
|
||||
end
|
||||
|
||||
describe "::additional_tags_influx" do
|
||||
describe "::default_tags_influx" do
|
||||
let(:ci) { ", CI" if ENV["CI"] }
|
||||
|
||||
it "returns OS_VERSION and prefix when HOMEBREW_PREFIX is a custom prefix on intel" do
|
||||
expect(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once)
|
||||
expect(described_class.additional_tags_influx).to have_key(:prefix)
|
||||
expect(described_class.additional_tags_influx[:prefix]).to eq "custom-prefix"
|
||||
expect(described_class.default_tags_influx).to have_key(:prefix)
|
||||
expect(described_class.default_tags_influx[:prefix]).to eq "custom-prefix"
|
||||
end
|
||||
|
||||
it "returns OS_VERSION, ARM and prefix when HOMEBREW_PREFIX is a custom prefix on arm" do
|
||||
expect(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once)
|
||||
expect(described_class.additional_tags_influx).to have_key(:arch)
|
||||
expect(described_class.additional_tags_influx[:arch]).to eq HOMEBREW_PHYSICAL_PROCESSOR
|
||||
expect(described_class.additional_tags_influx).to have_key(:prefix)
|
||||
expect(described_class.additional_tags_influx[:prefix]).to eq "custom-prefix"
|
||||
expect(described_class.default_tags_influx).to have_key(:arch)
|
||||
expect(described_class.default_tags_influx[:arch]).to eq HOMEBREW_PHYSICAL_PROCESSOR
|
||||
expect(described_class.default_tags_influx).to have_key(:prefix)
|
||||
expect(described_class.default_tags_influx[:prefix]).to eq "custom-prefix"
|
||||
end
|
||||
|
||||
it "returns OS_VERSION, Rosetta and prefix when HOMEBREW_PREFIX is a custom prefix on Rosetta", :needs_macos do
|
||||
expect(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once)
|
||||
expect(described_class.additional_tags_influx).to have_key(:prefix)
|
||||
expect(described_class.additional_tags_influx[:prefix]).to eq "custom-prefix"
|
||||
expect(described_class.default_tags_influx).to have_key(:prefix)
|
||||
expect(described_class.default_tags_influx[:prefix]).to eq "custom-prefix"
|
||||
end
|
||||
|
||||
it "does not include prefix when HOMEBREW_PREFIX is the default prefix" do
|
||||
expect(Homebrew).to receive(:default_prefix?).and_return(true).at_least(:once)
|
||||
expect(described_class.additional_tags_influx).to have_key(:prefix)
|
||||
expect(described_class.additional_tags_influx[:prefix]).to eq HOMEBREW_PREFIX.to_s
|
||||
expect(described_class.default_tags_influx).to have_key(:prefix)
|
||||
expect(described_class.default_tags_influx[:prefix]).to eq HOMEBREW_PREFIX.to_s
|
||||
end
|
||||
|
||||
it "includes CI when ENV['CI'] is set" do
|
||||
ENV["CI"] = "1"
|
||||
expect(described_class.additional_tags_influx).to have_key(:ci)
|
||||
expect(described_class.default_tags_influx).to have_key(:ci)
|
||||
end
|
||||
|
||||
it "includes developer when ENV['HOMEBREW_DEVELOPER'] is set" do
|
||||
expect(Homebrew::EnvConfig).to receive(:developer?).and_return(true)
|
||||
expect(described_class.additional_tags_influx).to have_key(:developer)
|
||||
expect(described_class.default_tags_influx).to have_key(:developer)
|
||||
end
|
||||
end
|
||||
|
||||
describe "::report_event" do
|
||||
let(:f) { formula { url "foo-1.0" } }
|
||||
let(:options) { ["--head"].join }
|
||||
let(:action) { "#{f.full_name} #{options}".strip }
|
||||
let(:package_name) { f.name }
|
||||
let(:tap_name) { f.tap.name }
|
||||
let(:on_request) { false }
|
||||
let(:options) { "--HEAD" }
|
||||
|
||||
context "when ENV vars is set" do
|
||||
it "returns nil when HOMEBREW_NO_ANALYTICS is true" do
|
||||
ENV["HOMEBREW_NO_ANALYTICS"] = "true"
|
||||
expect(described_class).not_to receive(:report_google)
|
||||
expect(described_class).not_to receive(:report_influx)
|
||||
described_class.report_event(:install, action)
|
||||
described_class.report_event(:install, package_name: package_name, tap_name: tap_name,
|
||||
on_request: on_request, options: options)
|
||||
end
|
||||
|
||||
it "returns nil when HOMEBREW_NO_ANALYTICS_THIS_RUN is true" do
|
||||
ENV["HOMEBREW_NO_ANALYTICS_THIS_RUN"] = "true"
|
||||
expect(described_class).not_to receive(:report_google)
|
||||
expect(described_class).not_to receive(:report_influx)
|
||||
described_class.report_event(:install, action)
|
||||
described_class.report_event(:install, package_name: package_name, tap_name: tap_name,
|
||||
on_request: on_request, options: options)
|
||||
end
|
||||
|
||||
it "returns nil when HOMEBREW_ANALYTICS_DEBUG is true" do
|
||||
@ -112,7 +116,8 @@ describe Utils::Analytics do
|
||||
expect(described_class).to receive(:report_google)
|
||||
expect(described_class).to receive(:report_influx)
|
||||
|
||||
described_class.report_event(:install, action)
|
||||
described_class.report_event(:install, package_name: package_name, tap_name: tap_name,
|
||||
on_request: on_request, options: options)
|
||||
end
|
||||
end
|
||||
|
||||
@ -120,40 +125,47 @@ describe Utils::Analytics do
|
||||
ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
|
||||
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
||||
ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
|
||||
expect(Homebrew::EnvConfig).to receive(:developer?).and_return(false)
|
||||
expect(described_class).to receive(:report_google).with(:event, hash_including(ea: action)).once
|
||||
expect(described_class).to receive(:report_influx).with(:install, "formula_name --head", false,
|
||||
hash_including(developer: false)).once
|
||||
described_class.report_event(:install, action)
|
||||
expect(described_class).to receive(:report_google).with(:event,
|
||||
hash_including(ea: "#{package_name} #{options}")).once
|
||||
expect(described_class).to receive(:report_influx).with(:install, hash_including(package_name: package_name,
|
||||
on_request: on_request)).once
|
||||
described_class.report_event(:install, package_name: package_name, tap_name: tap_name,
|
||||
on_request: on_request, options: options)
|
||||
end
|
||||
|
||||
it "sends to google twice on request" do
|
||||
ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
|
||||
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
||||
ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
|
||||
expect(Homebrew::EnvConfig).to receive(:developer?).and_return(false)
|
||||
expect(described_class).to receive(:report_google).with(:event, hash_including(ea: action, ec: :install)).once
|
||||
expect(described_class).to receive(:report_google).with(:event,
|
||||
hash_including(ea: action,
|
||||
hash_including(ea: "#{package_name} #{options}",
|
||||
ec: :install)).once
|
||||
expect(described_class).to receive(:report_google).with(:event,
|
||||
hash_including(ea: "#{package_name} #{options}",
|
||||
ec: :install_on_request)).once
|
||||
expect(described_class).to receive(:report_influx).with(:install, "formula_name --head", true,
|
||||
hash_including(developer: false)).once
|
||||
expect(described_class).to receive(:report_influx).with(:install,
|
||||
hash_including(package_name: package_name,
|
||||
on_request: true)).once
|
||||
|
||||
described_class.report_event(:install, action, on_request: true)
|
||||
described_class.report_event(:install, package_name: package_name, tap_name: tap_name,
|
||||
on_request: true, options: options)
|
||||
end
|
||||
end
|
||||
|
||||
describe "::report_influx" do
|
||||
let(:f) { formula { url "foo-1.0" } }
|
||||
let(:options) { ["--head"].join }
|
||||
let(:action) { "#{f.full_name} #{options}".strip }
|
||||
let(:package_name) { f.name }
|
||||
let(:tap_name) { f.tap.name }
|
||||
let(:on_request) { false }
|
||||
let(:options) { "--HEAD" }
|
||||
|
||||
it "outputs in debug mode" do
|
||||
ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
|
||||
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
||||
ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
|
||||
expect(described_class).to receive(:deferred_curl).once
|
||||
described_class.report_influx(:install, action, true, developer: true, CI: true)
|
||||
described_class.report_influx(:install, package_name: package_name, tap_name: tap_name, on_request: on_request,
|
||||
options: options)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,6 +70,12 @@ describe Utils do
|
||||
expect(described_class.pluralize("foo", 1, singular: "o", plural: "es")).to eq("fooo")
|
||||
expect(described_class.pluralize("foo", 2, singular: "o", plural: "es")).to eq("fooes")
|
||||
end
|
||||
|
||||
it "includes the count when requested" do
|
||||
expect(described_class.pluralize("foo", 0, include_count: true)).to eq("0 foos")
|
||||
expect(described_class.pluralize("foo", 1, include_count: true)).to eq("1 foo")
|
||||
expect(described_class.pluralize("foo", 2, include_count: true)).to eq("2 foos")
|
||||
end
|
||||
end
|
||||
|
||||
describe ".underscore" do
|
||||
|
@ -1,29 +1,8 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "system_command"
|
||||
|
||||
# Helper module for iterating over directory trees.
|
||||
#
|
||||
# @api private
|
||||
module PathnameEachDirectory
|
||||
refine Pathname do
|
||||
extend T::Sig
|
||||
|
||||
sig {
|
||||
type_parameters(:T)
|
||||
.params(
|
||||
_block: T.proc.params(path: Pathname).returns(T.type_parameter(:T)),
|
||||
).returns(T.type_parameter(:T))
|
||||
}
|
||||
def each_directory(&_block)
|
||||
find do |path|
|
||||
yield path if path.directory?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Module containing all available strategies for unpacking archives.
|
||||
#
|
||||
# @api private
|
||||
@ -33,38 +12,6 @@ module UnpackStrategy
|
||||
|
||||
include SystemCommand::Mixin
|
||||
|
||||
using PathnameEachDirectory
|
||||
|
||||
# Helper module for identifying the file type.
|
||||
module Magic
|
||||
# Length of the longest regex (currently Tar).
|
||||
MAX_MAGIC_NUMBER_LENGTH = 262
|
||||
private_constant :MAX_MAGIC_NUMBER_LENGTH
|
||||
|
||||
refine Pathname do
|
||||
def magic_number
|
||||
@magic_number ||= if directory?
|
||||
""
|
||||
else
|
||||
binread(MAX_MAGIC_NUMBER_LENGTH) || ""
|
||||
end
|
||||
end
|
||||
|
||||
def file_type
|
||||
@file_type ||= system_command("file", args: ["-b", self], print_stderr: false)
|
||||
.stdout.chomp
|
||||
end
|
||||
|
||||
def zipinfo
|
||||
@zipinfo ||= system_command("zipinfo", args: ["-1", self], print_stderr: false)
|
||||
.stdout
|
||||
.encode(Encoding::UTF_8, invalid: :replace)
|
||||
.split("\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
private_constant :Magic
|
||||
|
||||
def self.strategies
|
||||
@strategies ||= [
|
||||
Tar, # Needs to be before Bzip2/Gzip/Xz/Lzma/Zstd.
|
||||
@ -195,7 +142,7 @@ module UnpackStrategy
|
||||
end
|
||||
|
||||
# Ensure all extracted directories are writable.
|
||||
tmp_unpack_dir.each_directory do |path|
|
||||
each_directory(tmp_unpack_dir) do |path|
|
||||
next if path.writable?
|
||||
|
||||
FileUtils.chmod "u+w", path, verbose: verbose
|
||||
@ -208,6 +155,19 @@ module UnpackStrategy
|
||||
def dependencies
|
||||
[]
|
||||
end
|
||||
|
||||
# Helper method for iterating over directory trees.
|
||||
sig {
|
||||
params(
|
||||
pathname: Pathname,
|
||||
_block: T.proc.params(path: Pathname).void,
|
||||
).returns(T.nilable(Pathname))
|
||||
}
|
||||
def each_directory(pathname, &_block)
|
||||
pathname.find do |path|
|
||||
yield path if path.directory?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
require "unpack_strategy/air"
|
||||
|
@ -3,14 +3,3 @@
|
||||
module UnpackStrategy
|
||||
include Kernel
|
||||
end
|
||||
|
||||
class Pathname
|
||||
sig { returns(String) }
|
||||
def magic_number; end
|
||||
|
||||
sig { returns(String) }
|
||||
def file_type; end
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def zipinfo; end
|
||||
end
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".air"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
class Bazaar < Directory
|
||||
extend T::Sig
|
||||
|
||||
using Magic
|
||||
|
||||
def self.can_extract?(path)
|
||||
super && (path/".bzr").directory?
|
||||
end
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".bz2"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".cab"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
class Compress < Tar
|
||||
extend T::Sig
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".Z"]
|
||||
|
@ -6,8 +6,6 @@ require_relative "directory"
|
||||
module UnpackStrategy
|
||||
# Strategy for unpacking CVS repositories.
|
||||
class Cvs < Directory
|
||||
using Magic
|
||||
|
||||
def self.can_extract?(path)
|
||||
super && (path/"CVS").directory?
|
||||
end
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[]
|
||||
|
@ -1,4 +1,4 @@
|
||||
# typed: false
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "tempfile"
|
||||
@ -12,6 +12,8 @@ module UnpackStrategy
|
||||
|
||||
# Helper module for listing the contents of a volume mounted from a disk image.
|
||||
module Bom
|
||||
extend T::Sig
|
||||
|
||||
DMG_METADATA = Set.new(%w[
|
||||
.background
|
||||
.com.apple.timemachine.donotpresent
|
||||
@ -35,28 +37,25 @@ module UnpackStrategy
|
||||
end
|
||||
end
|
||||
|
||||
refine Pathname do
|
||||
extend T::Sig
|
||||
|
||||
# Check if path is considered disk image metadata.
|
||||
sig { returns(T::Boolean) }
|
||||
def dmg_metadata?
|
||||
DMG_METADATA.include?(cleanpath.ascend.to_a.last.to_s)
|
||||
sig { params(pathname: Pathname).returns(T::Boolean) }
|
||||
def self.dmg_metadata?(pathname)
|
||||
DMG_METADATA.include?(pathname.cleanpath.ascend.to_a.last.to_s)
|
||||
end
|
||||
|
||||
# Check if path is a symlink to a system directory (commonly to /Applications).
|
||||
sig { returns(T::Boolean) }
|
||||
def system_dir_symlink?
|
||||
symlink? && MacOS.system_dir?(dirname.join(readlink))
|
||||
sig { params(pathname: Pathname).returns(T::Boolean) }
|
||||
def self.system_dir_symlink?(pathname)
|
||||
pathname.symlink? && MacOS.system_dir?(pathname.dirname.join(pathname.readlink))
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def bom
|
||||
sig { params(pathname: Pathname).returns(String) }
|
||||
def self.bom(pathname)
|
||||
tries = 0
|
||||
result = loop do
|
||||
# We need to use `find` here instead of Ruby in order to properly handle
|
||||
# file names containing special characters, such as “e” + “´” vs. “é”.
|
||||
r = system_command("find", args: [".", "-print0"], chdir: self, print_stderr: false)
|
||||
r = system_command("find", args: [".", "-print0"], chdir: pathname, print_stderr: false)
|
||||
tries += 1
|
||||
|
||||
# Spurious bug on CI, which in most cases can be worked around by retrying.
|
||||
@ -65,31 +64,28 @@ module UnpackStrategy
|
||||
raise "Command `#{r.command.shelljoin}` was interrupted." if tries >= 3
|
||||
end
|
||||
|
||||
odebug "Command `#{result.command.shelljoin}` in '#{self}' took #{tries} tries." if tries > 1
|
||||
odebug "Command `#{result.command.shelljoin}` in '#{pathname}' took #{tries} tries." if tries > 1
|
||||
|
||||
bom_paths = result.stdout.split("\0")
|
||||
|
||||
raise EmptyError, self if bom_paths.empty?
|
||||
raise EmptyError, pathname if bom_paths.empty?
|
||||
|
||||
bom_paths
|
||||
.reject { |path| Pathname(path).dmg_metadata? }
|
||||
.reject { |path| (self/path).system_dir_symlink? }
|
||||
.reject { |path| dmg_metadata?(Pathname(path)) }
|
||||
.reject { |path| system_dir_symlink?(pathname/path) }
|
||||
.join("\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
private_constant :Bom
|
||||
|
||||
# Strategy for unpacking a volume mounted from a disk image.
|
||||
class Mount
|
||||
extend T::Sig
|
||||
|
||||
using Bom
|
||||
include UnpackStrategy
|
||||
|
||||
def eject(verbose: false)
|
||||
tries ||= 3
|
||||
|
||||
tries = 3
|
||||
begin
|
||||
return unless path.exist?
|
||||
|
||||
if tries > 1
|
||||
@ -126,26 +122,22 @@ module UnpackStrategy
|
||||
sleep 1
|
||||
retry
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
|
||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||
tries = 3
|
||||
bom = begin
|
||||
tries ||= 10
|
||||
|
||||
path.bom
|
||||
Bom.bom(path)
|
||||
rescue Bom::EmptyError => e
|
||||
raise "#{e} No retries left." if (tries -= 1).zero?
|
||||
raise e if (tries -= 1).zero?
|
||||
|
||||
sleep 1
|
||||
retry
|
||||
end
|
||||
|
||||
# TODO: Remove this if we actually ever hit this, i.e. if we actually found
|
||||
# some files after waiting longer for the DMG to be mounted.
|
||||
raise "BOM for path '#{path}' was empty but retrying for #{10 - tries} seconds helped." if tries != 10
|
||||
|
||||
Tempfile.open(["", ".bom"]) do |bomfile|
|
||||
bomfile.close
|
||||
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
class Executable < Uncompressed
|
||||
extend T::Sig
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".sh", ".bash"]
|
||||
|
@ -11,8 +11,6 @@ module UnpackStrategy
|
||||
include UnpackStrategy
|
||||
extend SystemCommand::Mixin
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[]
|
||||
|
@ -6,8 +6,6 @@ require_relative "directory"
|
||||
module UnpackStrategy
|
||||
# Strategy for unpacking Git repositories.
|
||||
class Git < Directory
|
||||
using Magic
|
||||
|
||||
def self.can_extract?(path)
|
||||
super && (path/".git").directory?
|
||||
end
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".gz"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
class Jar < Uncompressed
|
||||
extend T::Sig
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".apk", ".jar"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".lha", ".lzh"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
class LuaRock < Uncompressed
|
||||
extend T::Sig
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".rock"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".lz"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".lzma"]
|
||||
|
@ -6,8 +6,6 @@ require_relative "directory"
|
||||
module UnpackStrategy
|
||||
# Strategy for unpacking Mercurial repositories.
|
||||
class Mercurial < Directory
|
||||
using Magic
|
||||
|
||||
def self.can_extract?(path)
|
||||
super && (path/".hg").directory?
|
||||
end
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
class MicrosoftOfficeXml < Uncompressed
|
||||
extend T::Sig
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
class Otf < Uncompressed
|
||||
extend T::Sig
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".otf"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".7z"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".pax"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
class Pkg < Uncompressed
|
||||
extend T::Sig
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".pkg", ".mkpg"]
|
||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
||||
|
||||
include UnpackStrategy
|
||||
|
||||
using Magic
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def self.extensions
|
||||
[".rar"]
|
||||
|
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