rubocop 0.9.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rubocop might be problematic. Click here for more details.

Files changed (149) hide show
  1. data/.travis.yml +3 -1
  2. data/CHANGELOG.md +38 -0
  3. data/README.md +34 -0
  4. data/Rakefile +3 -0
  5. data/config/default.yml +14 -1
  6. data/config/enabled.yml +30 -7
  7. data/lib/rubocop.rb +15 -0
  8. data/lib/rubocop/cli.rb +48 -154
  9. data/lib/rubocop/config.rb +19 -22
  10. data/lib/rubocop/config_store.rb +2 -4
  11. data/lib/rubocop/cop/commissioner.rb +90 -0
  12. data/lib/rubocop/cop/cop.rb +38 -31
  13. data/lib/rubocop/cop/corrector.rb +84 -0
  14. data/lib/rubocop/cop/lint/assignment_in_condition.rb +0 -3
  15. data/lib/rubocop/cop/lint/block_alignment.rb +151 -0
  16. data/lib/rubocop/cop/lint/empty_ensure.rb +18 -0
  17. data/lib/rubocop/cop/lint/end_alignment.rb +0 -124
  18. data/lib/rubocop/cop/lint/end_in_method.rb +0 -2
  19. data/lib/rubocop/cop/lint/ensure_return.rb +3 -3
  20. data/lib/rubocop/cop/lint/eval.rb +0 -2
  21. data/lib/rubocop/cop/lint/handle_exceptions.rb +0 -2
  22. data/lib/rubocop/cop/lint/literal_in_condition.rb +0 -10
  23. data/lib/rubocop/cop/lint/loop.rb +0 -2
  24. data/lib/rubocop/cop/lint/rescue_exception.rb +0 -2
  25. data/lib/rubocop/cop/lint/shadowing_outer_local_variable.rb +2 -2
  26. data/lib/rubocop/cop/lint/unreachable_code.rb +0 -2
  27. data/lib/rubocop/cop/lint/unused_local_variable.rb +2 -2
  28. data/lib/rubocop/cop/lint/void.rb +0 -2
  29. data/lib/rubocop/cop/offence.rb +9 -0
  30. data/lib/rubocop/cop/rails/validation.rb +2 -1
  31. data/lib/rubocop/cop/style/access_control.rb +4 -3
  32. data/lib/rubocop/cop/style/alias.rb +2 -4
  33. data/lib/rubocop/cop/style/align_parameters.rb +0 -2
  34. data/lib/rubocop/cop/style/and_or.rb +4 -6
  35. data/lib/rubocop/cop/style/ascii_comments.rb +2 -2
  36. data/lib/rubocop/cop/style/ascii_identifiers.rb +2 -2
  37. data/lib/rubocop/cop/style/attr.rb +0 -2
  38. data/lib/rubocop/cop/style/avoid_class_vars.rb +0 -1
  39. data/lib/rubocop/cop/style/avoid_for.rb +0 -2
  40. data/lib/rubocop/cop/style/avoid_global_vars.rb +3 -7
  41. data/lib/rubocop/cop/style/avoid_perl_backrefs.rb +0 -2
  42. data/lib/rubocop/cop/style/avoid_perlisms.rb +2 -4
  43. data/lib/rubocop/cop/style/begin_block.rb +0 -2
  44. data/lib/rubocop/cop/style/block_comments.rb +2 -2
  45. data/lib/rubocop/cop/style/block_nesting.rb +3 -3
  46. data/lib/rubocop/cop/style/blocks.rb +0 -2
  47. data/lib/rubocop/cop/style/case_equality.rb +0 -2
  48. data/lib/rubocop/cop/style/case_indentation.rb +0 -2
  49. data/lib/rubocop/cop/style/character_literal.rb +10 -6
  50. data/lib/rubocop/cop/style/class_and_module_camel_case.rb +0 -4
  51. data/lib/rubocop/cop/style/class_methods.rb +1 -1
  52. data/lib/rubocop/cop/style/collection_methods.rb +3 -5
  53. data/lib/rubocop/cop/style/colon_method_call.rb +3 -3
  54. data/lib/rubocop/cop/style/comment_annotation.rb +44 -0
  55. data/lib/rubocop/cop/style/constant_name.rb +0 -2
  56. data/lib/rubocop/cop/style/def_parentheses.rb +0 -8
  57. data/lib/rubocop/cop/style/documentation.rb +6 -2
  58. data/lib/rubocop/cop/style/dot_position.rb +0 -2
  59. data/lib/rubocop/cop/style/empty_line_between_defs.rb +0 -2
  60. data/lib/rubocop/cop/style/empty_lines.rb +10 -8
  61. data/lib/rubocop/cop/style/empty_literal.rb +3 -1
  62. data/lib/rubocop/cop/style/encoding.rb +7 -6
  63. data/lib/rubocop/cop/style/end_block.rb +0 -2
  64. data/lib/rubocop/cop/style/end_of_line.rb +4 -3
  65. data/lib/rubocop/cop/style/favor_join.rb +0 -2
  66. data/lib/rubocop/cop/style/favor_modifier.rb +9 -9
  67. data/lib/rubocop/cop/style/favor_sprintf.rb +0 -2
  68. data/lib/rubocop/cop/style/favor_unless_over_negated_if.rb +0 -2
  69. data/lib/rubocop/cop/style/hash_syntax.rb +0 -2
  70. data/lib/rubocop/cop/style/if_then_else.rb +0 -2
  71. data/lib/rubocop/cop/style/lambda.rb +0 -2
  72. data/lib/rubocop/cop/style/leading_comment_space.rb +2 -2
  73. data/lib/rubocop/cop/style/line_continuation.rb +4 -3
  74. data/lib/rubocop/cop/style/line_length.rb +4 -3
  75. data/lib/rubocop/cop/style/method_and_variable_snake_case.rb +4 -3
  76. data/lib/rubocop/cop/style/method_call_parentheses.rb +0 -2
  77. data/lib/rubocop/cop/style/method_length.rb +0 -4
  78. data/lib/rubocop/cop/style/not.rb +0 -2
  79. data/lib/rubocop/cop/style/op_method.rb +0 -2
  80. data/lib/rubocop/cop/style/parameter_lists.rb +0 -2
  81. data/lib/rubocop/cop/style/parentheses_around_condition.rb +12 -6
  82. data/lib/rubocop/cop/style/proc.rb +0 -2
  83. data/lib/rubocop/cop/style/reduce_arguments.rb +0 -2
  84. data/lib/rubocop/cop/style/redundant_begin.rb +45 -0
  85. data/lib/rubocop/cop/style/redundant_return.rb +59 -0
  86. data/lib/rubocop/cop/style/redundant_self.rb +83 -0
  87. data/lib/rubocop/cop/style/regexp_literal.rb +0 -2
  88. data/lib/rubocop/cop/style/rescue_modifier.rb +13 -21
  89. data/lib/rubocop/cop/style/semicolon.rb +15 -9
  90. data/lib/rubocop/cop/style/single_line_methods.rb +0 -4
  91. data/lib/rubocop/cop/style/space_after_comma_etc.rb +2 -2
  92. data/lib/rubocop/cop/style/space_after_control_keyword.rb +0 -1
  93. data/lib/rubocop/cop/style/string_literals.rb +5 -2
  94. data/lib/rubocop/cop/style/surrounding_space.rb +106 -91
  95. data/lib/rubocop/cop/style/tab.rb +4 -3
  96. data/lib/rubocop/cop/style/ternary_operator.rb +0 -4
  97. data/lib/rubocop/cop/style/trailing_whitespace.rb +4 -3
  98. data/lib/rubocop/cop/style/trivial_accessors.rb +51 -6
  99. data/lib/rubocop/cop/style/unless_else.rb +0 -2
  100. data/lib/rubocop/cop/style/variable_interpolation.rb +0 -2
  101. data/lib/rubocop/cop/style/when_then.rb +3 -3
  102. data/lib/rubocop/cop/style/while_until_do.rb +3 -5
  103. data/lib/rubocop/cop/style/word_array.rb +0 -2
  104. data/lib/rubocop/cop/util.rb +0 -4
  105. data/lib/rubocop/formatter/file_list_formatter.rb +18 -0
  106. data/lib/rubocop/formatter/formatter_set.rb +2 -1
  107. data/lib/rubocop/processed_source.rb +27 -0
  108. data/lib/rubocop/rake_task.rb +50 -0
  109. data/lib/rubocop/source_parser.rb +105 -0
  110. data/lib/rubocop/target_finder.rb +67 -0
  111. data/lib/rubocop/token.rb +22 -0
  112. data/lib/rubocop/version.rb +1 -1
  113. data/rubocop.gemspec +5 -3
  114. data/spec/project_spec.rb +0 -11
  115. data/spec/rubocop/cli_spec.rb +112 -6
  116. data/spec/rubocop/config_spec.rb +13 -17
  117. data/spec/rubocop/config_store_spec.rb +8 -23
  118. data/spec/rubocop/cops/commissioner_spec.rb +72 -0
  119. data/spec/rubocop/cops/corrector_spec.rb +63 -0
  120. data/spec/rubocop/cops/lint/assignment_in_condition_spec.rb +2 -2
  121. data/spec/rubocop/cops/lint/block_alignment_spec.rb +357 -0
  122. data/spec/rubocop/cops/lint/empty_ensure_spec.rb +33 -0
  123. data/spec/rubocop/cops/lint/end_alignment_spec.rb +0 -263
  124. data/spec/rubocop/cops/lint/ensure_return_spec.rb +6 -9
  125. data/spec/rubocop/cops/offence_spec.rb +28 -0
  126. data/spec/rubocop/cops/style/and_or_spec.rb +21 -11
  127. data/spec/rubocop/cops/style/ascii_identifiers_spec.rb +14 -0
  128. data/spec/rubocop/cops/style/avoid_global_vars_spec.rb +10 -14
  129. data/spec/rubocop/cops/style/character_literal_spec.rb +17 -2
  130. data/spec/rubocop/cops/style/colon_method_call_spec.rb +20 -15
  131. data/spec/rubocop/cops/style/comment_annotation_spec.rb +62 -0
  132. data/spec/rubocop/cops/style/encoding_spec.rb +7 -0
  133. data/spec/rubocop/cops/style/parentheses_around_condition_spec.rb +37 -9
  134. data/spec/rubocop/cops/style/redundant_begin_spec.rb +63 -0
  135. data/spec/rubocop/cops/style/redundant_return_spec.rb +64 -0
  136. data/spec/rubocop/cops/style/redundant_self_spec.rb +76 -0
  137. data/spec/rubocop/cops/style/string_literals_spec.rb +18 -13
  138. data/spec/rubocop/cops/style/trivial_accessors_spec.rb +110 -52
  139. data/spec/rubocop/cops/style/when_then_spec.rb +14 -7
  140. data/spec/rubocop/cops/style/while_until_do_spec.rb +12 -0
  141. data/spec/rubocop/cops/variable_inspector_spec.rb +3 -5
  142. data/spec/rubocop/formatter/file_list_formatter_spec.rb +33 -0
  143. data/spec/rubocop/processed_source_spec.rb +67 -0
  144. data/spec/rubocop/source_parser_spec.rb +141 -0
  145. data/spec/rubocop/target_finder_spec.rb +180 -0
  146. data/spec/rubocop/token_spec.rb +27 -0
  147. data/spec/spec_helper.rb +24 -4
  148. metadata +108 -18
  149. checksums.yaml +0 -7
