brew/Library/Homebrew/rubocops/cask/stanza_order.rb

67 lines
2.4 KiB
Ruby
Raw Normal View History

2020-10-10 14:16:11 +02:00
# typed: true
# frozen_string_literal: true
require "forwardable"
module RuboCop
module Cop
module Cask
# This cop checks that a cask's stanzas are ordered correctly.
# @see https://docs.brew.sh/Cask-Cookbook#stanza-order
2021-01-12 18:25:05 +11:00
class StanzaOrder < Base
extend Forwardable
2021-01-12 18:25:05 +11:00
extend AutoCorrector
include CaskHelp
ON_SYSTEM_METHODS = RuboCop::Cask::Constants::ON_SYSTEM_METHODS
2019-10-03 08:50:45 +02:00
MESSAGE = "`%<stanza>s` stanza out of order"
def on_cask(cask_block)
@cask_block = cask_block
add_offenses(toplevel_stanzas)
return unless (on_blocks = toplevel_stanzas.select { |s| ON_SYSTEM_METHODS.include?(s.stanza_name) }).any?
on_blocks.map(&:method_node).each do |on_block|
next unless on_block.block_type?
block_contents = on_block.child_nodes.select(&:begin_type?)
inner_nodes = block_contents.map(&:child_nodes).flatten.select(&:send_type?)
inner_stanzas = inner_nodes.map { |node| RuboCop::Cask::AST::Stanza.new(node, processed_source.comments) }
add_offenses(inner_stanzas, inner: true)
end
end
private
attr_reader :cask_block
def_delegators :cask_block, :cask_node, :toplevel_stanzas,
:sorted_toplevel_stanzas, :sorted_inner_stanzas
def add_offenses(stanzas, inner: false)
sorted_stanzas = inner ? sorted_inner_stanzas(stanzas) : sorted_toplevel_stanzas
offending_stanzas(stanzas, inner: inner).each do |stanza|
message = format(MESSAGE, stanza: stanza.stanza_name)
2021-01-12 18:25:05 +11:00
add_offense(stanza.source_range_with_comments, message: message) do |corrector|
correct_stanza_index = stanzas.index(stanza)
correct_stanza = sorted_stanzas[correct_stanza_index]
2021-01-12 18:25:05 +11:00
corrector.replace(stanza.source_range_with_comments,
correct_stanza.source_with_comments)
end
end
end
def offending_stanzas(stanzas, inner: false)
sorted_stanzas = inner ? sorted_inner_stanzas(stanzas) : sorted_toplevel_stanzas
stanza_pairs = stanzas.zip(sorted_stanzas)
stanza_pairs.each_with_object([]) do |stanza_pair, offending_stanzas|
stanza, sorted_stanza = *stanza_pair
2023-04-18 15:06:50 -07:00
offending_stanzas << stanza if stanza != sorted_stanza
end
end
end
end
end
end