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
|
uses: Homebrew/actions/setup-homebrew@master
|
||||||
|
|
||||||
- name: Cache Bundler RubyGems
|
- name: Cache Bundler RubyGems
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||||
@ -73,7 +73,7 @@ jobs:
|
|||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@master
|
||||||
|
|
||||||
- name: Cache Bundler RubyGems
|
- name: Cache Bundler RubyGems
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||||
@ -231,7 +231,7 @@ jobs:
|
|||||||
uses: Homebrew/actions/setup-homebrew@master
|
uses: Homebrew/actions/setup-homebrew@master
|
||||||
|
|
||||||
- name: Cache Bundler RubyGems
|
- name: Cache Bundler RubyGems
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||||
@ -276,7 +276,7 @@ jobs:
|
|||||||
HOMEBREW_NO_INSTALL_FROM_API: 1
|
HOMEBREW_NO_INSTALL_FROM_API: 1
|
||||||
|
|
||||||
- name: Cache Bundler RubyGems
|
- name: Cache Bundler RubyGems
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
path: ${{ steps.set-up-homebrew.outputs.gems-path }}
|
||||||
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }}
|
||||||
@ -289,7 +289,7 @@ jobs:
|
|||||||
run: mkdir tests
|
run: mkdir tests
|
||||||
|
|
||||||
- name: Cache parallel tests log
|
- name: Cache parallel tests log
|
||||||
uses: actions/cache@v1
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
path: tests
|
path: tests
|
||||||
key: ${{ runner.os }}-${{ matrix.test-flags }}-parallel_runtime_rspec-${{ github.sha }}
|
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:
|
steps:
|
||||||
- name: Re-run this workflow
|
- name: Re-run this workflow
|
||||||
if: github.event_name == 'schedule' || github.event.action == 'closed'
|
if: github.event_name == 'schedule' || github.event.action == 'closed'
|
||||||
uses: reitermarkus/rerun-workflow@1a15891377b6667377207cdd85b628b79ebd6f81
|
uses: reitermarkus/rerun-workflow@7381e98aa2bc4464acef4b60ade8d1d1d90e6e65
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
token: ${{ secrets.HOMEBREW_GITHUB_PUBLIC_REPO_TOKEN }}
|
||||||
continuous-label: waiting for feedback
|
continuous-label: waiting for feedback
|
||||||
|
@ -28,6 +28,7 @@ gem "rubocop", require: false
|
|||||||
gem "rubocop-ast", require: false
|
gem "rubocop-ast", require: false
|
||||||
gem "simplecov", require: false
|
gem "simplecov", require: false
|
||||||
gem "simplecov-cobertura", require: false
|
gem "simplecov-cobertura", require: false
|
||||||
|
gem "stackprof", require: false
|
||||||
gem "warning", require: false
|
gem "warning", require: false
|
||||||
|
|
||||||
group :sorbet, optional: true do
|
group :sorbet, optional: true do
|
||||||
|
@ -188,6 +188,7 @@ GEM
|
|||||||
sorbet (>= 0.5.9204)
|
sorbet (>= 0.5.9204)
|
||||||
sorbet-runtime (>= 0.5.9204)
|
sorbet-runtime (>= 0.5.9204)
|
||||||
thor (>= 0.19.2)
|
thor (>= 0.19.2)
|
||||||
|
stackprof (0.2.24)
|
||||||
tapioca (0.7.3)
|
tapioca (0.7.3)
|
||||||
bundler (>= 1.17.3)
|
bundler (>= 1.17.3)
|
||||||
pry (>= 0.12.2)
|
pry (>= 0.12.2)
|
||||||
@ -257,6 +258,7 @@ DEPENDENCIES
|
|||||||
sorbet-runtime
|
sorbet-runtime
|
||||||
sorbet-static-and-runtime
|
sorbet-static-and-runtime
|
||||||
spoom
|
spoom
|
||||||
|
stackprof
|
||||||
tapioca
|
tapioca
|
||||||
warning
|
warning
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# `HOMEBREW_STACKPROF` should be set via `brew prof --stackprof`, not manually.
|
||||||
if ENV["HOMEBREW_STACKPROF"]
|
if ENV["HOMEBREW_STACKPROF"]
|
||||||
require "rubygems"
|
require "rubygems"
|
||||||
require "stackprof"
|
require "stackprof"
|
||||||
@ -35,8 +36,8 @@ begin
|
|||||||
empty_argv = ARGV.empty?
|
empty_argv = ARGV.empty?
|
||||||
help_flag_list = %w[-h --help --usage -?]
|
help_flag_list = %w[-h --help --usage -?]
|
||||||
help_flag = !ENV["HOMEBREW_HELP"].nil?
|
help_flag = !ENV["HOMEBREW_HELP"].nil?
|
||||||
help_cmd_index = nil
|
help_cmd_index = T.let(nil, T.nilable(Integer))
|
||||||
cmd = nil
|
cmd = T.let(nil, T.nilable(String))
|
||||||
|
|
||||||
ARGV.each_with_index do |arg, i|
|
ARGV.each_with_index do |arg, i|
|
||||||
break if help_flag && cmd
|
break if help_flag && cmd
|
||||||
@ -64,7 +65,7 @@ begin
|
|||||||
path.prepend(HOMEBREW_SHIMS_PATH/"shared")
|
path.prepend(HOMEBREW_SHIMS_PATH/"shared")
|
||||||
homebrew_path.prepend(HOMEBREW_SHIMS_PATH/"shared")
|
homebrew_path.prepend(HOMEBREW_SHIMS_PATH/"shared")
|
||||||
|
|
||||||
ENV["PATH"] = path
|
ENV["PATH"] = path.to_s
|
||||||
|
|
||||||
require "commands"
|
require "commands"
|
||||||
require "settings"
|
require "settings"
|
||||||
@ -76,7 +77,7 @@ begin
|
|||||||
homebrew_path.append(Tap.cmd_directories)
|
homebrew_path.append(Tap.cmd_directories)
|
||||||
|
|
||||||
# External commands expect a normal PATH
|
# External commands expect a normal PATH
|
||||||
ENV["PATH"] = homebrew_path
|
ENV["PATH"] = homebrew_path.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
# Usage instructions should be displayed if and only if one of:
|
# Usage instructions should be displayed if and only if one of:
|
||||||
|
@ -6,8 +6,6 @@ require "timeout"
|
|||||||
require "utils/user"
|
require "utils/user"
|
||||||
require "cask/artifact/abstract_artifact"
|
require "cask/artifact/abstract_artifact"
|
||||||
require "cask/pkg"
|
require "cask/pkg"
|
||||||
require "extend/hash_validator"
|
|
||||||
using HashValidator
|
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
module Artifact
|
module Artifact
|
||||||
@ -38,7 +36,7 @@ module Cask
|
|||||||
attr_reader :directives
|
attr_reader :directives
|
||||||
|
|
||||||
def initialize(cask, directives)
|
def initialize(cask, directives)
|
||||||
directives.assert_valid_keys!(*ORDERED_DIRECTIVES)
|
directives.assert_valid_keys(*ORDERED_DIRECTIVES)
|
||||||
|
|
||||||
super(cask, **directives)
|
super(cask, **directives)
|
||||||
directives[:signal] = Array(directives[:signal]).flatten.each_slice(2).to_a
|
directives[:signal] = Array(directives[:signal]).flatten.each_slice(2).to_a
|
||||||
|
@ -3,9 +3,6 @@
|
|||||||
|
|
||||||
require "cask/artifact/moved"
|
require "cask/artifact/moved"
|
||||||
|
|
||||||
require "extend/hash_validator"
|
|
||||||
using HashValidator
|
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
module Artifact
|
module Artifact
|
||||||
# Generic artifact corresponding to the `artifact` stanza.
|
# Generic artifact corresponding to the `artifact` stanza.
|
||||||
|
@ -3,9 +3,6 @@
|
|||||||
|
|
||||||
require "cask/artifact/abstract_artifact"
|
require "cask/artifact/abstract_artifact"
|
||||||
|
|
||||||
require "extend/hash_validator"
|
|
||||||
using HashValidator
|
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
module Artifact
|
module Artifact
|
||||||
# Artifact corresponding to the `installer` stanza.
|
# Artifact corresponding to the `installer` stanza.
|
||||||
@ -67,7 +64,7 @@ module Cask
|
|||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
args.assert_valid_keys!(*VALID_KEYS)
|
args.assert_valid_keys(*VALID_KEYS)
|
||||||
new(cask, **args)
|
new(cask, **args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -6,9 +6,6 @@ require "plist"
|
|||||||
require "utils/user"
|
require "utils/user"
|
||||||
require "cask/artifact/abstract_artifact"
|
require "cask/artifact/abstract_artifact"
|
||||||
|
|
||||||
require "extend/hash_validator"
|
|
||||||
using HashValidator
|
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
module Artifact
|
module Artifact
|
||||||
# Artifact corresponding to the `pkg` stanza.
|
# Artifact corresponding to the `pkg` stanza.
|
||||||
@ -18,7 +15,7 @@ module Cask
|
|||||||
attr_reader :path, :stanza_options
|
attr_reader :path, :stanza_options
|
||||||
|
|
||||||
def self.from_args(cask, 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)
|
new(cask, path, **stanza_options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3,9 +3,6 @@
|
|||||||
|
|
||||||
require "cask/artifact/abstract_artifact"
|
require "cask/artifact/abstract_artifact"
|
||||||
|
|
||||||
require "extend/hash_validator"
|
|
||||||
using HashValidator
|
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
module Artifact
|
module Artifact
|
||||||
# Superclass for all artifacts which have a source and a target location.
|
# Superclass for all artifacts which have a source and a target location.
|
||||||
@ -20,7 +17,7 @@ module Cask
|
|||||||
if target_hash
|
if target_hash
|
||||||
raise CaskInvalidError unless target_hash.respond_to?(:keys)
|
raise CaskInvalidError unless target_hash.respond_to?(:keys)
|
||||||
|
|
||||||
target_hash.assert_valid_keys!(:target)
|
target_hash.assert_valid_keys(:target)
|
||||||
end
|
end
|
||||||
|
|
||||||
target_hash ||= {}
|
target_hash ||= {}
|
||||||
|
@ -20,9 +20,6 @@ module Cask
|
|||||||
extend APIHashable
|
extend APIHashable
|
||||||
include Metadata
|
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_reader :token, :sourcefile_path, :source, :config, :default_config, :loader
|
||||||
attr_accessor :download, :allow_reassignment
|
attr_accessor :download, :allow_reassignment
|
||||||
|
|
||||||
|
@ -326,13 +326,10 @@ module Cask
|
|||||||
end
|
end
|
||||||
|
|
||||||
def from_h_string_gsubs(string, appdir)
|
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
|
string.to_s
|
||||||
.gsub(HOMEBREW_HOME_PLACEHOLDER, Dir.home)
|
.gsub(HOMEBREW_HOME_PLACEHOLDER, Dir.home)
|
||||||
.gsub(HOMEBREW_PREFIX_PLACEHOLDER, HOMEBREW_PREFIX)
|
.gsub(HOMEBREW_PREFIX_PLACEHOLDER, HOMEBREW_PREFIX)
|
||||||
.gsub(HOMEBREW_CASK_APPDIR_PLACEHOLDER, appdir)
|
.gsub(HOMEBREW_CASK_APPDIR_PLACEHOLDER, appdir)
|
||||||
.gsub(Cask::HOMEBREW_OLD_PREFIX_PLACEHOLDER, HOMEBREW_PREFIX)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def from_h_array_gsubs(array, appdir)
|
def from_h_array_gsubs(array, appdir)
|
||||||
|
@ -11,7 +11,6 @@ require "cask/config"
|
|||||||
|
|
||||||
require "cask/cmd/abstract_command"
|
require "cask/cmd/abstract_command"
|
||||||
require "cask/cmd/audit"
|
require "cask/cmd/audit"
|
||||||
require "cask/cmd/fetch"
|
|
||||||
require "cask/cmd/install"
|
require "cask/cmd/install"
|
||||||
require "cask/cmd/reinstall"
|
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 dry_run
|
||||||
if (casks_to_install = casks.reject(&:installed?).presence)
|
if (casks_to_install = casks.reject(&:installed?).presence)
|
||||||
plural = ::Utils.pluralize("cask", casks_to_install.count)
|
ohai "Would install #{::Utils.pluralize("cask", casks_to_install.count, include_count: true)}:"
|
||||||
ohai "Would install #{casks_to_install.count} #{plural}:"
|
|
||||||
puts casks_to_install.map(&:full_name).join(" ")
|
puts casks_to_install.map(&:full_name).join(" ")
|
||||||
end
|
end
|
||||||
casks.each do |cask|
|
casks.each do |cask|
|
||||||
@ -97,8 +96,8 @@ module Cask
|
|||||||
.map(&:name)
|
.map(&:name)
|
||||||
next if dep_names.blank?
|
next if dep_names.blank?
|
||||||
|
|
||||||
plural = ::Utils.pluralize("dependenc", dep_names.count, plural: "ies", singular: "y")
|
ohai "Would install #{::Utils.pluralize("dependenc", dep_names.count, plural: "ies", singular: "y",
|
||||||
ohai "Would install #{dep_names.count} #{plural} for #{cask.full_name}:"
|
include_count: true)} for #{cask.full_name}:"
|
||||||
puts dep_names.join(" ")
|
puts dep_names.join(" ")
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
@ -6,9 +6,6 @@ require "json"
|
|||||||
require "lazy_object"
|
require "lazy_object"
|
||||||
require "locale"
|
require "locale"
|
||||||
|
|
||||||
require "extend/hash_validator"
|
|
||||||
using HashValidator
|
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
# Configuration for installing casks.
|
# Configuration for installing casks.
|
||||||
#
|
#
|
||||||
@ -110,8 +107,8 @@ module Cask
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@env&.assert_valid_keys!(*self.class.defaults.keys)
|
@env&.assert_valid_keys(*self.class.defaults.keys)
|
||||||
@explicit.assert_valid_keys!(*self.class.defaults.keys)
|
@explicit.assert_valid_keys(*self.class.defaults.keys)
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) }
|
sig { returns(T::Hash[Symbol, T.any(String, Pathname, T::Array[String])]) }
|
||||||
@ -169,10 +166,12 @@ module Cask
|
|||||||
|
|
||||||
DEFAULT_DIRS.each_key do |dir|
|
DEFAULT_DIRS.each_key do |dir|
|
||||||
define_method(dir) do
|
define_method(dir) do
|
||||||
|
T.bind(self, Config)
|
||||||
explicit.fetch(dir, env.fetch(dir, default.fetch(dir)))
|
explicit.fetch(dir, env.fetch(dir, default.fetch(dir)))
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method(:"#{dir}=") do |path|
|
define_method(:"#{dir}=") do |path|
|
||||||
|
T.bind(self, Config)
|
||||||
explicit[dir] = Pathname(path).expand_path
|
explicit[dir] = Pathname(path).expand_path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -339,6 +339,7 @@ module Cask
|
|||||||
|
|
||||||
ORDINARY_ARTIFACT_CLASSES.each do |klass|
|
ORDINARY_ARTIFACT_CLASSES.each do |klass|
|
||||||
define_method(klass.dsl_key) do |*args, **kwargs|
|
define_method(klass.dsl_key) do |*args, **kwargs|
|
||||||
|
T.bind(self, DSL)
|
||||||
if [*artifacts.map(&:class), klass].include?(Artifact::StageOnly) &&
|
if [*artifacts.map(&:class), klass].include?(Artifact::StageOnly) &&
|
||||||
(artifacts.map(&:class) & ACTIVATABLE_ARTIFACT_CLASSES).any?
|
(artifacts.map(&:class) & ACTIVATABLE_ARTIFACT_CLASSES).any?
|
||||||
raise CaskInvalidError.new(cask, "'stage_only' must be the only activatable artifact.")
|
raise CaskInvalidError.new(cask, "'stage_only' must be the only activatable artifact.")
|
||||||
@ -355,6 +356,7 @@ module Cask
|
|||||||
ARTIFACT_BLOCK_CLASSES.each do |klass|
|
ARTIFACT_BLOCK_CLASSES.each do |klass|
|
||||||
[klass.dsl_key, klass.uninstall_dsl_key].each do |dsl_key|
|
[klass.dsl_key, klass.uninstall_dsl_key].each do |dsl_key|
|
||||||
define_method(dsl_key) do |&block|
|
define_method(dsl_key) do |&block|
|
||||||
|
T.bind(self, DSL)
|
||||||
artifacts.add(klass.new(cask, dsl_key => block))
|
artifacts.add(klass.new(cask, dsl_key => block))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "delegate"
|
require "delegate"
|
||||||
|
|
||||||
require "extend/hash_validator"
|
|
||||||
using HashValidator
|
|
||||||
|
|
||||||
module Cask
|
module Cask
|
||||||
class DSL
|
class DSL
|
||||||
# Class corresponding to the `conflicts_with` stanza.
|
# Class corresponding to the `conflicts_with` stanza.
|
||||||
@ -22,16 +19,16 @@ module Cask
|
|||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
def initialize(**options)
|
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
|
conflicts.default = Set.new
|
||||||
|
|
||||||
super(conflicts)
|
super(conflicts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_json(generator)
|
def to_json(generator)
|
||||||
transform_values(&:to_a).to_json(generator)
|
__getobj__.transform_values(&:to_a).to_json(generator)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "delegate"
|
require "delegate"
|
||||||
@ -38,7 +38,7 @@ module Cask
|
|||||||
pairs.each do |key, value|
|
pairs.each do |key, value|
|
||||||
raise "invalid depends_on key: '#{key.inspect}'" unless VALID_KEYS.include?(key)
|
raise "invalid depends_on key: '#{key.inspect}'" unless VALID_KEYS.include?(key)
|
||||||
|
|
||||||
self[key] = send(:"#{key}=", *value)
|
__getobj__[key] = send(:"#{key}=", *value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -54,15 +54,18 @@ module Cask
|
|||||||
def macos=(*args)
|
def macos=(*args)
|
||||||
raise "Only a single 'depends_on macos' is allowed." if defined?(@macos)
|
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
|
begin
|
||||||
@macos = if args.count > 1
|
@macos = if args.count > 1
|
||||||
MacOSRequirement.new([args], comparator: "==")
|
MacOSRequirement.new([args], comparator: "==")
|
||||||
elsif MacOSVersions::SYMBOLS.key?(args.first)
|
elsif MacOSVersions::SYMBOLS.key?(args.first)
|
||||||
MacOSRequirement.new([args.first], comparator: "==")
|
MacOSRequirement.new([args.first], comparator: "==")
|
||||||
elsif /^\s*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/ =~ args.first
|
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*:(?<version>\S+)\s*$/.match(first_arg))
|
||||||
MacOSRequirement.new([version.to_sym], comparator: comparator)
|
MacOSRequirement.new([T.must(md[:version]).to_sym], comparator: md[:comparator])
|
||||||
elsif /^\s*(?<comparator><|>|[=<>]=)\s*(?<version>\S+)\s*$/ =~ args.first
|
elsif (md = /^\s*(?<comparator><|>|[=<>]=)\s*(?<version>\S+)\s*$/.match(first_arg))
|
||||||
MacOSRequirement.new([version], comparator: comparator)
|
MacOSRequirement.new([md[:version]], comparator: md[:comparator])
|
||||||
else # rubocop:disable Lint/DuplicateBranch
|
else # rubocop:disable Lint/DuplicateBranch
|
||||||
MacOSRequirement.new([args.first], comparator: "==")
|
MacOSRequirement.new([args.first], comparator: "==")
|
||||||
end
|
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)
|
def define_divider_deletion_method(divider)
|
||||||
method_name = deletion_method_name(divider)
|
method_name = deletion_method_name(divider)
|
||||||
define_method(method_name) do
|
define_method(method_name) do
|
||||||
|
T.bind(self, Version)
|
||||||
version { delete(divider) }
|
version { delete(divider) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -49,6 +50,7 @@ module Cask
|
|||||||
def define_divider_conversion_method(left_divider, right_divider)
|
def define_divider_conversion_method(left_divider, right_divider)
|
||||||
method_name = conversion_method_name(left_divider, right_divider)
|
method_name = conversion_method_name(left_divider, right_divider)
|
||||||
define_method(method_name) do
|
define_method(method_name) do
|
||||||
|
T.bind(self, Version)
|
||||||
version { gsub(left_divider, right_divider) }
|
version { gsub(left_divider, right_divider) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "formula_installer"
|
require "formula_installer"
|
||||||
@ -112,8 +112,9 @@ module Cask
|
|||||||
|
|
||||||
install_artifacts
|
install_artifacts
|
||||||
|
|
||||||
if @cask.tap&.should_report_analytics?
|
if (tap = @cask.tap) && tap.should_report_analytics?
|
||||||
::Utils::Analytics.report_event(:cask_install, @cask.token, on_request: true)
|
::Utils::Analytics.report_event(:cask_install, package_name: @cask.token, tap_name: tap.name,
|
||||||
|
on_request: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
purge_backed_up_versioned_files
|
purge_backed_up_versioned_files
|
||||||
@ -241,7 +242,7 @@ module Cask
|
|||||||
save_download_sha if @cask.version.latest?
|
save_download_sha if @cask.version.latest?
|
||||||
rescue => e
|
rescue => e
|
||||||
begin
|
begin
|
||||||
already_installed_artifacts.each do |artifact|
|
already_installed_artifacts&.each do |artifact|
|
||||||
if artifact.respond_to?(:uninstall_phase)
|
if artifact.respond_to?(:uninstall_phase)
|
||||||
odebug "Reverting installation of artifact of class #{artifact.class}"
|
odebug "Reverting installation of artifact of class #{artifact.class}"
|
||||||
artifact.uninstall_phase(command: @command, verbose: verbose?, force: force?)
|
artifact.uninstall_phase(command: @command, verbose: verbose?, force: force?)
|
||||||
@ -296,7 +297,7 @@ module Cask
|
|||||||
|
|
||||||
graph = ::Utils::TopologicalHash.graph_package_dependencies(@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)
|
::Utils::TopologicalHash.graph_package_dependencies(primary_container.dependencies, graph)
|
||||||
|
|
||||||
@ -454,7 +455,7 @@ module Cask
|
|||||||
artifacts = @cask.artifacts
|
artifacts = @cask.artifacts
|
||||||
|
|
||||||
odebug "Uninstalling 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|
|
artifacts.each do |artifact|
|
||||||
if artifact.respond_to?(:uninstall_phase)
|
if artifact.respond_to?(:uninstall_phase)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "development_tools"
|
require "development_tools"
|
||||||
@ -11,29 +11,27 @@ module Cask
|
|||||||
module Quarantine
|
module Quarantine
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
module_function
|
|
||||||
|
|
||||||
QUARANTINE_ATTRIBUTE = "com.apple.quarantine"
|
QUARANTINE_ATTRIBUTE = "com.apple.quarantine"
|
||||||
|
|
||||||
QUARANTINE_SCRIPT = (HOMEBREW_LIBRARY_PATH/"cask/utils/quarantine.swift").freeze
|
QUARANTINE_SCRIPT = (HOMEBREW_LIBRARY_PATH/"cask/utils/quarantine.swift").freeze
|
||||||
|
|
||||||
def swift
|
def self.swift
|
||||||
@swift ||= DevelopmentTools.locate("swift")
|
@swift ||= DevelopmentTools.locate("swift")
|
||||||
end
|
end
|
||||||
private :swift
|
private_class_method :swift
|
||||||
|
|
||||||
def xattr
|
def self.xattr
|
||||||
@xattr ||= DevelopmentTools.locate("xattr")
|
@xattr ||= DevelopmentTools.locate("xattr")
|
||||||
end
|
end
|
||||||
private :xattr
|
private_class_method :xattr
|
||||||
|
|
||||||
def swift_target_args
|
def self.swift_target_args
|
||||||
["-target", "#{Hardware::CPU.arch}-apple-macosx#{MacOS.version}"]
|
["-target", "#{Hardware::CPU.arch}-apple-macosx#{MacOS.version}"]
|
||||||
end
|
end
|
||||||
private :swift_target_args
|
private_class_method :swift_target_args
|
||||||
|
|
||||||
sig { returns(Symbol) }
|
sig { returns(Symbol) }
|
||||||
def check_quarantine_support
|
def self.check_quarantine_support
|
||||||
odebug "Checking quarantine support"
|
odebug "Checking quarantine support"
|
||||||
|
|
||||||
if !system_command(xattr, args: ["-h"], print_stderr: false).success?
|
if !system_command(xattr, args: ["-h"], print_stderr: false).success?
|
||||||
@ -58,13 +56,13 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def available?
|
def self.available?
|
||||||
@status ||= check_quarantine_support
|
@status ||= check_quarantine_support
|
||||||
|
|
||||||
@status == :quarantine_available
|
@status == :quarantine_available
|
||||||
end
|
end
|
||||||
|
|
||||||
def detect(file)
|
def self.detect(file)
|
||||||
return if file.nil?
|
return if file.nil?
|
||||||
|
|
||||||
odebug "Verifying Gatekeeper status of #{file}"
|
odebug "Verifying Gatekeeper status of #{file}"
|
||||||
@ -76,13 +74,13 @@ module Cask
|
|||||||
quarantine_status
|
quarantine_status
|
||||||
end
|
end
|
||||||
|
|
||||||
def status(file)
|
def self.status(file)
|
||||||
system_command(xattr,
|
system_command(xattr,
|
||||||
args: ["-p", QUARANTINE_ATTRIBUTE, file],
|
args: ["-p", QUARANTINE_ATTRIBUTE, file],
|
||||||
print_stderr: false).stdout.rstrip
|
print_stderr: false).stdout.rstrip
|
||||||
end
|
end
|
||||||
|
|
||||||
def toggle_no_translocation_bit(attribute)
|
def self.toggle_no_translocation_bit(attribute)
|
||||||
fields = attribute.split(";")
|
fields = attribute.split(";")
|
||||||
|
|
||||||
# Fields: status, epoch, download agent, event ID
|
# Fields: status, epoch, download agent, event ID
|
||||||
@ -94,7 +92,7 @@ module Cask
|
|||||||
fields.join(";")
|
fields.join(";")
|
||||||
end
|
end
|
||||||
|
|
||||||
def release!(download_path: nil)
|
def self.release!(download_path: nil)
|
||||||
return unless detect(download_path)
|
return unless detect(download_path)
|
||||||
|
|
||||||
odebug "Releasing #{download_path} from quarantine"
|
odebug "Releasing #{download_path} from quarantine"
|
||||||
@ -112,7 +110,7 @@ module Cask
|
|||||||
raise CaskQuarantineReleaseError.new(download_path, quarantiner.stderr)
|
raise CaskQuarantineReleaseError.new(download_path, quarantiner.stderr)
|
||||||
end
|
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 cask.nil? || download_path.nil?
|
||||||
|
|
||||||
return if detect(download_path)
|
return if detect(download_path)
|
||||||
@ -139,7 +137,7 @@ module Cask
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def propagate(from: nil, to: nil)
|
def self.propagate(from: nil, to: nil)
|
||||||
return if from.nil? || to.nil?
|
return if from.nil? || to.nil?
|
||||||
|
|
||||||
raise CaskError, "#{from} was not quarantined properly." unless detect(from)
|
raise CaskError, "#{from} was not quarantined properly." unless detect(from)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "env_config"
|
require "env_config"
|
||||||
@ -124,7 +124,9 @@ module Cask
|
|||||||
|
|
||||||
return true if caught_exceptions.empty?
|
return true if caught_exceptions.empty?
|
||||||
raise MultipleCaskErrors, caught_exceptions if caught_exceptions.count > 1
|
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
|
end
|
||||||
|
|
||||||
def self.upgrade_cask(
|
def self.upgrade_cask(
|
||||||
|
@ -94,7 +94,8 @@ class Caveats
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
s << "\n"
|
s << "\n" unless s.end_with?("\n")
|
||||||
|
s
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -124,7 +124,7 @@ module Homebrew
|
|||||||
return unless HOMEBREW_CELLAR.exist?
|
return unless HOMEBREW_CELLAR.exist?
|
||||||
|
|
||||||
count = Formula.racks.length
|
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
|
end
|
||||||
|
|
||||||
sig { params(args: CLI::Args).void }
|
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
|
command_count += tap.command_files.size
|
||||||
private_count += 1 if tap.private?
|
private_count += 1 if tap.private?
|
||||||
end
|
end
|
||||||
info = "#{tap_count} #{Utils.pluralize("tap", tap_count)}"
|
info = Utils.pluralize("tap", tap_count, include_count: true)
|
||||||
info += ", #{private_count} private"
|
info += ", #{private_count} private"
|
||||||
info += ", #{formula_count} #{Utils.pluralize("formula", formula_count, plural: "e")}"
|
info += ", #{Utils.pluralize("formula", formula_count, plural: "e", include_count: true)}"
|
||||||
info += ", #{command_count} #{Utils.pluralize("command", command_count)}"
|
info += ", #{Utils.pluralize("command", command_count, include_count: true)}"
|
||||||
info += ", #{Tap::TAP_DIRECTORY.dup.abv}" if Tap::TAP_DIRECTORY.directory?
|
info += ", #{Tap::TAP_DIRECTORY.dup.abv}" if Tap::TAP_DIRECTORY.directory?
|
||||||
puts info
|
puts info
|
||||||
else
|
else
|
||||||
|
@ -233,8 +233,7 @@ module Homebrew
|
|||||||
|
|
||||||
unless updated_taps.empty?
|
unless updated_taps.empty?
|
||||||
auto_update_header args: args
|
auto_update_header args: args
|
||||||
noun = Utils.pluralize("tap", updated_taps.count)
|
puts "Updated #{Utils.pluralize("tap", updated_taps.count, include_count: true)} (#{updated_taps.to_sentence})."
|
||||||
puts "Updated #{updated_taps.count} #{noun} (#{updated_taps.to_sentence})."
|
|
||||||
updated = true
|
updated = true
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -656,12 +655,12 @@ class ReporterHub
|
|||||||
output_dump_formula_or_cask_report "Outdated Casks", outdated_casks
|
output_dump_formula_or_cask_report "Outdated Casks", outdated_casks
|
||||||
elsif report_all
|
elsif report_all
|
||||||
if (changed_formulae = select_formula_or_cask(:M).count) && changed_formulae.positive?
|
if (changed_formulae = select_formula_or_cask(:M).count) && changed_formulae.positive?
|
||||||
noun = Utils.pluralize("formula", changed_formulae, plural: "e")
|
ohai "Modified Formulae",
|
||||||
ohai "Modified Formulae", "Modified #{changed_formulae} #{noun}."
|
"Modified #{Utils.pluralize("formula", changed_formulae, plural: "e", include_count: true)}."
|
||||||
end
|
end
|
||||||
|
|
||||||
if (changed_casks = select_formula_or_cask(:MC).count) && changed_casks.positive?
|
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
|
end
|
||||||
else
|
else
|
||||||
outdated_formulae = Formula.installed.select(&:outdated?).map(&:name)
|
outdated_formulae = Formula.installed.select(&:outdated?).map(&:name)
|
||||||
|
@ -12,6 +12,10 @@ git() {
|
|||||||
# HOMEBREW_LIBRARY is set by bin/brew
|
# HOMEBREW_LIBRARY is set by bin/brew
|
||||||
# shellcheck disable=SC2154
|
# shellcheck disable=SC2154
|
||||||
GIT_EXECUTABLE="$("${HOMEBREW_LIBRARY}/Homebrew/shims/shared/git" --homebrew=print-path)"
|
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
|
fi
|
||||||
"${GIT_EXECUTABLE}" "$@"
|
"${GIT_EXECUTABLE}" "$@"
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,10 @@ curl() {
|
|||||||
if [[ -z "${CURL_EXECUTABLE}" ]]
|
if [[ -z "${CURL_EXECUTABLE}" ]]
|
||||||
then
|
then
|
||||||
CURL_EXECUTABLE="$("${HOMEBREW_LIBRARY}/Homebrew/shims/shared/curl" --homebrew=print-path)"
|
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
|
fi
|
||||||
"${CURL_EXECUTABLE}" "$@"
|
"${CURL_EXECUTABLE}" "$@"
|
||||||
}
|
}
|
||||||
@ -33,6 +37,10 @@ git() {
|
|||||||
if [[ -z "${GIT_EXECUTABLE}" ]]
|
if [[ -z "${GIT_EXECUTABLE}" ]]
|
||||||
then
|
then
|
||||||
GIT_EXECUTABLE="$("${HOMEBREW_LIBRARY}/Homebrew/shims/shared/git" --homebrew=print-path)"
|
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
|
fi
|
||||||
"${GIT_EXECUTABLE}" "$@"
|
"${GIT_EXECUTABLE}" "$@"
|
||||||
}
|
}
|
||||||
|
@ -275,22 +275,21 @@ module Homebrew
|
|||||||
if total_problems_count.positive?
|
if total_problems_count.positive?
|
||||||
puts new_formula_problem_lines.map { |s| " #{s}" }
|
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 = []
|
error_sources = []
|
||||||
if formula_count.positive?
|
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
|
end
|
||||||
error_sources << "#{cask_count} #{Utils.pluralize("cask", cask_count)}" if cask_count.positive?
|
error_sources << Utils.pluralize("cask", cask_count, include_count: true) if cask_count.positive?
|
||||||
error_sources << "#{tap_count} #{Utils.pluralize("tap", tap_count)}" if tap_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 += " in #{error_sources.to_sentence}" if error_sources.any?
|
||||||
|
|
||||||
errors_summary += " detected"
|
errors_summary += " detected"
|
||||||
|
|
||||||
if corrected_problem_count.positive?
|
if corrected_problem_count.positive?
|
||||||
noun = Utils.pluralize("problem", corrected_problem_count)
|
errors_summary += ", #{Utils.pluralize("problem", corrected_problem_count, include_count: true)} corrected"
|
||||||
errors_summary += ", #{corrected_problem_count} #{noun} corrected"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
ofail errors_summary
|
ofail errors_summary
|
||||||
|
@ -64,7 +64,8 @@ module Homebrew
|
|||||||
results[user] = scan_repositories(repos, user, args)
|
results[user] = scan_repositories(repos, user, args)
|
||||||
grand_totals[user] = total(results[user])
|
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?
|
puts generate_csv(T.must(user), results[user], grand_totals[user]) if args.csv?
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -79,7 +80,8 @@ module Homebrew
|
|||||||
results[username] = scan_repositories(repos, username, args)
|
results[username] = scan_repositories(repos, username, args)
|
||||||
grand_totals[username] = total(results[username])
|
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
|
end
|
||||||
|
|
||||||
puts generate_maintainers_csv(grand_totals) if args.csv?
|
puts generate_maintainers_csv(grand_totals) if args.csv?
|
||||||
|
@ -22,6 +22,8 @@ module Homebrew
|
|||||||
description: "Download the bottles but don't upload them."
|
description: "Download the bottles but don't upload them."
|
||||||
switch "--no-commit",
|
switch "--no-commit",
|
||||||
description: "Do not generate a new commit before uploading."
|
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",
|
switch "-n", "--dry-run",
|
||||||
description: "Print what would be done rather than doing it."
|
description: "Print what would be done rather than doing it."
|
||||||
switch "--clean",
|
switch "--clean",
|
||||||
@ -447,10 +449,16 @@ module Homebrew
|
|||||||
ohai "Fetching #{tap} pull request ##{pr}"
|
ohai "Fetching #{tap} pull request ##{pr}"
|
||||||
Dir.mktmpdir pr do |dir|
|
Dir.mktmpdir pr do |dir|
|
||||||
cd dir do
|
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?
|
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?
|
if !args.no_autosquash? && !args.dry_run?
|
||||||
autosquash!(original_commit, tap: tap,
|
autosquash!(original_commit, tap: tap,
|
||||||
verbose: args.verbose?, resolve: args.resolve?, reason: args.message)
|
verbose: args.verbose?, resolve: args.resolve?, reason: args.message)
|
||||||
|
@ -908,7 +908,7 @@ module Homebrew
|
|||||||
0
|
0
|
||||||
end
|
end
|
||||||
|
|
||||||
"#{tap.path} (#{cask_count} #{Utils.pluralize("cask", cask_count)})"
|
"#{tap.path} (#{Utils.pluralize("cask", cask_count, include_count: true)})"
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -491,10 +491,13 @@ class CurlDownloadStrategy < AbstractFileDownloadStrategy
|
|||||||
end
|
end
|
||||||
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:
|
# 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.
|
# - 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.
|
# - Directory traversal attacks are possible without limiting this to just the basename.
|
||||||
File.basename(filename || content_disposition.filename)
|
File.basename(filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
filenames = lines.map(&parse_content_disposition).compact
|
filenames = lines.map(&parse_content_disposition).compact
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
|
|
||||||
module GitRepositoryExtension
|
module GitRepositoryExtension
|
||||||
include Kernel
|
requires_ancestor { Pathname }
|
||||||
|
|
||||||
sig { params(args: T.any(String, Pathname)).returns(Pathname) }
|
|
||||||
def join(*args); end
|
|
||||||
end
|
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
|
if seconds > 59
|
||||||
minutes = seconds / 60
|
minutes = seconds / 60
|
||||||
seconds %= 60
|
seconds %= 60
|
||||||
res = +"#{minutes} #{Utils.pluralize("minute", minutes)}"
|
res = +Utils.pluralize("minute", minutes, include_count: true)
|
||||||
return res.freeze if seconds.zero?
|
return res.freeze if seconds.zero?
|
||||||
|
|
||||||
res << " "
|
res << " "
|
||||||
end
|
end
|
||||||
|
|
||||||
res << "#{seconds} #{Utils.pluralize("second", seconds)}"
|
res << Utils.pluralize("second", seconds, include_count: true)
|
||||||
res.freeze
|
res.freeze
|
||||||
end
|
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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "simulate_system"
|
require "simulate_system"
|
||||||
@ -9,17 +9,15 @@ module OnSystem
|
|||||||
ARCH_OPTIONS = [:intel, :arm].freeze
|
ARCH_OPTIONS = [:intel, :arm].freeze
|
||||||
BASE_OS_OPTIONS = [:macos, :linux].freeze
|
BASE_OS_OPTIONS = [:macos, :linux].freeze
|
||||||
|
|
||||||
module_function
|
|
||||||
|
|
||||||
sig { params(arch: Symbol).returns(T::Boolean) }
|
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)
|
raise ArgumentError, "Invalid arch condition: #{arch.inspect}" if ARCH_OPTIONS.exclude?(arch)
|
||||||
|
|
||||||
arch == Homebrew::SimulateSystem.current_arch
|
arch == Homebrew::SimulateSystem.current_arch
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(os_name: Symbol, or_condition: T.nilable(Symbol)).returns(T::Boolean) }
|
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)
|
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)
|
raise ArgumentError, "Invalid OS condition: #{os_name.inspect}" unless MacOSVersions::SYMBOLS.key?(os_name)
|
||||||
@ -46,17 +44,17 @@ module OnSystem
|
|||||||
end
|
end
|
||||||
|
|
||||||
sig { params(method_name: Symbol).returns(Symbol) }
|
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
|
method_name.to_s.sub(/^on_/, "").to_sym
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { params(base: Class).void }
|
sig { params(base: Class).void }
|
||||||
def setup_arch_methods(base)
|
def self.setup_arch_methods(base)
|
||||||
ARCH_OPTIONS.each do |arch|
|
ARCH_OPTIONS.each do |arch|
|
||||||
base.define_method("on_#{arch}") do |&block|
|
base.define_method("on_#{arch}") do |&block|
|
||||||
@on_system_blocks_exist = true
|
@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
|
@called_in_on_system_block = true
|
||||||
result = block.call
|
result = block.call
|
||||||
@ -75,12 +73,12 @@ module OnSystem
|
|||||||
end
|
end
|
||||||
|
|
||||||
sig { params(base: Class).void }
|
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_OS_OPTIONS.each do |base_os|
|
||||||
base.define_method("on_#{base_os}") do |&block|
|
base.define_method("on_#{base_os}") do |&block|
|
||||||
@on_system_blocks_exist = true
|
@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
|
@called_in_on_system_block = true
|
||||||
result = block.call
|
result = block.call
|
||||||
@ -118,12 +116,12 @@ module OnSystem
|
|||||||
end
|
end
|
||||||
|
|
||||||
sig { params(base: Class).void }
|
sig { params(base: Class).void }
|
||||||
def setup_macos_methods(base)
|
def self.setup_macos_methods(base)
|
||||||
MacOSVersions::SYMBOLS.each_key do |os_name|
|
MacOSVersions::SYMBOLS.each_key do |os_name|
|
||||||
base.define_method("on_#{os_name}") do |or_condition = nil, &block|
|
base.define_method("on_#{os_name}") do |or_condition = nil, &block|
|
||||||
@on_system_blocks_exist = true
|
@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
|
return unless OnSystem.os_condition_met? os_condition, or_condition
|
||||||
|
|
||||||
@called_in_on_system_block = true
|
@called_in_on_system_block = true
|
||||||
|
@ -11,8 +11,6 @@ module UnpackStrategy
|
|||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
include SystemCommand::Mixin
|
include SystemCommand::Mixin
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
|
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
with_env(TZ: "UTC") do
|
with_env(TZ: "UTC") do
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
|
|
||||||
module UnpackStrategy
|
module UnpackStrategy::Zip::MacOSZipExtension
|
||||||
class Zip
|
|
||||||
module MacOSZipExtension
|
|
||||||
include Kernel
|
include Kernel
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
@ -343,14 +343,24 @@ class Pathname
|
|||||||
chmod saved_perms if saved_perms
|
chmod saved_perms if saved_perms
|
||||||
end
|
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
|
# @private
|
||||||
def install_info
|
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
|
end
|
||||||
|
|
||||||
# @private
|
# @private
|
||||||
def uninstall_info
|
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
|
end
|
||||||
|
|
||||||
# Writes an exec script in this folder for each target pathname.
|
# Writes an exec script in this folder for each target pathname.
|
||||||
@ -456,6 +466,32 @@ class Pathname
|
|||||||
def rpaths
|
def rpaths
|
||||||
[]
|
[]
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
require "extend/os/pathname"
|
require "extend/os/pathname"
|
||||||
|
@ -1,19 +1,9 @@
|
|||||||
# typed: strict
|
# typed: strict
|
||||||
|
|
||||||
module DiskUsageExtension
|
module DiskUsageExtension
|
||||||
include Kernel
|
requires_ancestor { Pathname }
|
||||||
|
|
||||||
def exist?; end
|
|
||||||
|
|
||||||
def symlink?; end
|
|
||||||
|
|
||||||
def resolved_path; end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module ObserverPathnameExtension
|
module ObserverPathnameExtension
|
||||||
include Kernel
|
requires_ancestor { Pathname }
|
||||||
|
|
||||||
def dirname; end
|
|
||||||
|
|
||||||
def basename; end
|
|
||||||
end
|
end
|
||||||
|
@ -466,6 +466,16 @@ module Homebrew
|
|||||||
"They must not be upgraded to version 7.11 or newer."
|
"They must not be upgraded to version 7.11 or newer."
|
||||||
end
|
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
|
def audit_versioned_keg_only
|
||||||
return unless @versioned_formula
|
return unless @versioned_formula
|
||||||
return unless @core_tap
|
return unless @core_tap
|
||||||
|
@ -414,9 +414,9 @@ class FormulaInstaller
|
|||||||
options = display_options(formula).join(" ")
|
options = display_options(formula).join(" ")
|
||||||
oh1 "Installing #{Formatter.identifier(formula.full_name)} #{options}".strip if show_header?
|
oh1 "Installing #{Formatter.identifier(formula.full_name)} #{options}".strip if show_header?
|
||||||
|
|
||||||
if formula.tap&.should_report_analytics?
|
if (tap = formula.tap) && tap.should_report_analytics?
|
||||||
action = "#{formula.full_name} #{options}".strip
|
Utils::Analytics.report_event(:formula_install, package_name: formula.name, tap_name: tap.name,
|
||||||
Utils::Analytics.report_event(:formula_install, action, on_request: installed_on_request?)
|
on_request: installed_on_request?, options: options)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.class.attempted << formula
|
self.class.attempted << formula
|
||||||
|
@ -326,8 +326,8 @@ module Homebrew
|
|||||||
|
|
||||||
if dry_run
|
if dry_run
|
||||||
if (formulae_name_to_install = formulae_to_install.map(&:name))
|
if (formulae_name_to_install = formulae_to_install.map(&:name))
|
||||||
plural = Utils.pluralize("formula", formulae_name_to_install.count, plural: "e")
|
ohai "Would install #{Utils.pluralize("formula", formulae_name_to_install.count,
|
||||||
ohai "Would install #{formulae_name_to_install.count} #{plural}:"
|
plural: "e", include_count: true)}:"
|
||||||
puts formulae_name_to_install.join(" ")
|
puts formulae_name_to_install.join(" ")
|
||||||
|
|
||||||
formula_installers.each do |fi|
|
formula_installers.each do |fi|
|
||||||
@ -355,8 +355,8 @@ module Homebrew
|
|||||||
def print_dry_run_dependencies(formula, dependencies, &block)
|
def print_dry_run_dependencies(formula, dependencies, &block)
|
||||||
return if dependencies.empty?
|
return if dependencies.empty?
|
||||||
|
|
||||||
plural = Utils.pluralize("dependenc", dependencies.count, plural: "ies", singular: "y")
|
ohai "Would install #{Utils.pluralize("dependenc", dependencies.count, plural: "ies", singular: "y",
|
||||||
ohai "Would install #{dependencies.count} #{plural} for #{formula.name}:"
|
include_count: true)} for #{formula.name}:"
|
||||||
formula_names = dependencies.map(&:first).map(&:to_formula).map(&block)
|
formula_names = dependencies.map(&:first).map(&:to_formula).map(&block)
|
||||||
puts formula_names.join(" ")
|
puts formula_names.join(" ")
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "keg_relocate"
|
require "keg_relocate"
|
||||||
@ -524,8 +524,8 @@ class Keg
|
|||||||
end
|
end
|
||||||
|
|
||||||
def delete_pyc_files!
|
def delete_pyc_files!
|
||||||
find { |pn| pn.delete if PYC_EXTENSIONS.include?(pn.extname) }
|
path.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| FileUtils.rm_rf pn if pn.basename.to_s == "__pycache__" }
|
||||||
end
|
end
|
||||||
|
|
||||||
def binary_executable_or_library_files
|
def binary_executable_or_library_files
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Performs {Formula#mktemp}'s functionality, and tracks the results.
|
# Performs {Formula#mktemp}'s functionality, and tracks the results.
|
||||||
@ -70,7 +70,7 @@ class Mktemp
|
|||||||
begin
|
begin
|
||||||
chown(nil, group_id, @tmpdir)
|
chown(nil, group_id, @tmpdir)
|
||||||
rescue Errno::EPERM
|
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
|
end
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# A formula option.
|
# 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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# {Pathname} extension for dealing with ELF files.
|
# {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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "macho"
|
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) }
|
sig { returns(T.self_type) }
|
||||||
def strip_patch
|
def strip_patch
|
||||||
# Big Sur is 11.x but Catalina is 10.15.x.
|
# 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)
|
self.class.new(major.to_s)
|
||||||
else
|
else
|
||||||
major_minor
|
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
|
end
|
||||||
|
|
||||||
def toplevel_stanzas
|
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
|
end
|
||||||
|
|
||||||
def sorted_toplevel_stanzas
|
def sorted_toplevel_stanzas
|
||||||
|
@ -52,10 +52,6 @@ module RuboCop
|
|||||||
stanza_group == other.stanza_group
|
stanza_group == other.stanza_group
|
||||||
end
|
end
|
||||||
|
|
||||||
def toplevel_stanza?
|
|
||||||
parent_node.cask_block? || parent_node.parent.cask_block?
|
|
||||||
end
|
|
||||||
|
|
||||||
def ==(other)
|
def ==(other)
|
||||||
self.class == other.class && stanza_node == other.stanza_node
|
self.class == other.class && stanza_node == other.stanza_node
|
||||||
end
|
end
|
||||||
|
@ -17,6 +17,8 @@ module RuboCop
|
|||||||
def_node_matcher :cask_block?, "(block (send nil? :cask _) args ...)"
|
def_node_matcher :cask_block?, "(block (send nil? :cask _) args ...)"
|
||||||
def_node_matcher :arch_variable?, "(lvasgn _ (send nil? :on_arch_conditional ...))"
|
def_node_matcher :arch_variable?, "(lvasgn _ (send nil? :on_arch_conditional ...))"
|
||||||
|
|
||||||
|
def_node_matcher :begin_block?, "(begin ...)"
|
||||||
|
|
||||||
def stanza?
|
def stanza?
|
||||||
return true if arch_variable?
|
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
|
class RuboCop::AST::Node
|
||||||
def arch_variable?(param0=T.unsafe(nil)); end
|
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_args(param0=T.unsafe(nil)); end
|
||||||
|
|
||||||
def block_body(param0=T.unsafe(nil)); end
|
def block_body(param0=T.unsafe(nil)); end
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
# typed: false
|
# typed: false
|
||||||
|
|
||||||
module ::StackProf; end
|
|
||||||
module T::InterfaceWrapper::Helpers; end
|
module T::InterfaceWrapper::Helpers; end
|
||||||
module T::Private::Abstract::Hooks; end
|
module T::Private::Abstract::Hooks; end
|
||||||
module T::Private::Methods::MethodHooks; 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/io"
|
||||||
require "extend/predicable"
|
require "extend/predicable"
|
||||||
require "extend/hash_validator"
|
|
||||||
|
|
||||||
require "extend/time"
|
require "extend/time"
|
||||||
|
|
||||||
|
@ -475,15 +475,15 @@ class Tap
|
|||||||
contents = []
|
contents = []
|
||||||
|
|
||||||
if (command_count = command_files.count).positive?
|
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
|
end
|
||||||
|
|
||||||
if (cask_count = cask_files.count).positive?
|
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
|
end
|
||||||
|
|
||||||
if (formula_count = formula_files.count).positive?
|
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
|
end
|
||||||
|
|
||||||
contents
|
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
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "cask/cmd/audit"
|
require "cask/cmd/audit"
|
||||||
require "cask/cmd/fetch"
|
|
||||||
require "cask/cmd/install"
|
require "cask/cmd/install"
|
||||||
require "cask/cask_loader"
|
require "cask/cask_loader"
|
||||||
require "cask/download"
|
require "cask/download"
|
||||||
@ -29,7 +28,8 @@ describe Cask::Quarantine, :cask do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "quarantines Cask fetches" do
|
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"))
|
local_transmission = Cask::CaskLoader.load(cask_path("local-transmission"))
|
||||||
cached_location = Cask::Download.new(local_transmission).fetch
|
cached_location = Cask::Download.new(local_transmission).fetch
|
||||||
|
|
||||||
@ -50,7 +50,8 @@ describe Cask::Quarantine, :cask do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "quarantines Cask installs even if the fetch was not" do
|
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")
|
Cask::Cmd::Install.run("local-transmission")
|
||||||
|
|
||||||
@ -144,7 +145,8 @@ describe Cask::Quarantine, :cask do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "does not quarantine Cask fetches" do
|
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"))
|
local_transmission = Cask::CaskLoader.load(cask_path("local-transmission"))
|
||||||
cached_location = Cask::Download.new(local_transmission).fetch
|
cached_location = Cask::Download.new(local_transmission).fetch
|
||||||
|
|
||||||
@ -165,7 +167,8 @@ describe Cask::Quarantine, :cask do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "does not quarantine Cask installs even if the fetch was" do
|
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")
|
Cask::Cmd::Install.run("local-transmission", "--no-quarantine")
|
||||||
|
|
||||||
|
@ -249,6 +249,32 @@ describe Caveats do
|
|||||||
expect(caveats).to include("#{f.opt_share}/pkgconfig")
|
expect(caveats).to include("#{f.opt_share}/pkgconfig")
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
describe "shell completions" do
|
describe "shell completions" do
|
||||||
|
@ -6,7 +6,7 @@ require "formula_installer"
|
|||||||
|
|
||||||
describe Utils::Analytics do
|
describe Utils::Analytics do
|
||||||
before do
|
before do
|
||||||
described_class.clear_additional_tags_cache
|
described_class.clear_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "::label_google" do
|
describe "::label_google" do
|
||||||
@ -45,64 +45,68 @@ describe Utils::Analytics do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "::additional_tags_influx" do
|
describe "::default_tags_influx" do
|
||||||
let(:ci) { ", CI" if ENV["CI"] }
|
let(:ci) { ", CI" if ENV["CI"] }
|
||||||
|
|
||||||
it "returns OS_VERSION and prefix when HOMEBREW_PREFIX is a custom prefix on intel" do
|
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(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once)
|
||||||
expect(described_class.additional_tags_influx).to have_key(:prefix)
|
expect(described_class.default_tags_influx).to have_key(:prefix)
|
||||||
expect(described_class.additional_tags_influx[:prefix]).to eq "custom-prefix"
|
expect(described_class.default_tags_influx[:prefix]).to eq "custom-prefix"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns OS_VERSION, ARM and prefix when HOMEBREW_PREFIX is a custom prefix on arm" do
|
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(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once)
|
||||||
expect(described_class.additional_tags_influx).to have_key(:arch)
|
expect(described_class.default_tags_influx).to have_key(:arch)
|
||||||
expect(described_class.additional_tags_influx[:arch]).to eq HOMEBREW_PHYSICAL_PROCESSOR
|
expect(described_class.default_tags_influx[:arch]).to eq HOMEBREW_PHYSICAL_PROCESSOR
|
||||||
expect(described_class.additional_tags_influx).to have_key(:prefix)
|
expect(described_class.default_tags_influx).to have_key(:prefix)
|
||||||
expect(described_class.additional_tags_influx[:prefix]).to eq "custom-prefix"
|
expect(described_class.default_tags_influx[:prefix]).to eq "custom-prefix"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns OS_VERSION, Rosetta and prefix when HOMEBREW_PREFIX is a custom prefix on Rosetta", :needs_macos do
|
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(Homebrew).to receive(:default_prefix?).and_return(false).at_least(:once)
|
||||||
expect(described_class.additional_tags_influx).to have_key(:prefix)
|
expect(described_class.default_tags_influx).to have_key(:prefix)
|
||||||
expect(described_class.additional_tags_influx[:prefix]).to eq "custom-prefix"
|
expect(described_class.default_tags_influx[:prefix]).to eq "custom-prefix"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "does not include prefix when HOMEBREW_PREFIX is the default prefix" do
|
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(Homebrew).to receive(:default_prefix?).and_return(true).at_least(:once)
|
||||||
expect(described_class.additional_tags_influx).to have_key(:prefix)
|
expect(described_class.default_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[:prefix]).to eq HOMEBREW_PREFIX.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
it "includes CI when ENV['CI'] is set" do
|
it "includes CI when ENV['CI'] is set" do
|
||||||
ENV["CI"] = "1"
|
ENV["CI"] = "1"
|
||||||
expect(described_class.additional_tags_influx).to have_key(:ci)
|
expect(described_class.default_tags_influx).to have_key(:ci)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "includes developer when ENV['HOMEBREW_DEVELOPER'] is set" do
|
it "includes developer when ENV['HOMEBREW_DEVELOPER'] is set" do
|
||||||
expect(Homebrew::EnvConfig).to receive(:developer?).and_return(true)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "::report_event" do
|
describe "::report_event" do
|
||||||
let(:f) { formula { url "foo-1.0" } }
|
let(:f) { formula { url "foo-1.0" } }
|
||||||
let(:options) { ["--head"].join }
|
let(:package_name) { f.name }
|
||||||
let(:action) { "#{f.full_name} #{options}".strip }
|
let(:tap_name) { f.tap.name }
|
||||||
|
let(:on_request) { false }
|
||||||
|
let(:options) { "--HEAD" }
|
||||||
|
|
||||||
context "when ENV vars is set" do
|
context "when ENV vars is set" do
|
||||||
it "returns nil when HOMEBREW_NO_ANALYTICS is true" do
|
it "returns nil when HOMEBREW_NO_ANALYTICS is true" do
|
||||||
ENV["HOMEBREW_NO_ANALYTICS"] = "true"
|
ENV["HOMEBREW_NO_ANALYTICS"] = "true"
|
||||||
expect(described_class).not_to receive(:report_google)
|
expect(described_class).not_to receive(:report_google)
|
||||||
expect(described_class).not_to receive(:report_influx)
|
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
|
end
|
||||||
|
|
||||||
it "returns nil when HOMEBREW_NO_ANALYTICS_THIS_RUN is true" do
|
it "returns nil when HOMEBREW_NO_ANALYTICS_THIS_RUN is true" do
|
||||||
ENV["HOMEBREW_NO_ANALYTICS_THIS_RUN"] = "true"
|
ENV["HOMEBREW_NO_ANALYTICS_THIS_RUN"] = "true"
|
||||||
expect(described_class).not_to receive(:report_google)
|
expect(described_class).not_to receive(:report_google)
|
||||||
expect(described_class).not_to receive(:report_influx)
|
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
|
end
|
||||||
|
|
||||||
it "returns nil when HOMEBREW_ANALYTICS_DEBUG is true" do
|
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_google)
|
||||||
expect(described_class).to receive(:report_influx)
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -120,40 +125,47 @@ describe Utils::Analytics do
|
|||||||
ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
|
ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
|
||||||
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
||||||
ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
|
ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
|
||||||
expect(Homebrew::EnvConfig).to receive(:developer?).and_return(false)
|
expect(described_class).to receive(:report_google).with(:event,
|
||||||
expect(described_class).to receive(:report_google).with(:event, hash_including(ea: action)).once
|
hash_including(ea: "#{package_name} #{options}")).once
|
||||||
expect(described_class).to receive(:report_influx).with(:install, "formula_name --head", false,
|
expect(described_class).to receive(:report_influx).with(:install, hash_including(package_name: package_name,
|
||||||
hash_including(developer: false)).once
|
on_request: on_request)).once
|
||||||
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
|
||||||
|
|
||||||
it "sends to google twice on request" do
|
it "sends to google twice on request" do
|
||||||
ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
|
ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
|
||||||
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
||||||
ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
|
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,
|
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
|
ec: :install_on_request)).once
|
||||||
expect(described_class).to receive(:report_influx).with(:install, "formula_name --head", true,
|
expect(described_class).to receive(:report_influx).with(:install,
|
||||||
hash_including(developer: false)).once
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "::report_influx" do
|
describe "::report_influx" do
|
||||||
let(:f) { formula { url "foo-1.0" } }
|
let(:f) { formula { url "foo-1.0" } }
|
||||||
let(:options) { ["--head"].join }
|
let(:package_name) { f.name }
|
||||||
let(:action) { "#{f.full_name} #{options}".strip }
|
let(:tap_name) { f.tap.name }
|
||||||
|
let(:on_request) { false }
|
||||||
|
let(:options) { "--HEAD" }
|
||||||
|
|
||||||
it "outputs in debug mode" do
|
it "outputs in debug mode" do
|
||||||
ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
|
ENV.delete("HOMEBREW_NO_ANALYTICS_THIS_RUN")
|
||||||
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
ENV.delete("HOMEBREW_NO_ANALYTICS")
|
||||||
ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
|
ENV["HOMEBREW_ANALYTICS_DEBUG"] = "true"
|
||||||
expect(described_class).to receive(:deferred_curl).once
|
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
|
||||||
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", 1, singular: "o", plural: "es")).to eq("fooo")
|
||||||
expect(described_class.pluralize("foo", 2, singular: "o", plural: "es")).to eq("fooes")
|
expect(described_class.pluralize("foo", 2, singular: "o", plural: "es")).to eq("fooes")
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
describe ".underscore" do
|
describe ".underscore" do
|
||||||
|
@ -1,29 +1,8 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "system_command"
|
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.
|
# Module containing all available strategies for unpacking archives.
|
||||||
#
|
#
|
||||||
# @api private
|
# @api private
|
||||||
@ -33,38 +12,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include SystemCommand::Mixin
|
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
|
def self.strategies
|
||||||
@strategies ||= [
|
@strategies ||= [
|
||||||
Tar, # Needs to be before Bzip2/Gzip/Xz/Lzma/Zstd.
|
Tar, # Needs to be before Bzip2/Gzip/Xz/Lzma/Zstd.
|
||||||
@ -195,7 +142,7 @@ module UnpackStrategy
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Ensure all extracted directories are writable.
|
# Ensure all extracted directories are writable.
|
||||||
tmp_unpack_dir.each_directory do |path|
|
each_directory(tmp_unpack_dir) do |path|
|
||||||
next if path.writable?
|
next if path.writable?
|
||||||
|
|
||||||
FileUtils.chmod "u+w", path, verbose: verbose
|
FileUtils.chmod "u+w", path, verbose: verbose
|
||||||
@ -208,6 +155,19 @@ module UnpackStrategy
|
|||||||
def dependencies
|
def dependencies
|
||||||
[]
|
[]
|
||||||
end
|
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
|
end
|
||||||
|
|
||||||
require "unpack_strategy/air"
|
require "unpack_strategy/air"
|
||||||
|
@ -3,14 +3,3 @@
|
|||||||
module UnpackStrategy
|
module UnpackStrategy
|
||||||
include Kernel
|
include Kernel
|
||||||
end
|
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
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".air"]
|
[".air"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
class Bazaar < Directory
|
class Bazaar < Directory
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
def self.can_extract?(path)
|
def self.can_extract?(path)
|
||||||
super && (path/".bzr").directory?
|
super && (path/".bzr").directory?
|
||||||
end
|
end
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".bz2"]
|
[".bz2"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".cab"]
|
[".cab"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
class Compress < Tar
|
class Compress < Tar
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".Z"]
|
[".Z"]
|
||||||
|
@ -6,8 +6,6 @@ require_relative "directory"
|
|||||||
module UnpackStrategy
|
module UnpackStrategy
|
||||||
# Strategy for unpacking CVS repositories.
|
# Strategy for unpacking CVS repositories.
|
||||||
class Cvs < Directory
|
class Cvs < Directory
|
||||||
using Magic
|
|
||||||
|
|
||||||
def self.can_extract?(path)
|
def self.can_extract?(path)
|
||||||
super && (path/"CVS").directory?
|
super && (path/"CVS").directory?
|
||||||
end
|
end
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[]
|
[]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# typed: false
|
# typed: true
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
require "tempfile"
|
require "tempfile"
|
||||||
@ -12,6 +12,8 @@ module UnpackStrategy
|
|||||||
|
|
||||||
# Helper module for listing the contents of a volume mounted from a disk image.
|
# Helper module for listing the contents of a volume mounted from a disk image.
|
||||||
module Bom
|
module Bom
|
||||||
|
extend T::Sig
|
||||||
|
|
||||||
DMG_METADATA = Set.new(%w[
|
DMG_METADATA = Set.new(%w[
|
||||||
.background
|
.background
|
||||||
.com.apple.timemachine.donotpresent
|
.com.apple.timemachine.donotpresent
|
||||||
@ -35,28 +37,25 @@ module UnpackStrategy
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
refine Pathname do
|
|
||||||
extend T::Sig
|
|
||||||
|
|
||||||
# Check if path is considered disk image metadata.
|
# Check if path is considered disk image metadata.
|
||||||
sig { returns(T::Boolean) }
|
sig { params(pathname: Pathname).returns(T::Boolean) }
|
||||||
def dmg_metadata?
|
def self.dmg_metadata?(pathname)
|
||||||
DMG_METADATA.include?(cleanpath.ascend.to_a.last.to_s)
|
DMG_METADATA.include?(pathname.cleanpath.ascend.to_a.last.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check if path is a symlink to a system directory (commonly to /Applications).
|
# Check if path is a symlink to a system directory (commonly to /Applications).
|
||||||
sig { returns(T::Boolean) }
|
sig { params(pathname: Pathname).returns(T::Boolean) }
|
||||||
def system_dir_symlink?
|
def self.system_dir_symlink?(pathname)
|
||||||
symlink? && MacOS.system_dir?(dirname.join(readlink))
|
pathname.symlink? && MacOS.system_dir?(pathname.dirname.join(pathname.readlink))
|
||||||
end
|
end
|
||||||
|
|
||||||
sig { returns(String) }
|
sig { params(pathname: Pathname).returns(String) }
|
||||||
def bom
|
def self.bom(pathname)
|
||||||
tries = 0
|
tries = 0
|
||||||
result = loop do
|
result = loop do
|
||||||
# We need to use `find` here instead of Ruby in order to properly handle
|
# We need to use `find` here instead of Ruby in order to properly handle
|
||||||
# file names containing special characters, such as “e” + “´” vs. “é”.
|
# 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
|
tries += 1
|
||||||
|
|
||||||
# Spurious bug on CI, which in most cases can be worked around by retrying.
|
# 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
|
raise "Command `#{r.command.shelljoin}` was interrupted." if tries >= 3
|
||||||
end
|
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")
|
bom_paths = result.stdout.split("\0")
|
||||||
|
|
||||||
raise EmptyError, self if bom_paths.empty?
|
raise EmptyError, pathname if bom_paths.empty?
|
||||||
|
|
||||||
bom_paths
|
bom_paths
|
||||||
.reject { |path| Pathname(path).dmg_metadata? }
|
.reject { |path| dmg_metadata?(Pathname(path)) }
|
||||||
.reject { |path| (self/path).system_dir_symlink? }
|
.reject { |path| system_dir_symlink?(pathname/path) }
|
||||||
.join("\n")
|
.join("\n")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
private_constant :Bom
|
|
||||||
|
|
||||||
# Strategy for unpacking a volume mounted from a disk image.
|
# Strategy for unpacking a volume mounted from a disk image.
|
||||||
class Mount
|
class Mount
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
using Bom
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
def eject(verbose: false)
|
def eject(verbose: false)
|
||||||
tries ||= 3
|
tries = 3
|
||||||
|
begin
|
||||||
return unless path.exist?
|
return unless path.exist?
|
||||||
|
|
||||||
if tries > 1
|
if tries > 1
|
||||||
@ -126,26 +122,22 @@ module UnpackStrategy
|
|||||||
sleep 1
|
sleep 1
|
||||||
retry
|
retry
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
|
sig { override.params(unpack_dir: Pathname, basename: Pathname, verbose: T::Boolean).returns(T.untyped) }
|
||||||
def extract_to_dir(unpack_dir, basename:, verbose:)
|
def extract_to_dir(unpack_dir, basename:, verbose:)
|
||||||
|
tries = 3
|
||||||
bom = begin
|
bom = begin
|
||||||
tries ||= 10
|
Bom.bom(path)
|
||||||
|
|
||||||
path.bom
|
|
||||||
rescue Bom::EmptyError => e
|
rescue Bom::EmptyError => e
|
||||||
raise "#{e} No retries left." if (tries -= 1).zero?
|
raise e if (tries -= 1).zero?
|
||||||
|
|
||||||
sleep 1
|
sleep 1
|
||||||
retry
|
retry
|
||||||
end
|
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|
|
Tempfile.open(["", ".bom"]) do |bomfile|
|
||||||
bomfile.close
|
bomfile.close
|
||||||
|
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
class Executable < Uncompressed
|
class Executable < Uncompressed
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".sh", ".bash"]
|
[".sh", ".bash"]
|
||||||
|
@ -11,8 +11,6 @@ module UnpackStrategy
|
|||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
extend SystemCommand::Mixin
|
extend SystemCommand::Mixin
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[]
|
[]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[]
|
[]
|
||||||
|
@ -6,8 +6,6 @@ require_relative "directory"
|
|||||||
module UnpackStrategy
|
module UnpackStrategy
|
||||||
# Strategy for unpacking Git repositories.
|
# Strategy for unpacking Git repositories.
|
||||||
class Git < Directory
|
class Git < Directory
|
||||||
using Magic
|
|
||||||
|
|
||||||
def self.can_extract?(path)
|
def self.can_extract?(path)
|
||||||
super && (path/".git").directory?
|
super && (path/".git").directory?
|
||||||
end
|
end
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".gz"]
|
[".gz"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
class Jar < Uncompressed
|
class Jar < Uncompressed
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".apk", ".jar"]
|
[".apk", ".jar"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".lha", ".lzh"]
|
[".lha", ".lzh"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
class LuaRock < Uncompressed
|
class LuaRock < Uncompressed
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".rock"]
|
[".rock"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".lz"]
|
[".lz"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".lzma"]
|
[".lzma"]
|
||||||
|
@ -6,8 +6,6 @@ require_relative "directory"
|
|||||||
module UnpackStrategy
|
module UnpackStrategy
|
||||||
# Strategy for unpacking Mercurial repositories.
|
# Strategy for unpacking Mercurial repositories.
|
||||||
class Mercurial < Directory
|
class Mercurial < Directory
|
||||||
using Magic
|
|
||||||
|
|
||||||
def self.can_extract?(path)
|
def self.can_extract?(path)
|
||||||
super && (path/".hg").directory?
|
super && (path/".hg").directory?
|
||||||
end
|
end
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
class MicrosoftOfficeXml < Uncompressed
|
class MicrosoftOfficeXml < Uncompressed
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[
|
[
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
class Otf < Uncompressed
|
class Otf < Uncompressed
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".otf"]
|
[".otf"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".7z"]
|
[".7z"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".pax"]
|
[".pax"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
class Pkg < Uncompressed
|
class Pkg < Uncompressed
|
||||||
extend T::Sig
|
extend T::Sig
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".pkg", ".mkpg"]
|
[".pkg", ".mkpg"]
|
||||||
|
@ -8,8 +8,6 @@ module UnpackStrategy
|
|||||||
|
|
||||||
include UnpackStrategy
|
include UnpackStrategy
|
||||||
|
|
||||||
using Magic
|
|
||||||
|
|
||||||
sig { returns(T::Array[String]) }
|
sig { returns(T::Array[String]) }
|
||||||
def self.extensions
|
def self.extensions
|
||||||
[".rar"]
|
[".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