rails_best_practices 1.19.2 → 1.20.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (149) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/.travis.yml +2 -3
  4. data/CHANGELOG.md +7 -7
  5. data/Gemfile +3 -5
  6. data/Gemfile.lock +125 -0
  7. data/Guardfile +2 -0
  8. data/README.md +6 -6
  9. data/Rakefile +2 -17
  10. data/assets/result.html.erb +2 -0
  11. data/lib/rails_best_practices.rb +3 -2
  12. data/lib/rails_best_practices/analyzer.rb +61 -49
  13. data/lib/rails_best_practices/cli.rb +22 -0
  14. data/lib/rails_best_practices/command.rb +1 -131
  15. data/lib/rails_best_practices/core/check.rb +64 -56
  16. data/lib/rails_best_practices/core/checks_loader.rb +24 -23
  17. data/lib/rails_best_practices/core/configs.rb +1 -2
  18. data/lib/rails_best_practices/core/controllers.rb +1 -2
  19. data/lib/rails_best_practices/core/error.rb +1 -1
  20. data/lib/rails_best_practices/core/helpers.rb +1 -2
  21. data/lib/rails_best_practices/core/mailers.rb +1 -2
  22. data/lib/rails_best_practices/core/methods.rb +27 -21
  23. data/lib/rails_best_practices/core/model_associations.rb +10 -5
  24. data/lib/rails_best_practices/core/models.rb +1 -2
  25. data/lib/rails_best_practices/core/modules.rb +1 -1
  26. data/lib/rails_best_practices/core/routes.rb +2 -2
  27. data/lib/rails_best_practices/core/runner.rb +67 -73
  28. data/lib/rails_best_practices/lexicals/long_line_check.rb +7 -3
  29. data/lib/rails_best_practices/option_parser.rb +156 -0
  30. data/lib/rails_best_practices/prepares.rb +1 -1
  31. data/lib/rails_best_practices/prepares/controller_prepare.rb +24 -17
  32. data/lib/rails_best_practices/prepares/gemfile_prepare.rb +2 -2
  33. data/lib/rails_best_practices/prepares/helper_prepare.rb +6 -1
  34. data/lib/rails_best_practices/prepares/initializer_prepare.rb +3 -3
  35. data/lib/rails_best_practices/prepares/mailer_prepare.rb +2 -1
  36. data/lib/rails_best_practices/prepares/model_prepare.rb +63 -23
  37. data/lib/rails_best_practices/prepares/route_prepare.rb +28 -21
  38. data/lib/rails_best_practices/prepares/schema_prepare.rb +1 -1
  39. data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +38 -34
  40. data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +94 -89
  41. data/lib/rails_best_practices/reviews/check_destroy_return_value_review.rb +15 -5
  42. data/lib/rails_best_practices/reviews/check_save_return_value_review.rb +20 -8
  43. data/lib/rails_best_practices/reviews/default_scope_is_evil_review.rb +1 -1
  44. data/lib/rails_best_practices/reviews/dry_bundler_in_capistrano_review.rb +1 -1
  45. data/lib/rails_best_practices/reviews/hash_syntax_review.rb +16 -16
  46. data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +12 -12
  47. data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +10 -11
  48. data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +25 -24
  49. data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +4 -4
  50. data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +9 -10
  51. data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +10 -11
  52. data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +24 -22
  53. data/lib/rails_best_practices/reviews/not_rescue_exception_review.rb +1 -1
  54. data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +1 -2
  55. data/lib/rails_best_practices/reviews/not_use_time_ago_in_words_review.rb +1 -1
  56. data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +8 -8
  57. data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +35 -32
  58. data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +4 -4
  59. data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +26 -19
  60. data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +12 -10
  61. data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +38 -18
  62. data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +11 -11
  63. data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +77 -74
  64. data/lib/rails_best_practices/reviews/review.rb +2 -1
  65. data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +2 -3
  66. data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +12 -12
  67. data/lib/rails_best_practices/reviews/use_before_filter_review.rb +18 -15
  68. data/lib/rails_best_practices/reviews/use_model_association_review.rb +15 -15
  69. data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +24 -22
  70. data/lib/rails_best_practices/reviews/use_observer_review.rb +28 -28
  71. data/lib/rails_best_practices/reviews/use_parentheses_in_method_def_review.rb +6 -6
  72. data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +68 -66
  73. data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +9 -8
  74. data/lib/rails_best_practices/reviews/use_scope_access_review.rb +16 -14
  75. data/lib/rails_best_practices/reviews/use_turbo_sprockets_rails3_review.rb +2 -1
  76. data/lib/rails_best_practices/version.rb +1 -1
  77. data/rails_best_practices.gemspec +38 -43
  78. data/spec/fixtures/lib/rails_best_practices/plugins/reviews/not_use_rails_root_review.rb +1 -2
  79. data/spec/rails_best_practices/analyzer_spec.rb +73 -42
  80. data/spec/rails_best_practices/core/check_spec.rb +5 -5
  81. data/spec/rails_best_practices/core/checks_loader_spec.rb +3 -3
  82. data/spec/rails_best_practices/core/configs_spec.rb +1 -1
  83. data/spec/rails_best_practices/core/controllers_spec.rb +1 -1
  84. data/spec/rails_best_practices/core/error_spec.rb +21 -18
  85. data/spec/rails_best_practices/core/except_methods_spec.rb +7 -7
  86. data/spec/rails_best_practices/core/gems_spec.rb +4 -4
  87. data/spec/rails_best_practices/core/helpers_spec.rb +1 -1
  88. data/spec/rails_best_practices/core/klasses_spec.rb +3 -3
  89. data/spec/rails_best_practices/core/mailers_spec.rb +1 -1
  90. data/spec/rails_best_practices/core/methods_spec.rb +6 -6
  91. data/spec/rails_best_practices/core/model_associations_spec.rb +10 -6
  92. data/spec/rails_best_practices/core/model_attributes_spec.rb +4 -4
  93. data/spec/rails_best_practices/core/models_spec.rb +1 -1
  94. data/spec/rails_best_practices/core/modules_spec.rb +5 -5
  95. data/spec/rails_best_practices/core/routes_spec.rb +5 -5
  96. data/spec/rails_best_practices/core/runner_spec.rb +9 -7
  97. data/spec/rails_best_practices/core_ext/erubis_spec.rb +10 -10
  98. data/spec/rails_best_practices/lexicals/long_line_check_spec.rb +32 -31
  99. data/spec/rails_best_practices/lexicals/remove_tab_check_spec.rb +6 -6
  100. data/spec/rails_best_practices/lexicals/remove_trailing_whitespace_check_spec.rb +6 -6
  101. data/spec/rails_best_practices/prepares/config_prepare_spec.rb +2 -2
  102. data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +18 -10
  103. data/spec/rails_best_practices/prepares/gemfile_prepare_spec.rb +17 -17
  104. data/spec/rails_best_practices/prepares/helper_prepare_spec.rb +3 -3
  105. data/spec/rails_best_practices/prepares/initializer_prepare_spec.rb +3 -3
  106. data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +2 -2
  107. data/spec/rails_best_practices/prepares/model_prepare_spec.rb +79 -43
  108. data/spec/rails_best_practices/prepares/route_prepare_spec.rb +141 -76
  109. data/spec/rails_best_practices/prepares/schema_prepare_spec.rb +2 -2
  110. data/spec/rails_best_practices/reviews/add_model_virtual_attribute_review_spec.rb +18 -12
  111. data/spec/rails_best_practices/reviews/always_add_db_index_review_spec.rb +28 -22
  112. data/spec/rails_best_practices/reviews/check_destroy_return_value_review_spec.rb +15 -13
  113. data/spec/rails_best_practices/reviews/check_save_return_value_review_spec.rb +31 -21
  114. data/spec/rails_best_practices/reviews/default_scope_is_evil_review_spec.rb +6 -6
  115. data/spec/rails_best_practices/reviews/dry_bundler_in_capistrano_review_spec.rb +5 -5
  116. data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +13 -13
  117. data/spec/rails_best_practices/reviews/isolate_seed_data_review_spec.rb +7 -7
  118. data/spec/rails_best_practices/reviews/keep_finders_on_their_own_model_review_spec.rb +9 -9
  119. data/spec/rails_best_practices/reviews/law_of_demeter_review_spec.rb +29 -22
  120. data/spec/rails_best_practices/reviews/move_code_into_controller_review_spec.rb +6 -6
  121. data/spec/rails_best_practices/reviews/move_code_into_helper_review_spec.rb +11 -6
  122. data/spec/rails_best_practices/reviews/move_code_into_model_review_spec.rb +32 -22
  123. data/spec/rails_best_practices/reviews/move_finder_to_named_scope_review_spec.rb +7 -7
  124. data/spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb +9 -7
  125. data/spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb +9 -9
  126. data/spec/rails_best_practices/reviews/not_rescue_exception_review_spec.rb +9 -9
  127. data/spec/rails_best_practices/reviews/not_use_default_route_review_spec.rb +5 -5
  128. data/spec/rails_best_practices/reviews/not_use_time_ago_in_words_review_spec.rb +7 -7
  129. data/spec/rails_best_practices/reviews/overuse_route_customizations_review_spec.rb +7 -7
  130. data/spec/rails_best_practices/reviews/protect_mass_assignment_review_spec.rb +24 -17
  131. data/spec/rails_best_practices/reviews/remove_empty_helpers_review_spec.rb +6 -6
  132. data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +64 -31
  133. data/spec/rails_best_practices/reviews/remove_unused_methods_in_helpers_review_spec.rb +21 -14
  134. data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +57 -53
  135. data/spec/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review_spec.rb +10 -8
  136. data/spec/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review_spec.rb +20 -14
  137. data/spec/rails_best_practices/reviews/restrict_auto_generated_routes_review_spec.rb +54 -31
  138. data/spec/rails_best_practices/reviews/simplify_render_in_controllers_review_spec.rb +9 -9
  139. data/spec/rails_best_practices/reviews/simplify_render_in_views_review_spec.rb +13 -13
  140. data/spec/rails_best_practices/reviews/use_before_filter_review_spec.rb +11 -9
  141. data/spec/rails_best_practices/reviews/use_model_association_review_spec.rb +7 -7
  142. data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +35 -31
  143. data/spec/rails_best_practices/reviews/use_observer_review_spec.rb +6 -6
  144. data/spec/rails_best_practices/reviews/use_parentheses_in_method_def_review_spec.rb +10 -8
  145. data/spec/rails_best_practices/reviews/use_query_attribute_review_spec.rb +31 -24
  146. data/spec/rails_best_practices/reviews/use_say_with_time_in_migrations_review_spec.rb +15 -11
  147. data/spec/rails_best_practices/reviews/use_scope_access_review_spec.rb +14 -14
  148. data/spec/rails_best_practices/reviews/use_turbo_sprockets_rails3_review_spec.rb +61 -59
  149. metadata +16 -18
