| 
									
										
										
										
											2024-07-14 00:24:16 +00:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-20 10:22:39 -08:00
										 |  |  | require "rubocops/extend/formula_cop" | 
					
						
							| 
									
										
										
										
											2017-09-04 13:47:05 +05:30
										 |  |  | 
 | 
					
						
							|  |  |  | module RuboCop | 
					
						
							|  |  |  |   module Cop | 
					
						
							|  |  |  |     module FormulaAudit | 
					
						
							| 
									
										
										
										
											2020-11-05 17:17:03 -05:00
										 |  |  |       # This cop makes sure that {Formula} is used as superclass. | 
					
						
							| 
									
										
										
										
											2023-02-20 18:10:59 -08:00
										 |  |  |       class ClassName < FormulaCop | 
					
						
							| 
									
										
										
										
											2021-01-12 13:33:23 +11:00
										 |  |  |         extend AutoCorrector | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-04 13:47:05 +05:30
										 |  |  |         DEPRECATED_CLASSES = %w[
 | 
					
						
							|  |  |  |           GithubGistFormula | 
					
						
							|  |  |  |           ScriptFileFormula | 
					
						
							|  |  |  |           AmazonWebServicesFormula | 
					
						
							|  |  |  |         ].freeze | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-07 15:18:29 -04:00
										 |  |  |         sig { override.params(formula_nodes: FormulaNodes).void } | 
					
						
							|  |  |  |         def audit_formula(formula_nodes) | 
					
						
							|  |  |  |           parent_class_node = formula_nodes.parent_class_node | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-04 13:47:05 +05:30
										 |  |  |           parent_class = class_name(parent_class_node) | 
					
						
							|  |  |  |           return unless DEPRECATED_CLASSES.include?(parent_class) | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-12 13:33:23 +11:00
										 |  |  |           problem "#{parent_class} is deprecated, use Formula instead" do |corrector| | 
					
						
							|  |  |  |             corrector.replace(parent_class_node.source_range, "Formula") | 
					
						
							| 
									
										
										
										
											2017-09-04 13:47:05 +05:30
										 |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2018-08-15 19:29:22 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-08-26 02:28:17 +02:00
										 |  |  |       # This cop makes sure that a `test` block contains a proper test. | 
					
						
							| 
									
										
										
										
											2023-02-20 18:10:59 -08:00
										 |  |  |       class Test < FormulaCop | 
					
						
							| 
									
										
										
										
											2021-01-12 13:33:23 +11:00
										 |  |  |         extend AutoCorrector | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-07 15:18:29 -04:00
										 |  |  |         sig { override.params(formula_nodes: FormulaNodes).void } | 
					
						
							|  |  |  |         def audit_formula(formula_nodes) | 
					
						
							|  |  |  |           test = find_block(formula_nodes.body_node, :test) | 
					
						
							| 
									
										
										
										
											2018-08-16 16:38:41 -04:00
										 |  |  |           return unless test | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 14:34:05 +01:00
										 |  |  |           if test.body.nil? | 
					
						
							|  |  |  |             problem "`test do` should not be empty" | 
					
						
							|  |  |  |             return | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           problem "`test do` should contain a real test" if test.body.single_line? && test.body.source.to_s == "true" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-16 16:38:41 -04:00
										 |  |  |           test_calls(test) do |node, params| | 
					
						
							| 
									
										
										
										
											2018-08-15 19:29:22 -04:00
										 |  |  |             p1, p2 = params | 
					
						
							| 
									
										
										
										
											2021-02-12 18:33:37 +05:30
										 |  |  |             if (match = string_content(p1).match(%r{(/usr/local/(s?bin))})) | 
					
						
							| 
									
										
										
										
											2018-08-15 19:29:22 -04:00
										 |  |  |               offending_node(p1) | 
					
						
							| 
									
										
										
										
											2021-01-12 13:33:23 +11:00
										 |  |  |               problem "use \#{#{match[2]}} instead of #{match[1]} in #{node}" do |corrector| | 
					
						
							|  |  |  |                 corrector.replace(p1.source_range, p1.source.sub(match[1], "\#{#{match[2]}}")) | 
					
						
							|  |  |  |               end | 
					
						
							| 
									
										
										
										
											2018-08-15 19:29:22 -04:00
										 |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if node == :shell_output && node_equals?(p2, 0) | 
					
						
							|  |  |  |               offending_node(p2) | 
					
						
							| 
									
										
										
										
											2021-01-12 13:33:23 +11:00
										 |  |  |               problem "Passing 0 to shell_output() is redundant" do |corrector| | 
					
						
							|  |  |  |                 corrector.remove(range_with_surrounding_comma(range_with_surrounding_space(range: p2.source_range, | 
					
						
							|  |  |  |                                                                                            side:  :left))) | 
					
						
							|  |  |  |               end | 
					
						
							| 
									
										
										
										
											2018-08-16 12:42:45 -04:00
										 |  |  |             end | 
					
						
							|  |  |  |           end | 
					
						
							|  |  |  |         end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-15 19:29:22 -04:00
										 |  |  |         def_node_search :test_calls, <<~EOS | 
					
						
							|  |  |  |           (send nil? ${:system :shell_output :pipe_output} $...) | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  |       end | 
					
						
							| 
									
										
										
										
											2017-09-04 13:47:05 +05:30
										 |  |  |     end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-13 14:34:05 +01:00
										 |  |  |     module FormulaAuditStrict | 
					
						
							| 
									
										
										
										
											2020-08-26 02:28:17 +02:00
										 |  |  |       # This cop makes sure that a `test` block exists. | 
					
						
							| 
									
										
										
										
											2023-02-20 18:10:59 -08:00
										 |  |  |       class TestPresent < FormulaCop | 
					
						
							| 
									
										
										
										
											2024-07-07 15:18:29 -04:00
										 |  |  |         sig { override.params(formula_nodes: FormulaNodes).void } | 
					
						
							|  |  |  |         def audit_formula(formula_nodes) | 
					
						
							|  |  |  |           body_node = formula_nodes.body_node | 
					
						
							| 
									
										
										
										
											2020-04-13 14:34:05 +01:00
										 |  |  |           return if find_block(body_node, :test) | 
					
						
							| 
									
										
										
										
											2024-07-03 10:24:40 +01:00
										 |  |  |           return if find_node_method_by_name(body_node, :disable!) | 
					
						
							| 
									
										
										
										
											2018-09-17 02:45:00 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-07-07 15:18:29 -04:00
										 |  |  |           offending_node(formula_nodes.class_node) if body_node.nil? | 
					
						
							| 
									
										
										
										
											2020-04-13 14:34:05 +01:00
										 |  |  |           problem "A `test do` test block should be added" | 
					
						
							| 
									
										
										
										
											2017-09-04 13:47:05 +05:30
										 |  |  |         end | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							|  |  |  |   end | 
					
						
							|  |  |  | end |