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.
- 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
|