@@ -7,13 +7,14 @@ module Rubocop
7
7
  class Tab < Cop
8
8
  MSG = 'Tab detected.'
9
9
 
10
- def inspect(source_buffer, source, tokens, ast, comments)
11
- source.each_with_index do |line, index|
10
+ def investigate(processed_source)
11
+ processed_source.lines.each_with_index do |line, index|
12
12
  match = line.match(/^( *)\t/)
13
13
  if match
14
14
  spaces = match.captures[0]
15
15
  add_offence(:convention,
16
- source_range(source_buffer, source[0...index],
16
+ source_range(processed_source.buffer,
17
+ processed_source[0...index],
17
18
  spaces.length, 8),
18
19
  MSG)
19
20
  end
@@ -17,8 +17,6 @@ module Rubocop
17
17
  if loc.line != loc.colon.line
18
18
  add_offence(:convention, loc.expression, MSG)
19
19
  end
20
-
21
- super
22
20
  end
23
21
  end
24
22
 
@@ -40,8 +38,6 @@ module Rubocop
40
38
  end
41
39
  end
42
40
  end
43
-
44
- super
45
41
  end
46
42
  end
47
43
  end
@@ -7,11 +7,12 @@ module Rubocop
7
7
  class TrailingWhitespace < Cop
8
8
  MSG = 'Trailing whitespace detected.'
9
9
 
10
- def inspect(source_buffer, source, tokens, ast, comments)
11
- source.each_with_index do |line, index|
10
+ def investigate(processed_source)
11
+ processed_source.lines.each_with_index do |line, index|
12
12
  if line =~ /.*[ \t]+$/
13
13
  add_offence(:convention,
14
- source_range(source_buffer, source[0...index],
14
+ source_range(processed_source.buffer,
15
+ processed_source[0...index],
15
16
  line.rstrip.length,
16
17
  line.length - line.rstrip.length),
17
18
  MSG)
@@ -11,12 +11,21 @@ module Rubocop
11
11
  def on_def(node)
12
12
  method_name, args, body = *node
13
13
 
14
- kind = if body && body.type == :ivar
14
+ check(node, method_name, args, body)
15
+ end
16
+
17
+ def on_defs(node)
18
+ _scope, method_name, args, body = *node
19
+
20
+ check(node, method_name, args, body)
21
+ end
22
+
23
+ private
24
+
25
+ def check(node, method_name, args, body)
26
+ kind = if trivial_reader?(method_name, args, body)
15
27
  'reader'
16
- elsif args.children.size == 1 &&
17
- body && body.type == :ivasgn &&
18
- body.children[1] && body.children[1].type == :lvar &&
19
- method_name != :initialize
28
+ elsif trivial_writer?(method_name, args, body)
20
29
  'writer'
21
30
  end
22
31
  if kind
@@ -24,7 +33,43 @@ module Rubocop
24
33
  sprintf(MSG, kind, kind))
25
34
  end
26
35
 
27
- super
36
+ end
37
+
38
+ def exact_name_match?
39
+ TrivialAccessors.config['ExactNameMatch']
40
+ end
41
+
42
+ def allow_predicates?
43
+ TrivialAccessors.config['AllowPredicates']
44
+ end
45
+
46
+ def predicate?(method_name)
47
+ method_name[-1] == '?'
48
+ end
49
+
50
+ def trivial_reader?(method_name, args, body)
51
+ return false unless args.children.size == 0
52
+
53
+ return false unless body && body.type == :ivar
54
+
55
+ return false if allow_predicates? && predicate?(method_name)
56
+
57
+ exact_name_match? ? names_match?(method_name, body) : true
58
+ end
59
+
60
+ def trivial_writer?(method_name, args, body)
61
+ return false unless args.children.size == 1 &&
62
+ body && body.type == :ivasgn &&
63
+ body.children[1] && body.children[1].type == :lvar &&
64
+ method_name != :initialize
65
+
66
+ exact_name_match? ? names_match?(method_name, body) : true
67
+ end
68
+
69
+ def names_match?(method_name, body)
70
+ ivar_name, = *body
71
+
72
+ method_name.to_s.chomp('=') == ivar_name[1..-1]
28
73
  end
29
74
  end
30
75
  end
@@ -17,8 +17,6 @@ module Rubocop
17
17
  if loc.keyword.is?('unless') && loc.else
18
18
  add_offence(:convention, loc.expression, MSG)
19
19
  end
20
-
21
- super
22
20
  end
23
21
  end
24
22
  end
@@ -17,8 +17,6 @@ module Rubocop
17
17
  sprintf(MSG, var, var))