@@ -2,7 +2,6 @@
2
2
 
3
3
  module RailsBestPractices
4
4
  module Core
5
- class Configs < Hash
6
- end
5
+ class Configs < Hash; end
7
6
  end
8
7
  end
@@ -5,7 +5,6 @@ require_rel 'klasses'
5
5
  module RailsBestPractices
6
6
  module Core
7
7
  # Controller classes.
8
- class Controllers < Klasses
9
- end
8
+ class Controllers < Klasses; end
10
9
  end
11
10
  end
@@ -20,7 +20,7 @@ module RailsBestPractices
20
20
  end
21
21
 
22
22
  def short_filename
23
- File.expand_path(filename)[File.expand_path(Core::Runner.base_path).size..-1].sub(/^\//, '')
23
+ File.expand_path(filename)[File.expand_path(Core::Runner.base_path).size..-1].sub(%r{^/}, '')
24
24
  end
25
25
 
26
26
  def first_line_number
@@ -5,7 +5,6 @@ require_rel 'modules'
5
5
  module RailsBestPractices
6
6
  module Core
7
7
  # Helper moduels.
8
- class Helpers < Modules
9
- end
8
+ class Helpers < Modules; end
10
9
  end
11
10
  end
@@ -3,7 +3,6 @@
3
3
  module RailsBestPractices
4
4
  module Core
5
5
  # Mailer classes.
6
- class Mailers < Klasses
7
- end
6
+ class Mailers < Klasses; end
8
7
  end
9
8
  end
@@ -18,6 +18,7 @@ module RailsBestPractices
18
18
  def add_method(class_name, method_name, meta = {}, access_control = 'public')
19
19
  return if class_name == ''
20
20
  return if has_method?(class_name, method_name)
21
+
21
22
  methods(class_name) << Method.new(class_name, method_name, access_control, meta)
22
23
  if access_control == 'public'
23
24
  @possible_methods[method_name] = false
@@ -45,7 +46,9 @@ module RailsBestPractices
45
46
  # @return [Boolean] has a method or not
46
47
  def has_method?(class_name, method_name, access_control = nil)
47
48
  if access_control
48
- !!methods(class_name).find { |method| method.method_name == method_name && method.access_control == access_control }
49
+ !!methods(class_name).find do |method|
50
+ method.method_name == method_name && method.access_control == access_control
51
+ end
49
52
  else
50
53
  !!methods(class_name).find { |method| method.method_name == method_name }
51
54
  end
@@ -57,10 +60,10 @@ module RailsBestPractices
57
60
  # @param [String] method name
58
61
  def mark_parent_class_method_used(class_name, method_name)
59
62
  klass = Prepares.klasses.find { |klass| klass.to_s == class_name }
60
- if klass && klass.extend_class_name
63
+ if klass&.extend_class_name
61
64
  mark_parent_class_method_used(klass.extend_class_name, method_name)
62
65
  method = get_method(klass.extend_class_name, method_name)
63
- method.mark_used if method
66
+ method&.mark_used
64
67
  end
65
68
  end
66
69
 
@@ -72,7 +75,7 @@ module RailsBestPractices
72
75
  Prepares.klasses.select { |klass| klass.extend_class_name == class_name }.each do |klass|
73
76
  mark_subclasses_method_used(klass.to_s, method_name)
74
77
  method = get_method(klass.to_s, method_name)
75
- method.mark_used if method
78
+ method&.mark_used
76
79
  end
77
80
  end
78
81
 
@@ -82,7 +85,7 @@ module RailsBestPractices
82
85
  # @param [String] method name
83
86
  def mark_publicize(class_name, method_name)
84
87
  method = get_method(class_name, method_name)
85
- method.publicize if method
88
+ method&.publicize
86
89
  end
87
90
 
88
91
  # Mark parent classs' method as public.
@@ -91,7 +94,7 @@ module RailsBestPractices
91
94
  # @param [String] method name
92
95
  def mark_parent_class_methods_publicize(class_name, method_name)
93
96
  klass = Prepares.klasses.find { |klass| klass.to_s == class_name }
94
- if klass && klass.extend_class_name
97
+ if klass&.extend_class_name
95
98
  mark_parent_class_methods_publicize(klass.extend_class_name, method_name)
96
99
  mark_publicize(class_name, method_name)
97
100
  end
@@ -112,7 +115,9 @@ module RailsBestPractices
112
115
  # @return [Method] Method object
113
116
  def get_method(class_name, method_name, access_control = nil)
114
117
  if access_control
115
- methods(class_name).find { |method| method.method_name == method_name && method.access_control == access_control }
118
+ methods(class_name).find do |method|
119
+ method.method_name == method_name && method.access_control == access_control
120
+ end
116
121
  else
117
122
  methods(class_name).find { |method| method.method_name == method_name }
118
123
  end
@@ -123,24 +128,25 @@ module RailsBestPractices
123
128
  # @param [String] access control
124
129
  # @return [Array] array of Method
125
130
  def get_all_unused_methods(access_control = nil)
126
- @methods.inject([]) { |unused_methods, (_class_name, methods)|
127
- unused_methods += if access_control
128
- methods.select { |method| method.access_control == access_control && !method.used }
129
- else
130
- methods.reject { |method| method.used }
131
- end
132
- }.reject { |method| method.access_control == 'public' && @possible_methods[method.method_name] }
131
+ @methods.inject([]) do |unused_methods, (_class_name, methods)|
132
+ unused_methods +=
133
+ if access_control
134
+ methods.select { |method| method.access_control == access_control && !method.used }
135
+ else
136
+ methods.reject(&:used)
137
+ end
138
+ end.reject { |method| method.access_control == 'public' && @possible_methods[method.method_name] }
133
139
  end
134
140
 
135
141
  private
136
142
 
137
- # Methods of a class.
138
- #
139
- # @param [String] class name
140
- # @return [Array] array of methods
141
- def methods(class_name)
142
- @methods[class_name] ||= []
143
- end
143
+ # Methods of a class.
144
+ #
145
+ # @param [String] class name
146
+ # @return [Array] array of methods
147
+ def methods(class_name)
148
+ @methods[class_name] ||= []
149
+ end
144
150
  end
145
151
 
146
152
  # Method info includes class name, method name, access control, file, line_number, used.
@@ -15,7 +15,9 @@ module RailsBestPractices
15
15
  # @param [String] association class name
16
16
  def add_association(model_name, association_name, association_meta, association_class = nil)
17
17
  @associations[model_name] ||= {}
18
- @associations[model_name][association_name] = { 'meta' => association_meta, 'class_name' => association_class || association_name.classify }
18
+ @associations[model_name][association_name] = {
19
+ 'meta' => association_meta, 'class_name' => association_class || association_name.classify
20
+ }
19
21
  end
20
22
 
21
23
  # Get a model association.
@@ -25,7 +27,7 @@ module RailsBestPractices
25
27
  # @return [Hash] {"meta" => association_meta, "class_name" => association_class}
26
28
  def get_association(model_name, association_name)
27
29
  associations = @associations[model_name]
28
- associations and associations[association_name]
30
+ associations && associations[association_name]
29
31
  end
30
32
 
31
33
  # If it is a model's association.
@@ -39,7 +41,7 @@ module RailsBestPractices
39
41
  end
40
42
 
41
43
  # delegate each to @associations.
42
- def each(&block)
44
+ def each
43
45
  @associations.each { |model, model_associations| yield model, model_associations }
44
46
  end
45
47
 
@@ -49,8 +51,11 @@ module RailsBestPractices
49
51
  # @param [String] association_name
50
52
  # @return [String] association's class name
51
53
  def get_association_class_name(table_name, association_name)
52
- associations = @associations.select { |model, _model_associations| model.gsub('::', '').tableize == table_name }.values.first and
53
- association_meta = associations.select { |name, _meta| name == association_name }.values.first and
54
+ (
55
+ associations =
56
+ @associations.select { |model, _model_associations| model.gsub('::', '').tableize == table_name }.values
57
+ .first
58
+ ) && (association_meta = associations.select { |name, _meta| name == association_name }.values.first) &&
54
59
  association_meta['class_name']
55
60
  end
56
61
  end
@@ -3,7 +3,6 @@
3
3
  module RailsBestPractices
4
4
  module Core
5
5
  # Model classes.
6
- class Models < Klasses
7
- end
6
+ class Models < Klasses; end
8
7
  end
9
8
  end
@@ -10,7 +10,7 @@ module RailsBestPractices
10
10
  # @param [String] descendant name
11
11
  def add_module_descendant(module_name, descendant)
12
12
  mod = find { |mod| mod.to_s == module_name }
13
- mod.add_descendant(descendant) if mod
13
+ mod&.add_descendant(descendant)
14
14
  end
15
15
  end
16
16
 
@@ -24,8 +24,8 @@ module RailsBestPractices
24
24
  # mappings can be specified by e.g.
25
25
  # post 'some/:pattern' => 'controller#action'
26
26
  if action_name.is_a?(String) && action_name =~ /\A(\w+)#(\w+)\z/
27
- controller_name = $1
28
- action_name = $2
27
+ controller_name = Regexp.last_match(1)
28
+ action_name = Regexp.last_match(2)
29
29
  end
30
30
 
31
31
  if controller_name
@@ -20,33 +20,23 @@ module RailsBestPractices
20
20
  class Runner
21
21
  attr_reader :checks
22
22
 
23
- # set the base path.
24
- #
25
- # @param [String] path the base path
26
- def self.base_path=(path)
27
- @base_path = path
28
- end
29
-
30
- # get the base path, by default, the base path is current path.
31
- #
32
- # @return [String] the base path
33
- def self.base_path
34
- @base_path || '.'
35
- end
23
+ class << self
24
+ attr_writer :base_path, :config_path
36
25
 
37
- # set the configuration path
38
- #
39
- # @param path [String] path to rbc config file
40
- def self.config_path=(path)
41
- @config_path = path
42
- end
26
+ # get the base path, by default, the base path is current path.
27
+ #
28
+ # @return [String] the base path
29
+ def base_path
30
+ @base_path || '.'
31
+ end
43
32
 
44
- # get the configuration path, if will default to config/rails_best_practices.yml
45
- #
46
- # @return [String] the config path
47
- def self.config_path
48
- custom_config = @config_path || File.join(Runner.base_path, 'config/rails_best_practices.yml')
49
- File.exist?(custom_config) ? custom_config : RailsBestPractices::Analyzer::DEFAULT_CONFIG
33
+ # get the configuration path, if will default to config/rails_best_practices.yml
34
+ #
35
+ # @return [String] the config path
36
+ def config_path
37
+ custom_config = @config_path || File.join(Runner.base_path, 'config/rails_best_practices.yml')
38
+ File.exist?(custom_config) ? custom_config : RailsBestPractices::Analyzer::DEFAULT_CONFIG
39
+ end
50
40
  end
51
41
 
52
42
  # initialize the runner.
@@ -66,8 +56,14 @@ module RailsBestPractices
66
56
  load_plugin_reviews if reviews.empty?
67
57
 
68
58
  @lexical_checker ||= CodeAnalyzer::CheckingVisitor::Plain.new(checkers: @lexicals)
69
- @plain_prepare_checker ||= CodeAnalyzer::CheckingVisitor::Plain.new(checkers: @prepares.select { |checker| checker.is_a? Prepares::GemfilePrepare })
70
- @default_prepare_checker ||= CodeAnalyzer::CheckingVisitor::Default.new(checkers: @prepares.reject { |checker| checker.is_a? Prepares::GemfilePrepare })
59
+ @plain_prepare_checker ||=
60
+ CodeAnalyzer::CheckingVisitor::Plain.new(
61
+ checkers: @prepares.select { |checker| checker.is_a? Prepares::GemfilePrepare }
62
+ )
63
+ @default_prepare_checker ||=
64
+ CodeAnalyzer::CheckingVisitor::Default.new(
65
+ checkers: @prepares.reject { |checker| checker.is_a? Prepares::GemfilePrepare }
66
+ )
71
67
  @review_checker ||= CodeAnalyzer::CheckingVisitor::Default.new(checkers: @reviews)
72
68
  end
73
69
 
@@ -119,58 +115,56 @@ module RailsBestPractices
119
115
 
120
116
  private
121
117
 
122
- # parse html template code, erb, haml and slim.
123
- #
124
- # @param [String] filename is the filename of the erb, haml or slim code.
125
- # @param [String] content is the source code of erb, haml or slim file.
126
- def parse_html_template(filename, content)
127
- if filename =~ /.*\.erb$|.*\.rhtml$/
128
- content = Erubis::OnlyRuby.new(content).src
129
- elsif filename =~ /.*\.haml$/
130
- begin
131
- require 'haml'
132
- content = Haml::Engine.new(content).precompiled
133
- # remove \xxx characters
134
- content.gsub!(/\\\d{3}/, '')
135
- rescue LoadError
136
- raise "In order to parse #{filename}, please install the haml gem"
137
- rescue Haml::Error, SyntaxError
138
- # do nothing, just ignore the wrong haml files.
139
- end
140
- elsif filename =~ /.*\.slim$/
141
- begin
142
- require 'slim'
143
- content = Slim::Engine.new.call(content)
144
- rescue LoadError
145
- raise "In order to parse #{filename}, please install the slim gem"
146
- rescue SyntaxError
147
- # do nothing, just ignore the wrong slim files
148
- end
118
+ # parse html template code, erb, haml and slim.
119
+ #
120
+ # @param [String] filename is the filename of the erb, haml or slim code.
121
+ # @param [String] content is the source code of erb, haml or slim file.
122
+ def parse_html_template(filename, content)
123
+ if filename =~ /.*\.erb$|.*\.rhtml$/
124
+ content = Erubis::OnlyRuby.new(content).src
125
+ elsif filename =~ /.*\.haml$/
126
+ begin
127
+ require 'haml'
128
+ content = Haml::Engine.new(content).precompiled
129
+ # remove \xxx characters
130
+ content.gsub!(/\\\d{3}/, '')
131
+ rescue LoadError
132
+ raise "In order to parse #{filename}, please install the haml gem"
133
+ rescue Haml::Error, SyntaxError
134
+ # do nothing, just ignore the wrong haml files.
135
+ end
136
+ elsif filename =~ /.*\.slim$/
137
+ begin
138
+ require 'slim'
139
+ content = Slim::Engine.new.call(content)
140
+ rescue LoadError
141
+ raise "In order to parse #{filename}, please install the slim gem"
142
+ rescue SyntaxError
143
+ # do nothing, just ignore the wrong slim files
149
144
  end
150
- content
151
145
  end
146
+ content
147
+ end
152
148
 
153
- # load all prepares.
154
- def load_prepares
155
- Prepares.constants.map { |prepare| Prepares.const_get(prepare).new }
156
- end
149
+ # load all prepares.
150
+ def load_prepares
151
+ Prepares.constants.map { |prepare| Prepares.const_get(prepare).new }
152
+ end
157
153
 
158
- # load all plugin reviews.
159
- def load_plugin_reviews
160
-
161
- plugins = File.join(Runner.base_path, 'lib', 'rails_best_practices', 'plugins', 'reviews')
162
- if File.directory?(plugins)
163
- Dir[File.expand_path(File.join(plugins, '*.rb'))].each do |review|
164
- require review
165
- end
166
- if RailsBestPractices.constants.map(&:to_sym).include? :Plugins
167
- RailsBestPractices::Plugins::Reviews.constants.each do |review|
168
- @reviews << RailsBestPractices::Plugins::Reviews.const_get(review).new
169
- end
170
- end
154
+ # load all plugin reviews.
155
+ def load_plugin_reviews
156
+ plugins = File.join(Runner.base_path, 'lib', 'rails_best_practices', 'plugins', 'reviews')
157
+ if File.directory?(plugins)
158
+ Dir[File.expand_path(File.join(plugins, '*.rb'))].each do |review|
159
+ require review
160
+ end
161
+ if RailsBestPractices.constants.map(&:to_sym).include? :Plugins
162
+ RailsBestPractices::Plugins::Reviews.constants.each do |review|
163
+ @reviews << RailsBestPractices::Plugins::Reviews.const_get(review).new
171
164
  end
172
-
165
+ end
173
166
  end
167
+ end
174
168
  end
175
169
  end
176
170
  end
@@ -22,9 +22,13 @@ module RailsBestPractices
22
22
  content.each_line do |line|
23
23
  line_no += 1
24
24
  actual_line_length = line.sub(/\s+$/, '').length
25
- if actual_line_length > @max_line_length
26
- add_error("line is longer than #{@max_line_length} characters (#{actual_line_length} characters)", filename, line_no)
27
- end
25
+ next unless actual_line_length > @max_line_length
26
+
27
+ add_error(
28
+ "line is longer than #{@max_line_length} characters (#{actual_line_length} characters)",
29
+ filename,
30
+ line_no
31
+ )
28
32
  end
29
33
  end
30
34
  end
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'optparse'
4
+
5
+ module RailsBestPractices
6
+ class OptionParser
7
+ # Usage: rails_best_practices [options] path
8
+ # -d, --debug debug mode
9
+ # --silent silent mode
10
+ # -f, --format FORMAT output format (text, html, yaml, json, xml)
11
+ # --output-file FILE output html file for the analyzing result
12
+ # --without-color only output plain text without color
13
+ # --with-textmate open file by textmate in html format
14
+ # --with-vscode open file by vscode in html format
15
+ # --with-sublime open file by sublime in html format (requires subl-handler)
16
+ # --with-mvim open file by mvim in html format
17
+ # --with-github GITHUB_NAME open file on github in html format, GITHUB_NAME is like railsbp/rails-bestpractices.com
18
+ # --with-git display git commit and username, only support html format
19
+ # --with-hg display hg commit and username, only support html format
20
+ # --template TEMPLATE customize erb template
21
+ # --vendor include vendor files
22
+ # --spec include spec files
23
+ # --test include test files
24
+ # --features include features files
25
+ # -x, --exclude PATTERNS don't analyze files matching a pattern
26
+ # (comma-separated regexp list)
27
+ # -o, --only PATTERNS analyze files only matching a pattern
28
+ # (comma-separated regexp list)
29
+ # -g, --generate generate configuration yaml
30
+ # -v, --version show this version
31
+ # -h, --help show this message
32
+
33
+ def self.parse!(argv = ARGV)
34
+ options = {}
35
+ OptParse.new do |opts|
36
+ opts.default_argv = argv
37
+
38
+ opts.banner = 'Usage: rails_best_practices [options] path'
39
+
40
+ opts.on('-d', '--debug', 'Debug mode') do
41
+ options['debug'] = true
42
+ end
43
+
44
+ opts.on('-f', '--format FORMAT', 'output format (text, html, yaml, json, xml)') do |format|
45
+ options['format'] = format
46
+ end
47
+
48
+ opts.on('--without-color', 'only output plain text without color') do
49
+ options['without-color'] = true
50
+ end
51
+
52
+ opts.on('--with-textmate', 'open file by textmate in html format') do
53
+ options['with-textmate'] = true
54
+ end
55
+
56
+ opts.on('--with-vscode', 'open file by vscode in html format') do
57
+ options['with-vscode'] = true
58
+ end
59
+
60
+ opts.on('--with-sublime', 'open file by sublime in html format') do
61
+ options['with-sublime'] = true
62
+ end
63
+
64
+ opts.on('--with-mvim', 'open file by mvim in html format') do
65
+ options['with-mvim'] = true
66
+ end
67
+
68
+ opts.on('--with-github GITHUB_NAME', 'open file on github in html format') do |github_name|
69
+ options['with-github'] = true
70
+ options['github-name'] = github_name
71
+ end
72
+
73
+ opts.on('--last-commit-id COMMIT_ID', 'last commit id') do |commit_id|
74
+ options['last-commit-id'] = commit_id
75
+ end
76
+
77
+ opts.on('--with-hg', 'display hg commit and username, only support html format') do
78
+ options['with-hg'] = true
79
+ end
80
+
81
+ opts.on('--with-git', 'display git commit and username, only support html format') do
82
+ options['with-git'] = true
83
+ end
84
+
85
+ opts.on('--template TEMPLATE', 'customize erb template') do |template|
86
+ options['template'] = template
87
+ end
88
+
89
+ opts.on('--output-file OUTPUT_FILE', 'output html file for the analyzing result') do |output_file|
90
+ options['output-file'] = output_file
91
+ end
92
+
93
+ opts.on('--silent', 'silent mode') do
94
+ options['silent'] = true
95
+ end
96
+
97
+ %w[vendor spec test features].each do |pattern|
98
+ opts.on("--#{pattern}", "include #{pattern} files") do
99
+ options[pattern] = true
100
+ end
101
+ end
102
+
103
+ opts.on_tail('-v', '--version', 'Show this version') do
104
+ require 'rails_best_practices/version'
105
+ puts RailsBestPractices::VERSION
106
+ exit
107
+ end
108
+
109
+ opts.on_tail('-h', '--help', 'Show this message') do
110
+ puts opts
111
+ exit
112
+ end
113
+
114
+ opts.on(
115
+ '-x',
116
+ '--exclude PATTERNS',
117
+ "Don't analyze files matching a pattern",
118
+ '(comma-separated regexp list)'
119
+ ) do |list|
120
+ begin
121
+ options['exclude'] = list.split(',').map { |x| Regexp.new x }
122
+ rescue RegexpError => e
123
+ raise OptionParser::InvalidArgument, e.message
124
+ end
125
+ end
126
+
127
+ opts.on(
128
+ '-o',
129
+ '--only PATTERNS',
130
+ 'Analyze files only matching a pattern',
131
+ '(comma-separated regexp list)'
132
+ ) do |list|
133
+ begin
134
+ options['only'] = list.split(',').map { |x| Regexp.new x }
135
+ rescue RegexpError => e
136
+ raise OptionParser::InvalidArgument, e.message
137
+ end
138
+ end
139
+
140
+ opts.on('-g', '--generate', 'Generate configuration yaml') do
141
+ options['generate'] = true
142
+ end
143
+
144
+ opts.on(
145
+ '-c',
146
+ '--config CONFIG_PATH',
147
+ 'configuration file location (defaults to config/rails_best_practices.yml)'
148
+ ) do |config_path|
149
+ options['config'] = config_path
150
+ end
151
+ opts.parse!
152
+ end
153
+ options
154
+ end
155
+ end
156
+ end