Merge branch 'Homebrew:master' into mohammad
This commit is contained in:
commit
461ae71229
@ -21,6 +21,7 @@ Metrics/BlockLength:
|
||||
# TODO: extract more of the bottling logic
|
||||
- "dev-cmd/bottle.rb"
|
||||
- "test/**/*"
|
||||
- "cmd/install.rb"
|
||||
Metrics/BlockNesting:
|
||||
Max: 5
|
||||
Metrics/ClassLength:
|
||||
|
||||
@ -2,7 +2,11 @@
|
||||
|
||||
source "https://rubygems.org"
|
||||
|
||||
ruby ">= 2.6.0"
|
||||
if ENV.fetch("HOMEBREW_DEVELOPER", "").empty? || ENV.fetch("HOMEBREW_USE_RUBY_FROM_PATH", "").empty?
|
||||
ruby "~> 2.6.0"
|
||||
else
|
||||
ruby ">= 2.6.0"
|
||||
end
|
||||
|
||||
# disallowed gems (should not be used)
|
||||
# * nokogiri - use rexml instead for XML parsing
|
||||
|
||||
@ -7,8 +7,8 @@ GEM
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
addressable (2.8.1)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
ast (2.4.2)
|
||||
bindata (2.4.10)
|
||||
bootsnap (1.13.0)
|
||||
@ -57,8 +57,8 @@ GEM
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2022.0105)
|
||||
mini_portile2 (2.8.0)
|
||||
minitest (5.16.2)
|
||||
msgpack (1.5.4)
|
||||
minitest (5.16.3)
|
||||
msgpack (1.5.5)
|
||||
mustache (1.1.1)
|
||||
net-http-digest_auth (1.4.1)
|
||||
net-http-persistent (4.0.1)
|
||||
@ -82,7 +82,7 @@ GEM
|
||||
pry (0.14.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
public_suffix (4.0.7)
|
||||
public_suffix (5.0.0)
|
||||
racc (1.6.0)
|
||||
rack (2.2.4)
|
||||
rainbow (3.1.1)
|
||||
@ -124,14 +124,14 @@ GEM
|
||||
rspec (>= 3, < 4)
|
||||
rspec_junit_formatter (0.5.1)
|
||||
rspec-core (>= 2, < 4, != 2.12.0)
|
||||
rubocop (1.34.1)
|
||||
rubocop (1.35.1)
|
||||
json (~> 2.3)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.1.2.1)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml (>= 3.2.5, < 4.0)
|
||||
rubocop-ast (>= 1.20.0, < 2.0)
|
||||
rubocop-ast (>= 1.20.1, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 3.0)
|
||||
rubocop-ast (1.21.0)
|
||||
@ -170,7 +170,7 @@ GEM
|
||||
sorbet (>= 0.5.9204)
|
||||
sorbet-runtime (>= 0.5.9204)
|
||||
thor (>= 0.19.2)
|
||||
tapioca (0.7.2)
|
||||
tapioca (0.7.3)
|
||||
bundler (>= 1.17.3)
|
||||
pry (>= 0.12.2)
|
||||
rbi (~> 0.0.0, >= 0.0.14)
|
||||
|
||||
@ -79,10 +79,11 @@ class Build
|
||||
ENV.deps = formula_deps
|
||||
ENV.run_time_deps = run_time_deps
|
||||
ENV.setup_build_environment(
|
||||
formula: formula,
|
||||
cc: args.cc,
|
||||
build_bottle: args.build_bottle?,
|
||||
bottle_arch: args.bottle_arch,
|
||||
formula: formula,
|
||||
cc: args.cc,
|
||||
build_bottle: args.build_bottle?,
|
||||
bottle_arch: args.bottle_arch,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
)
|
||||
reqs.each do |req|
|
||||
req.modify_build_environment(
|
||||
@ -92,10 +93,11 @@ class Build
|
||||
deps.each(&:modify_build_environment)
|
||||
else
|
||||
ENV.setup_build_environment(
|
||||
formula: formula,
|
||||
cc: args.cc,
|
||||
build_bottle: args.build_bottle?,
|
||||
bottle_arch: args.bottle_arch,
|
||||
formula: formula,
|
||||
cc: args.cc,
|
||||
build_bottle: args.build_bottle?,
|
||||
bottle_arch: args.bottle_arch,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
)
|
||||
reqs.each do |req|
|
||||
req.modify_build_environment(
|
||||
@ -127,9 +129,10 @@ class Build
|
||||
formula.update_head_version
|
||||
|
||||
formula.brew(
|
||||
fetch: false,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
interactive: args.interactive?,
|
||||
fetch: false,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
interactive: args.interactive?,
|
||||
) do
|
||||
with_env(
|
||||
# For head builds, HOMEBREW_FORMULA_PREFIX should include the commit,
|
||||
|
||||
@ -55,22 +55,23 @@ class BuildEnvironment
|
||||
].freeze
|
||||
private_constant :KEYS
|
||||
|
||||
sig { params(env: T.untyped).returns(T::Array[String]) }
|
||||
sig { params(env: T::Hash[String, T.nilable(T.any(String, Pathname))]).returns(T::Array[String]) }
|
||||
def self.keys(env)
|
||||
KEYS & env.keys
|
||||
end
|
||||
|
||||
sig { params(env: T.untyped, f: IO).void }
|
||||
sig { params(env: T::Hash[String, T.nilable(T.any(String, Pathname))], f: IO).void }
|
||||
def self.dump(env, f = $stdout)
|
||||
keys = self.keys(env)
|
||||
keys -= %w[CC CXX OBJC OBJCXX] if env["CC"] == env["HOMEBREW_CC"]
|
||||
|
||||
keys.each do |key|
|
||||
value = env.fetch(key)
|
||||
|
||||
s = +"#{key}: #{value}"
|
||||
case key
|
||||
when "CC", "CXX", "LD"
|
||||
s << " => #{Pathname.new(value).realpath}" if File.symlink?(value)
|
||||
s << " => #{Pathname.new(value).realpath}" if value.present? && File.symlink?(value)
|
||||
end
|
||||
s.freeze
|
||||
f.puts s
|
||||
|
||||
@ -20,28 +20,31 @@ module Cask
|
||||
|
||||
attr_reader :cask, :download
|
||||
|
||||
attr_predicate :appcast?, :new_cask?, :strict?, :online?, :token_conflicts?
|
||||
attr_predicate :appcast?, :new_cask?, :strict?, :signing?, :online?, :token_conflicts?
|
||||
|
||||
def initialize(cask, appcast: nil, download: nil, quarantine: nil,
|
||||
token_conflicts: nil, online: nil, strict: nil,
|
||||
token_conflicts: nil, online: nil, strict: nil, signing: nil,
|
||||
new_cask: nil)
|
||||
|
||||
# `new_cask` implies `online` and `strict`
|
||||
# `new_cask` implies `online`, `token_conflicts`, `strict` and `signing`
|
||||
online = new_cask if online.nil?
|
||||
strict = new_cask if strict.nil?
|
||||
signing = new_cask if signing.nil?
|
||||
token_conflicts = new_cask if token_conflicts.nil?
|
||||
|
||||
# `online` implies `appcast` and `download`
|
||||
appcast = online if appcast.nil?
|
||||
download = online if download.nil?
|
||||
|
||||
# `new_cask` implies `token_conflicts`
|
||||
token_conflicts = new_cask if token_conflicts.nil?
|
||||
# `signing` implies `download`
|
||||
download = signing if download.nil?
|
||||
|
||||
@cask = cask
|
||||
@appcast = appcast
|
||||
@download = Download.new(cask, quarantine: quarantine) if download
|
||||
@online = online
|
||||
@strict = strict
|
||||
@signing = signing
|
||||
@new_cask = new_cask
|
||||
@token_conflicts = token_conflicts
|
||||
end
|
||||
@ -81,6 +84,7 @@ module Cask
|
||||
check_github_repository_archived
|
||||
check_github_prerelease_version
|
||||
check_bitbucket_repository
|
||||
check_signing
|
||||
self
|
||||
rescue => e
|
||||
odebug e, e.backtrace
|
||||
@ -550,6 +554,38 @@ module Cask
|
||||
add_error "download not possible: #{e}"
|
||||
end
|
||||
|
||||
def check_signing
|
||||
return if !signing? || download.blank? || cask.url.blank?
|
||||
|
||||
odebug "Auditing signing"
|
||||
odebug cask.artifacts
|
||||
artifacts = cask.artifacts.select { |k| k.is_a?(Artifact::Pkg) || k.is_a?(Artifact::App) }
|
||||
|
||||
return if artifacts.empty?
|
||||
|
||||
downloaded_path = download.fetch
|
||||
primary_container = UnpackStrategy.detect(downloaded_path, type: @cask.container&.type, merge_xattrs: true)
|
||||
|
||||
return if primary_container.nil?
|
||||
|
||||
Dir.mktmpdir do |tmpdir|
|
||||
tmpdir = Pathname(tmpdir)
|
||||
primary_container.extract_nestedly(to: tmpdir, basename: downloaded_path.basename, verbose: false)
|
||||
artifacts.each do |artifact|
|
||||
path = case artifact
|
||||
when Artifact::Moved
|
||||
tmpdir/artifact.source.basename
|
||||
when Artifact::Pkg
|
||||
artifact.path
|
||||
end
|
||||
next unless path.exist?
|
||||
|
||||
result = system_command("codesign", args: ["--verify", path], print_stderr: false)
|
||||
add_warning result.merged_output unless result.success?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def check_livecheck_version
|
||||
return unless appcast?
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ module Cask
|
||||
audit_online: nil,
|
||||
audit_new_cask: nil,
|
||||
audit_strict: nil,
|
||||
audit_signing: nil,
|
||||
audit_token_conflicts: nil,
|
||||
quarantine: nil,
|
||||
any_named_args: nil,
|
||||
@ -29,6 +30,7 @@ module Cask
|
||||
audit_online: audit_online,
|
||||
audit_new_cask: audit_new_cask,
|
||||
audit_strict: audit_strict,
|
||||
audit_signing: audit_signing,
|
||||
audit_token_conflicts: audit_token_conflicts,
|
||||
quarantine: quarantine,
|
||||
any_named_args: any_named_args,
|
||||
@ -46,6 +48,7 @@ module Cask
|
||||
audit_appcast: nil,
|
||||
audit_online: nil,
|
||||
audit_strict: nil,
|
||||
audit_signing: nil,
|
||||
audit_token_conflicts: nil,
|
||||
audit_new_cask: nil,
|
||||
quarantine: nil,
|
||||
@ -60,6 +63,7 @@ module Cask
|
||||
@audit_online = audit_online
|
||||
@audit_new_cask = audit_new_cask
|
||||
@audit_strict = audit_strict
|
||||
@audit_signing = audit_signing
|
||||
@quarantine = quarantine
|
||||
@audit_token_conflicts = audit_token_conflicts
|
||||
@any_named_args = any_named_args
|
||||
@ -133,6 +137,7 @@ module Cask
|
||||
appcast: @audit_appcast,
|
||||
online: @audit_online,
|
||||
strict: @audit_strict,
|
||||
signing: @audit_signing,
|
||||
new_cask: @audit_new_cask,
|
||||
token_conflicts: @audit_token_conflicts,
|
||||
download: @audit_download,
|
||||
|
||||
@ -19,6 +19,8 @@ module Cask
|
||||
description: "Audit the appcast"
|
||||
switch "--[no-]token-conflicts",
|
||||
description: "Audit for token conflicts"
|
||||
switch "--[no-]signing",
|
||||
description: "Audit for signed apps, which is required on ARM"
|
||||
switch "--[no-]strict",
|
||||
description: "Run additional, stricter style checks"
|
||||
switch "--[no-]online",
|
||||
@ -50,6 +52,7 @@ module Cask
|
||||
appcast: args.appcast?,
|
||||
online: args.online?,
|
||||
strict: args.strict?,
|
||||
signing: args.signing?,
|
||||
new_cask: args.new_cask?,
|
||||
token_conflicts: args.token_conflicts?,
|
||||
quarantine: args.quarantine?,
|
||||
@ -71,6 +74,7 @@ module Cask
|
||||
appcast: nil,
|
||||
online: nil,
|
||||
strict: nil,
|
||||
signing: nil,
|
||||
new_cask: nil,
|
||||
token_conflicts: nil,
|
||||
quarantine: nil,
|
||||
@ -84,6 +88,7 @@ module Cask
|
||||
audit_appcast: appcast,
|
||||
audit_online: online,
|
||||
audit_strict: strict,
|
||||
audit_signing: signing,
|
||||
audit_new_cask: new_cask,
|
||||
audit_token_conflicts: token_conflicts,
|
||||
quarantine: quarantine,
|
||||
|
||||
@ -79,7 +79,7 @@ module Cask
|
||||
end
|
||||
|
||||
def self.title_info(cask)
|
||||
title = "#{cask.token}: #{cask.version}"
|
||||
title = "#{oh1_title(cask.token)}: #{cask.version}"
|
||||
title += " (auto_updates)" if cask.auto_updates
|
||||
title
|
||||
end
|
||||
|
||||
@ -230,8 +230,13 @@ module Cask
|
||||
end
|
||||
|
||||
# @api public
|
||||
def sha256(arg = nil)
|
||||
set_unique_stanza(:sha256, arg.nil?) do
|
||||
def sha256(arg = nil, arm: nil, intel: nil)
|
||||
should_return = arg.nil? && arm.nil? && intel.nil?
|
||||
|
||||
set_unique_stanza(:sha256, should_return) do
|
||||
@on_system_blocks_exist = true if arm.present? || intel.present?
|
||||
|
||||
arg ||= on_arch_conditional(arm: arm, intel: intel)
|
||||
case arg
|
||||
when :no_check
|
||||
arg
|
||||
@ -245,7 +250,7 @@ module Cask
|
||||
|
||||
# @api public
|
||||
def arch(arm: nil, intel: nil)
|
||||
should_return = arm.blank? && intel.blank?
|
||||
should_return = arm.nil? && intel.nil?
|
||||
|
||||
set_unique_stanza(:arch, should_return) do
|
||||
@on_system_blocks_exist = true
|
||||
|
||||
@ -150,20 +150,6 @@ module Cask
|
||||
version { split(",", 2).second }
|
||||
end
|
||||
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def before_colon
|
||||
odisabled "Cask::DSL::Version#before_colon", "Cask::DSL::Version#csv"
|
||||
version { split(":", 2).first }
|
||||
end
|
||||
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def after_colon
|
||||
odisabled "Cask::DSL::Version#after_colon", "Cask::DSL::Version#csv"
|
||||
version { split(":", 2).second }
|
||||
end
|
||||
|
||||
# @api public
|
||||
sig { returns(T.self_type) }
|
||||
def no_dividers
|
||||
|
||||
@ -189,8 +189,8 @@ module Homebrew
|
||||
def self.skip_clean_formula?(f)
|
||||
return false if Homebrew::EnvConfig.no_cleanup_formulae.blank?
|
||||
|
||||
skip_clean_formulae = Homebrew::EnvConfig.no_cleanup_formulae.split(",")
|
||||
skip_clean_formulae.include?(f.name) || (skip_clean_formulae & f.aliases).present?
|
||||
@skip_clean_formulae ||= Homebrew::EnvConfig.no_cleanup_formulae.split(",")
|
||||
@skip_clean_formulae.include?(f.name) || (@skip_clean_formulae & f.aliases).present?
|
||||
end
|
||||
|
||||
def self.periodic_clean_due?
|
||||
@ -428,7 +428,6 @@ module Homebrew
|
||||
next if !use_system_ruby && portable_ruby_latest_version == path.basename.to_s
|
||||
|
||||
portable_rubies_to_remove << path
|
||||
puts "Would remove: #{path} (#{path.abv})" if dry_run?
|
||||
end
|
||||
|
||||
return if portable_rubies_to_remove.empty?
|
||||
@ -440,20 +439,16 @@ module Homebrew
|
||||
puts Utils.popen_read("git", "-C", HOMEBREW_REPOSITORY, "clean", "-ffqx", bundler_path).chomp
|
||||
end
|
||||
|
||||
return if dry_run?
|
||||
|
||||
FileUtils.rm_rf portable_rubies_to_remove
|
||||
portable_rubies_to_remove.each do |portable_ruby|
|
||||
cleanup_path(portable_ruby) { portable_ruby.rmtree }
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup_bootsnap
|
||||
bootsnap = cache/"bootsnap"
|
||||
return unless bootsnap.exist?
|
||||
|
||||
if dry_run?
|
||||
puts "Would remove: #{bootsnap} (#{bootsnap.abv})"
|
||||
else
|
||||
FileUtils.rm_rf bootsnap
|
||||
end
|
||||
cleanup_path(bootsnap) { bootsnap.rmtree }
|
||||
end
|
||||
|
||||
def cleanup_cache_db(rack = nil)
|
||||
@ -540,8 +535,12 @@ module Homebrew
|
||||
# the cache of installed formulae may no longer be valid.
|
||||
Formula.clear_cache unless dry_run
|
||||
|
||||
# Remove formulae listed in HOMEBREW_NO_CLEANUP_FORMULAE.
|
||||
formulae = Formula.installed.reject(&method(:skip_clean_formula?))
|
||||
formulae = Formula.installed
|
||||
# Remove formulae listed in HOMEBREW_NO_CLEANUP_FORMULAE and their dependencies.
|
||||
if Homebrew::EnvConfig.no_cleanup_formulae.present?
|
||||
formulae -= formulae.select(&method(:skip_clean_formula?))
|
||||
.flat_map { |f| [f, *f.runtime_formula_dependencies] }
|
||||
end
|
||||
casks = Cask::Caskroom.casks
|
||||
|
||||
removable_formulae = Formula.unused_formulae_with_no_dependents(formulae, casks)
|
||||
|
||||
@ -90,6 +90,9 @@ module Homebrew
|
||||
sig { returns(T::Boolean) }
|
||||
def keep_tmp?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def debug_symbols?; end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def overwrite?; end
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ module Homebrew
|
||||
if shell.nil?
|
||||
BuildEnvironment.dump ENV
|
||||
else
|
||||
BuildEnvironment.keys(ENV).each do |key|
|
||||
BuildEnvironment.keys(ENV.to_h).each do |key|
|
||||
puts Utils::Shell.export_value(key, ENV.fetch(key), shell)
|
||||
end
|
||||
end
|
||||
|
||||
@ -274,7 +274,7 @@ module Homebrew
|
||||
attrs << "pinned at #{f.pinned_version}" if f.pinned?
|
||||
attrs << "keg-only" if f.keg_only?
|
||||
|
||||
puts "#{f.full_name}: #{specs * ", "}#{" [#{attrs * ", "}]" unless attrs.empty?}"
|
||||
puts "#{oh1_title(f.full_name)}: #{specs * ", "}#{" [#{attrs * ", "}]" unless attrs.empty?}"
|
||||
puts f.desc if f.desc
|
||||
puts Formatter.url(f.homepage) if f.homepage
|
||||
|
||||
|
||||
@ -91,6 +91,10 @@ module Homebrew
|
||||
[:switch, "--keep-tmp", {
|
||||
description: "Retain the temporary files created during installation.",
|
||||
}],
|
||||
[:switch, "--debug-symbols", {
|
||||
depends_on: "--build-from-source",
|
||||
description: "Generate debug symbols on build. Source will be retained in a cache directory. ",
|
||||
}],
|
||||
[:switch, "--build-bottle", {
|
||||
description: "Prepare the formula for eventual bottling during installation, skipping any " \
|
||||
"post-install steps.",
|
||||
@ -232,6 +236,7 @@ module Homebrew
|
||||
git: args.git?,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
force: args.force?,
|
||||
overwrite: args.overwrite?,
|
||||
debug: args.debug?,
|
||||
@ -247,6 +252,7 @@ module Homebrew
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
|
||||
@ -70,14 +70,6 @@ module Homebrew
|
||||
def list
|
||||
args = list_args.parse
|
||||
|
||||
# Unbrewed uses the PREFIX, which will exist
|
||||
# Things below use the CELLAR, which doesn't until the first formula is installed.
|
||||
unless HOMEBREW_CELLAR.exist?
|
||||
raise NoSuchKegError, args.named.first if args.named.present? && !args.cask?
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
if args.full_name?
|
||||
unless args.cask?
|
||||
formula_names = args.no_named? ? Formula.installed : args.named.to_resolved_formulae
|
||||
@ -112,12 +104,10 @@ module Homebrew
|
||||
if !args.cask? && HOMEBREW_CELLAR.exist? && HOMEBREW_CELLAR.children.any?
|
||||
ohai "Formulae" if $stdout.tty? && !args.formula?
|
||||
safe_system "ls", *ls_args, HOMEBREW_CELLAR
|
||||
puts if $stdout.tty? && !args.formula?
|
||||
end
|
||||
if !args.formula? && Cask::Caskroom.any_casks_installed?
|
||||
if $stdout.tty? && !args.cask?
|
||||
puts
|
||||
ohai "Casks"
|
||||
end
|
||||
ohai "Casks" if $stdout.tty? && !args.cask?
|
||||
safe_system "ls", *ls_args, Cask::Caskroom.path
|
||||
end
|
||||
else
|
||||
|
||||
@ -57,6 +57,10 @@ module Homebrew
|
||||
[:switch, "--keep-tmp", {
|
||||
description: "Retain the temporary files created during installation.",
|
||||
}],
|
||||
[:switch, "--debug-symbols", {
|
||||
depends_on: "--build-from-source",
|
||||
description: "Generate debug symbols on build. Source will be retained in a cache directory. ",
|
||||
}],
|
||||
[:switch, "--display-times", {
|
||||
env: :display_install_times,
|
||||
description: "Print install times for each formula at the end of the run.",
|
||||
@ -115,6 +119,7 @@ module Homebrew
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
@ -132,6 +137,7 @@ module Homebrew
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
|
||||
@ -68,6 +68,10 @@ module Homebrew
|
||||
[:switch, "--keep-tmp", {
|
||||
description: "Retain the temporary files created during installation.",
|
||||
}],
|
||||
[:switch, "--debug-symbols", {
|
||||
depends_on: "--build-from-source",
|
||||
description: "Generate debug symbols on build. Source will be retained in a cache directory. ",
|
||||
}],
|
||||
[:switch, "--display-times", {
|
||||
env: :display_install_times,
|
||||
description: "Print install times for each package at the end of the run.",
|
||||
@ -187,6 +191,7 @@ module Homebrew
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
@ -202,6 +207,7 @@ module Homebrew
|
||||
build_from_source_formulae: args.build_from_source_formulae,
|
||||
interactive: args.interactive?,
|
||||
keep_tmp: args.keep_tmp?,
|
||||
debug_symbols: args.debug_symbols?,
|
||||
force: args.force?,
|
||||
debug: args.debug?,
|
||||
quiet: args.quiet?,
|
||||
|
||||
@ -1,21 +1,2 @@
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Cask
|
||||
class Cask
|
||||
extend Enumerable
|
||||
|
||||
def self.each(&block)
|
||||
odisabled "`Enumerable` methods on `Cask::Cask`",
|
||||
"`Cask::Cask.all` (but avoid looping over all casks, it's slow and insecure)"
|
||||
|
||||
return to_enum unless block
|
||||
|
||||
Tap.flat_map(&:cask_files).each do |f|
|
||||
yield CaskLoader::FromTapPathLoader.new(f).load(config: nil)
|
||||
rescue CaskUnreadableError => e
|
||||
opoo e.message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,20 +1,2 @@
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Formula
|
||||
extend Enumerable
|
||||
|
||||
def self.each(&_block)
|
||||
odisabled "`Enumerable` methods on `Formula`",
|
||||
"`Formula.all` (but avoid looping over all formulae, it's slow and insecure)"
|
||||
|
||||
files.each do |file|
|
||||
yield Formulary.factory(file)
|
||||
rescue FormulaUnavailableError, FormulaUnreadableError => e
|
||||
# Don't let one broken formula break commands. But do complain.
|
||||
onoe "Failed to import: #{file}"
|
||||
$stderr.puts e
|
||||
next
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -172,7 +172,7 @@ class CompilerSelector
|
||||
def compiler_version(name)
|
||||
case name.to_s
|
||||
when "gcc", GNU_GCC_REGEXP
|
||||
versions.non_apple_gcc_version(name.to_s)
|
||||
versions.gcc_version(name.to_s)
|
||||
else
|
||||
versions.send("#{name}_build_version")
|
||||
end
|
||||
|
||||
@ -1,22 +1,55 @@
|
||||
{
|
||||
"licenseListVersion": "3.17",
|
||||
"licenseListVersion": "3.18",
|
||||
"exceptions": [
|
||||
{
|
||||
"reference": "./FLTK-exception.json",
|
||||
"reference": "./Qt-GPL-exception-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./FLTK-exception.html",
|
||||
"detailsUrl": "./Qt-GPL-exception-1.0.html",
|
||||
"referenceNumber": 1,
|
||||
"name": "FLTK exception",
|
||||
"licenseExceptionId": "FLTK-exception",
|
||||
"name": "Qt GPL exception 1.0",
|
||||
"licenseExceptionId": "Qt-GPL-exception-1.0",
|
||||
"seeAlso": [
|
||||
"http://www.fltk.org/COPYING.php"
|
||||
"http://code.qt.io/cgit/qt/qtbase.git/tree/LICENSE.GPL3-EXCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Fawkes-Runtime-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Fawkes-Runtime-exception.html",
|
||||
"referenceNumber": 2,
|
||||
"name": "Fawkes Runtime Exception",
|
||||
"licenseExceptionId": "Fawkes-Runtime-exception",
|
||||
"seeAlso": [
|
||||
"http://www.fawkesrobotics.org/about/license/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./openvpn-openssl-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./openvpn-openssl-exception.html",
|
||||
"referenceNumber": 3,
|
||||
"name": "OpenVPN OpenSSL Exception",
|
||||
"licenseExceptionId": "openvpn-openssl-exception",
|
||||
"seeAlso": [
|
||||
"http://openvpn.net/index.php/license.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./DigiRule-FOSS-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./DigiRule-FOSS-exception.html",
|
||||
"referenceNumber": 4,
|
||||
"name": "DigiRule FOSS License Exception",
|
||||
"licenseExceptionId": "DigiRule-FOSS-exception",
|
||||
"seeAlso": [
|
||||
"http://www.digirulesolutions.com/drupal/foss"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Bootloader-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Bootloader-exception.html",
|
||||
"referenceNumber": 2,
|
||||
"referenceNumber": 5,
|
||||
"name": "Bootloader Distribution Exception",
|
||||
"licenseExceptionId": "Bootloader-exception",
|
||||
"seeAlso": [
|
||||
@ -24,87 +57,21 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./WxWindows-exception-3.1.json",
|
||||
"reference": "./OpenJDK-assembly-exception-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./WxWindows-exception-3.1.html",
|
||||
"referenceNumber": 3,
|
||||
"name": "WxWindows Library Exception 3.1",
|
||||
"licenseExceptionId": "WxWindows-exception-3.1",
|
||||
"seeAlso": [
|
||||
"http://www.opensource.org/licenses/WXwindows"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Linux-syscall-note.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Linux-syscall-note.html",
|
||||
"referenceNumber": 4,
|
||||
"name": "Linux Syscall Note",
|
||||
"licenseExceptionId": "Linux-syscall-note",
|
||||
"seeAlso": [
|
||||
"https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/COPYING"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Qt-LGPL-exception-1.1.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Qt-LGPL-exception-1.1.html",
|
||||
"referenceNumber": 5,
|
||||
"name": "Qt LGPL exception 1.1",
|
||||
"licenseExceptionId": "Qt-LGPL-exception-1.1",
|
||||
"seeAlso": [
|
||||
"http://code.qt.io/cgit/qt/qtbase.git/tree/LGPL_EXCEPTION.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./LLVM-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./LLVM-exception.html",
|
||||
"detailsUrl": "./OpenJDK-assembly-exception-1.0.html",
|
||||
"referenceNumber": 6,
|
||||
"name": "LLVM Exception",
|
||||
"licenseExceptionId": "LLVM-exception",
|
||||
"name": "OpenJDK Assembly exception 1.0",
|
||||
"licenseExceptionId": "OpenJDK-assembly-exception-1.0",
|
||||
"seeAlso": [
|
||||
"http://llvm.org/foundation/relicensing/LICENSE.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./PS-or-PDF-font-exception-20170817.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./PS-or-PDF-font-exception-20170817.html",
|
||||
"referenceNumber": 7,
|
||||
"name": "PS/PDF font exception (2017-08-17)",
|
||||
"licenseExceptionId": "PS-or-PDF-font-exception-20170817",
|
||||
"seeAlso": [
|
||||
"https://github.com/ArtifexSoftware/urw-base35-fonts/blob/65962e27febc3883a17e651cdb23e783668c996f/LICENSE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./GCC-exception-3.1.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./GCC-exception-3.1.html",
|
||||
"referenceNumber": 8,
|
||||
"name": "GCC Runtime Library exception 3.1",
|
||||
"licenseExceptionId": "GCC-exception-3.1",
|
||||
"seeAlso": [
|
||||
"http://www.gnu.org/licenses/gcc-exception-3.1.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Autoconf-exception-3.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Autoconf-exception-3.0.html",
|
||||
"referenceNumber": 9,
|
||||
"name": "Autoconf exception 3.0",
|
||||
"licenseExceptionId": "Autoconf-exception-3.0",
|
||||
"seeAlso": [
|
||||
"http://www.gnu.org/licenses/autoconf-exception-3.0.html"
|
||||
"http://openjdk.java.net/legal/assembly-exception.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./LGPL-3.0-linking-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./LGPL-3.0-linking-exception.html",
|
||||
"referenceNumber": 10,
|
||||
"referenceNumber": 7,
|
||||
"name": "LGPL-3.0 Linking Exception",
|
||||
"licenseExceptionId": "LGPL-3.0-linking-exception",
|
||||
"seeAlso": [
|
||||
@ -114,21 +81,21 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./GCC-exception-2.0.json",
|
||||
"reference": "./u-boot-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./GCC-exception-2.0.html",
|
||||
"referenceNumber": 11,
|
||||
"name": "GCC Runtime Library exception 2.0",
|
||||
"licenseExceptionId": "GCC-exception-2.0",
|
||||
"detailsUrl": "./u-boot-exception-2.0.html",
|
||||
"referenceNumber": 8,
|
||||
"name": "U-Boot exception 2.0",
|
||||
"licenseExceptionId": "u-boot-exception-2.0",
|
||||
"seeAlso": [
|
||||
"https://gcc.gnu.org/git/?p\u003dgcc.git;a\u003dblob;f\u003dgcc/libgcc1.c;h\u003d762f5143fc6eed57b6797c82710f3538aa52b40b;hb\u003dcb143a3ce4fb417c68f5fa2691a1b1b1053dfba9#l10"
|
||||
"http://git.denx.de/?p\u003du-boot.git;a\u003dblob;f\u003dLicenses/Exceptions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Bison-exception-2.2.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Bison-exception-2.2.html",
|
||||
"referenceNumber": 12,
|
||||
"referenceNumber": 9,
|
||||
"name": "Bison exception 2.2",
|
||||
"licenseExceptionId": "Bison-exception-2.2",
|
||||
"seeAlso": [
|
||||
@ -136,37 +103,70 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./openvpn-openssl-exception.json",
|
||||
"reference": "./OCaml-LGPL-linking-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./openvpn-openssl-exception.html",
|
||||
"detailsUrl": "./OCaml-LGPL-linking-exception.html",
|
||||
"referenceNumber": 10,
|
||||
"name": "OCaml LGPL Linking Exception",
|
||||
"licenseExceptionId": "OCaml-LGPL-linking-exception",
|
||||
"seeAlso": [
|
||||
"https://caml.inria.fr/ocaml/license.en.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Swift-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Swift-exception.html",
|
||||
"referenceNumber": 11,
|
||||
"name": "Swift Exception",
|
||||
"licenseExceptionId": "Swift-exception",
|
||||
"seeAlso": [
|
||||
"https://swift.org/LICENSE.txt",
|
||||
"https://github.com/apple/swift-package-manager/blob/7ab2275f447a5eb37497ed63a9340f8a6d1e488b/LICENSE.txt#L205"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./CLISP-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./CLISP-exception-2.0.html",
|
||||
"referenceNumber": 12,
|
||||
"name": "CLISP exception 2.0",
|
||||
"licenseExceptionId": "CLISP-exception-2.0",
|
||||
"seeAlso": [
|
||||
"http://sourceforge.net/p/clisp/clisp/ci/default/tree/COPYRIGHT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Qwt-exception-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Qwt-exception-1.0.html",
|
||||
"referenceNumber": 13,
|
||||
"name": "OpenVPN OpenSSL Exception",
|
||||
"licenseExceptionId": "openvpn-openssl-exception",
|
||||
"name": "Qwt exception 1.0",
|
||||
"licenseExceptionId": "Qwt-exception-1.0",
|
||||
"seeAlso": [
|
||||
"http://openvpn.net/index.php/license.html"
|
||||
"http://qwt.sourceforge.net/qwtlicense.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Libtool-exception.json",
|
||||
"reference": "./Universal-FOSS-exception-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Libtool-exception.html",
|
||||
"detailsUrl": "./Universal-FOSS-exception-1.0.html",
|
||||
"referenceNumber": 14,
|
||||
"name": "Libtool Exception",
|
||||
"licenseExceptionId": "Libtool-exception",
|
||||
"name": "Universal FOSS Exception, Version 1.0",
|
||||
"licenseExceptionId": "Universal-FOSS-exception-1.0",
|
||||
"seeAlso": [
|
||||
"http://git.savannah.gnu.org/cgit/libtool.git/tree/m4/libtool.m4"
|
||||
"https://oss.oracle.com/licenses/universal-foss-exception/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Autoconf-exception-2.0.json",
|
||||
"reference": "./LLVM-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Autoconf-exception-2.0.html",
|
||||
"detailsUrl": "./LLVM-exception.html",
|
||||
"referenceNumber": 15,
|
||||
"name": "Autoconf exception 2.0",
|
||||
"licenseExceptionId": "Autoconf-exception-2.0",
|
||||
"name": "LLVM Exception",
|
||||
"licenseExceptionId": "LLVM-exception",
|
||||
"seeAlso": [
|
||||
"http://ac-archive.sourceforge.net/doc/copyright.html",
|
||||
"http://ftp.gnu.org/gnu/autoconf/autoconf-2.59.tar.gz"
|
||||
"http://llvm.org/foundation/relicensing/LICENSE.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
@ -181,11 +181,267 @@
|
||||
"https://github.com/mirror/wget/blob/master/src/http.c#L20"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./GStreamer-exception-2008.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./GStreamer-exception-2008.html",
|
||||
"referenceNumber": 17,
|
||||
"name": "GStreamer Exception (2008)",
|
||||
"licenseExceptionId": "GStreamer-exception-2008",
|
||||
"seeAlso": [
|
||||
"https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/licensing.html?gi-language\u003dc#licensing-of-applications-using-gstreamer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./FLTK-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./FLTK-exception.html",
|
||||
"referenceNumber": 18,
|
||||
"name": "FLTK exception",
|
||||
"licenseExceptionId": "FLTK-exception",
|
||||
"seeAlso": [
|
||||
"http://www.fltk.org/COPYING.php"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./GPL-3.0-linking-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./GPL-3.0-linking-exception.html",
|
||||
"referenceNumber": 19,
|
||||
"name": "GPL-3.0 Linking Exception",
|
||||
"licenseExceptionId": "GPL-3.0-linking-exception",
|
||||
"seeAlso": [
|
||||
"https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Qt-LGPL-exception-1.1.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Qt-LGPL-exception-1.1.html",
|
||||
"referenceNumber": 20,
|
||||
"name": "Qt LGPL exception 1.1",
|
||||
"licenseExceptionId": "Qt-LGPL-exception-1.1",
|
||||
"seeAlso": [
|
||||
"http://code.qt.io/cgit/qt/qtbase.git/tree/LGPL_EXCEPTION.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Classpath-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Classpath-exception-2.0.html",
|
||||
"referenceNumber": 21,
|
||||
"name": "Classpath exception 2.0",
|
||||
"licenseExceptionId": "Classpath-exception-2.0",
|
||||
"seeAlso": [
|
||||
"http://www.gnu.org/software/classpath/license.html",
|
||||
"https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Nokia-Qt-exception-1.1.json",
|
||||
"isDeprecatedLicenseId": true,
|
||||
"detailsUrl": "./Nokia-Qt-exception-1.1.html",
|
||||
"referenceNumber": 22,
|
||||
"name": "Nokia Qt LGPL exception 1.1",
|
||||
"licenseExceptionId": "Nokia-Qt-exception-1.1",
|
||||
"seeAlso": [
|
||||
"https://www.keepassx.org/dev/projects/keepassx/repository/revisions/b8dfb9cc4d5133e0f09cd7533d15a4f1c19a40f2/entry/LICENSE.NOKIA-LGPL-EXCEPTION"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./389-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./389-exception.html",
|
||||
"referenceNumber": 23,
|
||||
"name": "389 Directory Server Exception",
|
||||
"licenseExceptionId": "389-exception",
|
||||
"seeAlso": [
|
||||
"http://directory.fedoraproject.org/wiki/GPL_Exception_License_Text",
|
||||
"https://web.archive.org/web/20080828121337/http://directory.fedoraproject.org/wiki/GPL_Exception_License_Text"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Font-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Font-exception-2.0.html",
|
||||
"referenceNumber": 24,
|
||||
"name": "Font exception 2.0",
|
||||
"licenseExceptionId": "Font-exception-2.0",
|
||||
"seeAlso": [
|
||||
"http://www.gnu.org/licenses/gpl-faq.html#FontException"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./GStreamer-exception-2005.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./GStreamer-exception-2005.html",
|
||||
"referenceNumber": 25,
|
||||
"name": "GStreamer Exception (2005)",
|
||||
"licenseExceptionId": "GStreamer-exception-2005",
|
||||
"seeAlso": [
|
||||
"https://gstreamer.freedesktop.org/documentation/frequently-asked-questions/licensing.html?gi-language\u003dc#licensing-of-applications-using-gstreamer"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./SHL-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./SHL-2.0.html",
|
||||
"referenceNumber": 26,
|
||||
"name": "Solderpad Hardware License v2.0",
|
||||
"licenseExceptionId": "SHL-2.0",
|
||||
"seeAlso": [
|
||||
"https://solderpad.org/licenses/SHL-2.0/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./WxWindows-exception-3.1.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./WxWindows-exception-3.1.html",
|
||||
"referenceNumber": 27,
|
||||
"name": "WxWindows Library Exception 3.1",
|
||||
"licenseExceptionId": "WxWindows-exception-3.1",
|
||||
"seeAlso": [
|
||||
"http://www.opensource.org/licenses/WXwindows"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Autoconf-exception-3.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Autoconf-exception-3.0.html",
|
||||
"referenceNumber": 28,
|
||||
"name": "Autoconf exception 3.0",
|
||||
"licenseExceptionId": "Autoconf-exception-3.0",
|
||||
"seeAlso": [
|
||||
"http://www.gnu.org/licenses/autoconf-exception-3.0.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./PS-or-PDF-font-exception-20170817.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./PS-or-PDF-font-exception-20170817.html",
|
||||
"referenceNumber": 29,
|
||||
"name": "PS/PDF font exception (2017-08-17)",
|
||||
"licenseExceptionId": "PS-or-PDF-font-exception-20170817",
|
||||
"seeAlso": [
|
||||
"https://github.com/ArtifexSoftware/urw-base35-fonts/blob/65962e27febc3883a17e651cdb23e783668c996f/LICENSE"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Autoconf-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Autoconf-exception-2.0.html",
|
||||
"referenceNumber": 30,
|
||||
"name": "Autoconf exception 2.0",
|
||||
"licenseExceptionId": "Autoconf-exception-2.0",
|
||||
"seeAlso": [
|
||||
"http://ac-archive.sourceforge.net/doc/copyright.html",
|
||||
"http://ftp.gnu.org/gnu/autoconf/autoconf-2.59.tar.gz"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./SHL-2.1.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./SHL-2.1.html",
|
||||
"referenceNumber": 31,
|
||||
"name": "Solderpad Hardware License v2.1",
|
||||
"licenseExceptionId": "SHL-2.1",
|
||||
"seeAlso": [
|
||||
"https://solderpad.org/licenses/SHL-2.1/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./LZMA-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./LZMA-exception.html",
|
||||
"referenceNumber": 32,
|
||||
"name": "LZMA exception",
|
||||
"licenseExceptionId": "LZMA-exception",
|
||||
"seeAlso": [
|
||||
"http://nsis.sourceforge.net/Docs/AppendixI.html#I.6"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./GCC-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./GCC-exception-2.0.html",
|
||||
"referenceNumber": 33,
|
||||
"name": "GCC Runtime Library exception 2.0",
|
||||
"licenseExceptionId": "GCC-exception-2.0",
|
||||
"seeAlso": [
|
||||
"https://gcc.gnu.org/git/?p\u003dgcc.git;a\u003dblob;f\u003dgcc/libgcc1.c;h\u003d762f5143fc6eed57b6797c82710f3538aa52b40b;hb\u003dcb143a3ce4fb417c68f5fa2691a1b1b1053dfba9#l10"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./eCos-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./eCos-exception-2.0.html",
|
||||
"referenceNumber": 34,
|
||||
"name": "eCos exception 2.0",
|
||||
"licenseExceptionId": "eCos-exception-2.0",
|
||||
"seeAlso": [
|
||||
"http://ecos.sourceware.org/license-overview.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./gnu-javamail-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./gnu-javamail-exception.html",
|
||||
"referenceNumber": 35,
|
||||
"name": "GNU JavaMail exception",
|
||||
"licenseExceptionId": "gnu-javamail-exception",
|
||||
"seeAlso": [
|
||||
"http://www.gnu.org/software/classpathx/javamail/javamail.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./OCCT-exception-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./OCCT-exception-1.0.html",
|
||||
"referenceNumber": 36,
|
||||
"name": "Open CASCADE Exception 1.0",
|
||||
"licenseExceptionId": "OCCT-exception-1.0",
|
||||
"seeAlso": [
|
||||
"http://www.opencascade.com/content/licensing"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./KiCad-libraries-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./KiCad-libraries-exception.html",
|
||||
"referenceNumber": 37,
|
||||
"name": "KiCad Libraries Exception",
|
||||
"licenseExceptionId": "KiCad-libraries-exception",
|
||||
"seeAlso": [
|
||||
"https://www.kicad.org/libraries/license/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./GCC-exception-3.1.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./GCC-exception-3.1.html",
|
||||
"referenceNumber": 38,
|
||||
"name": "GCC Runtime Library exception 3.1",
|
||||
"licenseExceptionId": "GCC-exception-3.1",
|
||||
"seeAlso": [
|
||||
"http://www.gnu.org/licenses/gcc-exception-3.1.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./freertos-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./freertos-exception-2.0.html",
|
||||
"referenceNumber": 39,
|
||||
"name": "FreeRTOS Exception 2.0",
|
||||
"licenseExceptionId": "freertos-exception-2.0",
|
||||
"seeAlso": [
|
||||
"https://web.archive.org/web/20060809182744/http://www.freertos.org/a00114.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./GPL-CC-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./GPL-CC-1.0.html",
|
||||
"referenceNumber": 17,
|
||||
"referenceNumber": 40,
|
||||
"name": "GPL Cooperation Commitment 1.0",
|
||||
"licenseExceptionId": "GPL-CC-1.0",
|
||||
"seeAlso": [
|
||||
@ -193,143 +449,11 @@
|
||||
"https://gplcc.github.io/gplcc/Project/README-PROJECT.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./OCaml-LGPL-linking-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./OCaml-LGPL-linking-exception.html",
|
||||
"referenceNumber": 18,
|
||||
"name": "OCaml LGPL Linking Exception",
|
||||
"licenseExceptionId": "OCaml-LGPL-linking-exception",
|
||||
"seeAlso": [
|
||||
"https://caml.inria.fr/ocaml/license.en.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Universal-FOSS-exception-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Universal-FOSS-exception-1.0.html",
|
||||
"referenceNumber": 19,
|
||||
"name": "Universal FOSS Exception, Version 1.0",
|
||||
"licenseExceptionId": "Universal-FOSS-exception-1.0",
|
||||
"seeAlso": [
|
||||
"https://oss.oracle.com/licenses/universal-foss-exception/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./i2p-gpl-java-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./i2p-gpl-java-exception.html",
|
||||
"referenceNumber": 20,
|
||||
"name": "i2p GPL+Java Exception",
|
||||
"licenseExceptionId": "i2p-gpl-java-exception",
|
||||
"seeAlso": [
|
||||
"http://geti2p.net/en/get-involved/develop/licenses#java_exception"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./CLISP-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./CLISP-exception-2.0.html",
|
||||
"referenceNumber": 21,
|
||||
"name": "CLISP exception 2.0",
|
||||
"licenseExceptionId": "CLISP-exception-2.0",
|
||||
"seeAlso": [
|
||||
"http://sourceforge.net/p/clisp/clisp/ci/default/tree/COPYRIGHT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./OCCT-exception-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./OCCT-exception-1.0.html",
|
||||
"referenceNumber": 22,
|
||||
"name": "Open CASCADE Exception 1.0",
|
||||
"licenseExceptionId": "OCCT-exception-1.0",
|
||||
"seeAlso": [
|
||||
"http://www.opencascade.com/content/licensing"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Qwt-exception-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Qwt-exception-1.0.html",
|
||||
"referenceNumber": 23,
|
||||
"name": "Qwt exception 1.0",
|
||||
"licenseExceptionId": "Qwt-exception-1.0",
|
||||
"seeAlso": [
|
||||
"http://qwt.sourceforge.net/qwtlicense.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./gnu-javamail-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./gnu-javamail-exception.html",
|
||||
"referenceNumber": 24,
|
||||
"name": "GNU JavaMail exception",
|
||||
"licenseExceptionId": "gnu-javamail-exception",
|
||||
"seeAlso": [
|
||||
"http://www.gnu.org/software/classpathx/javamail/javamail.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./u-boot-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./u-boot-exception-2.0.html",
|
||||
"referenceNumber": 25,
|
||||
"name": "U-Boot exception 2.0",
|
||||
"licenseExceptionId": "u-boot-exception-2.0",
|
||||
"seeAlso": [
|
||||
"http://git.denx.de/?p\u003du-boot.git;a\u003dblob;f\u003dLicenses/Exceptions"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./freertos-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./freertos-exception-2.0.html",
|
||||
"referenceNumber": 26,
|
||||
"name": "FreeRTOS Exception 2.0",
|
||||
"licenseExceptionId": "freertos-exception-2.0",
|
||||
"seeAlso": [
|
||||
"https://web.archive.org/web/20060809182744/http://www.freertos.org/a00114.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Qt-GPL-exception-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Qt-GPL-exception-1.0.html",
|
||||
"referenceNumber": 27,
|
||||
"name": "Qt GPL exception 1.0",
|
||||
"licenseExceptionId": "Qt-GPL-exception-1.0",
|
||||
"seeAlso": [
|
||||
"http://code.qt.io/cgit/qt/qtbase.git/tree/LICENSE.GPL3-EXCEPT"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./OpenJDK-assembly-exception-1.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./OpenJDK-assembly-exception-1.0.html",
|
||||
"referenceNumber": 28,
|
||||
"name": "OpenJDK Assembly exception 1.0",
|
||||
"licenseExceptionId": "OpenJDK-assembly-exception-1.0",
|
||||
"seeAlso": [
|
||||
"http://openjdk.java.net/legal/assembly-exception.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./SHL-2.1.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./SHL-2.1.html",
|
||||
"referenceNumber": 29,
|
||||
"name": "Solderpad Hardware License v2.1",
|
||||
"licenseExceptionId": "SHL-2.1",
|
||||
"seeAlso": [
|
||||
"https://solderpad.org/licenses/SHL-2.1/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./mif-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./mif-exception.html",
|
||||
"referenceNumber": 30,
|
||||
"referenceNumber": 41,
|
||||
"name": "Macros and Inline Functions Exception",
|
||||
"licenseExceptionId": "mif-exception",
|
||||
"seeAlso": [
|
||||
@ -339,128 +463,38 @@
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Fawkes-Runtime-exception.json",
|
||||
"reference": "./Linux-syscall-note.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Fawkes-Runtime-exception.html",
|
||||
"referenceNumber": 31,
|
||||
"name": "Fawkes Runtime Exception",
|
||||
"licenseExceptionId": "Fawkes-Runtime-exception",
|
||||
"detailsUrl": "./Linux-syscall-note.html",
|
||||
"referenceNumber": 42,
|
||||
"name": "Linux Syscall Note",
|
||||
"licenseExceptionId": "Linux-syscall-note",
|
||||
"seeAlso": [
|
||||
"http://www.fawkesrobotics.org/about/license/"
|
||||
"https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/COPYING"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Swift-exception.json",
|
||||
"reference": "./i2p-gpl-java-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Swift-exception.html",
|
||||
"referenceNumber": 32,
|
||||
"name": "Swift Exception",
|
||||
"licenseExceptionId": "Swift-exception",
|
||||
"detailsUrl": "./i2p-gpl-java-exception.html",
|
||||
"referenceNumber": 43,
|
||||
"name": "i2p GPL+Java Exception",
|
||||
"licenseExceptionId": "i2p-gpl-java-exception",
|
||||
"seeAlso": [
|
||||
"https://swift.org/LICENSE.txt",
|
||||
"https://github.com/apple/swift-package-manager/blob/7ab2275f447a5eb37497ed63a9340f8a6d1e488b/LICENSE.txt#L205"
|
||||
"http://geti2p.net/en/get-involved/develop/licenses#java_exception"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./GPL-3.0-linking-exception.json",
|
||||
"reference": "./Libtool-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./GPL-3.0-linking-exception.html",
|
||||
"referenceNumber": 33,
|
||||
"name": "GPL-3.0 Linking Exception",
|
||||
"licenseExceptionId": "GPL-3.0-linking-exception",
|
||||
"detailsUrl": "./Libtool-exception.html",
|
||||
"referenceNumber": 44,
|
||||
"name": "Libtool Exception",
|
||||
"licenseExceptionId": "Libtool-exception",
|
||||
"seeAlso": [
|
||||
"https://www.gnu.org/licenses/gpl-faq.en.html#GPLIncompatibleLibs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./SHL-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./SHL-2.0.html",
|
||||
"referenceNumber": 34,
|
||||
"name": "Solderpad Hardware License v2.0",
|
||||
"licenseExceptionId": "SHL-2.0",
|
||||
"seeAlso": [
|
||||
"https://solderpad.org/licenses/SHL-2.0/"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Classpath-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Classpath-exception-2.0.html",
|
||||
"referenceNumber": 35,
|
||||
"name": "Classpath exception 2.0",
|
||||
"licenseExceptionId": "Classpath-exception-2.0",
|
||||
"seeAlso": [
|
||||
"http://www.gnu.org/software/classpath/license.html",
|
||||
"https://fedoraproject.org/wiki/Licensing/GPL_Classpath_Exception"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./LZMA-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./LZMA-exception.html",
|
||||
"referenceNumber": 36,
|
||||
"name": "LZMA exception",
|
||||
"licenseExceptionId": "LZMA-exception",
|
||||
"seeAlso": [
|
||||
"http://nsis.sourceforge.net/Docs/AppendixI.html#I.6"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Font-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./Font-exception-2.0.html",
|
||||
"referenceNumber": 37,
|
||||
"name": "Font exception 2.0",
|
||||
"licenseExceptionId": "Font-exception-2.0",
|
||||
"seeAlso": [
|
||||
"http://www.gnu.org/licenses/gpl-faq.html#FontException"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./Nokia-Qt-exception-1.1.json",
|
||||
"isDeprecatedLicenseId": true,
|
||||
"detailsUrl": "./Nokia-Qt-exception-1.1.html",
|
||||
"referenceNumber": 38,
|
||||
"name": "Nokia Qt LGPL exception 1.1",
|
||||
"licenseExceptionId": "Nokia-Qt-exception-1.1",
|
||||
"seeAlso": [
|
||||
"https://www.keepassx.org/dev/projects/keepassx/repository/revisions/b8dfb9cc4d5133e0f09cd7533d15a4f1c19a40f2/entry/LICENSE.NOKIA-LGPL-EXCEPTION"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./DigiRule-FOSS-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./DigiRule-FOSS-exception.html",
|
||||
"referenceNumber": 39,
|
||||
"name": "DigiRule FOSS License Exception",
|
||||
"licenseExceptionId": "DigiRule-FOSS-exception",
|
||||
"seeAlso": [
|
||||
"http://www.digirulesolutions.com/drupal/foss"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./eCos-exception-2.0.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./eCos-exception-2.0.html",
|
||||
"referenceNumber": 40,
|
||||
"name": "eCos exception 2.0",
|
||||
"licenseExceptionId": "eCos-exception-2.0",
|
||||
"seeAlso": [
|
||||
"http://ecos.sourceware.org/license-overview.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"reference": "./389-exception.json",
|
||||
"isDeprecatedLicenseId": false,
|
||||
"detailsUrl": "./389-exception.html",
|
||||
"referenceNumber": 41,
|
||||
"name": "389 Directory Server Exception",
|
||||
"licenseExceptionId": "389-exception",
|
||||
"seeAlso": [
|
||||
"http://directory.fedoraproject.org/wiki/GPL_Exception_License_Text"
|
||||
"http://git.savannah.gnu.org/cgit/libtool.git/tree/m4/libtool.m4"
|
||||
]
|
||||
}
|
||||
],
|
||||
"releaseDate": "2022-05-08"
|
||||
"releaseDate": "2022-08-12"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -30,12 +30,23 @@ class DependencyCollector
|
||||
@requirements = Requirements.new
|
||||
end
|
||||
|
||||
def initialize_copy(other)
|
||||
super
|
||||
@deps = @deps.dup
|
||||
@requirements = @requirements.dup
|
||||
end
|
||||
|
||||
def add(spec)
|
||||
case dep = fetch(spec)
|
||||
when Dependency
|
||||
@deps << dep
|
||||
when Requirement
|
||||
@requirements << dep
|
||||
when nil
|
||||
# no-op when we have a nil value
|
||||
nil
|
||||
else
|
||||
raise ArgumentError, "DependencyCollector#add passed something that isn't a Dependency or Requirement!"
|
||||
end
|
||||
dep
|
||||
end
|
||||
@ -63,7 +74,7 @@ class DependencyCollector
|
||||
Dependency.new("git", tags)
|
||||
end
|
||||
|
||||
def brewed_curl_dep_if_needed(tags)
|
||||
def curl_dep_if_needed(tags)
|
||||
Dependency.new("curl", tags)
|
||||
end
|
||||
|
||||
@ -148,7 +159,7 @@ class DependencyCollector
|
||||
strategy = spec.download_strategy
|
||||
|
||||
if strategy <= HomebrewCurlDownloadStrategy
|
||||
@deps << brewed_curl_dep_if_needed(tags)
|
||||
@deps << curl_dep_if_needed(tags)
|
||||
parse_url_spec(spec.url, tags)
|
||||
elsif strategy <= CurlDownloadStrategy
|
||||
parse_url_spec(spec.url, tags)
|
||||
|
||||
@ -138,11 +138,13 @@ module Homebrew
|
||||
replacement_pairs << fetch_cask(tmp_contents, config: lang_config)
|
||||
end
|
||||
|
||||
if tmp_contents.include?("Hardware::CPU.intel?")
|
||||
other_intel = !Hardware::CPU.intel?
|
||||
other_contents = tmp_contents.gsub("Hardware::CPU.intel?", other_intel.to_s)
|
||||
other_cask = Cask::CaskLoader.load(other_contents)
|
||||
# TODO: remove the `Hardware::CPU.intel?` substitution once no casks use the conditional
|
||||
other_intel = !Hardware::CPU.intel?
|
||||
Homebrew::SimulateSystem.arch = other_intel ? :intel : :arm
|
||||
other_contents = tmp_contents.gsub("Hardware::CPU.intel?", other_intel.to_s)
|
||||
other_cask = Cask::CaskLoader.load(other_contents)
|
||||
|
||||
if other_cask.url.to_s != tmp_cask.url.to_s
|
||||
if other_cask.sha256 != :no_check && other_cask.language.blank?
|
||||
replacement_pairs << fetch_cask(other_contents)
|
||||
end
|
||||
@ -152,6 +154,8 @@ module Homebrew
|
||||
replacement_pairs << fetch_cask(other_contents, config: lang_config)
|
||||
end
|
||||
end
|
||||
|
||||
Homebrew::SimulateSystem.clear
|
||||
end
|
||||
end
|
||||
|
||||
@ -159,8 +163,8 @@ module Homebrew
|
||||
hash_regex = (old_hash == :no_check) ? ":no_check" : "[\"']#{Regexp.escape(old_hash.to_s)}[\"']"
|
||||
|
||||
replacement_pairs << [
|
||||
/sha256\s+#{hash_regex}/m,
|
||||
"sha256 #{(new_hash == :no_check) ? ":no_check" : "\"#{new_hash}\""}",
|
||||
/#{hash_regex}/m,
|
||||
((new_hash == :no_check) ? ":no_check" : "\"#{new_hash}\"").to_s,
|
||||
]
|
||||
end
|
||||
|
||||
|
||||
@ -39,7 +39,6 @@ module Homebrew
|
||||
hidden: true
|
||||
switch "--write-only",
|
||||
description: "Make the expected file modifications without taking any Git actions."
|
||||
switch "--write", hidden: true
|
||||
switch "--commit",
|
||||
depends_on: "--write-only",
|
||||
description: "When passed with `--write-only`, generate a new commit after writing changes " \
|
||||
@ -87,7 +86,6 @@ module Homebrew
|
||||
description: "Exclude these Python packages when finding resources."
|
||||
|
||||
conflicts "--dry-run", "--write-only"
|
||||
conflicts "--dry-run", "--write"
|
||||
conflicts "--no-audit", "--strict"
|
||||
conflicts "--no-audit", "--online"
|
||||
conflicts "--url", "--tag"
|
||||
@ -100,8 +98,6 @@ module Homebrew
|
||||
def bump_formula_pr
|
||||
args = bump_formula_pr_args.parse
|
||||
|
||||
odisabled "`brew bump-formula-pr --write`", "`brew bump-formula-pr --write-only`" if args.write?
|
||||
|
||||
if args.revision.present? && args.tag.nil? && args.version.nil?
|
||||
raise UsageError, "`--revision` must be passed with either `--tag` or `--version`!"
|
||||
end
|
||||
|
||||
@ -50,7 +50,7 @@ module Homebrew
|
||||
|
||||
if args.test?
|
||||
result.display_test_output(strict: args.strict?)
|
||||
Homebrew.failed = true if result.broken_library_linkage?(strict: args.strict?)
|
||||
Homebrew.failed = true if result.broken_library_linkage?(test: true, strict: args.strict?)
|
||||
elsif args.reverse?
|
||||
result.display_reverse_output
|
||||
else
|
||||
|
||||
@ -30,7 +30,6 @@ module Homebrew
|
||||
description: "Skip running `brew bottle` before uploading."
|
||||
flag "--committer=",
|
||||
description: "Specify a committer name and email in `git`'s standard author format."
|
||||
flag "--github-org=", hidden: true
|
||||
flag "--root-url=",
|
||||
description: "Use the specified <URL> as the root of the bottle's URL instead of Homebrew's default."
|
||||
flag "--root-url-using=",
|
||||
@ -90,8 +89,6 @@ module Homebrew
|
||||
def pr_upload
|
||||
args = pr_upload_args.parse
|
||||
|
||||
odisabled "`brew pr-upload --github-org`", "`brew pr-upload` without `--github-org`" if args.github_org
|
||||
|
||||
json_files = Dir["*.bottle.json"]
|
||||
odie "No bottle JSON files found in the current working directory" if json_files.blank?
|
||||
bottles_hash = bottles_hash_from_json_files(json_files, args)
|
||||
|
||||
@ -119,6 +119,7 @@ module Homebrew
|
||||
if args.retry? && @test_failed.add?(f)
|
||||
oh1 "Testing #{f.full_name} (again)"
|
||||
f.clear_cache
|
||||
ENV["RUST_BACKTRACE"] = "full"
|
||||
true
|
||||
else
|
||||
Homebrew.failed = true
|
||||
|
||||
@ -78,8 +78,8 @@ class DevelopmentTools
|
||||
end
|
||||
|
||||
sig { params(cc: String).returns(Version) }
|
||||
def non_apple_gcc_version(cc)
|
||||
(@non_apple_gcc_version ||= {}).fetch(cc) do
|
||||
def gcc_version(cc)
|
||||
(@gcc_version ||= {}).fetch(cc) do
|
||||
path = HOMEBREW_PREFIX/"opt/#{CompilerSelector.preferred_gcc}/bin"/cc
|
||||
path = locate(cc) unless path.exist?
|
||||
version = if path &&
|
||||
@ -88,14 +88,14 @@ class DevelopmentTools
|
||||
else
|
||||
Version::NULL
|
||||
end
|
||||
@non_apple_gcc_version[cc] = version
|
||||
@gcc_version[cc] = version
|
||||
end
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def clear_version_cache
|
||||
@clang_version = @clang_build_version = nil
|
||||
@non_apple_gcc_version = {}
|
||||
@gcc_version = {}
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
|
||||
@ -466,9 +466,19 @@ end
|
||||
|
||||
# Raised when an error occurs during a formula build.
|
||||
class BuildError < RuntimeError
|
||||
extend T::Sig
|
||||
|
||||
attr_reader :cmd, :args, :env
|
||||
attr_accessor :formula, :options
|
||||
|
||||
sig {
|
||||
params(
|
||||
formula: T.nilable(Formula),
|
||||
cmd: T.any(String, Pathname),
|
||||
args: T::Array[T.any(String, Pathname, Integer)],
|
||||
env: T::Hash[String, T.untyped],
|
||||
).void
|
||||
}
|
||||
def initialize(formula, cmd, args, env)
|
||||
@formula = formula
|
||||
@cmd = cmd
|
||||
@ -478,10 +488,12 @@ class BuildError < RuntimeError
|
||||
super "Failed executing: #{cmd} #{pretty_args}".strip
|
||||
end
|
||||
|
||||
sig { returns(T::Array[T.untyped]) }
|
||||
def issues
|
||||
@issues ||= fetch_issues
|
||||
end
|
||||
|
||||
sig { returns(T::Array[T.untyped]) }
|
||||
def fetch_issues
|
||||
GitHub.issues_for_formula(formula.name, tap: formula.tap, state: "open")
|
||||
rescue GitHub::API::RateLimitExceededError => e
|
||||
@ -489,6 +501,7 @@ class BuildError < RuntimeError
|
||||
[]
|
||||
end
|
||||
|
||||
sig { params(verbose: T::Boolean).void }
|
||||
def dump(verbose: false)
|
||||
puts
|
||||
|
||||
|
||||
@ -33,19 +33,21 @@ module EnvActivation
|
||||
|
||||
sig {
|
||||
params(
|
||||
env: T.nilable(String),
|
||||
cc: T.nilable(String),
|
||||
build_bottle: T::Boolean,
|
||||
bottle_arch: T.nilable(String),
|
||||
_block: T.proc.returns(T.untyped),
|
||||
env: T.nilable(String),
|
||||
cc: T.nilable(String),
|
||||
build_bottle: T::Boolean,
|
||||
bottle_arch: T.nilable(String),
|
||||
debug_symbols: T.nilable(T::Boolean),
|
||||
_block: T.proc.returns(T.untyped),
|
||||
).returns(T.untyped)
|
||||
}
|
||||
def with_build_environment(env: nil, cc: nil, build_bottle: false, bottle_arch: nil, &_block)
|
||||
def with_build_environment(env: nil, cc: nil, build_bottle: false, bottle_arch: nil, debug_symbols: false, &_block)
|
||||
old_env = to_hash.dup
|
||||
tmp_env = to_hash.dup.extend(EnvActivation)
|
||||
T.cast(tmp_env, EnvActivation).activate_extensions!(env: env)
|
||||
T.cast(tmp_env, T.any(Superenv, Stdenv))
|
||||
.setup_build_environment(cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch)
|
||||
.setup_build_environment(cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch,
|
||||
debug_symbols: debug_symbols)
|
||||
replace(tmp_env)
|
||||
|
||||
begin
|
||||
|
||||
@ -40,13 +40,16 @@ module SharedEnvExtension
|
||||
build_bottle: T.nilable(T::Boolean),
|
||||
bottle_arch: T.nilable(String),
|
||||
testing_formula: T::Boolean,
|
||||
debug_symbols: T.nilable(T::Boolean),
|
||||
).void
|
||||
}
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false)
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
||||
debug_symbols: false)
|
||||
@formula = formula
|
||||
@cc = cc
|
||||
@build_bottle = build_bottle
|
||||
@bottle_arch = bottle_arch
|
||||
@debug_symbols = debug_symbols
|
||||
reset
|
||||
end
|
||||
private :setup_build_environment
|
||||
|
||||
@ -21,9 +21,11 @@ module Stdenv
|
||||
build_bottle: T.nilable(T::Boolean),
|
||||
bottle_arch: T.nilable(String),
|
||||
testing_formula: T::Boolean,
|
||||
debug_symbols: T.nilable(T::Boolean),
|
||||
).void
|
||||
}
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false)
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
||||
debug_symbols: false)
|
||||
super
|
||||
|
||||
self["HOMEBREW_ENV"] = "std"
|
||||
|
||||
@ -55,9 +55,11 @@ module Superenv
|
||||
build_bottle: T.nilable(T::Boolean),
|
||||
bottle_arch: T.nilable(String),
|
||||
testing_formula: T::Boolean,
|
||||
debug_symbols: T.nilable(T::Boolean),
|
||||
).void
|
||||
}
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false)
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
||||
debug_symbols: false)
|
||||
super
|
||||
send(compiler)
|
||||
|
||||
@ -87,6 +89,8 @@ module Superenv
|
||||
self["HOMEBREW_DEPENDENCIES"] = determine_dependencies
|
||||
self["HOMEBREW_FORMULA_PREFIX"] = @formula.prefix unless @formula.nil?
|
||||
|
||||
set_debug_symbols if debug_symbols
|
||||
|
||||
# The HOMEBREW_CCCFG ENV variable is used by the ENV/cc tool to control
|
||||
# compiler flag stripping. It consists of a string of characters which act
|
||||
# as flags. Some of these flags are mutually exclusive.
|
||||
@ -100,6 +104,7 @@ module Superenv
|
||||
# d - Don't strip -march=<target>. Use only in formulae that
|
||||
# have runtime detection of CPU features.
|
||||
# w - Pass -no_weak_imports to the linker
|
||||
# D - Generate debugging information
|
||||
#
|
||||
# These flags will also be present:
|
||||
# a - apply fix for apr-1-config path
|
||||
@ -125,8 +130,13 @@ module Superenv
|
||||
|
||||
sig { returns(T::Array[Pathname]) }
|
||||
def homebrew_extra_paths
|
||||
[]
|
||||
# Reverse sort by version so that we prefer the newest when there are multiple.
|
||||
deps.select { |d| d.name.match? Version.formula_optionally_versioned_regex(:python) }
|
||||
.sort_by(&:version)
|
||||
.reverse
|
||||
.map { |d| d.opt_libexec/"bin" }
|
||||
end
|
||||
alias generic_homebrew_extra_paths homebrew_extra_paths
|
||||
|
||||
sig { returns(T.nilable(PATH)) }
|
||||
def determine_path
|
||||
@ -331,6 +341,11 @@ module Superenv
|
||||
append_to_cccfg "g" if compiler == :clang
|
||||
end
|
||||
|
||||
sig { void }
|
||||
def set_debug_symbols
|
||||
append_to_cccfg "D"
|
||||
end
|
||||
|
||||
# @private
|
||||
sig { void }
|
||||
def refurbish_args
|
||||
|
||||
@ -4,8 +4,6 @@
|
||||
class CompilerSelector
|
||||
sig { returns(String) }
|
||||
def self.preferred_gcc
|
||||
# gcc-5 is the lowest gcc version we support on Linux.
|
||||
# gcc-5 is the default gcc in Ubuntu 16.04 (used for our CI)
|
||||
"gcc@5"
|
||||
OS::LINUX_PREFERRED_GCC_FORMULA
|
||||
end
|
||||
end
|
||||
|
||||
@ -139,6 +139,34 @@ module Homebrew
|
||||
e.g. by using homebrew instead).
|
||||
EOS
|
||||
end
|
||||
|
||||
def check_gcc_dependent_linkage
|
||||
gcc_dependents = Formula.installed.select do |formula|
|
||||
next false unless formula.tap&.core_tap?
|
||||
|
||||
formula.recursive_dependencies.map(&:name).include? "gcc"
|
||||
rescue TapFormulaUnavailableError
|
||||
false
|
||||
end
|
||||
return if gcc_dependents.empty?
|
||||
|
||||
badly_linked = gcc_dependents.select do |dependent|
|
||||
keg = Keg.new(dependent.prefix)
|
||||
keg.binary_executable_or_library_files.any? do |binary|
|
||||
paths = binary.rpath.split(":")
|
||||
versioned_linkage = paths.any? { |path| path.match?(%r{lib/gcc/\d+$}) }
|
||||
unversioned_linkage = paths.any? { |path| path.match?(%r{lib/gcc/current$}) }
|
||||
|
||||
versioned_linkage && !unversioned_linkage
|
||||
end
|
||||
end
|
||||
return if badly_linked.empty?
|
||||
|
||||
inject_file_list badly_linked, <<~EOS
|
||||
Formulae which link to GCC through a versioned path were found. These formulae
|
||||
are prone to breaking when GCC is updated. You should `brew reinstall` these formulae:
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -2,11 +2,10 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Stdenv
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false)
|
||||
generic_setup_build_environment(
|
||||
formula: formula, cc: cc, build_bottle: build_bottle,
|
||||
bottle_arch: bottle_arch, testing_formula: testing_formula
|
||||
)
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
||||
debug_symbols: false)
|
||||
generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch,
|
||||
testing_formula: testing_formula, debug_symbols: debug_symbols)
|
||||
|
||||
prepend_path "CPATH", HOMEBREW_PREFIX/"include"
|
||||
prepend_path "LIBRARY_PATH", HOMEBREW_PREFIX/"lib"
|
||||
|
||||
@ -15,11 +15,10 @@ module Superenv
|
||||
end
|
||||
|
||||
# @private
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false)
|
||||
generic_setup_build_environment(
|
||||
formula: formula, cc: cc, build_bottle: build_bottle,
|
||||
bottle_arch: bottle_arch, testing_formula: testing_formula
|
||||
)
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
||||
debug_symbols: false)
|
||||
generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch,
|
||||
testing_formula: testing_formula, debug_symbols: debug_symbols)
|
||||
self["HOMEBREW_OPTIMIZATION_LEVEL"] = "O2"
|
||||
self["HOMEBREW_DYNAMIC_LINKER"] = determine_dynamic_linker_path
|
||||
self["HOMEBREW_RPATH_PATHS"] = determine_rpath_paths(@formula)
|
||||
@ -27,7 +26,7 @@ module Superenv
|
||||
end
|
||||
|
||||
def homebrew_extra_paths
|
||||
paths = []
|
||||
paths = generic_homebrew_extra_paths
|
||||
paths += %w[binutils make].map do |f|
|
||||
bin = Formulary.factory(f).opt_bin
|
||||
bin if bin.directory?
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
class Formula
|
||||
undef shared_library
|
||||
undef rpath
|
||||
undef loader_path
|
||||
undef deuniversalize_machos
|
||||
|
||||
sig { params(name: String, version: T.nilable(T.any(String, Integer))).returns(String) }
|
||||
@ -17,8 +17,8 @@ class Formula
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def rpath
|
||||
"'$ORIGIN/../lib'"
|
||||
def loader_path
|
||||
"$ORIGIN"
|
||||
end
|
||||
|
||||
sig { params(targets: T.nilable(T.any(Pathname, String))).void }
|
||||
|
||||
@ -10,7 +10,6 @@ class LinkageChecker
|
||||
libanl.so.1
|
||||
libatomic.so.1
|
||||
libc.so.6
|
||||
libcrypt.so.1
|
||||
libdl.so.2
|
||||
libm.so.6
|
||||
libmvec.so.1
|
||||
@ -27,18 +26,26 @@ class LinkageChecker
|
||||
].freeze
|
||||
|
||||
def display_deprecated_warning(strict: false)
|
||||
return unless @libcrypt_found
|
||||
|
||||
# Steps when moving this to `odisabled`:
|
||||
# - Remove `libcrypt.so.1` from SYSTEM_LIBRARY_ALLOWLIST above.
|
||||
# Steps when moving these to `odisabled`:
|
||||
# - Remove the old library from SYSTEM_LIBRARY_ALLOWLIST above.
|
||||
# - Remove the `disable` and `disable_for_developer` kwargs here.
|
||||
# - Remove `broken_library_linkage?` override below and the generic alias in HOMEBREW_LIBRARY/linkage_checker.rb.
|
||||
# - Remove `fail_on_libcrypt1?`.
|
||||
# Steps when removing this entirely (assuming the above has already been done):
|
||||
# - Adjust the `broken_library_linkage?` override below to not check for the library.
|
||||
# - Remove the relevant `fail_on_lib*?`.
|
||||
# If there's no more deprecations left:
|
||||
# - Remove the `broken_library_linkage?` override and the generic alias in HOMEBREW_LIBRARY/linkage_checker.rb.
|
||||
#
|
||||
# Steps when removing handling for a library entirely (assuming the steps to `odisabled` has already been done):
|
||||
# - Remove the relevant setting of `@lib*_found` in `check_dylibs` below.
|
||||
# - Remove the `odisabled` line
|
||||
# If there's no library deprecated/disabled handling left:
|
||||
# - Remove the `display_` overrides here and the associated generic aliases in HOMEBREW_LIBRARY/linkage_checker.rb
|
||||
# - Remove the setting of `@libcrypt_found` in `check_dylibs` below.
|
||||
odeprecated "linkage to libcrypt.so.1", "libcrypt.so.2 in the libxcrypt formula",
|
||||
disable: fail_on_libcrypt1?(strict: strict),
|
||||
|
||||
odisabled "linkage to libcrypt.so.1", "libcrypt.so.2 in the libxcrypt formula" if @libcrypt_found
|
||||
|
||||
return unless @libnsl_found
|
||||
|
||||
odeprecated "linkage to libnsl.so.1", "libnsl.so.3 in the libnsl formula",
|
||||
disable: fail_on_libnsl1?(strict: strict),
|
||||
disable_for_developers: false
|
||||
end
|
||||
|
||||
@ -52,20 +59,21 @@ class LinkageChecker
|
||||
display_deprecated_warning(strict: strict)
|
||||
end
|
||||
|
||||
def broken_library_linkage?(strict: false)
|
||||
generic_broken_library_linkage?(strict: strict) || (fail_on_libcrypt1?(strict: strict) && @libcrypt_found)
|
||||
def broken_library_linkage?(test: false, strict: false)
|
||||
generic_broken_library_linkage?(test: test, strict: strict) || (fail_on_libnsl1?(strict: strict) && @libnsl_found)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fail_on_libcrypt1?(strict:)
|
||||
strict || ENV["HOMEBREW_DISALLOW_LIBCRYPT1"].present?
|
||||
def fail_on_libnsl1?(strict:)
|
||||
strict || ENV["HOMEBREW_DISALLOW_LIBNSL1"].present?
|
||||
end
|
||||
|
||||
def check_dylibs(rebuild_cache:)
|
||||
generic_check_dylibs(rebuild_cache: rebuild_cache)
|
||||
|
||||
@libcrypt_found = true if @system_dylibs.any? { |s| File.basename(s) == "libcrypt.so.1" }
|
||||
@libnsl_found = true if @system_dylibs.any? { |s| File.basename(s) == "libnsl.so.1" }
|
||||
|
||||
# glibc and gcc are implicit dependencies.
|
||||
# No other linkage to system libraries is expected or desired.
|
||||
|
||||
@ -4,11 +4,11 @@
|
||||
module SharedEnvExtension
|
||||
extend T::Sig
|
||||
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false)
|
||||
generic_shared_setup_build_environment(
|
||||
formula: formula, cc: cc, build_bottle: build_bottle,
|
||||
bottle_arch: bottle_arch, testing_formula: testing_formula
|
||||
)
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
||||
debug_symbols: false)
|
||||
generic_shared_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle,
|
||||
bottle_arch: bottle_arch, testing_formula: testing_formula,
|
||||
debug_symbols: debug_symbols)
|
||||
|
||||
# Normalise the system Perl version used, where multiple may be available
|
||||
self["VERSIONER_PERL_VERSION"] = MacOS.preferred_perl_version
|
||||
|
||||
@ -10,11 +10,10 @@ module Stdenv
|
||||
["#{HOMEBREW_LIBRARY}/Homebrew/os/mac/pkgconfig/#{MacOS.version}"]
|
||||
end
|
||||
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false)
|
||||
generic_setup_build_environment(
|
||||
formula: formula, cc: cc, build_bottle: build_bottle,
|
||||
bottle_arch: bottle_arch, testing_formula: testing_formula
|
||||
)
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
||||
debug_symbols: false)
|
||||
generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch,
|
||||
testing_formula: testing_formula, debug_symbols: debug_symbols)
|
||||
|
||||
append "LDFLAGS", "-Wl,-headerpad_max_install_names"
|
||||
|
||||
|
||||
@ -85,7 +85,8 @@ module Superenv
|
||||
end
|
||||
|
||||
# @private
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false)
|
||||
def setup_build_environment(formula: nil, cc: nil, build_bottle: false, bottle_arch: nil, testing_formula: false,
|
||||
debug_symbols: false)
|
||||
sdk = formula ? MacOS.sdk_for_formula(formula) : MacOS.sdk
|
||||
is_xcode_sdk = sdk&.source == :xcode
|
||||
|
||||
@ -100,10 +101,8 @@ module Superenv
|
||||
MacOS::CLT::PKG_PATH
|
||||
end
|
||||
|
||||
generic_setup_build_environment(
|
||||
formula: formula, cc: cc, build_bottle: build_bottle,
|
||||
bottle_arch: bottle_arch, testing_formula: testing_formula
|
||||
)
|
||||
generic_setup_build_environment(formula: formula, cc: cc, build_bottle: build_bottle, bottle_arch: bottle_arch,
|
||||
testing_formula: testing_formula, debug_symbols: debug_symbols)
|
||||
|
||||
# Filter out symbols known not to be defined since GNU Autotools can't
|
||||
# reliably figure this out with Xcode 8 and above.
|
||||
|
||||
@ -62,4 +62,19 @@ class Keg
|
||||
#{result.stderr}
|
||||
EOS
|
||||
end
|
||||
|
||||
def prepare_debug_symbols
|
||||
binary_executable_or_library_files.each do |file|
|
||||
odebug "Extracting symbols #{file}"
|
||||
|
||||
result = system_command("dsymutil", args: [file], print_stderr: false)
|
||||
next if result.success?
|
||||
|
||||
# If it fails again, error out
|
||||
ofail <<~EOS
|
||||
Failed to extract symbols from #{file}:
|
||||
#{result.stderr}
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -435,16 +435,26 @@ class Formula
|
||||
end
|
||||
|
||||
# If this is a `@`-versioned formula.
|
||||
sig { returns(T::Boolean) }
|
||||
def versioned_formula?
|
||||
name.include?("@")
|
||||
end
|
||||
|
||||
# Returns any `@`-versioned formulae for any formula (including versioned formulae).
|
||||
def versioned_formulae
|
||||
Pathname.glob(path.to_s.gsub(/(@[\d.]+)?\.rb$/, "@*.rb")).map do |versioned_path|
|
||||
# Returns any `@`-versioned formulae names for any formula (including versioned formulae).
|
||||
sig { returns(T::Array[String]) }
|
||||
def versioned_formulae_names
|
||||
@versioned_formulae_names ||= Pathname.glob(path.to_s.gsub(/(@[\d.]+)?\.rb$/, "@*.rb")).map do |versioned_path|
|
||||
next if versioned_path == path
|
||||
|
||||
Formula[versioned_path.basename(".rb").to_s]
|
||||
versioned_path.basename(".rb").to_s
|
||||
end.compact.sort
|
||||
end
|
||||
|
||||
# Returns any `@`-versioned Formula objects for any Formula (including versioned formulae).
|
||||
sig { returns(T::Array[Formula]) }
|
||||
def versioned_formulae
|
||||
@versioned_formulae ||= versioned_formulae_names.map do |name|
|
||||
Formula[name]
|
||||
rescue FormulaUnavailableError
|
||||
nil
|
||||
end.compact.sort_by(&:version).reverse
|
||||
@ -1270,11 +1280,11 @@ class Formula
|
||||
# Yields |self,staging| with current working directory set to the uncompressed tarball
|
||||
# where staging is a {Mktemp} staging context.
|
||||
# @private
|
||||
def brew(fetch: true, keep_tmp: false, interactive: false)
|
||||
def brew(fetch: true, keep_tmp: false, debug_symbols: false, interactive: false)
|
||||
@prefix_returns_versioned_prefix = true
|
||||
active_spec.fetch if fetch
|
||||
stage(interactive: interactive) do |staging|
|
||||
staging.retain! if keep_tmp
|
||||
stage(interactive: interactive, debug_symbols: debug_symbols) do |staging|
|
||||
staging.retain! if keep_tmp || debug_symbols
|
||||
|
||||
prepare_patches
|
||||
fetch_patches if fetch
|
||||
@ -1572,9 +1582,23 @@ class Formula
|
||||
end
|
||||
|
||||
# Executable/Library RPATH according to platform conventions.
|
||||
#
|
||||
# Optionally specify a `source` or `target` depending on the location
|
||||
# of the file containing the RPATH command and where its target is located.
|
||||
#
|
||||
# <pre>
|
||||
# rpath #=> "@loader_path/../lib"
|
||||
# rpath(target: frameworks) #=> "@loader_path/../Frameworks"
|
||||
# rpath(source: libexec/"bin") #=> "@loader_path/../../lib"
|
||||
# </pre>
|
||||
sig { params(source: Pathname, target: Pathname).returns(String) }
|
||||
def rpath(source: bin, target: lib)
|
||||
"#{loader_path}/#{target.relative_path_from(source)}"
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def rpath
|
||||
"@loader_path/../lib"
|
||||
def loader_path
|
||||
"@loader_path"
|
||||
end
|
||||
|
||||
# Creates a new `Time` object for use in the formula as the build time.
|
||||
@ -1622,6 +1646,98 @@ class Formula
|
||||
end
|
||||
private :extract_macho_slice_from
|
||||
|
||||
# Generate shell completions for a formula for bash, zsh, and fish, using the formula's executable.
|
||||
#
|
||||
# @param commands [Pathname, String] the path to the executable and any passed subcommand(s)
|
||||
# to use for generating the completion scripts.
|
||||
# @param base_name [String] the base name of the generated completion script. Defaults to the formula name.
|
||||
# @param shells [Array<Symbol>] the shells to generate completion scripts for. Defaults to `[:bash, :zsh, :fish]`.
|
||||
# @param shell_parameter_format [String, Symbol] specify how `shells` should each be passed
|
||||
# to the `executable`. Takes either a String representing a prefix, or one of [:flag, :arg, :none].
|
||||
# Defaults to plainly passing the shell.
|
||||
#
|
||||
# @example Using default values for optional arguments
|
||||
# generate_completions_from_executable(bin/"foo", "completions")
|
||||
# translates to
|
||||
#
|
||||
# (bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo", "completions", "bash")
|
||||
#
|
||||
# (zsh_completion/"_foo").write Utils.safe_popen_read({ "SHELL" => "zsh" }, bin/"foo", "completions", "zsh")
|
||||
#
|
||||
# (fish_completion/"foo.fish").write Utils.safe_popen_read({ "SHELL" => "fish" }, bin/"foo", "completions", "fish")
|
||||
#
|
||||
# @example Selecting shells and using a different base_name
|
||||
# generate_completions_from_executable(bin/"foo", "completions", shells: [:bash, :zsh], base_name: "bar")
|
||||
# translates to
|
||||
#
|
||||
# (bash_completion/"bar").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo", "completions", "bash")
|
||||
#
|
||||
# (zsh_completion/"_bar").write Utils.safe_popen_read({ "SHELL" => "zsh" }, bin/"foo", "completions", "zsh")
|
||||
#
|
||||
# @example Using predefined shell_parameter_format :flag
|
||||
# generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: :flag, shells: [:bash])
|
||||
# translates to
|
||||
#
|
||||
# (bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo", "completions", "--bash")
|
||||
#
|
||||
# @example Using predefined shell_parameter_format :arg
|
||||
# generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: :arg, shells: [:bash])
|
||||
# translates to
|
||||
#
|
||||
# (bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo",
|
||||
# "completions", "--shell=bash")
|
||||
#
|
||||
# @example Using predefined shell_parameter_format :none
|
||||
# generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: :none, shells: [:bash])
|
||||
# translates to
|
||||
#
|
||||
# (bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo", "completions")
|
||||
#
|
||||
# @example Using custom shell_parameter_format
|
||||
# generate_completions_from_executable(bin/"foo", "completions", shell_parameter_format: "--selected-shell=",
|
||||
# shells: [:bash])
|
||||
# translates to
|
||||
#
|
||||
# (bash_completion/"foo").write Utils.safe_popen_read({ "SHELL" => "bash" }, bin/"foo",
|
||||
# "completions", "--selected-shell=bash")
|
||||
sig {
|
||||
params(commands: T.any(Pathname, String), base_name: String, shells: T::Array[Symbol],
|
||||
shell_parameter_format: T.nilable(T.any(Symbol, String))).void
|
||||
}
|
||||
def generate_completions_from_executable(*commands,
|
||||
base_name: name,
|
||||
shells: [:bash, :zsh, :fish],
|
||||
shell_parameter_format: nil)
|
||||
completion_script_path_map = {
|
||||
bash: bash_completion/base_name,
|
||||
zsh: zsh_completion/"_#{base_name}",
|
||||
fish: fish_completion/"#{base_name}.fish",
|
||||
}
|
||||
|
||||
shells.each do |shell|
|
||||
script_path = completion_script_path_map[shell]
|
||||
shell_parameter = if shell_parameter_format.nil?
|
||||
shell.to_s
|
||||
elsif shell_parameter_format == :flag
|
||||
"--#{shell}"
|
||||
elsif shell_parameter_format == :arg
|
||||
"--shell=#{shell}"
|
||||
elsif shell_parameter_format == :none
|
||||
""
|
||||
else
|
||||
"#{shell_parameter_format}#{shell}"
|
||||
end
|
||||
|
||||
popen_read_args = %w[]
|
||||
popen_read_args << commands
|
||||
popen_read_args << shell_parameter
|
||||
popen_read_args.flatten!
|
||||
|
||||
script_path.dirname.mkpath
|
||||
script_path.write Utils.safe_popen_read({ "SHELL" => shell.to_s }, *popen_read_args)
|
||||
end
|
||||
end
|
||||
|
||||
# an array of all core {Formula} names
|
||||
# @private
|
||||
def self.core_names
|
||||
@ -1911,7 +2027,7 @@ class Formula
|
||||
# `any_installed_keg` and `runtime_dependencies` `select`s ensure
|
||||
# that we don't end up with something `Formula#runtime_dependencies` can't
|
||||
# read from a `Tab`.
|
||||
Formula.cache[:runtime_installed_formula_dependents] = {}
|
||||
Formula.cache[:runtime_installed_formula_dependents] ||= {}
|
||||
Formula.cache[:runtime_installed_formula_dependents][full_name] ||= Formula.installed
|
||||
.select(&:any_installed_keg)
|
||||
.select(&:runtime_dependencies)
|
||||
@ -2219,7 +2335,7 @@ class Formula
|
||||
def inreplace(paths, before = nil, after = nil, audit_result = true) # rubocop:disable Style/OptionalBooleanParameter
|
||||
super(paths, before, after, audit_result)
|
||||
rescue Utils::Inreplace::Error
|
||||
raise BuildError.new(self, "inreplace", paths, nil)
|
||||
raise BuildError.new(self, "inreplace", paths, {})
|
||||
end
|
||||
|
||||
protected
|
||||
@ -2529,8 +2645,8 @@ class Formula
|
||||
}
|
||||
end
|
||||
|
||||
def stage(interactive: false)
|
||||
active_spec.stage do |staging|
|
||||
def stage(interactive: false, debug_symbols: false)
|
||||
active_spec.stage(debug_symbols: debug_symbols) do |staging|
|
||||
@source_modified_time = active_spec.source_modified_time
|
||||
@buildpath = Pathname.pwd
|
||||
env_home = buildpath/".brew_home"
|
||||
|
||||
@ -263,7 +263,10 @@ module Homebrew
|
||||
next
|
||||
end
|
||||
|
||||
if dep_f.oldname && dep.name.split("/").last == dep_f.oldname
|
||||
# FIXME: Remove `glib-utils` exemption when the following PRs are merged:
|
||||
# https://github.com/Homebrew/homebrew-core/pull/108307
|
||||
# https://github.com/Homebrew/homebrew-core/pull/108497
|
||||
if dep_f.oldname && dep.name.split("/").last == dep_f.oldname && dep_f.oldname != "glib-utils"
|
||||
problem "Dependency '#{dep.name}' was renamed; use new name '#{dep_f.name}'."
|
||||
end
|
||||
|
||||
@ -332,6 +335,13 @@ module Homebrew
|
||||
end
|
||||
|
||||
return unless @core_tap
|
||||
|
||||
bad_gcc_dep = linux_only_gcc_dep?(formula) && (@strict || begin
|
||||
fv = FormulaVersions.new(formula)
|
||||
fv.formula_at_revision("origin/HEAD") { |prev_f| !linux_only_gcc_dep?(prev_f) }
|
||||
end)
|
||||
problem "Formulae in homebrew/core should not have a Linux-only dependency on GCC." if bad_gcc_dep
|
||||
|
||||
return if formula.tap&.audit_exception :versioned_dependencies_conflicts_allowlist, formula.name
|
||||
|
||||
# The number of conflicts on Linux is absurd.
|
||||
@ -344,6 +354,10 @@ module Homebrew
|
||||
recursive_runtime_formulae.each do |f|
|
||||
name = f.name
|
||||
unversioned_name, = name.split("@")
|
||||
# Allow use of the full versioned name (e.g. `python@3.99`) or an unversioned alias (`python`).
|
||||
next if formula.tap&.audit_exception :versioned_formula_dependent_conflicts_allowlist, name
|
||||
next if formula.tap&.audit_exception :versioned_formula_dependent_conflicts_allowlist, unversioned_name
|
||||
|
||||
version_hash[unversioned_name] ||= Set.new
|
||||
version_hash[unversioned_name] << name
|
||||
next if version_hash[unversioned_name].length < 2
|
||||
@ -419,11 +433,12 @@ module Homebrew
|
||||
def audit_glibc
|
||||
return unless @core_tap
|
||||
return if formula.name != "glibc"
|
||||
return if [OS::CI_GLIBC_VERSION, "2.27", "2.31", "2.35"].include?(formula.version.to_s)
|
||||
# Also allow LINUX_GLIBC_NEXT_CI_VERSION for when we're upgrading.
|
||||
return if [OS::LINUX_GLIBC_CI_VERSION, OS::LINUX_GLIBC_NEXT_CI_VERSION].include?(formula.version.to_s)
|
||||
|
||||
problem "The glibc version must be #{OS::CI_GLIBC_VERSION}, as this is the version used by our CI on Linux. " \
|
||||
"Glibc is for users who have a system Glibc with a lower version, " \
|
||||
"which allows them to use our Linux bottles, which were compiled against system Glibc on CI."
|
||||
problem "The glibc version must be #{OS::LINUX_GLIBC_CI_VERSION}, as needed by our CI on Linux. " \
|
||||
"The glibc formula is for users who have a system glibc with a lower version, " \
|
||||
"which allows them to use our Linux bottles, which were compiled against system glibc on CI."
|
||||
end
|
||||
|
||||
ELASTICSEARCH_KIBANA_RELICENSED_VERSION = "7.11"
|
||||
@ -848,5 +863,16 @@ module Homebrew
|
||||
def head_only?(formula)
|
||||
formula.head && formula.stable.nil?
|
||||
end
|
||||
|
||||
def linux_only_gcc_dep?(formula)
|
||||
# TODO: Make this check work when running on Linux and not simulating macOS too.
|
||||
return false unless Homebrew::SimulateSystem.simulating_or_running_on_macos?
|
||||
|
||||
formula_hash = formula.to_hash_with_variations
|
||||
deps = formula_hash["dependencies"]
|
||||
linux_deps = formula_hash.dig("variations", :x86_64_linux, "dependencies")
|
||||
|
||||
deps.exclude?("gcc") && linux_deps&.include?("gcc")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -39,6 +39,7 @@ class FormulaInstaller
|
||||
attr_predicate :installed_as_dependency?, :installed_on_request?
|
||||
attr_predicate :show_summary_heading?, :show_header?
|
||||
attr_predicate :force_bottle?, :ignore_deps?, :only_deps?, :interactive?, :git?, :force?, :overwrite?, :keep_tmp?
|
||||
attr_predicate :debug_symbols?
|
||||
attr_predicate :verbose?, :debug?, :quiet?
|
||||
|
||||
def initialize(
|
||||
@ -58,6 +59,7 @@ class FormulaInstaller
|
||||
git: false,
|
||||
interactive: false,
|
||||
keep_tmp: false,
|
||||
debug_symbols: false,
|
||||
cc: nil,
|
||||
options: Options.new,
|
||||
force: false,
|
||||
@ -71,6 +73,7 @@ class FormulaInstaller
|
||||
@force = force
|
||||
@overwrite = overwrite
|
||||
@keep_tmp = keep_tmp
|
||||
@debug_symbols = debug_symbols
|
||||
@link_keg = !formula.keg_only? || link_keg
|
||||
@show_header = show_header
|
||||
@ignore_deps = ignore_deps
|
||||
@ -688,6 +691,7 @@ class FormulaInstaller
|
||||
include_test_formulae: @include_test_formulae,
|
||||
build_from_source_formulae: @build_from_source_formulae,
|
||||
keep_tmp: keep_tmp?,
|
||||
debug_symbols: debug_symbols?,
|
||||
force: force?,
|
||||
debug: debug?,
|
||||
quiet: quiet?,
|
||||
@ -741,6 +745,7 @@ class FormulaInstaller
|
||||
include_test_formulae: @include_test_formulae,
|
||||
build_from_source_formulae: @build_from_source_formulae,
|
||||
keep_tmp: keep_tmp?,
|
||||
debug_symbols: debug_symbols?,
|
||||
force: force?,
|
||||
debug: debug?,
|
||||
quiet: quiet?,
|
||||
@ -802,6 +807,8 @@ class FormulaInstaller
|
||||
post_install
|
||||
end
|
||||
|
||||
keg.prepare_debug_symbols if debug_symbols?
|
||||
|
||||
# Updates the cache for a particular formula after doing an install
|
||||
CacheStoreDatabase.use(:linkage) do |db|
|
||||
break unless db.created?
|
||||
@ -873,6 +880,11 @@ class FormulaInstaller
|
||||
args << "--cc=#{@cc}" if @cc
|
||||
args << "--keep-tmp" if keep_tmp?
|
||||
|
||||
if debug_symbols?
|
||||
args << "--debug-symbols"
|
||||
args << "--build-from-source"
|
||||
end
|
||||
|
||||
if @env.present?
|
||||
args << "--env=#{@env}"
|
||||
elsif formula.env.std? || formula.deps.select(&:build?).any? { |d| d.name == "scons" }
|
||||
|
||||
@ -333,9 +333,9 @@ class GitHubPackages
|
||||
os_version ||= "macOS #{bottle_tag.to_macos_version}"
|
||||
when "linux"
|
||||
os_version&.delete_suffix!(" LTS")
|
||||
os_version ||= OS::CI_OS_VERSION
|
||||
os_version ||= OS::LINUX_CI_OS_VERSION
|
||||
glibc_version = tab["built_on"]["glibc_version"].presence if tab["built_on"].present?
|
||||
glibc_version ||= OS::CI_GLIBC_VERSION
|
||||
glibc_version ||= OS::LINUX_GLIBC_CI_VERSION
|
||||
cpu_variant = tab["oldest_cpu_family"] || Hardware::CPU::INTEL_64BIT_OLDEST_CPU.to_s
|
||||
end
|
||||
|
||||
|
||||
@ -269,6 +269,7 @@ module Homebrew
|
||||
git: false,
|
||||
interactive: false,
|
||||
keep_tmp: false,
|
||||
debug_symbols: false,
|
||||
force: false,
|
||||
overwrite: false,
|
||||
debug: false,
|
||||
@ -293,6 +294,7 @@ module Homebrew
|
||||
git: git,
|
||||
interactive: interactive,
|
||||
keep_tmp: keep_tmp,
|
||||
debug_symbols: debug_symbols,
|
||||
force: force,
|
||||
overwrite: overwrite,
|
||||
debug: debug,
|
||||
|
||||
@ -483,6 +483,8 @@ class Keg
|
||||
ObserverPathnameExtension.n
|
||||
end
|
||||
|
||||
def prepare_debug_symbols; end
|
||||
|
||||
def remove_oldname_opt_record
|
||||
return unless oldname_opt_record
|
||||
return if oldname_opt_record.resolved_path != path
|
||||
|
||||
@ -373,7 +373,7 @@ class Keg
|
||||
@bottle_dependencies ||= begin
|
||||
formulae = []
|
||||
gcc = Formulary.factory(CompilerSelector.preferred_gcc)
|
||||
formulae << gcc if DevelopmentTools.non_apple_gcc_version("gcc") < gcc.version.to_i
|
||||
formulae << gcc if DevelopmentTools.gcc_version("gcc") < gcc.version.to_i
|
||||
formulae
|
||||
end
|
||||
end
|
||||
|
||||
@ -103,16 +103,22 @@ module Language
|
||||
)
|
||||
end
|
||||
|
||||
def detected_python_shebang(formula = self)
|
||||
python_deps = formula.deps.map(&:name).grep(/^python(@.*)?$/)
|
||||
def detected_python_shebang(formula = self, use_python_from_path: false)
|
||||
python_path = if use_python_from_path
|
||||
"/usr/bin/env python3"
|
||||
else
|
||||
python_deps = formula.deps.map(&:name).grep(/^python(@.*)?$/)
|
||||
|
||||
raise ShebangDetectionError.new("Python", "formula does not depend on Python") if python_deps.empty?
|
||||
if python_deps.length > 1
|
||||
raise ShebangDetectionError.new("Python", "formula has multiple Python dependencies")
|
||||
raise ShebangDetectionError.new("Python", "formula does not depend on Python") if python_deps.empty?
|
||||
if python_deps.length > 1
|
||||
raise ShebangDetectionError.new("Python", "formula has multiple Python dependencies")
|
||||
end
|
||||
|
||||
python_dep = python_deps.first
|
||||
Formula[python_dep].opt_bin/python_dep.sub("@", "")
|
||||
end
|
||||
|
||||
python_dep = python_deps.first
|
||||
python_shebang_rewrite_info(Formula[python_dep].opt_bin/python_dep.sub("@", ""))
|
||||
python_shebang_rewrite_info(python_path)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@ -80,11 +80,16 @@ class LinkageChecker
|
||||
alias generic_display_test_output display_test_output
|
||||
private :generic_display_test_output
|
||||
|
||||
sig { params(strict: T::Boolean).returns(T::Boolean) }
|
||||
def broken_library_linkage?(strict: false)
|
||||
issues = [@broken_deps, @unwanted_system_dylibs, @version_conflict_deps]
|
||||
issues += [@undeclared_deps, @files_missing_rpaths] if strict
|
||||
[issues, unexpected_broken_dylibs, unexpected_present_dylibs].flatten.any?(&:present?)
|
||||
sig { params(test: T::Boolean, strict: T::Boolean).returns(T::Boolean) }
|
||||
def broken_library_linkage?(test: false, strict: false)
|
||||
raise ArgumentError, "Strict linkage checking requires test mode to be enabled." if strict && !test
|
||||
|
||||
issues = [@broken_deps, unexpected_broken_dylibs]
|
||||
if test
|
||||
issues += [@unwanted_system_dylibs, @version_conflict_deps, unexpected_present_dylibs]
|
||||
issues += [@undeclared_deps, @files_missing_rpaths] if strict
|
||||
end
|
||||
issues.any?(&:present?)
|
||||
end
|
||||
alias generic_broken_library_linkage? broken_library_linkage?
|
||||
private :generic_broken_library_linkage?
|
||||
|
||||
@ -89,6 +89,12 @@ module Homebrew
|
||||
uconv is part of the icu4c formula:
|
||||
brew install icu4c
|
||||
EOS
|
||||
when "postgresql", "postgres" then <<~EOS
|
||||
postgresql breaks existing databases on upgrade without human intervention.
|
||||
|
||||
See a more specific version to install with:
|
||||
brew formulae | grep postgresql@
|
||||
EOS
|
||||
end
|
||||
end
|
||||
alias generic_disallowed_reason disallowed_reason
|
||||
|
||||
@ -13,7 +13,8 @@ class Mktemp
|
||||
|
||||
def initialize(prefix, opts = {})
|
||||
@prefix = prefix
|
||||
@retain = opts[:retain]
|
||||
@retain_in_cache = opts[:retain_in_cache]
|
||||
@retain = opts[:retain] || @retain_in_cache
|
||||
@quiet = false
|
||||
end
|
||||
|
||||
@ -28,6 +29,11 @@ class Mktemp
|
||||
@retain
|
||||
end
|
||||
|
||||
# True if the source files should be retained.
|
||||
def retain_in_cache?
|
||||
@retain_in_cache
|
||||
end
|
||||
|
||||
# Instructs this Mktemp to not emit messages when retention is triggered.
|
||||
sig { void }
|
||||
def quiet!
|
||||
@ -40,7 +46,15 @@ class Mktemp
|
||||
end
|
||||
|
||||
def run
|
||||
@tmpdir = Pathname.new(Dir.mktmpdir("#{@prefix.tr "@", "AT"}-", HOMEBREW_TEMP))
|
||||
prefix_name = @prefix.tr "@", "AT"
|
||||
@tmpdir = if retain_in_cache?
|
||||
tmp_dir = HOMEBREW_CACHE/"Sources/#{prefix_name}"
|
||||
chmod_rm_rf(tmp_dir) # clear out previous staging directory
|
||||
tmp_dir.mkpath
|
||||
tmp_dir
|
||||
else
|
||||
Pathname.new(Dir.mktmpdir("#{prefix_name}-", HOMEBREW_TEMP))
|
||||
end
|
||||
|
||||
# Make sure files inside the temporary directory have the same group as the
|
||||
# brew instance.
|
||||
@ -54,18 +68,21 @@ class Mktemp
|
||||
Process.gid
|
||||
end
|
||||
begin
|
||||
chown(nil, group_id, tmpdir)
|
||||
chown(nil, group_id, @tmpdir)
|
||||
rescue Errno::EPERM
|
||||
opoo "Failed setting group \"#{Etc.getgrgid(group_id).name}\" on #{tmpdir}"
|
||||
opoo "Failed setting group \"#{Etc.getgrgid(group_id).name}\" on #{@tmpdir}"
|
||||
end
|
||||
|
||||
begin
|
||||
Dir.chdir(tmpdir) { yield self }
|
||||
ensure
|
||||
ignore_interrupts { chmod_rm_rf(tmpdir) } unless retain?
|
||||
ignore_interrupts { chmod_rm_rf(@tmpdir) } unless retain?
|
||||
end
|
||||
ensure
|
||||
ohai "Temporary files retained at:", @tmpdir.to_s if retain? && !@tmpdir.nil? && !@quiet
|
||||
if retain? && @tmpdir.present? && !@quiet
|
||||
message = retain_in_cache? ? "Source files for debugging available at:" : "Temporary files retained at:"
|
||||
ohai message, @tmpdir.to_s
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -45,8 +45,15 @@ module OS
|
||||
|
||||
::OS_VERSION = ENV.fetch("HOMEBREW_OS_VERSION").freeze
|
||||
|
||||
CI_GLIBC_VERSION = "2.23"
|
||||
CI_OS_VERSION = "Ubuntu 16.04"
|
||||
LINUX_CI_OS_VERSION = "Ubuntu 16.04"
|
||||
LINUX_GLIBC_CI_VERSION = "2.23"
|
||||
LINUX_GCC_CI_VERSION = "5.0"
|
||||
LINUX_PREFERRED_GCC_FORMULA = "gcc@5"
|
||||
|
||||
# Ubuntu 22.04 (see Linux-CI.md)
|
||||
LINUX_GLIBC_NEXT_CI_VERSION = "2.35"
|
||||
# LINUX_GCC_CI_VERSION = "11.0"
|
||||
# LINUX_PREFERRED_GCC_FORMULA = "gcc@11"
|
||||
|
||||
if OS.mac?
|
||||
require "os/mac"
|
||||
|
||||
@ -16,6 +16,7 @@ module Homebrew
|
||||
build_from_source_formulae: [],
|
||||
interactive: false,
|
||||
keep_tmp: false,
|
||||
debug_symbols: false,
|
||||
force: false,
|
||||
debug: false,
|
||||
quiet: false,
|
||||
@ -48,6 +49,7 @@ module Homebrew
|
||||
git: git,
|
||||
interactive: interactive,
|
||||
keep_tmp: keep_tmp,
|
||||
debug_symbols: debug_symbols,
|
||||
force: force,
|
||||
debug: debug,
|
||||
quiet: quiet,
|
||||
|
||||
@ -89,14 +89,14 @@ class Resource
|
||||
# dir using {Mktemp} so that works with all subtypes.
|
||||
#
|
||||
# @api public
|
||||
def stage(target = nil, &block)
|
||||
def stage(target = nil, debug_symbols: false, &block)
|
||||
raise ArgumentError, "target directory or block is required" if !target && block.blank?
|
||||
|
||||
prepare_patches
|
||||
fetch_patches(skip_downloaded: true)
|
||||
fetch unless downloaded?
|
||||
|
||||
unpack(target, &block)
|
||||
unpack(target, debug_symbols: debug_symbols, &block)
|
||||
end
|
||||
|
||||
def prepare_patches
|
||||
@ -120,9 +120,9 @@ class Resource
|
||||
# If block is given, yield to that block with `|stage|`, where stage
|
||||
# is a {ResourceStageContext}.
|
||||
# A target or a block must be given, but not both.
|
||||
def unpack(target = nil)
|
||||
def unpack(target = nil, debug_symbols: false)
|
||||
current_working_directory = Pathname.pwd
|
||||
mktemp(download_name) do |staging|
|
||||
stage_resource(download_name, debug_symbols: debug_symbols) do |staging|
|
||||
downloader.stage do
|
||||
@source_modified_time = downloader.source_modified_time
|
||||
apply_patches
|
||||
@ -235,8 +235,8 @@ class Resource
|
||||
|
||||
protected
|
||||
|
||||
def mktemp(prefix, &block)
|
||||
Mktemp.new(prefix).run(&block)
|
||||
def stage_resource(prefix, debug_symbols: false, &block)
|
||||
Mktemp.new(prefix, retain_in_cache: debug_symbols).run(&block)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@ -21,11 +21,11 @@ module RuboCop
|
||||
|
||||
alias stanza_node method_node
|
||||
|
||||
def_delegator :stanza_node, :method_name, :stanza_name
|
||||
def_delegator :stanza_node, :parent, :parent_node
|
||||
def_delegator :stanza_node, :arch_variable?
|
||||
|
||||
def source_range
|
||||
stanza_node.expression
|
||||
stanza_node.location_expression
|
||||
end
|
||||
|
||||
def source_range_with_comments
|
||||
@ -38,6 +38,12 @@ module RuboCop
|
||||
def_delegator :source_range_with_comments, :source,
|
||||
:source_with_comments
|
||||
|
||||
def stanza_name
|
||||
return :on_arch_conditional if arch_variable?
|
||||
|
||||
stanza_node.method_name
|
||||
end
|
||||
|
||||
def stanza_group
|
||||
Constants::STANZA_GROUP_HASH[stanza_name]
|
||||
end
|
||||
|
||||
@ -6,6 +6,7 @@ module RuboCop
|
||||
# Constants available globally for use in all cask cops.
|
||||
module Constants
|
||||
STANZA_GROUPS = [
|
||||
[:arch, :on_arch_conditional],
|
||||
[:version, :sha256],
|
||||
[:language],
|
||||
[:url, :appcast, :name, :desc, :homepage],
|
||||
|
||||
@ -15,8 +15,11 @@ module RuboCop
|
||||
def_node_matcher :val_node, "{(pair _ $_) (hash (pair _ $_) ...)}"
|
||||
|
||||
def_node_matcher :cask_block?, "(block (send nil? :cask _) args ...)"
|
||||
def_node_matcher :arch_variable?, "(lvasgn _ (send nil? :on_arch_conditional ...))"
|
||||
|
||||
def stanza?
|
||||
return true if arch_variable?
|
||||
|
||||
(send_type? || block_type?) && STANZA_ORDER.include?(method_name)
|
||||
end
|
||||
|
||||
@ -24,7 +27,7 @@ module RuboCop
|
||||
loc.is_a?(Parser::Source::Map::Heredoc)
|
||||
end
|
||||
|
||||
def expression
|
||||
def location_expression
|
||||
base_expression = loc.expression
|
||||
descendants.select(&:heredoc?).reduce(base_expression) do |expr, node|
|
||||
expr.join(node.loc.heredoc_end)
|
||||
|
||||
52
Library/Homebrew/rubocops/cask/on_system_conditionals.rb
Normal file
52
Library/Homebrew/rubocops/cask/on_system_conditionals.rb
Normal file
@ -0,0 +1,52 @@
|
||||
# typed: true
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "forwardable"
|
||||
require "rubocops/shared/on_system_conditionals_helper"
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Cask
|
||||
# This cop makes sure that OS conditionals are consistent.
|
||||
#
|
||||
# @example
|
||||
# # bad
|
||||
# cask 'foo' do
|
||||
# if MacOS.version == :high_sierra
|
||||
# sha256 "..."
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# # good
|
||||
# cask 'foo' do
|
||||
# on_high_sierra do
|
||||
# sha256 "..."
|
||||
# end
|
||||
# end
|
||||
class OnSystemConditionals < Base
|
||||
extend Forwardable
|
||||
extend AutoCorrector
|
||||
include OnSystemConditionalsHelper
|
||||
include CaskHelp
|
||||
|
||||
FLIGHT_STANZA_NAMES = [:preflight, :postflight, :uninstall_preflight, :uninstall_postflight].freeze
|
||||
|
||||
def on_cask(cask_block)
|
||||
@cask_block = cask_block
|
||||
|
||||
toplevel_stanzas.each do |stanza|
|
||||
next unless FLIGHT_STANZA_NAMES.include? stanza.stanza_name
|
||||
|
||||
audit_on_system_blocks(stanza.stanza_node, stanza.stanza_name)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :cask_block
|
||||
|
||||
def_delegators :cask_block, :toplevel_stanzas, :cask_body
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
76
Library/Homebrew/rubocops/cask/variables.rb
Normal file
76
Library/Homebrew/rubocops/cask/variables.rb
Normal file
@ -0,0 +1,76 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "forwardable"
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Cask
|
||||
# This cop audits variables in casks.
|
||||
#
|
||||
# @example
|
||||
# # bad
|
||||
# cask do
|
||||
# arch = Hardware::CPU.intel? ? "darwin" : "darwin-arm64"
|
||||
# end
|
||||
#
|
||||
# # good
|
||||
# cask 'foo' do
|
||||
# arch arm: "darwin-arm64", intel: "darwin"
|
||||
# end
|
||||
class Variables < Base
|
||||
extend Forwardable
|
||||
extend AutoCorrector
|
||||
include CaskHelp
|
||||
|
||||
def on_cask(cask_block)
|
||||
@cask_block = cask_block
|
||||
add_offenses
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def_delegator :@cask_block, :cask_node
|
||||
|
||||
def add_offenses
|
||||
variable_assignment(cask_node) do |node, var_name, arch_condition, true_node, false_node|
|
||||
arm_node, intel_node = if arch_condition == :arm?
|
||||
[true_node, false_node]
|
||||
else
|
||||
[false_node, true_node]
|
||||
end
|
||||
|
||||
replacement_string = if var_name == :arch
|
||||
"arch "
|
||||
else
|
||||
"#{var_name} = on_arch_conditional "
|
||||
end
|
||||
replacement_parameters = []
|
||||
replacement_parameters << "arm: #{arm_node.source}" unless blank_node?(arm_node)
|
||||
replacement_parameters << "intel: #{intel_node.source}" unless blank_node?(intel_node)
|
||||
replacement_string += replacement_parameters.join(", ")
|
||||
|
||||
add_offense(node, message: "Use `#{replacement_string}` instead of `#{node.source}`") do |corrector|
|
||||
corrector.replace(node, replacement_string)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def blank_node?(node)
|
||||
case node.type
|
||||
when :str
|
||||
node.value.empty?
|
||||
when :nil
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def_node_search :variable_assignment, <<~PATTERN
|
||||
$(lvasgn $_ (if (send (const (const nil? :Hardware) :CPU) ${:arm? :intel?}) $_ $_))
|
||||
PATTERN
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -3,6 +3,7 @@
|
||||
|
||||
require "macos_versions"
|
||||
require "rubocops/extend/formula"
|
||||
require "rubocops/shared/on_system_conditionals_helper"
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
@ -377,104 +378,20 @@ module RuboCop
|
||||
#
|
||||
# @api private
|
||||
class OnSystemConditionals < FormulaCop
|
||||
include OnSystemConditionalsHelper
|
||||
extend AutoCorrector
|
||||
|
||||
NO_ON_SYSTEM_METHOD_NAMES = [:install, :post_install].freeze
|
||||
NO_ON_SYSTEM_BLOCK_NAMES = [:service, :test].freeze
|
||||
|
||||
ON_ARCH_OPTIONS = [:intel, :arm].freeze
|
||||
ON_BASE_OS_OPTIONS = [:macos, :linux].freeze
|
||||
ON_MACOS_VERSION_OPTIONS = MacOSVersions::SYMBOLS.keys.freeze
|
||||
ALL_SYSTEM_OPTIONS = [*ON_ARCH_OPTIONS, *ON_BASE_OS_OPTIONS, *ON_MACOS_VERSION_OPTIONS, :system].freeze
|
||||
|
||||
MACOS_VERSION_CONDITIONALS = {
|
||||
"==" => nil,
|
||||
"<=" => :or_older,
|
||||
">=" => :or_newer,
|
||||
}.freeze
|
||||
|
||||
ON_SYSTEM_CONDITIONALS = [:<, :<=].freeze
|
||||
|
||||
def on_system_method_info(on_system_option)
|
||||
info = {}
|
||||
info[:method] = :"on_#{on_system_option}"
|
||||
info[:if_module], info[:if_method] = if ON_ARCH_OPTIONS.include?(on_system_option)
|
||||
["Hardware::CPU", :"#{on_system_option}?"]
|
||||
elsif ON_BASE_OS_OPTIONS.include?(on_system_option)
|
||||
["OS", (on_system_option == :macos) ? :mac? : :linux?]
|
||||
else
|
||||
["MacOS", :version]
|
||||
end
|
||||
info[:on_system_string] = "on_#{on_system_option}"
|
||||
info[:if_string] = if on_system_option == :system
|
||||
"if OS.linux? || MacOS.version"
|
||||
else
|
||||
"if #{info[:if_module]}.#{info[:if_method]}"
|
||||
end
|
||||
|
||||
info
|
||||
end
|
||||
|
||||
def audit_formula(_node, _class_node, _parent_class_node, body_node)
|
||||
top_level_nodes_to_check = []
|
||||
NO_ON_SYSTEM_METHOD_NAMES.each do |formula_method_name|
|
||||
method_node = find_method_def(body_node, formula_method_name)
|
||||
top_level_nodes_to_check << [formula_method_name, method_node] if method_node
|
||||
audit_on_system_blocks(method_node, formula_method_name) if method_node
|
||||
end
|
||||
NO_ON_SYSTEM_BLOCK_NAMES.each do |formula_block_name|
|
||||
block_node = find_block(body_node, formula_block_name)
|
||||
top_level_nodes_to_check << [formula_block_name, block_node] if block_node
|
||||
end
|
||||
|
||||
ALL_SYSTEM_OPTIONS.each do |on_system_option|
|
||||
method_info = on_system_method_info(on_system_option)
|
||||
|
||||
top_level_nodes_to_check.each do |top_level_name, top_level_node|
|
||||
top_level_node_string = if top_level_node.def_type?
|
||||
"def #{top_level_name}"
|
||||
else
|
||||
"#{top_level_name} do"
|
||||
end
|
||||
|
||||
find_every_method_call_by_name(top_level_node, method_info[:method]).each do |method|
|
||||
if ON_MACOS_VERSION_OPTIONS.include?(on_system_option)
|
||||
on_macos_version_method_call(method, on_method: method_info[:method]) do |on_method_parameters|
|
||||
if on_method_parameters.empty?
|
||||
method_info[:if_string] = "if MacOS.version == :#{on_system_option}"
|
||||
else
|
||||
method_info[:on_system_string] = "#{method_info[:method]} :#{on_method_parameters.first}"
|
||||
if_condition_operator = MACOS_VERSION_CONDITIONALS.key(on_method_parameters.first)
|
||||
method_info[:if_string] = "if MacOS.version #{if_condition_operator} :#{on_system_option}"
|
||||
end
|
||||
end
|
||||
elsif method_info[:method] == :on_system
|
||||
on_system_method_call(method) do |macos_symbol|
|
||||
base_os, condition = macos_symbol.to_s.split(/_(?=or_)/).map(&:to_sym)
|
||||
method_info[:on_system_string] = if condition.present?
|
||||
"on_system :linux, macos: :#{base_os}_#{condition}"
|
||||
else
|
||||
"on_system :linux, macos: :#{base_os}"
|
||||
end
|
||||
if_condition_operator = MACOS_VERSION_CONDITIONALS.key(condition)
|
||||
method_info[:if_string] = "if OS.linux? || MacOS.version #{if_condition_operator} :#{base_os}"
|
||||
end
|
||||
end
|
||||
|
||||
offending_node(method)
|
||||
|
||||
problem "Don't use `#{method_info[:on_system_string]}` in `#{top_level_node_string}`, " \
|
||||
"use `#{method_info[:if_string]}` instead." do |corrector|
|
||||
block_node = offending_node.parent
|
||||
next if block_node.type != :block
|
||||
|
||||
# TODO: could fix corrector to handle this but punting for now.
|
||||
next if block_node.single_line?
|
||||
|
||||
source_range = offending_node.source_range.join(offending_node.parent.loc.begin)
|
||||
corrector.replace(source_range, method_info[:if_string])
|
||||
end
|
||||
end
|
||||
end
|
||||
audit_on_system_blocks(block_node, formula_block_name) if block_node
|
||||
end
|
||||
|
||||
# Don't restrict OS.mac? or OS.linux? usage in taps; they don't care
|
||||
@ -483,115 +400,19 @@ module RuboCop
|
||||
# that case.
|
||||
return if formula_tap != "homebrew-core"
|
||||
|
||||
ALL_SYSTEM_OPTIONS.each do |on_system_option|
|
||||
method_info = on_system_method_info(on_system_option)
|
||||
audit_arch_conditionals(body_node,
|
||||
allowed_methods: NO_ON_SYSTEM_METHOD_NAMES,
|
||||
allowed_blocks: NO_ON_SYSTEM_BLOCK_NAMES)
|
||||
|
||||
if_nodes_to_check = []
|
||||
audit_base_os_conditionals(body_node,
|
||||
allowed_methods: NO_ON_SYSTEM_METHOD_NAMES,
|
||||
allowed_blocks: NO_ON_SYSTEM_BLOCK_NAMES)
|
||||
|
||||
if ON_ARCH_OPTIONS.include?(on_system_option)
|
||||
if_arch_node_search(body_node, arch: method_info[:if_method]) do |if_node, else_node|
|
||||
else_info = if else_node.present?
|
||||
{
|
||||
can_autocorrect: true,
|
||||
on_system_method: (on_system_option == :intel) ? "on_arm" : "on_intel",
|
||||
node: else_node,
|
||||
}
|
||||
end
|
||||
|
||||
if_nodes_to_check << [if_node, else_info]
|
||||
end
|
||||
elsif ON_BASE_OS_OPTIONS.include?(on_system_option)
|
||||
if_base_os_node_search(body_node, base_os: method_info[:if_method]) do |if_node, else_node|
|
||||
else_info = if else_node.present?
|
||||
{
|
||||
can_autocorrect: true,
|
||||
on_system_method: (on_system_option == :macos) ? "on_linux" : "on_macos",
|
||||
node: else_node,
|
||||
}
|
||||
end
|
||||
|
||||
if_nodes_to_check << [if_node, else_info]
|
||||
end
|
||||
else
|
||||
if_macos_version_node_search(body_node, os_name: on_system_option) do |if_node, operator, else_node|
|
||||
if operator == :<
|
||||
method_info[:on_system_string] = "on_system"
|
||||
elsif operator == :<=
|
||||
method_info[:on_system_string] = "on_system :linux, macos: :#{on_system_option}_or_older"
|
||||
elsif operator != :== && MACOS_VERSION_CONDITIONALS.key?(operator.to_s)
|
||||
method_info[:on_system_string] = "#{method_info[:method]} " \
|
||||
":#{MACOS_VERSION_CONDITIONALS[operator.to_s]}"
|
||||
end
|
||||
method_info[:if_string] = "if #{method_info[:if_module]}.#{method_info[:if_method]} #{operator} " \
|
||||
":#{on_system_option}"
|
||||
if else_node.present? || !MACOS_VERSION_CONDITIONALS.key?(operator.to_s)
|
||||
else_info = { can_autocorrect: false }
|
||||
end
|
||||
|
||||
if_nodes_to_check << [if_node, else_info]
|
||||
end
|
||||
end
|
||||
|
||||
if_nodes_to_check.each do |if_node, else_info|
|
||||
# TODO: check to see if it's legal
|
||||
valid = T.let(false, T::Boolean)
|
||||
if_node.each_ancestor do |ancestor|
|
||||
valid_method_names = case ancestor.type
|
||||
when :def
|
||||
NO_ON_SYSTEM_METHOD_NAMES
|
||||
when :block
|
||||
NO_ON_SYSTEM_BLOCK_NAMES
|
||||
else
|
||||
next
|
||||
end
|
||||
next unless valid_method_names.include?(ancestor.method_name)
|
||||
|
||||
valid = true
|
||||
break
|
||||
end
|
||||
next if valid
|
||||
|
||||
offending_node(if_node)
|
||||
|
||||
problem "Don't use `#{method_info[:if_string]}`, " \
|
||||
"use `#{method_info[:on_system_string]} do` instead." do |corrector|
|
||||
# TODO: could fix corrector to handle this but punting for now.
|
||||
next if if_node.unless?
|
||||
|
||||
if else_info.present?
|
||||
next unless else_info[:can_autocorrect]
|
||||
|
||||
corrector.replace(if_node.source_range,
|
||||
"#{method_info[:on_system_string]} do\n#{if_node.body.source}\nend\n" \
|
||||
"#{else_info[:on_system_method]} do\n#{else_info[:node].source}\nend")
|
||||
else
|
||||
corrector.replace(if_node.source_range,
|
||||
"#{method_info[:on_system_string]} do\n#{if_node.body.source}\nend")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
audit_macos_version_conditionals(body_node,
|
||||
allowed_methods: NO_ON_SYSTEM_METHOD_NAMES,
|
||||
allowed_blocks: NO_ON_SYSTEM_BLOCK_NAMES,
|
||||
recommend_on_system: true)
|
||||
end
|
||||
|
||||
def_node_matcher :on_macos_version_method_call, <<~PATTERN
|
||||
(send nil? %on_method (sym ${:or_newer :or_older})?)
|
||||
PATTERN
|
||||
|
||||
def_node_matcher :on_system_method_call, <<~PATTERN
|
||||
(send nil? :on_system (sym :linux) (hash (pair (sym :macos) (sym $_))))
|
||||
PATTERN
|
||||
|
||||
def_node_search :if_arch_node_search, <<~PATTERN
|
||||
$(if (send (const (const nil? :Hardware) :CPU) %arch) _ $_)
|
||||
PATTERN
|
||||
|
||||
def_node_search :if_base_os_node_search, <<~PATTERN
|
||||
$(if (send (const nil? :OS) %base_os) _ $_)
|
||||
PATTERN
|
||||
|
||||
def_node_search :if_macos_version_node_search, <<~PATTERN
|
||||
$(if (send (send (const nil? :MacOS) :version) ${:== :<= :< :>= :> :!=} (sym %os_name)) _ $_)
|
||||
PATTERN
|
||||
end
|
||||
|
||||
# This cop checks for other miscellaneous style violations.
|
||||
|
||||
@ -16,6 +16,8 @@ require_relative "cask/mixin/on_url_stanza"
|
||||
require_relative "cask/desc"
|
||||
require_relative "cask/homepage_url_trailing_slash"
|
||||
require_relative "cask/no_dsl_version"
|
||||
require_relative "cask/on_system_conditionals"
|
||||
require_relative "cask/stanza_order"
|
||||
require_relative "cask/stanza_grouping"
|
||||
require_relative "cask/url_legacy_comma_separators"
|
||||
require_relative "cask/variables"
|
||||
|
||||
@ -0,0 +1,196 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "macos_versions"
|
||||
require "rubocops/shared/helper_functions"
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
# This module performs common checks on `on_{system}` blocks in both formulae and casks.
|
||||
#
|
||||
# @api private
|
||||
module OnSystemConditionalsHelper
|
||||
extend NodePattern::Macros
|
||||
include HelperFunctions
|
||||
|
||||
ARCH_OPTIONS = [:arm, :intel].freeze
|
||||
BASE_OS_OPTIONS = [:macos, :linux].freeze
|
||||
MACOS_VERSION_OPTIONS = MacOSVersions::SYMBOLS.keys.freeze
|
||||
ON_SYSTEM_OPTIONS = [*ARCH_OPTIONS, *BASE_OS_OPTIONS, *MACOS_VERSION_OPTIONS, :system].freeze
|
||||
|
||||
MACOS_VERSION_CONDITIONALS = {
|
||||
"==" => nil,
|
||||
"<=" => :or_older,
|
||||
">=" => :or_newer,
|
||||
}.freeze
|
||||
|
||||
def audit_on_system_blocks(body_node, parent_name)
|
||||
parent_string = if body_node.def_type?
|
||||
"def #{parent_name}"
|
||||
else
|
||||
"#{parent_name} do"
|
||||
end
|
||||
|
||||
ON_SYSTEM_OPTIONS.each do |on_system_option|
|
||||
on_system_method = :"on_#{on_system_option}"
|
||||
if_statement_string = if ARCH_OPTIONS.include?(on_system_option)
|
||||
"if Hardware::CPU.#{on_system_option}?"
|
||||
elsif BASE_OS_OPTIONS.include?(on_system_option)
|
||||
"if OS.#{(on_system_option == :macos) ? "mac" : "linux"}?"
|
||||
elsif on_system_option == :system
|
||||
"if OS.linux? || MacOS.version"
|
||||
else
|
||||
"if MacOS.version"
|
||||
end
|
||||
|
||||
find_every_method_call_by_name(body_node, on_system_method).each do |on_system_node|
|
||||
if_conditional = ""
|
||||
if MACOS_VERSION_OPTIONS.include? on_system_option
|
||||
on_macos_version_method_call(on_system_node, on_method: on_system_method) do |on_method_parameters|
|
||||
if on_method_parameters.empty?
|
||||
if_conditional = " == :#{on_system_option}"
|
||||
else
|
||||
if_condition_operator = MACOS_VERSION_CONDITIONALS.key(on_method_parameters.first)
|
||||
if_conditional = " #{if_condition_operator} :#{on_system_option}"
|
||||
end
|
||||
end
|
||||
elsif on_system_option == :system
|
||||
on_system_method_call(on_system_node) do |macos_symbol|
|
||||
base_os, condition = macos_symbol.to_s.split(/_(?=or_)/).map(&:to_sym)
|
||||
if_condition_operator = MACOS_VERSION_CONDITIONALS.key(condition)
|
||||
if_conditional = " #{if_condition_operator} :#{base_os}"
|
||||
end
|
||||
end
|
||||
|
||||
offending_node(on_system_node)
|
||||
problem "Don't use `#{on_system_node.source}` in `#{parent_string}`, " \
|
||||
"use `#{if_statement_string}#{if_conditional}` instead." do |corrector|
|
||||
block_node = offending_node.parent
|
||||
next if block_node.type != :block
|
||||
|
||||
# TODO: could fix corrector to handle this but punting for now.
|
||||
next if block_node.single_line?
|
||||
|
||||
source_range = offending_node.source_range.join(offending_node.parent.loc.begin)
|
||||
corrector.replace(source_range, "#{if_statement_string}#{if_conditional}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def audit_arch_conditionals(body_node, allowed_methods: [], allowed_blocks: [])
|
||||
ARCH_OPTIONS.each do |arch_option|
|
||||
else_method = (arch_option == :arm) ? :on_intel : :on_arm
|
||||
if_arch_node_search(body_node, arch: :"#{arch_option}?") do |if_node, else_node|
|
||||
next if if_node_is_allowed?(if_node, allowed_methods: allowed_methods, allowed_blocks: allowed_blocks)
|
||||
|
||||
if_statement_problem(if_node, "if Hardware::CPU.#{arch_option}?", "on_#{arch_option}",
|
||||
else_method: else_method, else_node: else_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def audit_base_os_conditionals(body_node, allowed_methods: [], allowed_blocks: [])
|
||||
BASE_OS_OPTIONS.each do |base_os_option|
|
||||
os_method, else_method = if base_os_option == :macos
|
||||
[:mac?, :on_linux]
|
||||
else
|
||||
[:linux?, :on_macos]
|
||||
end
|
||||
if_base_os_node_search(body_node, base_os: os_method) do |if_node, else_node|
|
||||
next if if_node_is_allowed?(if_node, allowed_methods: allowed_methods, allowed_blocks: allowed_blocks)
|
||||
|
||||
if_statement_problem(if_node, "if OS.#{os_method}", "on_#{base_os_option}",
|
||||
else_method: else_method, else_node: else_node)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def audit_macos_version_conditionals(body_node, allowed_methods: [], allowed_blocks: [],
|
||||
recommend_on_system: true)
|
||||
MACOS_VERSION_OPTIONS.each do |macos_version_option|
|
||||
if_macos_version_node_search(body_node, os_version: macos_version_option) do |if_node, operator, else_node|
|
||||
next if if_node_is_allowed?(if_node, allowed_methods: allowed_methods, allowed_blocks: allowed_blocks)
|
||||
|
||||
autocorrect = else_node.blank? && MACOS_VERSION_CONDITIONALS.key?(operator.to_s)
|
||||
on_system_method_string = if recommend_on_system && operator == :<
|
||||
"on_system"
|
||||
elsif recommend_on_system && operator == :<=
|
||||
"on_system :linux, macos: :#{macos_version_option}_or_older"
|
||||
elsif operator != :== && MACOS_VERSION_CONDITIONALS.key?(operator.to_s)
|
||||
"on_#{macos_version_option} :#{MACOS_VERSION_CONDITIONALS[operator.to_s]}"
|
||||
else
|
||||
"on_#{macos_version_option}"
|
||||
end
|
||||
|
||||
if_statement_problem(if_node, "if MacOS.version #{operator} :#{macos_version_option}",
|
||||
on_system_method_string, autocorrect: autocorrect)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def if_statement_problem(if_node, if_statement_string, on_system_method_string,
|
||||
else_method: nil, else_node: nil, autocorrect: true)
|
||||
offending_node(if_node)
|
||||
problem "Don't use `#{if_statement_string}`, " \
|
||||
"use `#{on_system_method_string} do` instead." do |corrector|
|
||||
next unless autocorrect
|
||||
# TODO: could fix corrector to handle this but punting for now.
|
||||
next if if_node.unless?
|
||||
|
||||
if else_method.present? && else_node.present?
|
||||
corrector.replace(if_node.source_range,
|
||||
"#{on_system_method_string} do\n#{if_node.body.source}\nend\n" \
|
||||
"#{else_method} do\n#{else_node.source}\nend")
|
||||
else
|
||||
corrector.replace(if_node.source_range, "#{on_system_method_string} do\n#{if_node.body.source}\nend")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def if_node_is_allowed?(if_node, allowed_methods: [], allowed_blocks: [])
|
||||
# TODO: check to see if it's legal
|
||||
valid = false
|
||||
if_node.each_ancestor do |ancestor|
|
||||
valid_method_names = case ancestor.type
|
||||
when :def
|
||||
allowed_methods
|
||||
when :block
|
||||
allowed_blocks
|
||||
else
|
||||
next
|
||||
end
|
||||
next unless valid_method_names.include?(ancestor.method_name)
|
||||
|
||||
valid = true
|
||||
break
|
||||
end
|
||||
return true if valid
|
||||
|
||||
false
|
||||
end
|
||||
|
||||
def_node_matcher :on_macos_version_method_call, <<~PATTERN
|
||||
(send nil? %on_method (sym ${:or_newer :or_older})?)
|
||||
PATTERN
|
||||
|
||||
def_node_matcher :on_system_method_call, <<~PATTERN
|
||||
(send nil? :on_system (sym :linux) (hash (pair (sym :macos) (sym $_))))
|
||||
PATTERN
|
||||
|
||||
def_node_search :if_arch_node_search, <<~PATTERN
|
||||
$(if (send (const (const nil? :Hardware) :CPU) %arch) _ $_)
|
||||
PATTERN
|
||||
|
||||
def_node_search :if_base_os_node_search, <<~PATTERN
|
||||
$(if (send (const nil? :OS) %base_os) _ $_)
|
||||
PATTERN
|
||||
|
||||
def_node_search :if_macos_version_node_search, <<~PATTERN
|
||||
$(if (send (send (const nil? :MacOS) :version) ${:== :<= :< :>= :> :!=} (sym %os_version)) _ $_)
|
||||
PATTERN
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -28,6 +28,11 @@ module Homebrew
|
||||
@service_block = block
|
||||
end
|
||||
|
||||
sig { returns(Formula) }
|
||||
def f
|
||||
@formula
|
||||
end
|
||||
|
||||
sig { params(command: T.nilable(T.any(T::Array[String], String, Pathname))).returns(T.nilable(Array)) }
|
||||
def run(command = nil)
|
||||
case T.unsafe(command)
|
||||
|
||||
@ -292,6 +292,7 @@ class Cmd
|
||||
args.concat(optflags) unless runtime_cpu_detection?
|
||||
args.concat(archflags)
|
||||
args << "-std=#{@arg0}" if /c[89]9/.match?(@arg0)
|
||||
args << "-g" if debug_symbols?
|
||||
args
|
||||
end
|
||||
|
||||
@ -410,6 +411,10 @@ class Cmd
|
||||
config.include?("w")
|
||||
end
|
||||
|
||||
def debug_symbols?
|
||||
config.include?("D")
|
||||
end
|
||||
|
||||
def canonical_path(path)
|
||||
path = Pathname.new(path)
|
||||
path = path.realpath if path.exist?
|
||||
|
||||
@ -8,8 +8,8 @@ module Homebrew
|
||||
class TapAuditor
|
||||
extend T::Sig
|
||||
|
||||
attr_reader :name, :path, :formula_names, :cask_tokens, :tap_audit_exceptions, :tap_style_exceptions,
|
||||
:tap_pypi_formula_mappings, :problems
|
||||
attr_reader :name, :path, :formula_names, :formula_aliases, :cask_tokens,
|
||||
:tap_audit_exceptions, :tap_style_exceptions, :tap_pypi_formula_mappings, :problems
|
||||
|
||||
sig { params(tap: Tap, strict: T.nilable(T::Boolean)).void }
|
||||
def initialize(tap, strict:)
|
||||
@ -21,6 +21,7 @@ module Homebrew
|
||||
@tap_pypi_formula_mappings = tap.pypi_formula_mappings
|
||||
@problems = []
|
||||
|
||||
@formula_aliases = tap.aliases
|
||||
@formula_names = tap.formula_names.map do |formula_name|
|
||||
formula_name.split("/").last
|
||||
end
|
||||
@ -68,7 +69,9 @@ module Homebrew
|
||||
|
||||
list = list.keys if list.is_a? Hash
|
||||
invalid_formulae_casks = list.select do |formula_or_cask_name|
|
||||
@formula_names.exclude?(formula_or_cask_name) && @cask_tokens.exclude?("#{@name}/#{formula_or_cask_name}")
|
||||
formula_names.exclude?(formula_or_cask_name) &&
|
||||
formula_aliases.exclude?(formula_or_cask_name) &&
|
||||
cask_tokens.exclude?("#{@name}/#{formula_or_cask_name}")
|
||||
end
|
||||
|
||||
return if invalid_formulae_casks.empty?
|
||||
|
||||
@ -205,5 +205,12 @@ describe "ENV" do
|
||||
expect(env["HOMEBREW_CCCFG"]).to include("g")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#set_debug_symbols" do
|
||||
it "sets the debug symbols flag" do
|
||||
env.set_debug_symbols
|
||||
expect(env["HOMEBREW_CCCFG"]).to include("D")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -411,6 +411,53 @@ describe Cask::Audit, :cask do
|
||||
end
|
||||
end
|
||||
|
||||
describe "signing checks" do
|
||||
let(:download_double) { instance_double(Cask::Download) }
|
||||
let(:unpack_double) { instance_double(UnpackStrategy::Zip) }
|
||||
|
||||
before do
|
||||
allow(audit).to receive(:download).and_return(download_double)
|
||||
allow(audit).to receive(:signing?).and_return(true)
|
||||
allow(audit).to receive(:check_https_availability)
|
||||
end
|
||||
|
||||
context "when cask is not using a signed artifact" do
|
||||
let(:cask) do
|
||||
tmp_cask "signing-cask-test", <<~RUBY
|
||||
cask 'signing-cask-test' do
|
||||
version '1.0'
|
||||
url "https://brew.sh/index.html"
|
||||
binary 'Audit.app'
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "does not fail" do
|
||||
expect(download_double).not_to receive(:fetch)
|
||||
expect(UnpackStrategy).not_to receive(:detect)
|
||||
expect(run).not_to warn_with(/Audit\.app/)
|
||||
end
|
||||
end
|
||||
|
||||
context "when cask is using a signed artifact" do
|
||||
let(:cask) do
|
||||
tmp_cask "signing-cask-test", <<~RUBY
|
||||
cask 'signing-cask-test' do
|
||||
version '1.0'
|
||||
url "https://brew.sh/"
|
||||
pkg 'Audit.app'
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
|
||||
it "does not fail since no extract" do
|
||||
allow(download_double).to receive(:fetch).and_return(Pathname.new("/tmp/test.zip"))
|
||||
allow(UnpackStrategy).to receive(:detect).and_return(nil)
|
||||
expect(run).not_to warn_with(/Audit\.app/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "livecheck should be skipped" do
|
||||
let(:online) { true }
|
||||
let(:message) { /Version '[^']*' differs from '[^']*' retrieved by livecheck\./ }
|
||||
@ -888,7 +935,7 @@ describe Cask::Audit, :cask do
|
||||
end
|
||||
|
||||
describe "audit of downloads" do
|
||||
let(:cask_token) { "with-binary" }
|
||||
let(:cask_token) { "basic-cask" }
|
||||
let(:cask) { Cask::CaskLoader.load(cask_token) }
|
||||
let(:download_double) { instance_double(Cask::Download) }
|
||||
let(:message) { "Download Failed" }
|
||||
@ -896,10 +943,11 @@ describe Cask::Audit, :cask do
|
||||
before do
|
||||
allow(audit).to receive(:download).and_return(download_double)
|
||||
allow(audit).to receive(:check_https_availability)
|
||||
allow(UnpackStrategy).to receive(:detect).and_return(nil)
|
||||
end
|
||||
|
||||
it "when download and verification succeed it does not fail" do
|
||||
expect(download_double).to receive(:fetch)
|
||||
expect(download_double).to receive(:fetch).and_return(Pathname.new("/tmp/test.zip"))
|
||||
expect(run).to pass
|
||||
end
|
||||
|
||||
|
||||
@ -214,7 +214,7 @@ describe Cask::Cask, :cask do
|
||||
|
||||
describe "#to_hash_with_variations" do
|
||||
let!(:original_macos_version) { MacOS.full_version.to_s }
|
||||
let(:expected_variations) {
|
||||
let(:expected_versions_variations) {
|
||||
<<~JSON
|
||||
{
|
||||
"arm64_big_sur": {
|
||||
@ -243,6 +243,28 @@ describe Cask::Cask, :cask do
|
||||
}
|
||||
JSON
|
||||
}
|
||||
let(:expected_sha256_variations) {
|
||||
<<~JSON
|
||||
{
|
||||
"monterey": {
|
||||
"url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine-intel.zip",
|
||||
"sha256": "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"
|
||||
},
|
||||
"big_sur": {
|
||||
"url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine-intel.zip",
|
||||
"sha256": "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"
|
||||
},
|
||||
"catalina": {
|
||||
"url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine-intel.zip",
|
||||
"sha256": "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"
|
||||
},
|
||||
"mojave": {
|
||||
"url": "file://#{TEST_FIXTURE_DIR}/cask/caffeine-intel.zip",
|
||||
"sha256": "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"
|
||||
}
|
||||
}
|
||||
JSON
|
||||
}
|
||||
|
||||
before do
|
||||
# Use a more limited symbols list to shorten the variations hash
|
||||
@ -263,12 +285,20 @@ describe Cask::Cask, :cask do
|
||||
MacOS.full_version = original_macos_version
|
||||
end
|
||||
|
||||
it "returns the correct variations hash" do
|
||||
it "returns the correct variations hash for a cask with multiple versions" do
|
||||
c = Cask::CaskLoader.load("multiple-versions")
|
||||
h = c.to_hash_with_variations
|
||||
|
||||
expect(h).to be_a(Hash)
|
||||
expect(JSON.pretty_generate(h["variations"])).to eq expected_variations.strip
|
||||
expect(JSON.pretty_generate(h["variations"])).to eq expected_versions_variations.strip
|
||||
end
|
||||
|
||||
it "returns the correct variations hash for a cask different sha256s on each arch" do
|
||||
c = Cask::CaskLoader.load("sha256-arch")
|
||||
h = c.to_hash_with_variations
|
||||
|
||||
expect(h).to be_a(Hash)
|
||||
expect(JSON.pretty_generate(h["variations"])).to eq expected_sha256_variations.strip
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -8,7 +8,7 @@ describe Cask::Cmd::Info, :cask do
|
||||
expect {
|
||||
described_class.run("local-transmission")
|
||||
}.to output(<<~EOS).to_stdout
|
||||
local-transmission: 2.61
|
||||
==> local-transmission: 2.61
|
||||
https://transmissionbt.com/
|
||||
Not installed
|
||||
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/local-transmission.rb
|
||||
@ -25,7 +25,7 @@ describe Cask::Cmd::Info, :cask do
|
||||
expect {
|
||||
described_class.run("with-auto-updates")
|
||||
}.to output(<<~EOS).to_stdout
|
||||
with-auto-updates: 1.0 (auto_updates)
|
||||
==> with-auto-updates: 1.0 (auto_updates)
|
||||
https://brew.sh/autoupdates
|
||||
Not installed
|
||||
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/with-auto-updates.rb
|
||||
@ -41,7 +41,7 @@ describe Cask::Cmd::Info, :cask do
|
||||
describe "given multiple Casks" do
|
||||
let(:expected_output) {
|
||||
<<~EOS
|
||||
local-caffeine: 1.2.3
|
||||
==> local-caffeine: 1.2.3
|
||||
https://brew.sh/
|
||||
Not installed
|
||||
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/local-caffeine.rb
|
||||
@ -52,7 +52,7 @@ describe Cask::Cmd::Info, :cask do
|
||||
==> Artifacts
|
||||
Caffeine.app (App)
|
||||
|
||||
local-transmission: 2.61
|
||||
==> local-transmission: 2.61
|
||||
https://transmissionbt.com/
|
||||
Not installed
|
||||
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/local-transmission.rb
|
||||
@ -76,7 +76,7 @@ describe Cask::Cmd::Info, :cask do
|
||||
expect {
|
||||
described_class.run("with-caveats")
|
||||
}.to output(<<~EOS).to_stdout
|
||||
with-caveats: 1.2.3
|
||||
==> with-caveats: 1.2.3
|
||||
https://brew.sh/
|
||||
Not installed
|
||||
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/with-caveats.rb
|
||||
@ -103,7 +103,7 @@ describe Cask::Cmd::Info, :cask do
|
||||
expect {
|
||||
described_class.run("with-conditional-caveats")
|
||||
}.to output(<<~EOS).to_stdout
|
||||
with-conditional-caveats: 1.2.3
|
||||
==> with-conditional-caveats: 1.2.3
|
||||
https://brew.sh/
|
||||
Not installed
|
||||
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/with-conditional-caveats.rb
|
||||
@ -120,7 +120,7 @@ describe Cask::Cmd::Info, :cask do
|
||||
expect {
|
||||
described_class.run("with-languages")
|
||||
}.to output(<<~EOS).to_stdout
|
||||
with-languages: 1.2.3
|
||||
==> with-languages: 1.2.3
|
||||
https://brew.sh/
|
||||
Not installed
|
||||
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/with-languages.rb
|
||||
@ -139,7 +139,7 @@ describe Cask::Cmd::Info, :cask do
|
||||
expect {
|
||||
described_class.run("without-languages")
|
||||
}.to output(<<~EOS).to_stdout
|
||||
without-languages: 1.2.3
|
||||
==> without-languages: 1.2.3
|
||||
https://brew.sh/
|
||||
Not installed
|
||||
From: https://github.com/Homebrew/homebrew-cask/blob/HEAD/Casks/without-languages.rb
|
||||
|
||||
@ -126,6 +126,34 @@ describe Cask::DSL, :cask do
|
||||
|
||||
expect(cask.sha256).to eq("imasha2")
|
||||
end
|
||||
|
||||
context "with a different arm and intel checksum" do
|
||||
let(:cask) do
|
||||
Cask::Cask.new("checksum-cask") do
|
||||
sha256 arm: "imasha2arm", intel: "imasha2intel"
|
||||
end
|
||||
end
|
||||
|
||||
context "when running on arm" do
|
||||
before do
|
||||
allow(Hardware::CPU).to receive(:type).and_return(:arm)
|
||||
end
|
||||
|
||||
it "stores only the arm checksum" do
|
||||
expect(cask.sha256).to eq("imasha2arm")
|
||||
end
|
||||
end
|
||||
|
||||
context "when running on intel" do
|
||||
before do
|
||||
allow(Hardware::CPU).to receive(:type).and_return(:intel)
|
||||
end
|
||||
|
||||
it "stores only the intel checksum" do
|
||||
expect(cask.sha256).to eq("imasha2intel")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "language stanza" do
|
||||
|
||||
@ -72,4 +72,16 @@ describe "brew install" do
|
||||
.and be_a_success
|
||||
expect(HOMEBREW_CELLAR/"testball1/HEAD-d5eb689/foo/test").not_to be_a_file
|
||||
end
|
||||
|
||||
it "installs formulae with debug symbols", :integration_test do
|
||||
setup_test_formula "testball1"
|
||||
|
||||
expect { brew "install", "testball1", "--debug-symbols", "--build-from-source" }
|
||||
.to output(%r{#{HOMEBREW_CELLAR}/testball1/0\.1}o).to_stdout
|
||||
.and not_to_output.to_stderr
|
||||
.and be_a_success
|
||||
expect(HOMEBREW_CELLAR/"testball1/0.1/bin/test").to be_a_file
|
||||
expect(HOMEBREW_CELLAR/"testball1/0.1/bin/test.dSYM/Contents/Resources/DWARF/test").to be_a_file if OS.mac?
|
||||
expect(HOMEBREW_CACHE/"Sources/testball1").to be_a_directory
|
||||
end
|
||||
end
|
||||
|
||||
@ -18,7 +18,7 @@ describe CompilerSelector do
|
||||
end
|
||||
|
||||
before do
|
||||
allow(versions).to receive(:non_apple_gcc_version) do |name|
|
||||
allow(versions).to receive(:gcc_version) do |name|
|
||||
case name
|
||||
when "gcc-7" then Version.create("7.1")
|
||||
when "gcc-6" then Version.create("6.1")
|
||||
|
||||
@ -149,7 +149,7 @@ describe Formula do
|
||||
end
|
||||
end
|
||||
|
||||
it "returns true by default" do
|
||||
it "returns array with versioned formulae" do
|
||||
FileUtils.touch f.path
|
||||
FileUtils.touch f2.path
|
||||
allow(Formulary).to receive(:load_formula_from_path).with(f2.name, f2.path).and_return(f2)
|
||||
@ -1996,4 +1996,28 @@ describe Formula do
|
||||
}.to raise_error("ignore_missing_libraries is available on Linux only")
|
||||
end
|
||||
end
|
||||
|
||||
describe "#generate_completions_from_executable" do
|
||||
let(:f) do
|
||||
Class.new(Testball) do
|
||||
def install
|
||||
bin.mkpath
|
||||
(bin/"foo").write <<-EOF
|
||||
echo completion
|
||||
EOF
|
||||
|
||||
FileUtils.chmod "+x", bin/"foo"
|
||||
|
||||
generate_completions_from_executable(bin/"foo", "test")
|
||||
end
|
||||
end.new
|
||||
end
|
||||
|
||||
it "generates completion scripts" do
|
||||
f.brew { f.install }
|
||||
expect(f.bash_completion/"testball").to be_a_file
|
||||
expect(f.zsh_completion/"_testball").to be_a_file
|
||||
expect(f.fish_completion/"testball.fish").to be_a_file
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -21,7 +21,7 @@ describe Language::Python::Shebang do
|
||||
|
||||
before do
|
||||
file.write <<~EOS
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/python2
|
||||
a
|
||||
b
|
||||
c
|
||||
@ -34,7 +34,7 @@ describe Language::Python::Shebang do
|
||||
describe "#detected_python_shebang" do
|
||||
it "can be used to replace Python shebangs" do
|
||||
expect(Formulary).to receive(:factory).with(python_f.name).and_return(python_f)
|
||||
Utils::Shebang.rewrite_shebang described_class.detected_python_shebang(f), file
|
||||
Utils::Shebang.rewrite_shebang described_class.detected_python_shebang(f, use_python_from_path: false), file
|
||||
|
||||
expect(File.read(file)).to eq <<~EOS
|
||||
#!#{HOMEBREW_PREFIX}/opt/python@3.11/bin/python3.11
|
||||
@ -43,5 +43,16 @@ describe Language::Python::Shebang do
|
||||
c
|
||||
EOS
|
||||
end
|
||||
|
||||
it "can be pointed to a `python3` in PATH" do
|
||||
Utils::Shebang.rewrite_shebang described_class.detected_python_shebang(f, use_python_from_path: true), file
|
||||
|
||||
expect(File.read(file)).to eq <<~EOS
|
||||
#!/usr/bin/env python3
|
||||
a
|
||||
b
|
||||
c
|
||||
EOS
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -103,7 +103,7 @@ describe Homebrew::MissingFormula do
|
||||
let(:formula) { "local-caffeine" }
|
||||
let(:show_info) { true }
|
||||
|
||||
it { is_expected.to match(/Found a cask named "local-caffeine" instead.\n\nlocal-caffeine: 1.2.3\n/) }
|
||||
it { is_expected.to match(/Found a cask named "local-caffeine" instead.\n\n==> local-caffeine: 1.2.3\n/) }
|
||||
end
|
||||
|
||||
context "with a formula name that is not a cask" do
|
||||
|
||||
@ -0,0 +1,140 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rubocops/rubocop-cask"
|
||||
require "test/rubocops/cask/shared_examples/cask_cop"
|
||||
|
||||
describe RuboCop::Cop::Cask::OnSystemConditionals do
|
||||
include CaskCop
|
||||
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context "when auditing `postflight` stanzas" do
|
||||
context "when there are no on_system blocks" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
postflight do
|
||||
foobar
|
||||
end
|
||||
CASK
|
||||
end
|
||||
|
||||
include_examples "does not report any offenses"
|
||||
end
|
||||
|
||||
context "when there is an `on_intel` block" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
postflight do
|
||||
on_intel do
|
||||
foobar
|
||||
end
|
||||
end
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
postflight do
|
||||
if Hardware::CPU.intel?
|
||||
foobar
|
||||
end
|
||||
end
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: "Don't use `on_intel` in `postflight do`, use `if Hardware::CPU.intel?` instead.",
|
||||
severity: :convention,
|
||||
line: 3,
|
||||
column: 4,
|
||||
source: "on_intel",
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when there is an `on_monterey` block" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
postflight do
|
||||
on_monterey do
|
||||
foobar
|
||||
end
|
||||
end
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
postflight do
|
||||
if MacOS.version == :monterey
|
||||
foobar
|
||||
end
|
||||
end
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: "Don't use `on_monterey` in `postflight do`, use `if MacOS.version == :monterey` instead.",
|
||||
severity: :convention,
|
||||
line: 3,
|
||||
column: 4,
|
||||
source: "on_monterey",
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when there is an `on_monterey :or_older` block" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
postflight do
|
||||
on_monterey :or_older do
|
||||
foobar
|
||||
end
|
||||
end
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
postflight do
|
||||
if MacOS.version <= :monterey
|
||||
foobar
|
||||
end
|
||||
end
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: "Don't use `on_monterey :or_older` in `postflight do`, " \
|
||||
"use `if MacOS.version <= :monterey` instead.",
|
||||
severity: :convention,
|
||||
line: 3,
|
||||
column: 4,
|
||||
source: "on_monterey :or_older",
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -41,6 +41,22 @@ describe RuboCop::Cop::Cask::StanzaGrouping do
|
||||
include_examples "does not report any offenses"
|
||||
end
|
||||
|
||||
context "when no stanzas or variable assignments are incorrectly grouped" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm64", intel: "x86_64"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
end
|
||||
CASK
|
||||
end
|
||||
|
||||
include_examples "does not report any offenses"
|
||||
end
|
||||
|
||||
context "when one stanza is incorrectly grouped" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
@ -74,6 +90,78 @@ describe RuboCop::Cop::Cask::StanzaGrouping do
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when the arch stanza is incorrectly grouped" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm64", intel: "x86_64"
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm64", intel: "x86_64"
|
||||
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: missing_line_msg,
|
||||
severity: :convention,
|
||||
line: 3,
|
||||
column: 0,
|
||||
source: " version :latest",
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when one variable assignment is incorrectly grouped" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm64", intel: "x86_64"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm64", intel: "x86_64"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: missing_line_msg,
|
||||
severity: :convention,
|
||||
line: 4,
|
||||
column: 0,
|
||||
source: " version :latest",
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when many stanzas are incorrectly grouped" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
@ -142,6 +230,94 @@ describe RuboCop::Cop::Cask::StanzaGrouping do
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when many stanzas and variable assignments are incorrectly grouped" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm64", intel: "x86_64"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
|
||||
platform = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
url 'https://foo.brew.sh/foo.zip'
|
||||
|
||||
name 'Foo'
|
||||
|
||||
homepage 'https://foo.brew.sh'
|
||||
|
||||
app 'Foo.app'
|
||||
uninstall :quit => 'com.example.foo',
|
||||
:kext => 'com.example.foo.kextextension'
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm64", intel: "x86_64"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
platform = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
|
||||
url 'https://foo.brew.sh/foo.zip'
|
||||
name 'Foo'
|
||||
homepage 'https://foo.brew.sh'
|
||||
|
||||
app 'Foo.app'
|
||||
|
||||
uninstall :quit => 'com.example.foo',
|
||||
:kext => 'com.example.foo.kextextension'
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: extra_line_msg,
|
||||
severity: :convention,
|
||||
line: 4,
|
||||
column: 0,
|
||||
source: "\n",
|
||||
}, {
|
||||
message: missing_line_msg,
|
||||
severity: :convention,
|
||||
line: 6,
|
||||
column: 0,
|
||||
source: " version :latest",
|
||||
}, {
|
||||
message: missing_line_msg,
|
||||
severity: :convention,
|
||||
line: 8,
|
||||
column: 0,
|
||||
source: " url 'https://foo.brew.sh/foo.zip'",
|
||||
}, {
|
||||
message: extra_line_msg,
|
||||
severity: :convention,
|
||||
line: 9,
|
||||
column: 0,
|
||||
source: "\n",
|
||||
}, {
|
||||
message: extra_line_msg,
|
||||
severity: :convention,
|
||||
line: 11,
|
||||
column: 0,
|
||||
source: "\n",
|
||||
}, {
|
||||
message: missing_line_msg,
|
||||
severity: :convention,
|
||||
line: 15,
|
||||
column: 0,
|
||||
source: " uninstall :quit => 'com.example.foo',",
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when caveats stanza is incorrectly grouped" do
|
||||
let(:source) do
|
||||
format(<<-CASK.undent, caveats: caveats.strip)
|
||||
@ -284,6 +460,52 @@ describe RuboCop::Cop::Cask::StanzaGrouping do
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when a stanza has a comment and there is a variable assignment" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm64", intel: "x86_64"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
# comment with an empty line between
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
|
||||
# comment directly above
|
||||
postflight do
|
||||
puts 'We have liftoff!'
|
||||
end
|
||||
url 'https://foo.brew.sh/foo.zip'
|
||||
name 'Foo'
|
||||
app 'Foo.app'
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm64", intel: "x86_64"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
|
||||
# comment with an empty line between
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
|
||||
# comment directly above
|
||||
postflight do
|
||||
puts 'We have liftoff!'
|
||||
end
|
||||
|
||||
url 'https://foo.brew.sh/foo.zip'
|
||||
name 'Foo'
|
||||
|
||||
app 'Foo.app'
|
||||
end
|
||||
CASK
|
||||
end
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
# TODO: detect incorrectly grouped stanzas in nested expressions
|
||||
context "when stanzas are nested in a conditional expression" do
|
||||
let(:source) do
|
||||
|
||||
@ -25,8 +25,11 @@ describe RuboCop::Cop::Cask::StanzaOrder do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm", intel: "x86_64"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
foo = "bar"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
@ -72,6 +75,136 @@ describe RuboCop::Cop::Cask::StanzaOrder do
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when the arch stanza is out of order" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
arch arm: "arm", intel: "x86_64"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm", intel: "x86_64"
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: "`version` stanza out of order",
|
||||
severity: :convention,
|
||||
line: 2,
|
||||
column: 2,
|
||||
source: "version :latest",
|
||||
}, {
|
||||
message: "`sha256` stanza out of order",
|
||||
severity: :convention,
|
||||
line: 3,
|
||||
column: 2,
|
||||
source: "sha256 :no_check",
|
||||
}, {
|
||||
message: "`arch` stanza out of order",
|
||||
severity: :convention,
|
||||
line: 4,
|
||||
column: 2,
|
||||
source: 'arch arm: "arm", intel: "x86_64"',
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when an arch variable assignment is out of order" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm", intel: "x86_64"
|
||||
sha256 :no_check
|
||||
version :latest
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm", intel: "x86_64"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: "`sha256` stanza out of order",
|
||||
severity: :convention,
|
||||
line: 3,
|
||||
column: 2,
|
||||
source: "sha256 :no_check",
|
||||
}, {
|
||||
message: "`on_arch_conditional` stanza out of order",
|
||||
severity: :convention,
|
||||
line: 5,
|
||||
column: 2,
|
||||
source: 'folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"',
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when an arch variable assignment is above the arch stanza" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
arch arm: "arm", intel: "x86_64"
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm", intel: "x86_64"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: "`on_arch_conditional` stanza out of order",
|
||||
severity: :convention,
|
||||
line: 2,
|
||||
column: 2,
|
||||
source: 'folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"',
|
||||
}, {
|
||||
message: "`arch` stanza out of order",
|
||||
severity: :convention,
|
||||
line: 3,
|
||||
column: 2,
|
||||
source: 'arch arm: "arm", intel: "x86_64"',
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when many stanzas are out of order" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
@ -197,6 +330,41 @@ describe RuboCop::Cop::Cask::StanzaOrder do
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when a variable assignment is out of order with a comment" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
# comment with an empty line between
|
||||
|
||||
# comment directly above
|
||||
postflight do
|
||||
puts 'We have liftoff!'
|
||||
end
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin" # comment on same line
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin" # comment on same line
|
||||
version :latest
|
||||
sha256 :no_check
|
||||
# comment with an empty line between
|
||||
|
||||
# comment directly above
|
||||
postflight do
|
||||
puts 'We have liftoff!'
|
||||
end
|
||||
end
|
||||
CASK
|
||||
end
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when the caveats stanza is out of order" do
|
||||
let(:source) do
|
||||
format(<<-CASK.undent, caveats: caveats.strip)
|
||||
|
||||
282
Library/Homebrew/test/rubocops/cask/variables_spec.rb
Normal file
282
Library/Homebrew/test/rubocops/cask/variables_spec.rb
Normal file
@ -0,0 +1,282 @@
|
||||
# typed: false
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "rubocops/rubocop-cask"
|
||||
require "test/rubocops/cask/shared_examples/cask_cop"
|
||||
|
||||
describe RuboCop::Cop::Cask::Variables do
|
||||
include CaskCop
|
||||
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context "when there are no variables" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask "foo" do
|
||||
version :latest
|
||||
end
|
||||
CASK
|
||||
end
|
||||
|
||||
include_examples "does not report any offenses"
|
||||
end
|
||||
|
||||
context "when there is an arch stanza" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask "foo" do
|
||||
arch arm: "darwin-arm64", intel: "darwin"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
|
||||
include_examples "does not report any offenses"
|
||||
end
|
||||
|
||||
context "when there is a non-arch variable that uses the arch conditional" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask "foo" do
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
|
||||
include_examples "does not report any offenses"
|
||||
end
|
||||
|
||||
context "when there is an arch variable" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch = Hardware::CPU.intel? ? "darwin" : "darwin-arm64"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "darwin-arm64", intel: "darwin"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: 'Use `arch arm: "darwin-arm64", intel: "darwin"` instead of ' \
|
||||
'`arch = Hardware::CPU.intel? ? "darwin" : "darwin-arm64"`',
|
||||
severity: :convention,
|
||||
line: 2,
|
||||
column: 2,
|
||||
source: 'arch = Hardware::CPU.intel? ? "darwin" : "darwin-arm64"',
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when there is an arch variable that doesn't use strings" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch = Hardware::CPU.intel? ? :darwin : :darwin_arm64
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: :darwin_arm64, intel: :darwin
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: "Use `arch arm: :darwin_arm64, intel: :darwin` instead of " \
|
||||
"`arch = Hardware::CPU.intel? ? :darwin : :darwin_arm64`",
|
||||
severity: :convention,
|
||||
line: 2,
|
||||
column: 2,
|
||||
source: "arch = Hardware::CPU.intel? ? :darwin : :darwin_arm64",
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when there is an arch with an empty string" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch = Hardware::CPU.intel? ? "" : "arm64"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "arm64"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: 'Use `arch arm: "arm64"` instead of ' \
|
||||
'`arch = Hardware::CPU.intel? ? "" : "arm64"`',
|
||||
severity: :convention,
|
||||
line: 2,
|
||||
column: 2,
|
||||
source: 'arch = Hardware::CPU.intel? ? "" : "arm64"',
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when there is a non-arch variable" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
folder = Hardware::CPU.intel? ? "darwin" : "darwin-arm64"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: 'Use `folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"` instead of ' \
|
||||
'`folder = Hardware::CPU.intel? ? "darwin" : "darwin-arm64"`',
|
||||
severity: :convention,
|
||||
line: 2,
|
||||
column: 2,
|
||||
source: 'folder = Hardware::CPU.intel? ? "darwin" : "darwin-arm64"',
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when there is a non-arch variable with an empty string" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
folder = Hardware::CPU.intel? ? "amd64" : ""
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
folder = on_arch_conditional intel: "amd64"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: 'Use `folder = on_arch_conditional intel: "amd64"` instead of ' \
|
||||
'`folder = Hardware::CPU.intel? ? "amd64" : ""`',
|
||||
severity: :convention,
|
||||
line: 2,
|
||||
column: 2,
|
||||
source: 'folder = Hardware::CPU.intel? ? "amd64" : ""',
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when there is an arch and a non-arch variable" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch = Hardware::CPU.arm? ? "darwin-arm64" : "darwin"
|
||||
folder = Hardware::CPU.arm? ? "darwin-arm64" : "darwin"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
arch arm: "darwin-arm64", intel: "darwin"
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: 'Use `arch arm: "darwin-arm64", intel: "darwin"` instead of ' \
|
||||
'`arch = Hardware::CPU.arm? ? "darwin-arm64" : "darwin"`',
|
||||
severity: :convention,
|
||||
line: 2,
|
||||
column: 2,
|
||||
source: 'arch = Hardware::CPU.arm? ? "darwin-arm64" : "darwin"',
|
||||
}, {
|
||||
message: 'Use `folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"` instead of ' \
|
||||
'`folder = Hardware::CPU.arm? ? "darwin-arm64" : "darwin"`',
|
||||
severity: :convention,
|
||||
line: 3,
|
||||
column: 2,
|
||||
source: 'folder = Hardware::CPU.arm? ? "darwin-arm64" : "darwin"',
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
|
||||
context "when there are two non-arch variables" do
|
||||
let(:source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
folder = Hardware::CPU.arm? ? "darwin-arm64" : "darwin"
|
||||
platform = Hardware::CPU.intel? ? "darwin": "darwin-arm64"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:correct_source) do
|
||||
<<-CASK.undent
|
||||
cask 'foo' do
|
||||
folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
platform = on_arch_conditional arm: "darwin-arm64", intel: "darwin"
|
||||
end
|
||||
CASK
|
||||
end
|
||||
let(:expected_offenses) do
|
||||
[{
|
||||
message: 'Use `folder = on_arch_conditional arm: "darwin-arm64", intel: "darwin"` instead of ' \
|
||||
'`folder = Hardware::CPU.arm? ? "darwin-arm64" : "darwin"`',
|
||||
severity: :convention,
|
||||
line: 2,
|
||||
column: 2,
|
||||
source: 'folder = Hardware::CPU.arm? ? "darwin-arm64" : "darwin"',
|
||||
}, {
|
||||
message: 'Use `platform = on_arch_conditional arm: "darwin-arm64", intel: "darwin"` instead of ' \
|
||||
'`platform = Hardware::CPU.intel? ? "darwin": "darwin-arm64"`',
|
||||
severity: :convention,
|
||||
line: 3,
|
||||
column: 2,
|
||||
source: 'platform = Hardware::CPU.intel? ? "darwin": "darwin-arm64"',
|
||||
}]
|
||||
end
|
||||
|
||||
include_examples "reports offenses"
|
||||
|
||||
include_examples "autocorrects source"
|
||||
end
|
||||
end
|
||||
@ -0,0 +1,12 @@
|
||||
cask "sha256-arch" do
|
||||
arch arm: "arm", intel: "intel"
|
||||
|
||||
version "1.2.3"
|
||||
sha256 arm: "67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94",
|
||||
intel: "8c62a2b791cf5f0da6066a0a4b6e85f62949cd60975da062df44adf887f4370b"
|
||||
|
||||
url "file://#{TEST_FIXTURE_DIR}/cask/caffeine-#{arch}.zip"
|
||||
homepage "https://brew.sh/"
|
||||
|
||||
app "Caffeine.app"
|
||||
end
|
||||
@ -24,6 +24,7 @@ module Homebrew
|
||||
build_from_source_formulae: [],
|
||||
interactive: false,
|
||||
keep_tmp: false,
|
||||
debug_symbols: false,
|
||||
force: false,
|
||||
debug: false,
|
||||
quiet: false,
|
||||
@ -61,6 +62,7 @@ module Homebrew
|
||||
build_from_source_formulae: build_from_source_formulae,
|
||||
interactive: interactive,
|
||||
keep_tmp: keep_tmp,
|
||||
debug_symbols: debug_symbols,
|
||||
force: force,
|
||||
debug: debug,
|
||||
quiet: quiet,
|
||||
@ -128,6 +130,7 @@ module Homebrew
|
||||
build_from_source_formulae: [],
|
||||
interactive: false,
|
||||
keep_tmp: false,
|
||||
debug_symbols: false,
|
||||
force: false,
|
||||
debug: false,
|
||||
quiet: false,
|
||||
@ -161,6 +164,7 @@ module Homebrew
|
||||
build_from_source_formulae: build_from_source_formulae,
|
||||
interactive: interactive,
|
||||
keep_tmp: keep_tmp,
|
||||
debug_symbols: debug_symbols,
|
||||
force: force,
|
||||
debug: debug,
|
||||
quiet: quiet,
|
||||
@ -254,6 +258,7 @@ module Homebrew
|
||||
build_from_source_formulae: [],
|
||||
interactive: false,
|
||||
keep_tmp: false,
|
||||
debug_symbols: false,
|
||||
force: false,
|
||||
debug: false,
|
||||
quiet: false,
|
||||
@ -339,6 +344,7 @@ module Homebrew
|
||||
build_from_source_formulae: build_from_source_formulae,
|
||||
interactive: interactive,
|
||||
keep_tmp: keep_tmp,
|
||||
debug_symbols: debug_symbols,
|
||||
force: force,
|
||||
debug: debug,
|
||||
quiet: quiet,
|
||||
@ -407,6 +413,7 @@ module Homebrew
|
||||
build_from_source_formulae: build_from_source_formulae + [formula.full_name],
|
||||
interactive: interactive,
|
||||
keep_tmp: keep_tmp,
|
||||
debug_symbols: debug_symbols,
|
||||
force: force,
|
||||
debug: debug,
|
||||
quiet: quiet,
|
||||
|
||||
@ -125,7 +125,7 @@ module Kernel
|
||||
puts sput unless sput.empty?
|
||||
end
|
||||
|
||||
def oh1(title, truncate: :auto)
|
||||
def oh1_title(title, truncate: :auto)
|
||||
verbose = if respond_to?(:verbose?)
|
||||
verbose?
|
||||
else
|
||||
@ -133,7 +133,11 @@ module Kernel
|
||||
end
|
||||
|
||||
title = Tty.truncate(title) if $stdout.tty? && !verbose && truncate == :auto
|
||||
puts Formatter.headline(title, color: :green)
|
||||
Formatter.headline(title, color: :green)
|
||||
end
|
||||
|
||||
def oh1(title, truncate: :auto)
|
||||
puts oh1_title(title, truncate: truncate)
|
||||
end
|
||||
|
||||
# Print a message prefixed with "Warning" (do this rarely).
|
||||
|
||||
14
Library/Homebrew/vendor/bundle/bundler/setup.rb
vendored
14
Library/Homebrew/vendor/bundle/bundler/setup.rb
vendored
@ -5,16 +5,16 @@ ruby_version = RbConfig::CONFIG["ruby_version"]
|
||||
path = File.expand_path('..', __FILE__)
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/concurrent-ruby-1.1.10/lib/concurrent-ruby"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/i18n-1.12.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.16.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/minitest-5.16.3/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tzinfo-2.0.5/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/zeitwerk-2.6.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/activesupport-6.1.6.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/public_suffix-4.0.7/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/addressable-2.8.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/public_suffix-5.0.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/addressable-2.8.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ast-2.4.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bindata-2.4.10/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-15/2.6.0-static/msgpack-1.5.4"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/msgpack-1.5.4/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-15/2.6.0-static/msgpack-1.5.5"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/msgpack-1.5.5/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-15/2.6.0-static/bootsnap-1.13.0"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bootsnap-1.13.0/lib"
|
||||
$:.unshift "#{path}/"
|
||||
@ -86,7 +86,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rspec_junit_formatter
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-ast-1.21.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.11.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-2.2.0/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-1.34.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-1.35.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-performance-1.14.3/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rails-2.15.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-2.12.1/lib"
|
||||
@ -103,5 +103,5 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/thor-1.2.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/spoom-1.1.11/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/yard-0.9.28/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/yard-sorbet-0.6.1/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tapioca-0.7.2/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/tapioca-0.7.3/lib"
|
||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/warning-1.3.0/lib"
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
@ -657,12 +656,12 @@ module Addressable
|
||||
def ordered_variable_defaults
|
||||
@ordered_variable_defaults ||= begin
|
||||
expansions, _ = parse_template_pattern(pattern)
|
||||
expansions.map do |capture|
|
||||
expansions.flat_map do |capture|
|
||||
_, _, varlist = *capture.match(EXPRESSION)
|
||||
varlist.split(',').map do |varspec|
|
||||
varspec[VARSPEC, 1]
|
||||
end
|
||||
end.flatten
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1023,7 +1022,7 @@ module Addressable
|
||||
end
|
||||
|
||||
# Ensure that the regular expression matches the whole URI.
|
||||
regexp_string = "^#{regexp_string}$"
|
||||
regexp_string = "\\A#{regexp_string}\\z"
|
||||
return expansions, Regexp.new(regexp_string)
|
||||
end
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
@ -38,20 +37,26 @@ module Addressable
|
||||
##
|
||||
# Container for the character classes specified in
|
||||
# <a href="http://www.ietf.org/rfc/rfc3986.txt">RFC 3986</a>.
|
||||
#
|
||||
# Note: Concatenated and interpolated `String`s are not affected by the
|
||||
# `frozen_string_literal` directive and must be frozen explicitly.
|
||||
#
|
||||
# Interpolated `String`s *were* frozen this way before Ruby 3.0:
|
||||
# https://bugs.ruby-lang.org/issues/17104
|
||||
module CharacterClasses
|
||||
ALPHA = "a-zA-Z"
|
||||
DIGIT = "0-9"
|
||||
GEN_DELIMS = "\\:\\/\\?\\#\\[\\]\\@"
|
||||
SUB_DELIMS = "\\!\\$\\&\\'\\(\\)\\*\\+\\,\\;\\="
|
||||
RESERVED = GEN_DELIMS + SUB_DELIMS
|
||||
UNRESERVED = ALPHA + DIGIT + "\\-\\.\\_\\~"
|
||||
PCHAR = UNRESERVED + SUB_DELIMS + "\\:\\@"
|
||||
SCHEME = ALPHA + DIGIT + "\\-\\+\\."
|
||||
HOST = UNRESERVED + SUB_DELIMS + "\\[\\:\\]"
|
||||
AUTHORITY = PCHAR + "\\[\\:\\]"
|
||||
PATH = PCHAR + "\\/"
|
||||
QUERY = PCHAR + "\\/\\?"
|
||||
FRAGMENT = PCHAR + "\\/\\?"
|
||||
RESERVED = (GEN_DELIMS + SUB_DELIMS).freeze
|
||||
UNRESERVED = (ALPHA + DIGIT + "\\-\\.\\_\\~").freeze
|
||||
PCHAR = (UNRESERVED + SUB_DELIMS + "\\:\\@").freeze
|
||||
SCHEME = (ALPHA + DIGIT + "\\-\\+\\.").freeze
|
||||
HOST = (UNRESERVED + SUB_DELIMS + "\\[\\:\\]").freeze
|
||||
AUTHORITY = (PCHAR + "\\[\\:\\]").freeze
|
||||
PATH = (PCHAR + "\\/").freeze
|
||||
QUERY = (PCHAR + "\\/\\?").freeze
|
||||
FRAGMENT = (PCHAR + "\\/\\?").freeze
|
||||
end
|
||||
|
||||
module NormalizeCharacterClasses
|
||||
@ -469,19 +474,13 @@ module Addressable
|
||||
"Expected Class (String or Addressable::URI), " +
|
||||
"got #{return_type.inspect}"
|
||||
end
|
||||
uri = uri.dup
|
||||
# Seriously, only use UTF-8. I'm really not kidding!
|
||||
uri.force_encoding("utf-8")
|
||||
|
||||
unless leave_encoded.empty?
|
||||
leave_encoded = leave_encoded.dup.force_encoding("utf-8")
|
||||
end
|
||||
|
||||
result = uri.gsub(/%[0-9a-f]{2}/iu) do |sequence|
|
||||
result = uri.gsub(/%[0-9a-f]{2}/i) do |sequence|
|
||||
c = sequence[1..3].to_i(16).chr
|
||||
c.force_encoding("utf-8")
|
||||
c.force_encoding(sequence.encoding)
|
||||
leave_encoded.include?(c) ? sequence : c
|
||||
end
|
||||
|
||||
result.force_encoding("utf-8")
|
||||
if return_type == String
|
||||
return result
|
||||
@ -561,10 +560,10 @@ module Addressable
|
||||
leave_re = if leave_encoded.length > 0
|
||||
character_class = "#{character_class}%" unless character_class.include?('%')
|
||||
|
||||
"|%(?!#{leave_encoded.chars.map do |char|
|
||||
"|%(?!#{leave_encoded.chars.flat_map do |char|
|
||||
seq = SEQUENCE_ENCODING_TABLE[char]
|
||||
[seq.upcase, seq.downcase]
|
||||
end.flatten.join('|')})"
|
||||
end.join('|')})"
|
||||
end
|
||||
|
||||
character_class = if leave_re
|
||||
@ -900,7 +899,7 @@ module Addressable
|
||||
end
|
||||
end
|
||||
# All normalized values should be UTF-8
|
||||
@normalized_scheme.force_encoding(Encoding::UTF_8) if @normalized_scheme
|
||||
force_utf8_encoding_if_needed(@normalized_scheme)
|
||||
@normalized_scheme
|
||||
end
|
||||
|
||||
@ -955,7 +954,7 @@ module Addressable
|
||||
end
|
||||
end
|
||||
# All normalized values should be UTF-8
|
||||
@normalized_user.force_encoding(Encoding::UTF_8) if @normalized_user
|
||||
force_utf8_encoding_if_needed(@normalized_user)
|
||||
@normalized_user
|
||||
end
|
||||
|
||||
@ -1012,9 +1011,7 @@ module Addressable
|
||||
end
|
||||
end
|
||||
# All normalized values should be UTF-8
|
||||
if @normalized_password
|
||||
@normalized_password.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
force_utf8_encoding_if_needed(@normalized_password)
|
||||
@normalized_password
|
||||
end
|
||||
|
||||
@ -1082,9 +1079,7 @@ module Addressable
|
||||
end
|
||||
end
|
||||
# All normalized values should be UTF-8
|
||||
if @normalized_userinfo
|
||||
@normalized_userinfo.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
force_utf8_encoding_if_needed(@normalized_userinfo)
|
||||
@normalized_userinfo
|
||||
end
|
||||
|
||||
@ -1151,9 +1146,7 @@ module Addressable
|
||||
end
|
||||
end
|
||||
# All normalized values should be UTF-8
|
||||
if @normalized_host && !@normalized_host.empty?
|
||||
@normalized_host.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
force_utf8_encoding_if_needed(@normalized_host)
|
||||
@normalized_host
|
||||
end
|
||||
|
||||
@ -1271,9 +1264,7 @@ module Addressable
|
||||
authority
|
||||
end
|
||||
# All normalized values should be UTF-8
|
||||
if @normalized_authority
|
||||
@normalized_authority.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
force_utf8_encoding_if_needed(@normalized_authority)
|
||||
@normalized_authority
|
||||
end
|
||||
|
||||
@ -1507,7 +1498,7 @@ module Addressable
|
||||
site_string
|
||||
end
|
||||
# All normalized values should be UTF-8
|
||||
@normalized_site.force_encoding(Encoding::UTF_8) if @normalized_site
|
||||
force_utf8_encoding_if_needed(@normalized_site)
|
||||
@normalized_site
|
||||
end
|
||||
|
||||
@ -1570,7 +1561,7 @@ module Addressable
|
||||
result
|
||||
end
|
||||
# All normalized values should be UTF-8
|
||||
@normalized_path.force_encoding(Encoding::UTF_8) if @normalized_path
|
||||
force_utf8_encoding_if_needed(@normalized_path)
|
||||
@normalized_path
|
||||
end
|
||||
|
||||
@ -1646,7 +1637,7 @@ module Addressable
|
||||
component == "" ? nil : component
|
||||
end
|
||||
# All normalized values should be UTF-8
|
||||
@normalized_query.force_encoding(Encoding::UTF_8) if @normalized_query
|
||||
force_utf8_encoding_if_needed(@normalized_query)
|
||||
@normalized_query
|
||||
end
|
||||
|
||||
@ -1842,9 +1833,7 @@ module Addressable
|
||||
component == "" ? nil : component
|
||||
end
|
||||
# All normalized values should be UTF-8
|
||||
if @normalized_fragment
|
||||
@normalized_fragment.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
force_utf8_encoding_if_needed(@normalized_fragment)
|
||||
@normalized_fragment
|
||||
end
|
||||
|
||||
@ -2440,30 +2429,35 @@ module Addressable
|
||||
def self.normalize_path(path)
|
||||
# Section 5.2.4 of RFC 3986
|
||||
|
||||
return nil if path.nil?
|
||||
return if path.nil?
|
||||
normalized_path = path.dup
|
||||
begin
|
||||
mod = nil
|
||||
loop do
|
||||
mod ||= normalized_path.gsub!(RULE_2A, SLASH)
|
||||
|
||||
pair = normalized_path.match(RULE_2B_2C)
|
||||
parent, current = pair[1], pair[2] if pair
|
||||
if pair
|
||||
parent = pair[1]
|
||||
current = pair[2]
|
||||
else
|
||||
parent = nil
|
||||
current = nil
|
||||
end
|
||||
|
||||
regexp = "/#{Regexp.escape(parent.to_s)}/\\.\\./|"
|
||||
regexp += "(/#{Regexp.escape(current.to_s)}/\\.\\.$)"
|
||||
|
||||
if pair && ((parent != SELF_REF && parent != PARENT) ||
|
||||
(current != SELF_REF && current != PARENT))
|
||||
mod ||= normalized_path.gsub!(
|
||||
Regexp.new(
|
||||
"/#{Regexp.escape(parent.to_s)}/\\.\\./|" +
|
||||
"(/#{Regexp.escape(current.to_s)}/\\.\\.$)"
|
||||
), SLASH
|
||||
)
|
||||
mod ||= normalized_path.gsub!(Regexp.new(regexp), SLASH)
|
||||
end
|
||||
|
||||
mod ||= normalized_path.gsub!(RULE_2D, EMPTY_STR)
|
||||
# Non-standard, removes prefixed dotted segments from path.
|
||||
mod ||= normalized_path.gsub!(RULE_PREFIXED_PARENT, SLASH)
|
||||
end until mod.nil?
|
||||
break if mod.nil?
|
||||
end
|
||||
|
||||
return normalized_path
|
||||
normalized_path
|
||||
end
|
||||
|
||||
##
|
||||
@ -2552,5 +2546,15 @@ module Addressable
|
||||
remove_instance_variable(:@uri_string) if defined?(@uri_string)
|
||||
remove_instance_variable(:@hash) if defined?(@hash)
|
||||
end
|
||||
|
||||
##
|
||||
# Converts the string to be UTF-8 if it is not already UTF-8
|
||||
#
|
||||
# @api private
|
||||
def force_utf8_encoding_if_needed(str)
|
||||
if str && str.encoding != Encoding::UTF_8
|
||||
str.force_encoding(Encoding::UTF_8)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1,6 +1,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# encoding:utf-8
|
||||
#--
|
||||
# Copyright (C) Bob Aman
|
||||
#
|
||||
@ -24,7 +23,7 @@ if !defined?(Addressable::VERSION)
|
||||
module VERSION
|
||||
MAJOR = 2
|
||||
MINOR = 8
|
||||
TINY = 0
|
||||
TINY = 1
|
||||
|
||||
STRING = [MAJOR, MINOR, TINY].join('.')
|
||||
end
|
||||
@ -1340,7 +1340,7 @@ tt.im
|
||||
tv.im
|
||||
|
||||
// in : https://en.wikipedia.org/wiki/.in
|
||||
// see also: https://registry.in/Policies
|
||||
// see also: https://registry.in/policies
|
||||
// Please note, that nic.in is not an official eTLD, but used by most
|
||||
// government institutions.
|
||||
in
|
||||
@ -7130,7 +7130,7 @@ org.zw
|
||||
|
||||
// newGTLDs
|
||||
|
||||
// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2022-03-27T15:13:38Z
|
||||
// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2022-07-03T15:13:53Z
|
||||
// This list is auto-generated, don't edit it manually.
|
||||
// aaa : 2015-02-26 American Automobile Association, Inc.
|
||||
aaa
|
||||
@ -7471,7 +7471,7 @@ bio
|
||||
// black : 2014-01-16 Afilias Limited
|
||||
black
|
||||
|
||||
// blackfriday : 2014-01-16 UNR Corp.
|
||||
// blackfriday : 2014-01-16 Registry Services, LLC
|
||||
blackfriday
|
||||
|
||||
// blockbuster : 2015-07-30 Dish DBS Corporation
|
||||
@ -7687,7 +7687,7 @@ chanel
|
||||
// channel : 2014-05-08 Charleston Road Registry Inc.
|
||||
channel
|
||||
|
||||
// charity : 2018-04-11 Binky Moon, LLC
|
||||
// charity : 2018-04-11 Public Interest Registry
|
||||
charity
|
||||
|
||||
// chase : 2015-04-30 JPMorgan Chase Bank, National Association
|
||||
@ -7834,7 +7834,7 @@ coupon
|
||||
// coupons : 2015-03-26 Binky Moon, LLC
|
||||
coupons
|
||||
|
||||
// courses : 2014-12-04 OPEN UNIVERSITIES AUSTRALIA PTY LTD
|
||||
// courses : 2014-12-04 Registry Services, LLC
|
||||
courses
|
||||
|
||||
// cpa : 2019-06-10 American Institute of Certified Public Accountants
|
||||
@ -8020,7 +8020,7 @@ dvag
|
||||
// dvr : 2016-05-26 DISH Technologies L.L.C.
|
||||
dvr
|
||||
|
||||
// earth : 2014-12-04 Interlink Co., Ltd.
|
||||
// earth : 2014-12-04 Interlink Systems Innovation Institute K.K.
|
||||
earth
|
||||
|
||||
// eat : 2014-01-23 Charleston Road Registry Inc.
|
||||
@ -8227,7 +8227,7 @@ forsale
|
||||
// forum : 2015-04-02 Fegistry, LLC
|
||||
forum
|
||||
|
||||
// foundation : 2013-12-05 Binky Moon, LLC
|
||||
// foundation : 2013-12-05 Public Interest Registry
|
||||
foundation
|
||||
|
||||
// fox : 2015-09-11 FOX Registry, LLC
|
||||
@ -8308,7 +8308,7 @@ gdn
|
||||
// gea : 2014-12-04 GEA Group Aktiengesellschaft
|
||||
gea
|
||||
|
||||
// gent : 2014-01-23 COMBELL NV
|
||||
// gent : 2014-01-23 Easyhost BV
|
||||
gent
|
||||
|
||||
// genting : 2015-03-12 Resorts World Inc Pte. Ltd.
|
||||
@ -8326,7 +8326,7 @@ gift
|
||||
// gifts : 2014-07-03 Binky Moon, LLC
|
||||
gifts
|
||||
|
||||
// gives : 2014-03-06 Dog Beach, LLC
|
||||
// gives : 2014-03-06 Public Interest Registry
|
||||
gives
|
||||
|
||||
// giving : 2014-11-13 Giving Limited
|
||||
@ -8452,7 +8452,7 @@ health
|
||||
// healthcare : 2014-06-12 Binky Moon, LLC
|
||||
healthcare
|
||||
|
||||
// help : 2014-06-26 UNR Corp.
|
||||
// help : 2014-06-26 Innovation service Limited
|
||||
help
|
||||
|
||||
// helsinki : 2015-02-05 City of Helsinki
|
||||
@ -8851,7 +8851,7 @@ lincoln
|
||||
// linde : 2014-12-04 Linde Aktiengesellschaft
|
||||
linde
|
||||
|
||||
// link : 2013-11-14 UNR Corp.
|
||||
// link : 2013-11-14 Nova Registry Ltd
|
||||
link
|
||||
|
||||
// lipsy : 2015-06-25 Lipsy Ltd
|
||||
@ -8866,7 +8866,7 @@ living
|
||||
// llc : 2017-12-14 Afilias Limited
|
||||
llc
|
||||
|
||||
// llp : 2019-08-26 UNR Corp.
|
||||
// llp : 2019-08-26 Intercap Registry Inc.
|
||||
llp
|
||||
|
||||
// loan : 2014-11-20 dot Loan Limited
|
||||
@ -9034,7 +9034,7 @@ mobile
|
||||
// moda : 2013-11-07 Dog Beach, LLC
|
||||
moda
|
||||
|
||||
// moe : 2013-11-13 Interlink Co., Ltd.
|
||||
// moe : 2013-11-13 Interlink Systems Innovation Institute K.K.
|
||||
moe
|
||||
|
||||
// moi : 2014-12-18 Amazon Registry Services, Inc.
|
||||
@ -9307,7 +9307,7 @@ philips
|
||||
// phone : 2016-06-02 Dish DBS Corporation
|
||||
phone
|
||||
|
||||
// photo : 2013-11-14 UNR Corp.
|
||||
// photo : 2013-11-14 Registry Services, LLC
|
||||
photo
|
||||
|
||||
// photography : 2013-09-20 Binky Moon, LLC
|
||||
@ -9550,7 +9550,7 @@ rsvp
|
||||
// rugby : 2016-12-15 World Rugby Strategic Developments Limited
|
||||
rugby
|
||||
|
||||
// ruhr : 2013-10-02 regiodot GmbH & Co. KG
|
||||
// ruhr : 2013-10-02 dotSaarland GmbH
|
||||
ruhr
|
||||
|
||||
// run : 2015-03-19 Binky Moon, LLC
|
||||
@ -9841,7 +9841,7 @@ stream
|
||||
// studio : 2015-02-11 Dog Beach, LLC
|
||||
studio
|
||||
|
||||
// study : 2014-12-11 OPEN UNIVERSITIES AUSTRALIA PTY LTD
|
||||
// study : 2014-12-11 Registry Services, LLC
|
||||
study
|
||||
|
||||
// style : 2014-12-04 Binky Moon, LLC
|
||||
@ -9901,7 +9901,7 @@ tatamotors
|
||||
// tatar : 2014-04-24 Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic"
|
||||
tatar
|
||||
|
||||
// tattoo : 2013-08-30 UNR Corp.
|
||||
// tattoo : 2013-08-30 Top Level Design, LLC
|
||||
tattoo
|
||||
|
||||
// tax : 2014-03-20 Binky Moon, LLC
|
||||
@ -12111,6 +12111,7 @@ kill.jp
|
||||
kilo.jp
|
||||
kuron.jp
|
||||
littlestar.jp
|
||||
lolipopmc.jp
|
||||
lolitapunk.jp
|
||||
lomo.jp
|
||||
lovepop.jp
|
||||
@ -12281,6 +12282,10 @@ blogspot.vn
|
||||
// Submitted by Niels Martignene <hello@goupile.fr>
|
||||
goupile.fr
|
||||
|
||||
// Government of the Netherlands: https://www.government.nl
|
||||
// Submitted by <domeinnaam@minaz.nl>
|
||||
gov.nl
|
||||
|
||||
// Group 53, LLC : https://www.group53.com
|
||||
// Submitted by Tyler Todd <noc@nova53.net>
|
||||
awsmppl.com
|
||||
@ -12357,7 +12362,6 @@ ltd.ng
|
||||
ngo.ng
|
||||
edu.scot
|
||||
sch.so
|
||||
org.yt
|
||||
|
||||
// HostyHosting (hostyhosting.com)
|
||||
hostyhosting.io
|
||||
@ -12375,6 +12379,11 @@ moonscale.net
|
||||
// Submitted by Hannu Aronsson <haa@iki.fi>
|
||||
iki.fi
|
||||
|
||||
// iliad italia: https://www.iliad.it
|
||||
// Submitted by Marios Makassikis <mmakassikis@freebox.fr>
|
||||
ibxos.it
|
||||
iliadboxos.it
|
||||
|
||||
// Impertrix Solutions : <https://impertrixcdn.com>
|
||||
// Submitted by Zhixiang Zhao <csuite@impertrix.com>
|
||||
impertrixcdn.com
|
||||
@ -12455,9 +12464,11 @@ iopsys.se
|
||||
// Submitted by Matthew Hardeman <mhardeman@ipifony.com>
|
||||
ipifony.net
|
||||
|
||||
// IServ GmbH : https://iserv.eu
|
||||
// Submitted by Kim-Alexander Brodowski <info@iserv.eu>
|
||||
// IServ GmbH : https://iserv.de
|
||||
// Submitted by Mario Hoberg <info@iserv.de>
|
||||
iservschule.de
|
||||
mein-iserv.de
|
||||
schulplattform.de
|
||||
schulserver.de
|
||||
test-iserv.de
|
||||
iserv.dev
|
||||
@ -12779,6 +12790,10 @@ hra.health
|
||||
miniserver.com
|
||||
memset.net
|
||||
|
||||
// Messerli Informatik AG : https://www.messerli.ch/
|
||||
// Submitted by Ruben Schmidmeister <psl-maintainers@messerli.ch>
|
||||
messerli.app
|
||||
|
||||
// MetaCentrum, CESNET z.s.p.o. : https://www.metacentrum.cz/en/
|
||||
// Submitted by Zdeněk Šustr <zdenek.sustr@cesnet.cz>
|
||||
*.cloud.metacentrum.cz
|
||||
@ -12798,12 +12813,13 @@ eu.meteorapp.com
|
||||
co.pl
|
||||
|
||||
// Microsoft Corporation : http://microsoft.com
|
||||
// Submitted by Mitch Webster <miwebst@microsoft.com>
|
||||
// Submitted by Public Suffix List Admin <msftpsladmin@microsoft.com>
|
||||
*.azurecontainer.io
|
||||
azurewebsites.net
|
||||
azure-mobile.net
|
||||
cloudapp.net
|
||||
azurestaticapps.net
|
||||
1.azurestaticapps.net
|
||||
centralus.azurestaticapps.net
|
||||
eastasia.azurestaticapps.net
|
||||
eastus2.azurestaticapps.net
|
||||
@ -13388,6 +13404,12 @@ rocky.page
|
||||
спб.рус
|
||||
я.рус
|
||||
|
||||
// Salesforce.com, Inc. https://salesforce.com/
|
||||
// Submitted by Michael Biven <mbiven@salesforce.com>
|
||||
*.builder.code.com
|
||||
*.dev-builder.code.com
|
||||
*.stg-builder.code.com
|
||||
|
||||
// Sandstorm Development Group, Inc. : https://sandcats.io/
|
||||
// Submitted by Asheesh Laroia <asheesh@sandstorm.io>
|
||||
sandcats.io
|
||||
@ -13811,6 +13833,15 @@ hk.org
|
||||
ltd.hk
|
||||
inc.hk
|
||||
|
||||
// UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/
|
||||
// see also: whois -h whois.udr.org.yt help
|
||||
// Submitted by Atanunu Igbunuroghene <publicsuffixlist@udr.org.yt>
|
||||
name.pm
|
||||
sch.tf
|
||||
biz.wf
|
||||
sch.wf
|
||||
org.yt
|
||||
|
||||
// United Gameserver GmbH : https://united-gameserver.de
|
||||
// Submitted by Stefan Schwarz <sysadm@united-gameserver.de>
|
||||
virtualuser.de
|
||||
@ -169,7 +169,7 @@ module PublicSuffix
|
||||
|
||||
return DomainInvalid.new("Name is blank") if name.empty?
|
||||
return DomainInvalid.new("Name starts with a dot") if name.start_with?(DOT)
|
||||
return DomainInvalid.new("%s is not expected to contain a scheme" % name) if name.include?("://")
|
||||
return DomainInvalid.new(format("%s is not expected to contain a scheme", name)) if name.include?("://")
|
||||
|
||||
name
|
||||
end
|
||||
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