18
18
  end
19
19
  end
20
-
21
- super
22
20
  end
23
21
 
24
22
  private
@@ -12,12 +12,12 @@ module Rubocop
12
12
  add_offence(:convention, node.loc.begin, MSG)
13
13
  do_autocorrect(node)
14
14
  end
15
-
16
- super
17
15
  end
18
16
 
19
17
  def autocorrect_action(node)
20
- replace(node.loc.begin, ' then')
18
+ @corrections << lambda do |corrector|
19
+ corrector.replace(node.loc.begin, ' then')
20
+ end
21
21
  end
22
22
  end
23
23
  end
@@ -7,14 +7,10 @@ module Rubocop
7
7
  class WhileUntilDo < Cop
8
8
  def on_while(node)
9
9
  handle(node)
10
-
11
- super
12
10
  end
13
11
 
14
12
  def on_until(node)
15
13
  handle(node)
16
-
17
- super
18
14
  end
19
15
 
20
16
  def handle(node)
@@ -37,7 +33,9 @@ module Rubocop
37
33
  end
38
34
 
39
35
  def autocorrect_action(node)
40
- remove(node.loc.begin)
36
+ @corrections << lambda do |corrector|
37
+ corrector.remove(node.loc.begin)
38
+ end
41
39
  end
42
40
  end
