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.
- checksums.yaml +5 -5
- data/.gitignore +0 -1
- data/.travis.yml +2 -3
- data/CHANGELOG.md +7 -7
- data/Gemfile +3 -5
- data/Gemfile.lock +125 -0
- data/Guardfile +2 -0
- data/README.md +6 -6
- data/Rakefile +2 -17
- data/assets/result.html.erb +2 -0
- data/lib/rails_best_practices.rb +3 -2
- data/lib/rails_best_practices/analyzer.rb +61 -49
- data/lib/rails_best_practices/cli.rb +22 -0
- data/lib/rails_best_practices/command.rb +1 -131
- data/lib/rails_best_practices/core/check.rb +64 -56
- data/lib/rails_best_practices/core/checks_loader.rb +24 -23
- data/lib/rails_best_practices/core/configs.rb +1 -2
- data/lib/rails_best_practices/core/controllers.rb +1 -2
- data/lib/rails_best_practices/core/error.rb +1 -1
- data/lib/rails_best_practices/core/helpers.rb +1 -2
- data/lib/rails_best_practices/core/mailers.rb +1 -2
- data/lib/rails_best_practices/core/methods.rb +27 -21
- data/lib/rails_best_practices/core/model_associations.rb +10 -5
- data/lib/rails_best_practices/core/models.rb +1 -2
- data/lib/rails_best_practices/core/modules.rb +1 -1
- data/lib/rails_best_practices/core/routes.rb +2 -2
- data/lib/rails_best_practices/core/runner.rb +67 -73
- data/lib/rails_best_practices/lexicals/long_line_check.rb +7 -3
- data/lib/rails_best_practices/option_parser.rb +156 -0
- data/lib/rails_best_practices/prepares.rb +1 -1
- data/lib/rails_best_practices/prepares/controller_prepare.rb +24 -17
- data/lib/rails_best_practices/prepares/gemfile_prepare.rb +2 -2
- data/lib/rails_best_practices/prepares/helper_prepare.rb +6 -1
- data/lib/rails_best_practices/prepares/initializer_prepare.rb +3 -3
- data/lib/rails_best_practices/prepares/mailer_prepare.rb +2 -1
- data/lib/rails_best_practices/prepares/model_prepare.rb +63 -23
- data/lib/rails_best_practices/prepares/route_prepare.rb +28 -21
- data/lib/rails_best_practices/prepares/schema_prepare.rb +1 -1
- data/lib/rails_best_practices/reviews/add_model_virtual_attribute_review.rb +38 -34
- data/lib/rails_best_practices/reviews/always_add_db_index_review.rb +94 -89
- data/lib/rails_best_practices/reviews/check_destroy_return_value_review.rb +15 -5
- data/lib/rails_best_practices/reviews/check_save_return_value_review.rb +20 -8
- data/lib/rails_best_practices/reviews/default_scope_is_evil_review.rb +1 -1
- data/lib/rails_best_practices/reviews/dry_bundler_in_capistrano_review.rb +1 -1
- data/lib/rails_best_practices/reviews/hash_syntax_review.rb +16 -16
- data/lib/rails_best_practices/reviews/isolate_seed_data_review.rb +12 -12
- data/lib/rails_best_practices/reviews/keep_finders_on_their_own_model_review.rb +10 -11
- data/lib/rails_best_practices/reviews/law_of_demeter_review.rb +25 -24
- data/lib/rails_best_practices/reviews/move_code_into_controller_review.rb +4 -4
- data/lib/rails_best_practices/reviews/move_code_into_helper_review.rb +9 -10
- data/lib/rails_best_practices/reviews/move_finder_to_named_scope_review.rb +10 -11
- data/lib/rails_best_practices/reviews/needless_deep_nesting_review.rb +24 -22
- data/lib/rails_best_practices/reviews/not_rescue_exception_review.rb +1 -1
- data/lib/rails_best_practices/reviews/not_use_default_route_review.rb +1 -2
- data/lib/rails_best_practices/reviews/not_use_time_ago_in_words_review.rb +1 -1
- data/lib/rails_best_practices/reviews/overuse_route_customizations_review.rb +8 -8
- data/lib/rails_best_practices/reviews/protect_mass_assignment_review.rb +35 -32
- data/lib/rails_best_practices/reviews/remove_empty_helpers_review.rb +4 -4
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_controllers_review.rb +26 -19
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_helpers_review.rb +12 -10
- data/lib/rails_best_practices/reviews/remove_unused_methods_in_models_review.rb +38 -18
- data/lib/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review.rb +11 -11
- data/lib/rails_best_practices/reviews/restrict_auto_generated_routes_review.rb +77 -74
- data/lib/rails_best_practices/reviews/review.rb +2 -1
- data/lib/rails_best_practices/reviews/simplify_render_in_controllers_review.rb +2 -3
- data/lib/rails_best_practices/reviews/simplify_render_in_views_review.rb +12 -12
- data/lib/rails_best_practices/reviews/use_before_filter_review.rb +18 -15
- data/lib/rails_best_practices/reviews/use_model_association_review.rb +15 -15
- data/lib/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review.rb +24 -22
- data/lib/rails_best_practices/reviews/use_observer_review.rb +28 -28
- data/lib/rails_best_practices/reviews/use_parentheses_in_method_def_review.rb +6 -6
- data/lib/rails_best_practices/reviews/use_query_attribute_review.rb +68 -66
- data/lib/rails_best_practices/reviews/use_say_with_time_in_migrations_review.rb +9 -8
- data/lib/rails_best_practices/reviews/use_scope_access_review.rb +16 -14
- data/lib/rails_best_practices/reviews/use_turbo_sprockets_rails3_review.rb +2 -1
- data/lib/rails_best_practices/version.rb +1 -1
- data/rails_best_practices.gemspec +38 -43
- data/spec/fixtures/lib/rails_best_practices/plugins/reviews/not_use_rails_root_review.rb +1 -2
- data/spec/rails_best_practices/analyzer_spec.rb +73 -42
- data/spec/rails_best_practices/core/check_spec.rb +5 -5
- data/spec/rails_best_practices/core/checks_loader_spec.rb +3 -3
- data/spec/rails_best_practices/core/configs_spec.rb +1 -1
- data/spec/rails_best_practices/core/controllers_spec.rb +1 -1
- data/spec/rails_best_practices/core/error_spec.rb +21 -18
- data/spec/rails_best_practices/core/except_methods_spec.rb +7 -7
- data/spec/rails_best_practices/core/gems_spec.rb +4 -4
- data/spec/rails_best_practices/core/helpers_spec.rb +1 -1
- data/spec/rails_best_practices/core/klasses_spec.rb +3 -3
- data/spec/rails_best_practices/core/mailers_spec.rb +1 -1
- data/spec/rails_best_practices/core/methods_spec.rb +6 -6
- data/spec/rails_best_practices/core/model_associations_spec.rb +10 -6
- data/spec/rails_best_practices/core/model_attributes_spec.rb +4 -4
- data/spec/rails_best_practices/core/models_spec.rb +1 -1
- data/spec/rails_best_practices/core/modules_spec.rb +5 -5
- data/spec/rails_best_practices/core/routes_spec.rb +5 -5
- data/spec/rails_best_practices/core/runner_spec.rb +9 -7
- data/spec/rails_best_practices/core_ext/erubis_spec.rb +10 -10
- data/spec/rails_best_practices/lexicals/long_line_check_spec.rb +32 -31
- data/spec/rails_best_practices/lexicals/remove_tab_check_spec.rb +6 -6
- data/spec/rails_best_practices/lexicals/remove_trailing_whitespace_check_spec.rb +6 -6
- data/spec/rails_best_practices/prepares/config_prepare_spec.rb +2 -2
- data/spec/rails_best_practices/prepares/controller_prepare_spec.rb +18 -10
- data/spec/rails_best_practices/prepares/gemfile_prepare_spec.rb +17 -17
- data/spec/rails_best_practices/prepares/helper_prepare_spec.rb +3 -3
- data/spec/rails_best_practices/prepares/initializer_prepare_spec.rb +3 -3
- data/spec/rails_best_practices/prepares/mailer_prepare_spec.rb +2 -2
- data/spec/rails_best_practices/prepares/model_prepare_spec.rb +79 -43
- data/spec/rails_best_practices/prepares/route_prepare_spec.rb +141 -76
- data/spec/rails_best_practices/prepares/schema_prepare_spec.rb +2 -2
- data/spec/rails_best_practices/reviews/add_model_virtual_attribute_review_spec.rb +18 -12
- data/spec/rails_best_practices/reviews/always_add_db_index_review_spec.rb +28 -22
- data/spec/rails_best_practices/reviews/check_destroy_return_value_review_spec.rb +15 -13
- data/spec/rails_best_practices/reviews/check_save_return_value_review_spec.rb +31 -21
- data/spec/rails_best_practices/reviews/default_scope_is_evil_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/dry_bundler_in_capistrano_review_spec.rb +5 -5
- data/spec/rails_best_practices/reviews/hash_syntax_review_spec.rb +13 -13
- data/spec/rails_best_practices/reviews/isolate_seed_data_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/keep_finders_on_their_own_model_review_spec.rb +9 -9
- data/spec/rails_best_practices/reviews/law_of_demeter_review_spec.rb +29 -22
- data/spec/rails_best_practices/reviews/move_code_into_controller_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/move_code_into_helper_review_spec.rb +11 -6
- data/spec/rails_best_practices/reviews/move_code_into_model_review_spec.rb +32 -22
- data/spec/rails_best_practices/reviews/move_finder_to_named_scope_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/move_model_logic_into_model_review_spec.rb +9 -7
- data/spec/rails_best_practices/reviews/needless_deep_nesting_review_spec.rb +9 -9
- data/spec/rails_best_practices/reviews/not_rescue_exception_review_spec.rb +9 -9
- data/spec/rails_best_practices/reviews/not_use_default_route_review_spec.rb +5 -5
- data/spec/rails_best_practices/reviews/not_use_time_ago_in_words_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/overuse_route_customizations_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/protect_mass_assignment_review_spec.rb +24 -17
- data/spec/rails_best_practices/reviews/remove_empty_helpers_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_controllers_review_spec.rb +64 -31
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_helpers_review_spec.rb +21 -14
- data/spec/rails_best_practices/reviews/remove_unused_methods_in_models_review_spec.rb +57 -53
- data/spec/rails_best_practices/reviews/replace_complex_creation_with_factory_method_review_spec.rb +10 -8
- data/spec/rails_best_practices/reviews/replace_instance_variable_with_local_variable_review_spec.rb +20 -14
- data/spec/rails_best_practices/reviews/restrict_auto_generated_routes_review_spec.rb +54 -31
- data/spec/rails_best_practices/reviews/simplify_render_in_controllers_review_spec.rb +9 -9
- data/spec/rails_best_practices/reviews/simplify_render_in_views_review_spec.rb +13 -13
- data/spec/rails_best_practices/reviews/use_before_filter_review_spec.rb +11 -9
- data/spec/rails_best_practices/reviews/use_model_association_review_spec.rb +7 -7
- data/spec/rails_best_practices/reviews/use_multipart_alternative_as_content_type_of_email_review_spec.rb +35 -31
- data/spec/rails_best_practices/reviews/use_observer_review_spec.rb +6 -6
- data/spec/rails_best_practices/reviews/use_parentheses_in_method_def_review_spec.rb +10 -8
- data/spec/rails_best_practices/reviews/use_query_attribute_review_spec.rb +31 -24
- data/spec/rails_best_practices/reviews/use_say_with_time_in_migrations_review_spec.rb +15 -11
- data/spec/rails_best_practices/reviews/use_scope_access_review_spec.rb +14 -14
- data/spec/rails_best_practices/reviews/use_turbo_sprockets_rails3_review_spec.rb +61 -59
- metadata +16 -18
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsBestPractices
|
4
|
+
class CLI
|
5
|
+
# Run analyze with ruby code
|
6
|
+
# @param [Array] argv command argments
|
7
|
+
# @return [Boolean] return true, if there is no violation.
|
8
|
+
# @example
|
9
|
+
# RailsBestPractices::CLI.run(['-d', '-o', 'path/to/file'])
|
10
|
+
def self.run(argv)
|
11
|
+
options = OptionParser.parse!(argv)
|
12
|
+
if !argv.empty? && !File.exist?(argv.first)
|
13
|
+
raise Errno::ENOENT, "#{argv.first} doesn't exist"
|
14
|
+
end
|
15
|
+
|
16
|
+
analyzer = Analyzer.new(argv.first, options)
|
17
|
+
analyzer.analyze
|
18
|
+
analyzer.output
|
19
|
+
analyzer.runner.errors.empty?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,137 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'optparse'
|
4
|
-
|
5
|
-
# Usage: rails_best_practices [options] path
|
6
|
-
# -d, --debug debug mode
|
7
|
-
# --silent silent mode
|
8
|
-
# -f, --format FORMAT output format (text, html, yml, json, xml)
|
9
|
-
# --output-file FILE output html file for the analyzing result
|
10
|
-
# --without-color only output plain text without color
|
11
|
-
# --with-textmate open file by textmate in html format
|
12
|
-
# --with-sublime open file by sublime in html format (requires subl-handler)
|
13
|
-
# --with-mvim open file by mvim in html format
|
14
|
-
# --with-github GITHUB_NAME open file on github in html format, GITHUB_NAME is like railsbp/rails-bestpractices.com
|
15
|
-
# --with-git display git commit and username, only support html format
|
16
|
-
# --with-hg display hg commit and username, only support html format
|
17
|
-
# --template TEMPLATE customize erb template
|
18
|
-
# --vendor include vendor files
|
19
|
-
# --spec include spec files
|
20
|
-
# --test include test files
|
21
|
-
# --features include features files
|
22
|
-
# -x, --exclude PATTERNS don't analyze files matching a pattern
|
23
|
-
# (comma-separated regexp list)
|
24
|
-
# -o, --only PATTERNS analyze files only matching a pattern
|
25
|
-
# (comma-separated regexp list)
|
26
|
-
# -g, --generate generate configuration yaml
|
27
|
-
# -v, --version show this version
|
28
|
-
# -h, --help show this message
|
29
|
-
|
30
|
-
options = {}
|
31
|
-
|
32
|
-
OptionParser.new do |opts|
|
33
|
-
opts.banner = 'Usage: rails_best_practices [options] path'
|
34
|
-
|
35
|
-
opts.on('-d', '--debug', 'Debug mode') do
|
36
|
-
options['debug'] = true
|
37
|
-
end
|
38
|
-
|
39
|
-
opts.on('-f', '--format FORMAT', 'output format (text, html, yml, json, xml)') do |format|
|
40
|
-
options['format'] = format
|
41
|
-
end
|
42
|
-
|
43
|
-
opts.on('--without-color', 'only output plain text without color') do
|
44
|
-
options['without-color'] = true
|
45
|
-
end
|
46
|
-
|
47
|
-
opts.on('--with-textmate', 'open file by textmate in html format') do
|
48
|
-
options['with-textmate'] = true
|
49
|
-
end
|
50
|
-
|
51
|
-
opts.on('--with-sublime', 'open file by sublime in html format') do
|
52
|
-
options['with-sublime'] = true
|
53
|
-
end
|
54
|
-
|
55
|
-
opts.on('--with-mvim', 'open file by mvim in html format') do
|
56
|
-
options['with-mvim'] = true
|
57
|
-
end
|
58
|
-
|
59
|
-
opts.on('--with-github GITHUB_NAME', 'open file on github in html format') do |github_name|
|
60
|
-
options['with-github'] = true
|
61
|
-
options['github-name'] = github_name
|
62
|
-
end
|
63
|
-
|
64
|
-
opts.on('--last-commit-id COMMIT_ID', 'last commit id') do |commit_id|
|
65
|
-
options['last-commit-id'] = commit_id
|
66
|
-
end
|
67
|
-
|
68
|
-
opts.on('--with-hg', 'display hg commit and username, only support html format') do
|
69
|
-
options['with-hg'] = true
|
70
|
-
end
|
71
|
-
|
72
|
-
opts.on('--with-git', 'display git commit and username, only support html format') do
|
73
|
-
options['with-git'] = true
|
74
|
-
end
|
75
|
-
|
76
|
-
opts.on('--template TEMPLATE', 'customize erb template') do |template|
|
77
|
-
options['template'] = template
|
78
|
-
end
|
79
|
-
|
80
|
-
opts.on('--output-file OUTPUT_FILE', 'output html file for the analyzing result') do |output_file|
|
81
|
-
options['output-file'] = output_file
|
82
|
-
end
|
83
|
-
|
84
|
-
opts.on('--silent', 'silent mode') do
|
85
|
-
options['silent'] = true
|
86
|
-
end
|
87
|
-
|
88
|
-
%w[vendor spec test features].each do |pattern|
|
89
|
-
opts.on("--#{pattern}", "include #{pattern} files") do
|
90
|
-
options[pattern] = true
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
opts.on_tail('-v', '--version', 'Show this version') do
|
95
|
-
require 'rails_best_practices/version'
|
96
|
-
puts RailsBestPractices::VERSION
|
97
|
-
exit
|
98
|
-
end
|
99
|
-
|
100
|
-
opts.on_tail('-h', '--help', 'Show this message') do
|
101
|
-
puts opts
|
102
|
-
exit
|
103
|
-
end
|
104
|
-
|
105
|
-
opts.on('-x', '--exclude PATTERNS', "Don't analyze files matching a pattern", '(comma-separated regexp list)') do |list|
|
106
|
-
begin
|
107
|
-
options['exclude'] = list.split(',').map { |x| Regexp.new x }
|
108
|
-
rescue RegexpError => e
|
109
|
-
raise OptionParser::InvalidArgument, e.message
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
opts.on('-o', '--only PATTERNS', 'Analyze files only matching a pattern', '(comma-separated regexp list)') do |list|
|
114
|
-
begin
|
115
|
-
options['only'] = list.split(',').map { |x| Regexp.new x }
|
116
|
-
rescue RegexpError => e
|
117
|
-
raise OptionParser::InvalidArgument e.message
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
opts.on('-g', '--generate', 'Generate configuration yaml') do
|
122
|
-
options['generate'] = true
|
123
|
-
end
|
124
|
-
|
125
|
-
opts.on(
|
126
|
-
'-c',
|
127
|
-
'--config CONFIG_PATH', 'configuration file location (defaults to config/rails_best_practices.yml)'
|
128
|
-
) do |config_path|
|
129
|
-
options['config'] = config_path
|
130
|
-
end
|
131
|
-
|
132
|
-
opts.parse!
|
133
|
-
end
|
134
|
-
|
4
|
+
options = RailsBestPractices::OptionParser.parse!
|
135
5
|
if !ARGV.empty? && !File.exist?(ARGV.first)
|
136
6
|
puts "#{ARGV.first} doesn't exist"
|
137
7
|
exit 1
|
@@ -3,24 +3,25 @@
|
|
3
3
|
module RailsBestPractices
|
4
4
|
module Core
|
5
5
|
# A Check class that takes charge of checking the sexp.
|
6
|
+
|
6
7
|
class Check < CodeAnalyzer::Checker
|
7
|
-
ALL_FILES =
|
8
|
-
CONTROLLER_FILES = /
|
9
|
-
MIGRATION_FILES = /
|
10
|
-
MODEL_FILES = /
|
11
|
-
MAILER_FILES = /
|
12
|
-
VIEW_FILES = /
|
13
|
-
PARTIAL_VIEW_FILES = /
|
14
|
-
ROUTE_FILES = /
|
15
|
-
SCHEMA_FILE = /
|
16
|
-
HELPER_FILES = /
|
17
|
-
DEPLOY_FILES = /
|
18
|
-
CONFIG_FILES = /
|
19
|
-
INITIALIZER_FILES = /
|
20
|
-
CAPFILE = /Capfile
|
21
|
-
GEMFILE_LOCK = /Gemfile\.lock
|
22
|
-
|
23
|
-
SKIP_FILES = /
|
8
|
+
ALL_FILES = /.*/.freeze
|
9
|
+
CONTROLLER_FILES = %r{app/(controllers|cells)/.*\.rb$}.freeze
|
10
|
+
MIGRATION_FILES = %r{db/migrate/.*\.rb$}.freeze
|
11
|
+
MODEL_FILES = %r{app/models/.*\.rb$}.freeze
|
12
|
+
MAILER_FILES = %r{app/models/.*mailer\.rb$|app/mailers/.*\.rb}.freeze
|
13
|
+
VIEW_FILES = %r{app/(views|cells)/.*\.(erb|haml|slim|builder|rxml)$}.freeze
|
14
|
+
PARTIAL_VIEW_FILES = %r{app/(views|cells)/.*/_.*\.(erb|haml|slim|builder|rxml)$}.freeze
|
15
|
+
ROUTE_FILES = %r{config/routes.*\.rb}.freeze
|
16
|
+
SCHEMA_FILE = %r{db/schema\.rb}.freeze
|
17
|
+
HELPER_FILES = %r{app/helpers/.*\.rb$}.freeze
|
18
|
+
DEPLOY_FILES = %r{config/deploy.*\.rb}.freeze
|
19
|
+
CONFIG_FILES = %r{config/(application|environment|environments/.*)\.rb}.freeze
|
20
|
+
INITIALIZER_FILES = %r{config/initializers/.*\.rb}.freeze
|
21
|
+
CAPFILE = /Capfile/.freeze
|
22
|
+
GEMFILE_LOCK = /Gemfile\.lock/.freeze
|
23
|
+
|
24
|
+
SKIP_FILES = %r{db/schema.rb}.freeze
|
24
25
|
|
25
26
|
def initialize(options = {})
|
26
27
|
options.each do |key, value|
|
@@ -33,7 +34,7 @@ module RailsBestPractices
|
|
33
34
|
# @param [String] the file name of node.
|
34
35
|
# @return [Boolean] true if the check will need to parse the file.
|
35
36
|
def parse_file?(node_file)
|
36
|
-
is_interesting_file?(node_file)
|
37
|
+
node_file.is_a?(String) && is_interesting_file?(node_file) && !is_ignored?(node_file)
|
37
38
|
end
|
38
39
|
|
39
40
|
def is_interesting_file?(node_file)
|
@@ -60,13 +61,10 @@ module RailsBestPractices
|
|
60
61
|
# @param [String] filename, is the filename of source code
|
61
62
|
# @param [Integer] line_number, is the line number of the source code which is reviewing
|
62
63
|
def add_error(message, filename = @node.file, line_number = @node.line_number)
|
63
|
-
errors <<
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
type: self.class.to_s,
|
68
|
-
url: url
|
69
|
-
)
|
64
|
+
errors <<
|
65
|
+
RailsBestPractices::Core::Error.new(
|
66
|
+
filename: filename, line_number: line_number, message: message, type: self.class.to_s, url: url
|
67
|
+
)
|
70
68
|
end
|
71
69
|
|
72
70
|
# errors that violate the rails best practices.
|
@@ -99,9 +97,9 @@ module RailsBestPractices
|
|
99
97
|
end
|
100
98
|
end
|
101
99
|
|
102
|
-
class <<self
|
100
|
+
class << self
|
103
101
|
def url(url = nil)
|
104
|
-
url ?
|
102
|
+
url ? @url = url : @url
|
105
103
|
end
|
106
104
|
|
107
105
|
def debug?
|
@@ -114,6 +112,7 @@ module RailsBestPractices
|
|
114
112
|
end
|
115
113
|
|
116
114
|
# Helper to parse the class name.
|
115
|
+
|
117
116
|
module Classable
|
118
117
|
def self.included(base)
|
119
118
|
base.class_eval do
|
@@ -139,7 +138,7 @@ module RailsBestPractices
|
|
139
138
|
# end of the class
|
140
139
|
add_callback :end_class do |_node|
|
141
140
|
klasses.pop
|
142
|
-
|
141
|
+
@klass = nil
|
143
142
|
end
|
144
143
|
end
|
145
144
|
end
|
@@ -165,6 +164,7 @@ module RailsBestPractices
|
|
165
164
|
end
|
166
165
|
|
167
166
|
# Helper to parse the module name.
|
167
|
+
|
168
168
|
module Moduleable
|
169
169
|
def self.included(base)
|
170
170
|
base.class_eval do
|
@@ -197,7 +197,15 @@ module RailsBestPractices
|
|
197
197
|
module Callable
|
198
198
|
def self.included(base)
|
199
199
|
base.class_eval do
|
200
|
-
interesting_nodes :call,
|
200
|
+
interesting_nodes :call,
|
201
|
+
:fcall,
|
202
|
+
:var_ref,
|
203
|
+
:vcall,
|
204
|
+
:command_call,
|
205
|
+
:command,
|
206
|
+
:alias,
|
207
|
+
:bare_assoc_hash,
|
208
|
+
:method_add_arg
|
201
209
|
|
202
210
|
# remembe the message of call node.
|
203
211
|
add_callback :start_call do |node|
|
@@ -240,7 +248,7 @@ module RailsBestPractices
|
|
240
248
|
else
|
241
249
|
mark_used(node.message)
|
242
250
|
last_argument = node.arguments.all.last
|
243
|
-
if last_argument.present? &&
|
251
|
+
if last_argument.present? && last_argument.sexp_type == :bare_assoc_hash
|
244
252
|
last_argument.hash_values.each { |argument_value| mark_used(argument_value) }
|
245
253
|
end
|
246
254
|
end
|
@@ -283,27 +291,28 @@ module RailsBestPractices
|
|
283
291
|
|
284
292
|
private
|
285
293
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
call_method(method_name)
|
294
|
+
def mark_used(method_node)
|
295
|
+
return if method_node == :call
|
296
|
+
|
297
|
+
if method_node.sexp_type == :bare_assoc_hash
|
298
|
+
method_node.hash_values.each { |value_node| mark_used(value_node) }
|
299
|
+
elsif method_node.sexp_type == :array
|
300
|
+
method_node.array_values.each { |value_node| mark_used(value_node) }
|
301
|
+
else
|
302
|
+
method_name = method_node.to_s
|
296
303
|
end
|
304
|
+
call_method(method_name)
|
305
|
+
end
|
297
306
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
end
|
303
|
-
methods.mark_parent_class_method_used(name, method_name)
|
304
|
-
methods.mark_subclasses_method_used(name, method_name)
|
305
|
-
methods.possible_public_used(method_name)
|
307
|
+
def call_method(method_name, class_name = nil)
|
308
|
+
class_name ||= respond_to?(:current_class_name) ? current_class_name : current_module_name
|
309
|
+
if methods.has_method?(class_name, method_name)
|
310
|
+
methods.get_method(class_name, method_name).mark_used
|
306
311
|
end
|
312
|
+
methods.mark_parent_class_method_used(class_name, method_name)
|
313
|
+
methods.mark_subclasses_method_used(class_name, method_name)
|
314
|
+
methods.possible_public_used(method_name)
|
315
|
+
end
|
307
316
|
end
|
308
317
|
end
|
309
318
|
end
|
@@ -317,21 +326,21 @@ module RailsBestPractices
|
|
317
326
|
|
318
327
|
# check if the controller is inherit from InheritedResources::Base.
|
319
328
|
add_callback :start_class do |_node|
|
320
|
-
if 'InheritedResources::Base'
|
329
|
+
if current_extend_class_name == 'InheritedResources::Base'
|
321
330
|
@inherited_resources = true
|
322
331
|
end
|
323
332
|
end
|
324
333
|
|
325
334
|
# check if there is a DSL call inherit_resources.
|
326
335
|
add_callback :start_var_ref do |node|
|
327
|
-
if 'inherit_resources'
|
336
|
+
if node.to_s == 'inherit_resources'
|
328
337
|
@inherited_resources = true
|
329
338
|
end
|
330
339
|
end
|
331
340
|
|
332
341
|
# check if there is a DSL call inherit_resources.
|
333
342
|
add_callback :start_vcall do |node|
|
334
|
-
if 'inherit_resources'
|
343
|
+
if node.to_s == 'inherit_resources'
|
335
344
|
@inherited_resources = true
|
336
345
|
end
|
337
346
|
end
|
@@ -350,7 +359,7 @@ module RailsBestPractices
|
|
350
359
|
# check if the method is in the except methods list.
|
351
360
|
def excepted?(method)
|
352
361
|
is_ignored?(method.file) ||
|
353
|
-
|
362
|
+
except_methods.any? { |except_method| Exceptable.matches method, except_method }
|
354
363
|
end
|
355
364
|
|
356
365
|
def internal_except_methods
|
@@ -370,10 +379,8 @@ module RailsBestPractices
|
|
370
379
|
class_name = '.*' if class_name == '*'
|
371
380
|
class_expression = Regexp.new class_name
|
372
381
|
|
373
|
-
class_names =
|
374
|
-
|
375
|
-
.map(&:extend_class_name)
|
376
|
-
.compact
|
382
|
+
class_names =
|
383
|
+
Prepares.klasses.select { |klass| klass.class_name == method.class_name }.map(&:extend_class_name).compact
|
377
384
|
|
378
385
|
class_names.unshift method.class_name
|
379
386
|
matched = class_names.any? { |name| name =~ class_expression }
|
@@ -384,6 +391,7 @@ module RailsBestPractices
|
|
384
391
|
end
|
385
392
|
|
386
393
|
# Helper to parse the access control.
|
394
|
+
|
387
395
|
module Accessable
|
388
396
|
def self.included(base)
|
389
397
|
base.class_eval do
|
@@ -14,37 +14,38 @@ module RailsBestPractices
|
|
14
14
|
|
15
15
|
# load all reviews according to configuration.
|
16
16
|
def load_reviews
|
17
|
-
load_checks_from_config
|
17
|
+
load_checks_from_config do |check_name|
|
18
|
+
RailsBestPractices::Reviews.const_get(check_name.gsub(/Check$/, 'Review'))
|
19
|
+
end
|
18
20
|
end
|
19
21
|
|
20
22
|
private
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
# read the checks from yaml config.
|
25
|
+
def checks_from_config
|
26
|
+
@checks ||= YAML.load_file @config
|
27
|
+
end
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
active_checks
|
33
|
-
end
|
29
|
+
# load all checks from the configuration
|
30
|
+
def load_checks_from_config(&block)
|
31
|
+
checks_from_config.each_with_object([]) do |check, active_checks|
|
32
|
+
check_instance = instantiate_check(block, *check)
|
33
|
+
active_checks << check_instance unless check_instance.nil?
|
34
34
|
end
|
35
|
+
end
|
35
36
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
# instantiates a check
|
38
|
+
def instantiate_check(block, check_name, options)
|
39
|
+
check_class = load_check_class(check_name, &block)
|
40
|
+
check_class&.new(options || {})
|
41
|
+
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
43
|
+
# loads the class for a check by calling the given block
|
44
|
+
def load_check_class(check_name)
|
45
|
+
yield(check_name)
|
46
|
+
rescue NameError
|
47
|
+
# nothing to do, the check does not exist
|
48
|
+
end
|
48
49
|
end
|
49
50
|
end
|
50
51
|
end
|