206 lines
7.5 KiB
Ruby
Raw Normal View History

# typed: strict
# frozen_string_literal: true
2023-02-20 10:22:39 -08:00
require "rubocops/extend/formula_cop"
module RuboCop
module Cop
module FormulaAudit
# This cop audits the `bottle` block in formulae.
2023-02-20 18:10:59 -08:00
class BottleFormat < FormulaCop
extend AutoCorrector
sig { override.params(formula_nodes: FormulaNodes).void }
def audit_formula(formula_nodes)
bottle_node = find_block(formula_nodes.body_node, :bottle)
return if bottle_node.nil?
sha256_nodes = find_method_calls_by_name(bottle_node.body, :sha256)
cellar_node = find_node_method_by_name(bottle_node.body, :cellar)
cellar_source = cellar_node&.first_argument&.source
if sha256_nodes.present? && cellar_node.present?
offending_node(cellar_node)
problem "`cellar` should be a parameter to `sha256`" do |corrector|
corrector.remove(range_by_whole_lines(cellar_node.source_range, include_final_newline: true))
end
end
sha256_nodes.each do |sha256_node|
sha256_hash = sha256_node.last_argument
sha256_pairs = sha256_hash.pairs
next if sha256_pairs.count != 1
sha256_pair = sha256_pairs.first
sha256_key = sha256_pair.key
sha256_value = sha256_pair.value
next unless sha256_value.sym_type?
tag = sha256_value.value
digest_source = sha256_key.source
sha256_line = if cellar_source.present?
"sha256 cellar: #{cellar_source}, #{tag}: #{digest_source}"
else
"sha256 #{tag}: #{digest_source}"
end
offending_node(sha256_node)
problem "`sha256` should use new syntax" do |corrector|
corrector.replace(sha256_node.source_range, sha256_line)
end
end
end
end
# This cop audits the indentation of the bottle tags in the `bottle` block in formulae.
2023-02-20 18:10:59 -08:00
class BottleTagIndentation < FormulaCop
extend AutoCorrector
sig { override.params(formula_nodes: FormulaNodes).void }
def audit_formula(formula_nodes)
bottle_node = find_block(formula_nodes.body_node, :bottle)
return if bottle_node.nil?
sha256_nodes = find_method_calls_by_name(bottle_node.body, :sha256)
max_tag_column = 0
sha256_nodes.each do |sha256_node|
sha256_hash = sha256_node.last_argument
tag_column = T.let(sha256_hash.pairs.last.source_range.column, Integer)
max_tag_column = tag_column if tag_column > max_tag_column
end
# This must be in a separate loop to make sure max_tag_column is truly the maximum
sha256_nodes.each do |sha256_node| # rubocop:disable Style/CombinableLoops
sha256_hash = sha256_node.last_argument
hash = sha256_hash.pairs.last
tag_column = hash.source_range.column
next if tag_column == max_tag_column
offending_node(hash)
problem "Align bottle tags" do |corrector|
new_line = (" " * (max_tag_column - tag_column)) + hash.source
corrector.replace(hash.source_range, new_line)
end
end
end
end
# This cop audits the indentation of the sha256 digests in the`bottle` block in formulae.
2023-02-20 18:10:59 -08:00
class BottleDigestIndentation < FormulaCop
extend AutoCorrector
sig { override.params(formula_nodes: FormulaNodes).void }
def audit_formula(formula_nodes)
bottle_node = find_block(formula_nodes.body_node, :bottle)
return if bottle_node.nil?
sha256_nodes = find_method_calls_by_name(bottle_node.body, :sha256)
max_digest_column = 0
sha256_nodes.each do |sha256_node|
sha256_hash = sha256_node.last_argument
digest_column = T.let(sha256_hash.pairs.last.value.source_range.column, Integer)
max_digest_column = digest_column if digest_column > max_digest_column
end
# This must be in a separate loop to make sure max_digest_column is truly the maximum
sha256_nodes.each do |sha256_node| # rubocop:disable Style/CombinableLoops
sha256_hash = sha256_node.last_argument
hash = sha256_hash.pairs.last.value
digest_column = hash.source_range.column
next if digest_column == max_digest_column
offending_node(hash)
problem "Align bottle digests" do |corrector|
new_line = (" " * (max_digest_column - digest_column)) + hash.source
corrector.replace(hash.source_range, new_line)
end
end
end
end
# This cop audits the order of the `bottle` block in formulae.
2023-02-20 18:10:59 -08:00
class BottleOrder < FormulaCop
extend AutoCorrector
sig { override.params(formula_nodes: FormulaNodes).void }
def audit_formula(formula_nodes)
bottle_node = find_block(formula_nodes.body_node, :bottle)
return if bottle_node.nil?
return if bottle_node.child_nodes.blank?
non_sha256_nodes = []
sha256_nodes = []
bottle_block_method_calls = if bottle_node.child_nodes.last.begin_type?
bottle_node.child_nodes.last.child_nodes
else
[bottle_node.child_nodes.last]
end
bottle_block_method_calls.each do |node|
if node.method_name == :sha256
sha256_nodes << node
else
non_sha256_nodes << node
end
end
Fix bottle block generation and audit for arm64 Linux Before this change, `brew bottle` would add the `:arm64_linux` bottle lines last. This would make `brew style` complain because it wants the `arm64_*` bottles listed first. Let's fix this by retaining the existing style as closely as possible: - macOS bottles are listed first - for each OS, arm64 bottles are listed first (just as we do on macOS) In particular, `brew bottle` will now insert `:arm64_linux` bottle lines just above the `:x86_64_linux` bottle lines (but still below the macOS bottle lines). x86_64 may continue to be a more popular platform on Linux for quite some time. However, users looking for those bottles can continue to look in the same place as before this change (i.e., the last line of the bottle block). Taking this together with the consistency on macOS mentioned above, I think this is the right way forward here. For concreteness, here are some examples of bottle blocks before and after this change. Before this change, immediately after `brew bottle`: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" end Before this change, after doing `brew style --fix`: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" end After this change: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" end
2025-03-18 16:10:43 +08:00
arm64_macos_nodes = []
intel_macos_nodes = []
arm64_linux_nodes = []
intel_linux_nodes = []
sha256_nodes.each do |node|
version = sha256_bottle_tag node
Fix bottle block generation and audit for arm64 Linux Before this change, `brew bottle` would add the `:arm64_linux` bottle lines last. This would make `brew style` complain because it wants the `arm64_*` bottles listed first. Let's fix this by retaining the existing style as closely as possible: - macOS bottles are listed first - for each OS, arm64 bottles are listed first (just as we do on macOS) In particular, `brew bottle` will now insert `:arm64_linux` bottle lines just above the `:x86_64_linux` bottle lines (but still below the macOS bottle lines). x86_64 may continue to be a more popular platform on Linux for quite some time. However, users looking for those bottles can continue to look in the same place as before this change (i.e., the last line of the bottle block). Taking this together with the consistency on macOS mentioned above, I think this is the right way forward here. For concreteness, here are some examples of bottle blocks before and after this change. Before this change, immediately after `brew bottle`: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" end Before this change, after doing `brew style --fix`: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" end After this change: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" end
2025-03-18 16:10:43 +08:00
if version == :arm64_linux
arm64_linux_nodes << node
elsif version.to_s.start_with?("arm64")
arm64_macos_nodes << node
elsif version.to_s.end_with?("_linux")
intel_linux_nodes << node
else
Fix bottle block generation and audit for arm64 Linux Before this change, `brew bottle` would add the `:arm64_linux` bottle lines last. This would make `brew style` complain because it wants the `arm64_*` bottles listed first. Let's fix this by retaining the existing style as closely as possible: - macOS bottles are listed first - for each OS, arm64 bottles are listed first (just as we do on macOS) In particular, `brew bottle` will now insert `:arm64_linux` bottle lines just above the `:x86_64_linux` bottle lines (but still below the macOS bottle lines). x86_64 may continue to be a more popular platform on Linux for quite some time. However, users looking for those bottles can continue to look in the same place as before this change (i.e., the last line of the bottle block). Taking this together with the consistency on macOS mentioned above, I think this is the right way forward here. For concreteness, here are some examples of bottle blocks before and after this change. Before this change, immediately after `brew bottle`: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" end Before this change, after doing `brew style --fix`: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" end After this change: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" end
2025-03-18 16:10:43 +08:00
intel_macos_nodes << node
end
end
Fix bottle block generation and audit for arm64 Linux Before this change, `brew bottle` would add the `:arm64_linux` bottle lines last. This would make `brew style` complain because it wants the `arm64_*` bottles listed first. Let's fix this by retaining the existing style as closely as possible: - macOS bottles are listed first - for each OS, arm64 bottles are listed first (just as we do on macOS) In particular, `brew bottle` will now insert `:arm64_linux` bottle lines just above the `:x86_64_linux` bottle lines (but still below the macOS bottle lines). x86_64 may continue to be a more popular platform on Linux for quite some time. However, users looking for those bottles can continue to look in the same place as before this change (i.e., the last line of the bottle block). Taking this together with the consistency on macOS mentioned above, I think this is the right way forward here. For concreteness, here are some examples of bottle blocks before and after this change. Before this change, immediately after `brew bottle`: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" end Before this change, after doing `brew style --fix`: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" end After this change: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" end
2025-03-18 16:10:43 +08:00
sorted_nodes = arm64_macos_nodes + intel_macos_nodes + arm64_linux_nodes + intel_linux_nodes
return if sha256_order(sha256_nodes) == sha256_order(sorted_nodes)
2021-02-04 13:34:37 -05:00
offending_node(bottle_node)
problem "ARM bottles should be listed before Intel bottles" do |corrector|
lines = ["bottle do"]
lines += non_sha256_nodes.map { |node| " #{node.source}" }
Fix bottle block generation and audit for arm64 Linux Before this change, `brew bottle` would add the `:arm64_linux` bottle lines last. This would make `brew style` complain because it wants the `arm64_*` bottles listed first. Let's fix this by retaining the existing style as closely as possible: - macOS bottles are listed first - for each OS, arm64 bottles are listed first (just as we do on macOS) In particular, `brew bottle` will now insert `:arm64_linux` bottle lines just above the `:x86_64_linux` bottle lines (but still below the macOS bottle lines). x86_64 may continue to be a more popular platform on Linux for quite some time. However, users looking for those bottles can continue to look in the same place as before this change (i.e., the last line of the bottle block). Taking this together with the consistency on macOS mentioned above, I think this is the right way forward here. For concreteness, here are some examples of bottle blocks before and after this change. Before this change, immediately after `brew bottle`: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" end Before this change, after doing `brew style --fix`: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" end After this change: bottle do sha256 arm64_sequoia: "1a57e04052f4bae4172d546a7927c645fc29d2ef5fafbec19d08ee1dddc542fb" sha256 arm64_sonoma: "a58cf9af5d04d3d5709b5337f3793586087a79e178da51d1f3978c0c13b8cf34" sha256 ventura: "6d8b90b2cbb31dcb78394c6540f5454cd57232fc309921173814f880e63718f0" sha256 arm64_linux: "457d3e9bd0c287483e27f29a488a18c90e1f55be076fc49b07942ef396c419be" sha256 x86_64_linux: "cd5faac2834ba79e39429b9aac99e4f69d6e6023cbb1cbcd0b62e94cfc69bb2a" end
2025-03-18 16:10:43 +08:00
lines += arm64_macos_nodes.map { |node| " #{node.source}" }
lines += intel_macos_nodes.map { |node| " #{node.source}" }
lines += arm64_linux_nodes.map { |node| " #{node.source}" }
lines += intel_linux_nodes.map { |node| " #{node.source}" }
2021-02-04 13:34:37 -05:00
lines << " end"
corrector.replace(bottle_node.source_range, lines.join("\n"))
end
end
sig { params(nodes: T::Array[RuboCop::AST::SendNode]).returns(T::Array[T.any(String, Symbol)]) }
def sha256_order(nodes)
nodes.map do |node|
sha256_bottle_tag node
end
end
sig { params(node: AST::SendNode).returns(T.any(String, Symbol)) }
def sha256_bottle_tag(node)
hash_pair = node.last_argument.pairs.last
if hash_pair.key.sym_type?
hash_pair.key.value
else
hash_pair.value.value
end
end
end
end
end
end