43
41
  end
@@ -21,8 +21,6 @@ module Rubocop
21
21
  if string_array && !complex_content?(array_elems)
22
22
  add_offence(:convention, node.loc.expression, MSG)
23
23
  end
24
-
25
- super
26
24
  end
27
25
 
28
26
  private
@@ -22,10 +22,6 @@ module Rubocop
22
22
  def block_length(block_node)
23
23
  block_node.loc.end.line - block_node.loc.begin.line
24
24
  end
25
-
26
- def symbolize_keys(hash)
27
- Hash[hash.map { |(k, v)| [k.to_sym, v] }] if hash
28
- end
29
25
  end
30
26
  end
31
27
  end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ module Formatter
5
+ # This formatter displays just a list of the files with offences in them,
6
+ # separated by newlines.
7
+ #
8
+ # Here's the format:
9
+ #
10
+ # /some/file
11
+ # /some/other/file
12
+ class FileListFormatter < SimpleTextFormatter
13
+ def report_file(file, offences)
14
+ output.printf("%s\n", file)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -11,7 +11,8 @@ module Rubocop
11
11
  'simple' => SimpleTextFormatter,
12
12
  'clang' => ClangStyleFormatter,
13
13
  'emacs' => EmacsStyleFormatter,
14
- 'json' => JSONFormatter
14
+ 'json' => JSONFormatter,
15
+ 'files' => FileListFormatter
15
16
  }
