Merge branch 'Homebrew:master' into mohammad

This commit is contained in:
Mohammad Zain Abbas 2022-07-27 13:27:48 +02:00 committed by GitHub
commit eee457f8b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 907 additions and 148 deletions

View File

@ -58,12 +58,12 @@ GEM
mime-types-data (3.2022.0105) mime-types-data (3.2022.0105)
mini_portile2 (2.8.0) mini_portile2 (2.8.0)
minitest (5.16.2) minitest (5.16.2)
msgpack (1.5.3) msgpack (1.5.4)
mustache (1.1.1) mustache (1.1.1)
net-http-digest_auth (1.4.1) net-http-digest_auth (1.4.1)
net-http-persistent (4.0.1) net-http-persistent (4.0.1)
connection_pool (~> 2.2) connection_pool (~> 2.2)
nokogiri (1.13.7) nokogiri (1.13.8)
mini_portile2 (~> 2.8.0) mini_portile2 (~> 2.8.0)
racc (~> 1.4) racc (~> 1.4)
parallel (1.22.1) parallel (1.22.1)

View File

@ -29,6 +29,10 @@ FORMULA_COMPONENT_PRECEDENCE_LIST = [
[{ name: :depends_on, type: :method_call }], [{ name: :depends_on, type: :method_call }],
[{ name: :uses_from_macos, type: :method_call }], [{ name: :uses_from_macos, type: :method_call }],
[{ name: :on_macos, type: :block_call }], [{ name: :on_macos, type: :block_call }],
*MacOSVersions::SYMBOLS.keys.map do |os_name|
[{ name: :"on_#{os_name}", type: :block_call }]
end,
[{ name: :on_system, type: :block_call }],
[{ name: :on_linux, type: :block_call }], [{ name: :on_linux, type: :block_call }],
[{ name: :on_arm, type: :block_call }], [{ name: :on_arm, type: :block_call }],
[{ name: :on_intel, type: :block_call }], [{ name: :on_intel, type: :block_call }],

View File

@ -603,13 +603,13 @@ EOS
# Only try to `git fetch` when the upstream tags have changed # Only try to `git fetch` when the upstream tags have changed
# (so the API does not return 304: unmodified). # (so the API does not return 304: unmodified).
GITHUB_API_ETAG="$(sed -n 's/^ETag: "\([a-f0-9]\{32\}\)".*/\1/p' ".git/GITHUB_HEADERS" 2>/dev/null)" GITHUB_API_ETAG="$(sed -n 's/^ETag: "\([a-f0-9]\{32\}\)".*/\1/p' ".git/GITHUB_HEADERS" 2>/dev/null)"
GITHUB_API_ACCEPT="application/vnd.github.v3+json" GITHUB_API_ACCEPT="application/vnd.github+json"
GITHUB_API_ENDPOINT="tags" GITHUB_API_ENDPOINT="tags"
else else
# Only try to `git fetch` when the upstream branch is at a different SHA # Only try to `git fetch` when the upstream branch is at a different SHA
# (so the API does not return 304: unmodified). # (so the API does not return 304: unmodified).
GITHUB_API_ETAG="$(git rev-parse "refs/remotes/origin/${UPSTREAM_BRANCH_DIR}")" GITHUB_API_ETAG="$(git rev-parse "refs/remotes/origin/${UPSTREAM_BRANCH_DIR}")"
GITHUB_API_ACCEPT="application/vnd.github.v3.sha" GITHUB_API_ACCEPT="application/vnd.github.sha"
GITHUB_API_ENDPOINT="commits/${UPSTREAM_BRANCH_DIR}" GITHUB_API_ENDPOINT="commits/${UPSTREAM_BRANCH_DIR}"
fi fi

View File

@ -243,8 +243,8 @@ module Homebrew
elsif new_tag.present? elsif new_tag.present?
[ [
[ [
/#{formula_spec.specs[:tag]}(?=")/, /tag:(\s+")#{formula_spec.specs[:tag]}(?=")/,
new_tag, "tag:\\1#{new_tag}\\2",
], ],
[ [
formula_spec.specs[:revision], formula_spec.specs[:revision],

View File

@ -1034,7 +1034,7 @@ class GitHubGitDownloadStrategy < GitDownloadStrategy
output, _, status = curl_output( output, _, status = curl_output(
"--silent", "--head", "--location", "--silent", "--head", "--location",
"-H", "Accept: application/vnd.github.v3.sha", "-H", "Accept: application/vnd.github.sha",
"https://api.github.com/repos/#{@user}/#{@repo}/commits/#{@ref}" "https://api.github.com/repos/#{@user}/#{@repo}/commits/#{@ref}"
) )
@ -1051,7 +1051,7 @@ class GitHubGitDownloadStrategy < GitDownloadStrategy
output, _, status = curl_output( output, _, status = curl_output(
"--silent", "--head", "--location", "--silent", "--head", "--location",
"-H", "Accept: application/vnd.github.v3.sha", "-H", "Accept: application/vnd.github.sha",
"https://api.github.com/repos/#{@user}/#{@repo}/commits/#{commit}" "https://api.github.com/repos/#{@user}/#{@repo}/commits/#{commit}"
) )

View File

@ -15,7 +15,7 @@ module RuboCop
extend AutoCorrector extend AutoCorrector
def on_system_methods def on_system_methods
@on_system_methods ||= [:intel, :arm, :macos, :linux, *MacOSVersions::SYMBOLS.keys].map do |m| @on_system_methods ||= [:intel, :arm, :macos, :linux, :system, *MacOSVersions::SYMBOLS.keys].map do |m|
:"on_#{m}" :"on_#{m}"
end end
end end
@ -116,6 +116,15 @@ module RuboCop
end end
def check_on_system_block_content(component_precedence_list, on_system_block) def check_on_system_block_content(component_precedence_list, on_system_block)
if on_system_block.body.block_type? && !on_system_methods.include?(on_system_block.body.method_name)
offending_node(on_system_block)
problem "Nest `#{on_system_block.method_name}` blocks inside `#{on_system_block.body.method_name}` " \
"blocks when there is only one inner block." do |corrector|
original_source = on_system_block.source.split("\n")
new_source = [original_source.second, original_source.first, *original_source.drop(2)]
corrector.replace(on_system_block.source_range, new_source.join("\n"))
end
end
on_system_allowed_methods = %w[ on_system_allowed_methods = %w[
depends_on depends_on
patch patch

View File

@ -1,6 +1,7 @@
# typed: true # typed: true
# frozen_string_literal: true # frozen_string_literal: true
require "macos_versions"
require "rubocops/extend/formula" require "rubocops/extend/formula"
module RuboCop module RuboCop
@ -375,61 +376,171 @@ module RuboCop
# This cop makes sure that OS conditionals are consistent. # This cop makes sure that OS conditionals are consistent.
# #
# @api private # @api private
class OSConditionals < FormulaCop class OnSystemConditionals < FormulaCop
extend AutoCorrector 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) def audit_formula(_node, _class_node, _parent_class_node, body_node)
no_on_os_method_names = [:install, :post_install].freeze top_level_nodes_to_check = []
no_on_os_block_names = [:service, :test].freeze NO_ON_SYSTEM_METHOD_NAMES.each do |formula_method_name|
[[:on_macos, :mac?], [:on_linux, :linux?]].each do |on_method_name, if_method_name| method_node = find_method_def(body_node, formula_method_name)
if_method_and_class = "if OS.#{if_method_name}" top_level_nodes_to_check << [formula_method_name, method_node] if method_node
no_on_os_method_names.each do |formula_method_name| end
method_node = find_method_def(body_node, formula_method_name) NO_ON_SYSTEM_BLOCK_NAMES.each do |formula_block_name|
next unless method_node block_node = find_block(body_node, formula_block_name)
next unless method_called_ever?(method_node, on_method_name) top_level_nodes_to_check << [formula_block_name, block_node] if block_node
end
problem "Don't use '#{on_method_name}' in 'def #{formula_method_name}', " \ ALL_SYSTEM_OPTIONS.each do |on_system_option|
"use '#{if_method_and_class}' instead." do |corrector| method_info = on_system_method_info(on_system_option)
block_node = offending_node.parent
next if block_node.type != :block
# TODO: could fix corrector to handle this but punting for now. top_level_nodes_to_check.each do |top_level_name, top_level_node|
next if block_node.single_line? top_level_node_string = if top_level_node.def_type?
"def #{top_level_name}"
else
"#{top_level_name} do"
end
source_range = offending_node.source_range.join(offending_node.parent.loc.begin) find_every_method_call_by_name(top_level_node, method_info[:method]).each do |method|
corrector.replace(source_range, if_method_and_class) 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
end
# Don't restrict OS.mac? or OS.linux? usage in taps; they don't care
# as much as we do about e.g. formulae.brew.sh generation, often use
# platform-specific URLs and we don't want to add DSLs to support
# 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)
if_nodes_to_check = []
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
end end
no_on_os_block_names.each do |formula_block_name| if_nodes_to_check.each do |if_node, else_info|
block_node = find_block(body_node, formula_block_name) # TODO: check to see if it's legal
next unless block_node
next unless block_method_called_in_block?(block_node, on_method_name)
problem "Don't use '#{on_method_name}' in '#{formula_block_name} do', " \
"use '#{if_method_and_class}' instead." do |corrector|
# TODO: could fix corrector to handle this but punting for now.
next if offending_node.single_line?
source_range = offending_node.send_node.source_range.join(offending_node.body.source_range.begin)
corrector.replace(source_range, "#{if_method_and_class}\n")
end
end
# Don't restrict OS.mac? or OS.linux? usage in taps; they don't care
# as much as we do about e.g. formulae.brew.sh generation, often use
# platform-specific URLs and we don't want to add DSLs to support
# that case.
next if formula_tap != "homebrew-core"
find_instance_method_call(body_node, "OS", if_method_name) do |method|
valid = T.let(false, T::Boolean) valid = T.let(false, T::Boolean)
method.each_ancestor do |ancestor| if_node.each_ancestor do |ancestor|
valid_method_names = case ancestor.type valid_method_names = case ancestor.type
when :def when :def
no_on_os_method_names NO_ON_SYSTEM_METHOD_NAMES
when :block when :block
no_on_os_block_names NO_ON_SYSTEM_BLOCK_NAMES
else else
next next
end end
@ -440,19 +551,47 @@ module RuboCop
end end
next if valid next if valid
offending_node(method) offending_node(if_node)
problem "Don't use '#{if_method_and_class}', use '#{on_method_name} do' instead." do |corrector|
if_node = method.parent
next if if_node.type != :if
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. # TODO: could fix corrector to handle this but punting for now.
next if if_node.unless? next if if_node.unless?
corrector.replace(if_node.source_range, "#{on_method_name} do\n#{if_node.body.source}\nend") 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 end
end end
end 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 end
# This cop checks for other miscellaneous style violations. # This cop checks for other miscellaneous style violations.

View File

@ -0,0 +1,24 @@
# typed: strict
module RuboCop
module Cop
module FormulaAudit
class OnSystemConditionals < FormulaCop
sig { params(node: T.any, on_method: Symbol, block: T.proc.params(parameters: T::Array[T.any]).void).void }
def on_macos_version_method_call(node, on_method:, &block); end
sig { params(node: T.any, block: T.proc.params(macos_symbol: Symbol).void).void }
def on_system_method_call(node, &block); end
sig { params(node: T.any, arch: Symbol, block: T.proc.params(node: T.any, else_node: T.any).void).void }
def if_arch_node_search(node, arch:, &block); end
sig { params(node: T.any, base_os: Symbol, block: T.proc.params(node: T.any, else_node: T.any).void).void }
def if_base_os_node_search(node, base_os:, &block); end
sig { params(node: T.any, os_name: Symbol, block: T.proc.params(node: T.any, operator: Symbol, else_node: T.any).void).void }
def if_macos_version_node_search(node, os_name:, &block); end
end
end
end
end

View File

@ -679,6 +679,130 @@ describe RuboCop::Cop::FormulaAudit::ComponentsOrder do
RUBY RUBY
end end
it "reports an offense when a single `patch` block is inside the `on_arm` block" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
on_arm do
^^^^^^^^^ Nest `on_arm` blocks inside `patch` blocks when there is only one inner block.
patch do
url "https://brew.sh/patch1.tar.gz"
sha256 "2c39089f64d9d4c3e632f120894b36b68dcc8ae8c6f5130c0c2e6f5bb7aebf2f"
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
patch do
on_arm do
url "https://brew.sh/patch1.tar.gz"
sha256 "2c39089f64d9d4c3e632f120894b36b68dcc8ae8c6f5130c0c2e6f5bb7aebf2f"
end
end
end
RUBY
end
it "reports an offense when a single `resource` block is inside the `on_linux` block" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
on_linux do
^^^^^^^^^^^ Nest `on_linux` blocks inside `resource` blocks when there is only one inner block.
resource do
url "https://brew.sh/resource1.tar.gz"
sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
resource do
on_linux do
url "https://brew.sh/resource1.tar.gz"
sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"
end
end
end
RUBY
end
it "reports an offense when a single `patch` block is inside the `on_monterey :or_newer` block" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
on_monterey :or_newer do
^^^^^^^^^^^^^^^^^^^^^^^^ Nest `on_monterey` blocks inside `patch` blocks when there is only one inner block.
patch do
url "https://brew.sh/patch1.tar.gz"
sha256 "2c39089f64d9d4c3e632f120894b36b68dcc8ae8c6f5130c0c2e6f5bb7aebf2f"
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
patch do
on_monterey :or_newer do
url "https://brew.sh/patch1.tar.gz"
sha256 "2c39089f64d9d4c3e632f120894b36b68dcc8ae8c6f5130c0c2e6f5bb7aebf2f"
end
end
end
RUBY
end
it "reports an offense when a single `resource` block is inside the `on_system` block" do
expect_offense(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
on_system :linux, macos: :monterey_or_older do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Nest `on_system` blocks inside `resource` blocks when there is only one inner block.
resource do
url "https://brew.sh/resource1.tar.gz"
sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
resource do
on_system :linux, macos: :monterey_or_older do
url "https://brew.sh/resource1.tar.gz"
sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"
end
end
end
RUBY
end
it "reports no offenses when a single `on_arm` block is inside the `on_macos` block" do
expect_no_offenses(<<~RUBY)
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
on_macos do
on_arm do
resource do
url "https://brew.sh/resource1.tar.gz"
sha256 "586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"
end
end
end
end
RUBY
end
context "when in a resource block" do context "when in a resource block" do
it "reports no offenses for a valid `on_macos` and `on_linux` block" do it "reports no offenses for a valid `on_macos` and `on_linux` block" do
expect_no_offenses(<<~RUBY) expect_no_offenses(<<~RUBY)

View File

@ -1,86 +0,0 @@
# typed: false
# frozen_string_literal: true
require "rubocops/lines"
describe RuboCop::Cop::FormulaAudit::OSConditionals do
subject(:cop) { described_class.new }
context "when auditing OS conditionals" do
it "reports an offense when `OS.linux?` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if OS.linux?
^^^^^^^^^ Don't use 'if OS.linux?', use 'on_linux do' instead.
url 'https://brew.sh/linux-1.0.tgz'
else
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `OS.mac?` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if OS.mac?
^^^^^^^ Don't use 'if OS.mac?', use 'on_macos do' instead.
url 'https://brew.sh/mac-1.0.tgz'
else
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `on_macos` is used in install method" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
on_macos do
^^^^^^^^ Don't use 'on_macos' in 'def install', use 'if OS.mac?' instead.
true
end
end
end
RUBY
end
it "reports an offense when `on_linux` is used in install method" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
on_linux do
^^^^^^^^ Don't use 'on_linux' in 'def install', use 'if OS.linux?' instead.
true
end
end
end
RUBY
end
it "reports an offense when `on_macos` is used in test block" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
test do
on_macos do
^^^^^^^^ Don't use 'on_macos' in 'test do', use 'if OS.mac?' instead.
true
end
end
end
RUBY
end
end
end

View File

@ -0,0 +1,546 @@
# typed: false
# frozen_string_literal: true
require "rubocops/lines"
describe RuboCop::Cop::FormulaAudit::OnSystemConditionals do
subject(:cop) { described_class.new }
context "when auditing OS conditionals" do
it "reports an offense when `OS.linux?` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if OS.linux?
^^^^^^^^^^^^ Don't use `if OS.linux?`, use `on_linux do` instead.
url 'https://brew.sh/linux-1.0.tgz'
else
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
on_linux do
url 'https://brew.sh/linux-1.0.tgz'
end
on_macos do
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `OS.mac?` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if OS.mac?
^^^^^^^^^^ Don't use `if OS.mac?`, use `on_macos do` instead.
url 'https://brew.sh/mac-1.0.tgz'
else
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
on_macos do
url 'https://brew.sh/mac-1.0.tgz'
end
on_linux do
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `on_macos` is used in install method" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
on_macos do
^^^^^^^^ Don't use `on_macos` in `def install`, use `if OS.mac?` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
if OS.mac?
true
end
end
end
RUBY
end
it "reports an offense when `on_linux` is used in install method" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
on_linux do
^^^^^^^^ Don't use `on_linux` in `def install`, use `if OS.linux?` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
if OS.linux?
true
end
end
end
RUBY
end
it "reports an offense when `on_macos` is used in test block" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
test do
on_macos do
^^^^^^^^ Don't use `on_macos` in `test do`, use `if OS.mac?` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
test do
if OS.mac?
true
end
end
end
RUBY
end
end
context "when auditing Hardware::CPU conditionals" do
it "reports an offense when `Hardware::CPU.arm?` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if Hardware::CPU.arm?
^^^^^^^^^^^^^^^^^^^^^ Don't use `if Hardware::CPU.arm?`, use `on_arm do` instead.
url 'https://brew.sh/linux-1.0.tgz'
else
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
on_arm do
url 'https://brew.sh/linux-1.0.tgz'
end
on_intel do
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `Hardware::CPU.intel?` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if Hardware::CPU.intel?
^^^^^^^^^^^^^^^^^^^^^^^ Don't use `if Hardware::CPU.intel?`, use `on_intel do` instead.
url 'https://brew.sh/mac-1.0.tgz'
else
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
on_intel do
url 'https://brew.sh/mac-1.0.tgz'
end
on_arm do
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `on_intel` is used in install method" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
on_intel do
^^^^^^^^ Don't use `on_intel` in `def install`, use `if Hardware::CPU.intel?` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
if Hardware::CPU.intel?
true
end
end
end
RUBY
end
it "reports an offense when `on_arm` is used in install method" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
on_arm do
^^^^^^ Don't use `on_arm` in `def install`, use `if Hardware::CPU.arm?` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
if Hardware::CPU.arm?
true
end
end
end
RUBY
end
it "reports an offense when `on_intel` is used in test block" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
test do
on_intel do
^^^^^^^^ Don't use `on_intel` in `test do`, use `if Hardware::CPU.intel?` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
test do
if Hardware::CPU.intel?
true
end
end
end
RUBY
end
end
context "when auditing MacOS.version conditionals" do
it "reports an offense when `MacOS.version ==` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if MacOS.version == :monterey
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use `if MacOS.version == :monterey`, use `on_monterey do` instead.
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
on_monterey do
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `MacOS.version <=` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if MacOS.version <= :monterey
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use `if MacOS.version <= :monterey`, use `on_system :linux, macos: :monterey_or_older do` instead.
url 'https://brew.sh/mac-1.0.tgz'
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
on_system :linux, macos: :monterey_or_older do
url 'https://brew.sh/mac-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `MacOS.version <` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if MacOS.version < :monterey
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use `if MacOS.version < :monterey`, use `on_system do` instead.
url 'https://brew.sh/mac-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `MacOS.version >=` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if MacOS.version >= :monterey
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use `if MacOS.version >= :monterey`, use `on_monterey :or_newer do` instead.
url 'https://brew.sh/mac-1.0.tgz'
else
url 'https://brew.sh/linux-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `MacOS.version >` is used on Formula class" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
if MacOS.version > :monterey
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use `if MacOS.version > :monterey`, use `on_monterey do` instead.
url 'https://brew.sh/mac-1.0.tgz'
end
end
RUBY
end
it "reports an offense when `on_monterey` is used in install method" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
on_monterey do
^^^^^^^^^^^ Don't use `on_monterey` in `def install`, use `if MacOS.version == :monterey` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
if MacOS.version == :monterey
true
end
end
end
RUBY
end
it "reports an offense when `on_monterey :or_older` is used in install method" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
on_monterey :or_older do
^^^^^^^^^^^^^^^^^^^^^ Don't use `on_monterey :or_older` in `def install`, use `if MacOS.version <= :monterey` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
if MacOS.version <= :monterey
true
end
end
end
RUBY
end
it "reports an offense when `on_monterey :or_newer` is used in install method" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
on_monterey :or_newer do
^^^^^^^^^^^^^^^^^^^^^ Don't use `on_monterey :or_newer` in `def install`, use `if MacOS.version >= :monterey` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
if MacOS.version >= :monterey
true
end
end
end
RUBY
end
it "reports an offense when `on_system :linux, macos: :monterey_or_newer` is used in install method" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
on_system :linux, macos: :monterey_or_newer do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use `on_system :linux, macos: :monterey_or_newer` in `def install`, use `if OS.linux? || MacOS.version >= :monterey` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
def install
if OS.linux? || MacOS.version >= :monterey
true
end
end
end
RUBY
end
it "reports an offense when `on_monterey` is used in test block" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
test do
on_monterey do
^^^^^^^^^^^ Don't use `on_monterey` in `test do`, use `if MacOS.version == :monterey` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
test do
if MacOS.version == :monterey
true
end
end
end
RUBY
end
it "reports an offense when `on_system :linux, macos: :monterey` is used in test block" do
expect_offense(<<~RUBY, "/homebrew-core/Formula/foo.rb")
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
test do
on_system :linux, macos: :monterey do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Don't use `on_system :linux, macos: :monterey` in `test do`, use `if OS.linux? || MacOS.version == :monterey` instead.
true
end
end
end
RUBY
expect_correction(<<~RUBY)
class Foo < Formula
desc "foo"
url 'https://brew.sh/foo-1.0.tgz'
test do
if OS.linux? || MacOS.version == :monterey
true
end
end
end
RUBY
end
end
end

View File

@ -184,8 +184,7 @@ module GitHub
# This is a no-op if the user is opting out of using the GitHub API. # This is a no-op if the user is opting out of using the GitHub API.
return block_given? ? yield({}) : {} if Homebrew::EnvConfig.no_github_api? return block_given? ? yield({}) : {} if Homebrew::EnvConfig.no_github_api?
args = ["--header", "Accept: application/vnd.github.v3+json", "--write-out", "\n%\{http_code}"] args = ["--header", "Accept: application/vnd.github+json", "--write-out", "\n%\{http_code}"]
args += ["--header", "Accept: application/vnd.github.antiope-preview+json"]
token = credentials token = credentials
args += ["--header", "Authorization: token #{token}"] unless credentials_type == :none args += ["--header", "Authorization: token #{token}"] unless credentials_type == :none

View File

@ -13,8 +13,8 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/public_suffix-4.0.7/l
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/addressable-2.8.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/addressable-2.8.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ast-2.4.2/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}/gems/bindata-2.4.10/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-15/2.6.0-static/msgpack-1.5.3" $:.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.3/lib" $:.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/bootsnap-1.12.0" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-15/2.6.0-static/bootsnap-1.12.0"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bootsnap-1.12.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/bootsnap-1.12.0/lib"
$:.unshift "#{path}/" $:.unshift "#{path}/"
@ -49,7 +49,7 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/net-http-persistent-4
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mini_portile2-2.8.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/mini_portile2-2.8.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-15/2.6.0-static/racc-1.6.0" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/extensions/x86_64-darwin-15/2.6.0-static/racc-1.6.0"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/racc-1.6.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/racc-1.6.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/nokogiri-1.13.7-x86_64-darwin/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/nokogiri-1.13.8-x86_64-darwin/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubyntlm-0.6.3/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubyntlm-0.6.3/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/webrick-1.7.0/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/webrick-1.7.0/lib"
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/webrobots-0.1.2/lib" $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/webrobots-0.1.2/lib"

View File

@ -78,10 +78,10 @@ Homebrew provides pre-built binary packages for many formulae. These are referre
If available, bottled binaries will be used by default except under the following conditions: If available, bottled binaries will be used by default except under the following conditions:
* Options were passed to the install command, i.e. `brew install <formula>` will use a bottled version of the formula, but `brew install --enable-bar <formula>` will trigger a source build.
* The `--build-from-source` option is invoked. * The `--build-from-source` option is invoked.
* No bottle is available for the machine's currently running OS version. (Bottles for macOS are generated only for supported macOS versions.) * No bottle is available for the machine's currently running OS version. (Bottles for macOS are generated only for supported macOS versions.)
* Homebrew is installed to a prefix other than the default (although some bottles support this). * Homebrew is installed to a prefix other than the default (although some bottles support this).
* Formula options were passed to the install command. For example, `brew install <formula>` will try to find a bottled binary, but `brew install --with-foo <formula>` will trigger a source build.
We aim to bottle everything. We aim to bottle everything.