rails_best_practices 1.19.2 → 1.20.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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