16
17
 
17
18
  FORMATTER_APIS = [:started, :file_started, :file_finished, :finished]
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ # ProcessedSource contains objects which are generated by Parser
5
+ # and other information such as disabled lines for cops.
6
+ # It also provides a convenient way to access source lines.
7
+ class ProcessedSource
8
+ attr_reader :buffer, :ast, :comments, :tokens, :diagnostics
9
+ attr_accessor :disabled_lines_for_cops
10
+
11
+ def initialize(buffer, ast, comments, tokens, diagnostics)
12
+ @buffer = buffer
13
+ @ast = ast
14
+ @comments = comments
15
+ @tokens = tokens
16
+ @diagnostics = diagnostics
17
+ end
18
+
19
+ def lines
20
+ @lines ||= @buffer.source.split($RS)
21
+ end
22
+
23
+ def [](*args)
24
+ lines[*args]
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubocop'
4
+ require 'rake'
5
+ require 'rake/tasklib'
6
+
7
+ module Rubocop
8
+ # Provides a custom rake task.
9
+ #
10
+ # require 'rubocop/rake_task'
11
+ # Rubocop::RakeTask.new
12
+ class RakeTask < Rake::TaskLib
13
+
14
+ attr_accessor :name
15
+ attr_accessor :verbose
16
+ attr_accessor :fail_on_error
17
+ attr_accessor :patterns
18
+
19
+ def initialize(*args, &task_block)
20
+ setup_ivars(args)
21
+
22
+ desc 'Run RuboCop' unless ::Rake.application.last_comment
23
+
24
+ task(name, *args) do |_, task_args|
25
+ RakeFileUtils.send(:verbose, verbose) do
26
+ if task_block
27
+ task_block.call(*[self, task_args].slice(0, task_block.arity))
28
+ end
29
+ run_task(verbose)
30
+ end
31
+ end
32
+ end
33
+
34
+ def run_task(verbose)
35
+ cli = CLI.new
36
+ puts 'Running RuboCop...' if verbose
37
+ result = cli.run(patterns)
38
+ abort('RuboCop failed!') if fail_on_error unless result == 0
39
+ end
40
+
41
+ private
42
+
43
+ def setup_ivars(args)
44
+ @name = args.shift || :rubocop
45
+ @verbose = true
46
+ @fail_on_error = true
47
+ @patterns = []
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ # SourceParser provides a way to parse Ruby source with Parser gem
5
+ # and also parses comment directives which disable arbitrary cops.
6
+ module SourceParser
7
+ COMMENT_DIRECTIVE_REGEXP = Regexp.new(
8
+ '^.*?(\S)?.*# rubocop : ((?:dis|en)able)\b ((?:\w+,? )+)'
9
+ .gsub(' ', '\s*')
10
+ )
11
+
12
+ module_function
13
+
14
+ def parse(string, name = '(string)')
15
+ processed_source = parse_with_parser(string, name)
16
+ processed_source.disabled_lines_for_cops =
17
+ cop_disabled_lines_in(processed_source.lines)
18
+ processed_source
19
+ end
20
+
21
+ def parse_file(path)
22
+ parse(File.read(path), path)
23
+ end
24
+
25
+ def parse_with_parser(string, name)
26
+ source_buffer = Parser::Source::Buffer.new(name, 1)
27
+ source_buffer.source = string
28
+
29
+ parser = create_parser
30
+ diagnostics = []
31
+ parser.diagnostics.consumer = lambda do |diagnostic|
32
+ diagnostics << diagnostic
33
+ end
34
+
35
+ begin
36
+ ast, comments, tokens = parser.tokenize(source_buffer)
37
+ rescue Parser::SyntaxError # rubocop:disable HandleExceptions
38
+ # All errors are in diagnostics. No need to handle exception.
39
+ end
40
+
41
+ tokens = tokens.map { |t| Token.from_parser_token(t) } if tokens
42
+
43
+ ProcessedSource.new(source_buffer, ast, comments, tokens, diagnostics)
44
+ end
45
+
46
+ def create_parser
47
+ parser = Parser::CurrentRuby.new
48
+
49
+ # On JRuby and Rubinius, there's a risk that we hang in tokenize() if we
50
+ # don't set the all errors as fatal flag. The problem is caused by a bug
51
+ # in Racc that is discussed in issue #93 of the whitequark/parser project
52
+ # on GitHub.
53
+ parser.diagnostics.all_errors_are_fatal = RUBY_ENGINE != 'ruby'
54
+ parser.diagnostics.ignore_warnings = false
55
+
56
+ parser
57
+ end
58
+
59
+ def cop_disabled_lines_in(source_lines)
60
+ disabled_lines_for_cops = {}
61
+ current_disabled_cops = {}
62
+
63
+ source_lines.each_with_index do |line, index|
64
+ line_number = index + 1
65
+
66
+ each_mentioned_cop(line) do |cop_name, disabled, single_line|
67
+ if single_line
68
+ next unless disabled
69
+ disabled_lines_for_cops[cop_name] ||= []
70
+ disabled_lines_for_cops[cop_name] << line_number
71
+ else
72
+ current_disabled_cops[cop_name] = disabled
73
+ end
74
+ end
75
+
76
+ current_disabled_cops.each do |cop_name, disabled|
77
+ next unless disabled
78
+ disabled_lines_for_cops[cop_name] ||= []
79
+ disabled_lines_for_cops[cop_name] << line_number
80
+ end
81
+ end
82
+
83
+ disabled_lines_for_cops
84
+ end
85
+
86
+ def each_mentioned_cop(line)
87
+ match = line.match(COMMENT_DIRECTIVE_REGEXP)
88
+
89
+ return unless match
90
+
91
+ non_whitespace_before_comment, switch, cops_string = match.captures
92
+
93
+ if cops_string.include?('all')
94
+ cop_names = Cop::Cop.all.map(&:cop_name)
95
+ else
96
+ cop_names = cops_string.split(/,\s*/)
97
+ end
98
+
99
+ disabled = (switch == 'disable')
100
+ single_line = !non_whitespace_before_comment.nil?
101
+
102
+ cop_names.each { |cop_name| yield cop_name, disabled, single_line }
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,67 @@
1
+ # encoding: utf-8
2
+
3
+ module Rubocop
4
+ # This class finds target files to inspect by scanning directory tree
5
+ # and picking ruby files.
6
+ class TargetFinder
7
+ def initialize(config_store, debug = false)
8
+ @config_store = config_store
9
+ @debug = debug
10
+ end
11
+
12
+ # Generate a list of target files by expanding globing patterns
13
+ # (if any). If args is empty recursively finds all Ruby source
14
+ # files under the current directory
15
+ # @return [Array] array of file paths
16
+ def find(args)
17
+ return target_files_in_dir if args.empty?
18
+
19
+ files = []
20
+
21
+ args.uniq.each do |arg|
22
+ if File.directory?(arg)
23
+ files += target_files_in_dir(arg.chomp(File::SEPARATOR))
24
+ elsif arg.include?('*')
25
+ files += Dir[arg]
26
+ else
27
+ files << arg
28
+ end
29
+ end
30
+
31
+ files.map { |f| File.expand_path(f) }.uniq
32
+ end
33
+
34
+ # Finds all Ruby source files under the current or other supplied
35
+ # directory. A Ruby source file is defined as a file with the `.rb`
36
+ # extension or a file with no extension that has a ruby shebang line
37
+ # as its first line.
38
+ # It is possible to specify includes and excludes using the config file,
39
+ # so you can include other Ruby files like Rakefiles and gemspecs.
40
+ # @param root Root directory under which to search for ruby source files
41
+ # @return [Array] Array of filenames
42
+ def target_files_in_dir(base_dir = Dir.pwd)
43
+ files = Dir["#{base_dir}/**/*"].select { |path| FileTest.file?(path) }
44
+
45
+ target_files = files.select do |file|
46
+ config = @config_store.for(file)
47
+ next false if config.file_to_exclude?(file)
48
+ next true if File.extname(file) == '.rb'
49
+ next true if ruby_executable?(file)
50
+ config.file_to_include?(file)
51
+ end
52
+
53
+ target_files.uniq
54
+ end
55
+
56
+ def ruby_executable?(file)
57
+ return false unless File.extname(file).empty?
58
+ first_line = File.open(file) { |f| f.readline }
59
+ first_line =~ /#!.*ruby/
60
+ rescue EOFError, ArgumentError => e
61
+ if @debug
62
+ warn "Unprocessable file #{file}: #{e.class}, #{e.message}"
63
+ end
64
+ false
65
+ end
66
+ end
67
+ end