77 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # typed: strict
 | |
| # frozen_string_literal: true
 | |
| 
 | |
| require "rubocops/extend/formula_cop"
 | |
| 
 | |
| module RuboCop
 | |
|   module Cop
 | |
|     module FormulaAudit
 | |
|       # This cop checks if redundant components are present and for other component errors.
 | |
|       #
 | |
|       # - `url|checksum|mirror|version` should be inside `stable` block
 | |
|       # - `head` and `head do` should not be simultaneously present
 | |
|       # - `bottle :unneeded`/`:disable` and `bottle do` should not be simultaneously present
 | |
|       # - `stable do` should not be present without a `head` spec
 | |
|       # - `stable do` should not be present with only `url|checksum|mirror|version`
 | |
|       # - `head do` should not be present with only `url`
 | |
|       class ComponentsRedundancy < FormulaCop
 | |
|         HEAD_MSG = "`head` and `head do` should not be simultaneously present"
 | |
|         BOTTLE_MSG = "`bottle :modifier` and `bottle do` should not be simultaneously present"
 | |
|         STABLE_MSG = "`stable do` should not be present without a `head` spec"
 | |
|         STABLE_BLOCK_METHODS = [:url, :sha256, :mirror, :version].freeze
 | |
| 
 | |
|         sig { override.params(formula_nodes: FormulaNodes).void }
 | |
|         def audit_formula(formula_nodes)
 | |
|           return if (body_node = formula_nodes.body_node).nil?
 | |
| 
 | |
|           urls = find_method_calls_by_name(body_node, :url)
 | |
| 
 | |
|           urls.each do |url|
 | |
|             url.arguments.each do |arg|
 | |
|               next if arg.class != RuboCop::AST::HashNode
 | |
| 
 | |
|               url_args = arg.keys.each.map(&:value)
 | |
|               if method_called?(body_node, :sha256) && url_args.include?(:tag) && url_args.include?(:revision)
 | |
|                 problem "Do not use both `sha256` and `tag:`/`revision:`."
 | |
|               end
 | |
|             end
 | |
|           end
 | |
| 
 | |
|           stable_block = find_block(body_node, :stable)
 | |
|           if stable_block
 | |
|             STABLE_BLOCK_METHODS.each do |method_name|
 | |
|               problem "`#{method_name}` should be put inside `stable` block" if method_called?(body_node, method_name)
 | |
|             end
 | |
| 
 | |
|             unless stable_block.body.nil?
 | |
|               child_nodes = stable_block.body.begin_type? ? stable_block.body.child_nodes : [stable_block.body]
 | |
|               if child_nodes.all? { |n| n.send_type? && STABLE_BLOCK_METHODS.include?(n.method_name) }
 | |
|                 problem "`stable do` should not be present with only #{STABLE_BLOCK_METHODS.join("/")}"
 | |
|               end
 | |
|             end
 | |
|           end
 | |
| 
 | |
|           head_block = find_block(body_node, :head)
 | |
|           if head_block && !head_block.body.nil?
 | |
|             child_nodes = head_block.body.begin_type? ? head_block.body.child_nodes : [head_block.body]
 | |
|             if child_nodes.all? { |n| n.send_type? && n.method_name == :url }
 | |
|               problem "`head do` should not be present with only `url`"
 | |
|             end
 | |
|           end
 | |
| 
 | |
|           problem HEAD_MSG if method_called?(body_node, :head) &&
 | |
|                               find_block(body_node, :head)
 | |
| 
 | |
|           problem BOTTLE_MSG if method_called?(body_node, :bottle) &&
 | |
|                                 find_block(body_node, :bottle)
 | |
| 
 | |
|           return if method_called?(body_node, :head) ||
 | |
|                     find_block(body_node, :head)
 | |
| 
 | |
|           problem STABLE_MSG if stable_block
 | |
|         end
 | |
|       end
 | |
|     end
 | |
|   end
 | |
| end
 | 
