reek 1.2.2 → 1.2.3

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 (59) hide show
  1. data/History.txt +4 -0
  2. data/Rakefile +0 -1
  3. data/config/defaults.reek +4 -6
  4. data/features/masking_smells.feature +9 -9
  5. data/features/options.feature +2 -2
  6. data/features/profile.feature +34 -0
  7. data/features/rake_task.feature +74 -0
  8. data/features/reports.feature +1 -1
  9. data/features/samples.feature +4 -4
  10. data/features/stdin.feature +1 -1
  11. data/features/step_definitions/reek_steps.rb +11 -7
  12. data/features/support/env.rb +26 -18
  13. data/lib/reek.rb +1 -1
  14. data/lib/reek/adapters/application.rb +9 -2
  15. data/lib/reek/adapters/command_line.rb +2 -2
  16. data/lib/reek/adapters/source.rb +4 -1
  17. data/lib/reek/adapters/spec.rb +1 -3
  18. data/lib/reek/block_context.rb +14 -8
  19. data/lib/reek/class_context.rb +6 -66
  20. data/lib/reek/code_context.rb +10 -0
  21. data/lib/reek/code_parser.rb +25 -53
  22. data/lib/reek/configuration.rb +12 -6
  23. data/lib/reek/if_context.rb +2 -3
  24. data/lib/reek/method_context.rb +3 -12
  25. data/lib/reek/module_context.rb +30 -22
  26. data/lib/reek/name.rb +2 -0
  27. data/lib/reek/object_refs.rb +0 -3
  28. data/lib/reek/sexp_formatter.rb +0 -2
  29. data/lib/reek/smells/class_variable.rb +17 -4
  30. data/lib/reek/smells/control_couple.rb +3 -10
  31. data/lib/reek/smells/data_clump.rb +10 -10
  32. data/lib/reek/smells/feature_envy.rb +1 -8
  33. data/lib/reek/smells/large_class.rb +3 -3
  34. data/lib/reek/smells/simulated_polymorphism.rb +17 -3
  35. data/lib/reek/smells/smell_detector.rb +11 -2
  36. data/lib/reek/smells/utility_function.rb +1 -1
  37. data/lib/reek/sniffer.rb +0 -8
  38. data/lib/reek/stop_context.rb +1 -1
  39. data/lib/reek/tree_dresser.rb +74 -0
  40. data/reek.gemspec +3 -3
  41. data/spec/reek/block_context_spec.rb +6 -6
  42. data/spec/reek/class_context_spec.rb +2 -23
  43. data/spec/reek/code_context_spec.rb +149 -67
  44. data/spec/reek/code_parser_spec.rb +0 -102
  45. data/spec/reek/method_context_spec.rb +4 -4
  46. data/spec/reek/singleton_method_context_spec.rb +1 -1
  47. data/spec/reek/smells/attribute_spec.rb +1 -1
  48. data/spec/reek/smells/class_variable_spec.rb +96 -7
  49. data/spec/reek/smells/control_couple_spec.rb +1 -1
  50. data/spec/reek/smells/data_clump_spec.rb +31 -13
  51. data/spec/reek/smells/feature_envy_spec.rb +1 -1
  52. data/spec/reek/smells/large_class_spec.rb +32 -18
  53. data/spec/reek/smells/simulated_polymorphism_spec.rb +66 -18
  54. data/spec/reek/sniffer_spec.rb +1 -0
  55. data/spec/samples/not_quite_masked/dirty.rb +2 -0
  56. data/spec/spec_helper.rb +1 -1
  57. data/tasks/reek.rake +1 -1
  58. metadata +5 -3
  59. data/lib/reek/exceptions.reek +0 -20
@@ -1,32 +1,30 @@
1
1
  require 'reek/code_context'
2
+ require 'reek/code_parser'
3
+ require 'reek/sniffer'
2
4
 
3
5
  module Reek
4
6
  class ModuleContext < CodeContext
5
7
 
6
- def ModuleContext.create(outer, exp)
7
- res = Name.resolve(exp[1], outer)
8
- ModuleContext.new(res[0], res[1])
9
- end
8
+ class << self
9
+ def create(outer, exp)
10
+ res = Name.resolve(exp[1], outer)
11
+ new(res[0], res[1], exp)
12
+ end
10
13
 
11
- def ModuleContext.from_s(src)
12
- source = src.to_reek_source
13
- sniffer = Sniffer.new(source)
14
- CodeParser.new(sniffer).process_module(source.syntax_tree)
14
+ def from_s(src)
15
+ source = src.to_reek_source
16
+ sniffer = Sniffer.new(source)
17
+ CodeParser.new(sniffer).do_module_or_class(source.syntax_tree, self)
18
+ end
15
19
  end
16
20
 
17
- attr_reader :class_variables, :attributes
21
+ attr_reader :attributes
18
22
 
19
- def initialize(outer, name)
20
- super(outer, nil)
23
+ def initialize(outer, name, exp)
24
+ super(outer, exp)
21
25
  @name = name
22
26
  @attributes = Set.new
23
- @class_variables = Set.new
24
- end
25
-
26
- def check_for_attribute_declaration(exp)
27
- if [:attr, :attr_reader, :attr_writer, :attr_accessor].include? exp[2]
28
- exp[3][1..-1].each {|arg| record_attribute(arg[1])}
29
- end
27
+ @parsed_methods = []
30
28
  end
31
29
 
32
30
  def myself
@@ -38,16 +36,26 @@ module Reek
38
36
  @myself.const_or_nil(modname.to_s)
39
37
  end
40
38
 
41
- def outer_name
42
- "#{@outer.outer_name}#{@name}::"
39
+ def parameterized_methods(min_clump_size)
40
+ @parsed_methods.select {|meth| meth.parameters.length >= min_clump_size }
43
41
  end
44
42
 
45
43
  def record_attribute(attr)
46
44
  @attributes << Name.new(attr)
47
45
  end
48
46
 
49
- def record_class_variable(cvar)
50
- @class_variables << Name.new(cvar)
47
+ def record_method(meth)
48
+ @parsed_methods << meth
49
+ end
50
+
51
+ def check_for_attribute_declaration(exp)
52
+ if [:attr, :attr_reader, :attr_writer, :attr_accessor].include? exp[2]
53
+ exp[3][1..-1].each {|arg| record_attribute(arg[1])}
54
+ end
55
+ end
56
+
57
+ def outer_name
58
+ "#{@outer.outer_name}#{@name}::"
51
59
  end
52
60
 
53
61
  def variable_names
data/lib/reek/name.rb CHANGED
@@ -1,3 +1,5 @@
1
+ require 'ruby_parser'
2
+
1
3
  module Reek
2
4
  class Name
3
5
  include Comparable
@@ -1,6 +1,3 @@
1
- require 'rubygems'
2
- require 'sexp_processor'
3
-
4
1
  module Reek
5
2
 
6
3
  class ObjectRefs # :nodoc:
@@ -1,5 +1,3 @@
1
- require 'rubygems'
2
- require 'ruby_parser'
3
1
  require 'ruby2ruby'
4
2
 
5
3
  module Reek
@@ -18,14 +18,27 @@ module Reek
18
18
  end
19
19
 
20
20
  #
21
- # Checks whether the given class declares any class variables.
21
+ # Checks whether the given class or module declares any class variables.
22
22
  # Remembers any smells found.
23
23
  #
24
- def examine_context(klass)
25
- klass.class_variables.each do |cvar|
26
- found(klass, "declares the class variable #{cvar}")
24
+ def examine_context(mod)
25
+ class_variables_in(mod).each do |cvar_name|
26
+ found(mod, "declares the class variable #{cvar_name}")
27
27
  end
28
28
  end
29
+
30
+ #
31
+ # Collects the names of the class variables declared and/or used
32
+ # in the given module.
33
+ #
34
+ def class_variables_in(mod)
35
+ result = Set.new
36
+ collector = proc { |cvar_node| result << cvar_node.name }
37
+ [:cvar, :cvasgn, :cvdecl].each do |stmt_type|
38
+ mod.each(stmt_type, [:class, :module], &collector)
39
+ end
40
+ result
41
+ end
29
42
  end
30
43
  end
31
44
  end
@@ -34,19 +34,12 @@ module Reek
34
34
  # because it includes at least two different code paths.
35
35
  #
36
36
  class ControlCouple < SmellDetector
37
+ include ExcludeInitialize
37
38
 
38
39
  def self.contexts # :nodoc:
39
40
  [:if]
40
41
  end
41
42
 
42
- def self.default_config
43
- super.adopt(EXCLUDE_KEY => ['initialize'])
44
- end
45
-
46
- def initialize(config = ControlCouple.default_config)
47
- super
48
- end
49
-
50
43
  #
51
44
  # Checks whether the given conditional statement relies on a control couple.
52
45
  # Remembers any smells found.
@@ -56,8 +49,8 @@ module Reek
56
49
  # SMELL: Duplication
57
50
  # This smell is reported once for each conditional that tests the
58
51
  # same parameter. Which means that the same smell can recur within
59
- # a single sniffer. Which in turn means that the sniffer can't count
60
- # its smells without knowing which are duplicates.
52
+ # a single detector. Which in turn means that SmellDetector must
53
+ # use a Set to hold smells found.
61
54
  found(cond, "is controlled by argument #{SexpFormatter.format(cond.if_expr)}")
62
55
  end
63
56
  end
@@ -20,7 +20,7 @@ module Reek
20
20
  class DataClump < SmellDetector
21
21
 
22
22
  def self.contexts # :nodoc:
23
- [:class]
23
+ [:class, :module]
24
24
  end
25
25
 
26
26
  # The name of the config field that sets the maximum allowed
@@ -44,14 +44,14 @@ module Reek
44
44
  end
45
45
 
46
46
  #
47
- # Checks the given ClassContext for multiple identical conditional tests.
47
+ # Checks the given class or module for multiple identical parameter sets.
48
48
  # Remembers any smells found.
49
49
  #
50
- def examine_context(klass)
51
- max_copies = value(MAX_COPIES_KEY, klass, DEFAULT_MAX_COPIES)
52
- min_clump_size = value(MIN_CLUMP_SIZE_KEY, klass, DEFAULT_MIN_CLUMP_SIZE)
53
- MethodGroup.new(klass, min_clump_size, max_copies).clumps.each do |clump, occurs|
54
- found(klass, "takes parameters #{DataClump.print_clump(clump)} to #{occurs} methods")
50
+ def examine_context(ctx)
51
+ max_copies = value(MAX_COPIES_KEY, ctx, DEFAULT_MAX_COPIES)
52
+ min_clump_size = value(MIN_CLUMP_SIZE_KEY, ctx, DEFAULT_MIN_CLUMP_SIZE)
53
+ MethodGroup.new(ctx, min_clump_size, max_copies).clumps.each do |clump, occurs|
54
+ found(ctx, "takes parameters #{DataClump.print_clump(clump)} to #{occurs} methods")
55
55
  end
56
56
  end
57
57
 
@@ -68,15 +68,15 @@ module Reek
68
68
  methods.map {|meth| meth.parameters.names.sort}.intersection
69
69
  end
70
70
 
71
- def initialize(klass, min_clump_size, max_copies)
72
- @klass = klass
71
+ def initialize(ctx, min_clump_size, max_copies)
72
+ @ctx = ctx
73
73
  @min_clump_size = min_clump_size
74
74
  @max_copies = max_copies
75
75
  end
76
76
 
77
77
  def clumps
78
78
  results = Hash.new(0)
79
- @klass.parameterized_methods(@min_clump_size).bounded_power_set(@max_copies).each do |methods|
79
+ @ctx.parameterized_methods(@min_clump_size).bounded_power_set(@max_copies).each do |methods|
80
80
  clump = MethodGroup.intersection_of_parameters_of(methods)
81
81
  if clump.length >= @min_clump_size
82
82
  results[clump] = [methods.length, results[clump]].max
@@ -33,14 +33,7 @@ module Reek
33
33
  # often than it refers to (ie. send messages to) some other object.
34
34
  #
35
35
  class FeatureEnvy < SmellDetector
36
-
37
- def self.default_config
38
- super.adopt(EXCLUDE_KEY => ['initialize'])
39
- end
40
-
41
- def initialize(config = FeatureEnvy.default_config)
42
- super
43
- end
36
+ include ExcludeInitialize
44
37
 
45
38
  #
46
39
  # Checks whether the given +context+ includes any code fragment that
@@ -45,9 +45,9 @@ module Reek
45
45
  end
46
46
 
47
47
  def check_num_methods(klass) # :nodoc:
48
- count = klass.num_methods
49
- return if count <= value(MAX_ALLOWED_METHODS_KEY, klass, DEFAULT_MAX_METHODS)
50
- found(klass, "has at least #{count} methods")
48
+ actual = klass.each(:defn, [:class, :module]).length
49
+ return if actual <= value(MAX_ALLOWED_METHODS_KEY, klass, DEFAULT_MAX_METHODS)
50
+ found(klass, "has at least #{actual} methods")
51
51
  end
52
52
 
53
53
  def check_num_ivars(klass) # :nodoc:
@@ -47,12 +47,26 @@ module Reek
47
47
  # Remembers any smells found.
48
48
  #
49
49
  def examine_context(klass)
50
- counts = Hash.new(0)
51
- klass.conditionals.each {|cond| counts[cond] += 1}
52
- counts.each do |key, val|
50
+ conditional_counts(klass).each do |key, val|
53
51
  found(klass, "tests #{SexpFormatter.format(key)} at least #{val} times") if val > value(MAX_IDENTICAL_IFS_KEY, klass, DEFAULT_MAX_IFS)
54
52
  end
55
53
  end
54
+
55
+ #
56
+ # Returns a Hash listing all of the conditional expressions in
57
+ # the given syntax tree together with the number of times each
58
+ # occurs. Ignores nested classes and modules.
59
+ #
60
+ def conditional_counts(klass)
61
+ result = Hash.new(0)
62
+ collector = proc { |node|
63
+ condition = node.condition
64
+ result[condition] += 1 unless condition == s(:call, nil, :block_given?, s(:arglist))
65
+ }
66
+ klass.each(:if, [:class, :module], &collector)
67
+ klass.each(:case, [:class, :module], &collector)
68
+ result
69
+ end
56
70
  end
57
71
  end
58
72
  end
@@ -10,6 +10,15 @@ end
10
10
  module Reek
11
11
  module Smells
12
12
 
13
+ module ExcludeInitialize
14
+ def self.default_config
15
+ super.adopt(EXCLUDE_KEY => ['initialize'])
16
+ end
17
+ def initialize(config = self.class.default_config)
18
+ super
19
+ end
20
+ end
21
+
13
22
  class SmellDetector
14
23
 
15
24
  # The name of the config field that lists the names of code contexts
@@ -70,11 +79,11 @@ module Reek
70
79
  end
71
80
 
72
81
  def configure_with(config)
73
- @config.hash.adopt!(config)
82
+ @config.adopt!(config)
74
83
  end
75
84
 
76
85
  def copy
77
- self.class.new(@config.hash.deep_copy)
86
+ self.class.new(@config.deep_copy)
78
87
  end
79
88
 
80
89
  def supersede_with(config)
@@ -30,7 +30,7 @@ module Reek
30
30
  super.adopt(HELPER_CALLS_LIMIT_KEY => DEFAULT_HELPER_CALLS_LIMIT)
31
31
  end
32
32
 
33
- def initialize(config = Duplication.default_config)
33
+ def initialize(config = UtilityFunction.default_config)
34
34
  super(config)
35
35
  end
36
36
 
data/lib/reek/sniffer.rb CHANGED
@@ -125,10 +125,6 @@ module Reek
125
125
  stack.has_smell?(patterns)
126
126
  end
127
127
 
128
- def smells_only_of?(klass, patterns)
129
- num_smells == 1 and has_smell?(klass, patterns)
130
- end
131
-
132
128
  def sniff
133
129
  self
134
130
  end
@@ -175,10 +171,6 @@ private
175
171
  total
176
172
  end
177
173
 
178
- def smells_only_of?(klass, patterns)
179
- num_smells == 1 and has_smell?(klass, patterns)
180
- end
181
-
182
174
  def sniff
183
175
  self
184
176
  end
@@ -5,11 +5,11 @@ module Reek
5
5
  @refs = ObjectRefs.new
6
6
  @myself = Object
7
7
  end
8
+
8
9
  def method_missing(method, *args)
9
10
  nil
10
11
  end
11
12
 
12
-
13
13
  def count_statements(num)
14
14
  0
15
15
  end
@@ -0,0 +1,74 @@
1
+ module Reek
2
+
3
+ #
4
+ # Extensions to +Sexp+ to allow +CodeParser+ to navigate the abstract
5
+ # syntax tree more easily.
6
+ #
7
+ module SexpNode
8
+ def children
9
+ find_all { |item| Sexp === item }
10
+ end
11
+
12
+ def is_language_node?
13
+ first.class == Symbol
14
+ end
15
+
16
+ def has_type?(type)
17
+ is_language_node? and first == type
18
+ end
19
+
20
+ #
21
+ # Carries out a depth-first traversal of this syntax tree, yielding
22
+ # every Sexp of type +target_type+. The traversal ignores any node
23
+ # whose type is listed in the Array +ignoring+.
24
+ #
25
+ def look_for(target_type, ignoring, &blk)
26
+ each do |elem|
27
+ if Sexp === elem then
28
+ elem.look_for(target_type, ignoring, &blk) unless ignoring.include?(elem.first)
29
+ end
30
+ end
31
+ blk.call(self) if first == target_type
32
+ end
33
+ end
34
+
35
+ module CvarNode
36
+ def name
37
+ self[1]
38
+ end
39
+ end
40
+
41
+ module IfNode
42
+ def condition
43
+ self[1]
44
+ end
45
+ end
46
+
47
+ module CaseNode
48
+ def condition
49
+ self[1]
50
+ end
51
+ end
52
+
53
+ class TreeDresser
54
+ # SMELL: Duplication
55
+ # Put these into a new module and build the mapping automagically
56
+ # based on the node type
57
+ EXTENSIONS = {
58
+ :cvar => CvarNode,
59
+ :cvasgn => CvarNode,
60
+ :cvdecl => CvarNode,
61
+ :if => IfNode,
62
+ :case => CaseNode,
63
+ }
64
+
65
+ def dress(sexp)
66
+ sexp.extend(SexpNode)
67
+ if EXTENSIONS.has_key?(sexp[0])
68
+ sexp.extend(EXTENSIONS[sexp[0]])
69
+ end
70
+ sexp[0..-1].each { |sub| dress(sub) if Array === sub }
71
+ sexp
72
+ end
73
+ end
74
+ end
data/reek.gemspec CHANGED
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{reek}
5
- s.version = "1.2.2"
5
+ s.version = "1.2.3"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Kevin Rutherford"]
9
- s.date = %q{2009-10-06}
9
+ s.date = %q{2009-11-02}
10
10
  s.default_executable = %q{reek}
11
11
  s.description = %q{Code smell detector for Ruby}
12
12
  s.email = ["kevin@rutherford-software.com"]
13
13
  s.executables = ["reek"]
14
14
  s.extra_rdoc_files = ["History.txt", "License.txt", "README.rdoc"]
15
- s.files = ["History.txt", "License.txt", "README.rdoc", "Rakefile", "bin/reek", "config/defaults.reek", "features/masking_smells.feature", "features/options.feature", "features/reports.feature", "features/samples.feature", "features/stdin.feature", "features/step_definitions/reek_steps.rb", "features/support/env.rb", "lib/reek.rb", "lib/reek/adapters/application.rb", "lib/reek/adapters/command_line.rb", "lib/reek/adapters/config_file.rb", "lib/reek/adapters/core_extras.rb", "lib/reek/adapters/rake_task.rb", "lib/reek/adapters/report.rb", "lib/reek/adapters/source.rb", "lib/reek/adapters/spec.rb", "lib/reek/block_context.rb", "lib/reek/class_context.rb", "lib/reek/code_context.rb", "lib/reek/code_parser.rb", "lib/reek/configuration.rb", "lib/reek/detector_stack.rb", "lib/reek/exceptions.reek", "lib/reek/if_context.rb", "lib/reek/method_context.rb", "lib/reek/module_context.rb", "lib/reek/name.rb", "lib/reek/object_refs.rb", "lib/reek/sexp_formatter.rb", "lib/reek/singleton_method_context.rb", "lib/reek/smell_warning.rb", "lib/reek/smells/attribute.rb", "lib/reek/smells/class_variable.rb", "lib/reek/smells/control_couple.rb", "lib/reek/smells/data_clump.rb", "lib/reek/smells/duplication.rb", "lib/reek/smells/feature_envy.rb", "lib/reek/smells/large_class.rb", "lib/reek/smells/long_method.rb", "lib/reek/smells/long_parameter_list.rb", "lib/reek/smells/long_yield_list.rb", "lib/reek/smells/nested_iterators.rb", "lib/reek/smells/simulated_polymorphism.rb", "lib/reek/smells/smell_detector.rb", "lib/reek/smells/uncommunicative_name.rb", "lib/reek/smells/utility_function.rb", "lib/reek/sniffer.rb", "lib/reek/stop_context.rb", "lib/reek/yield_call_context.rb", "reek.gemspec", "spec/reek/adapters/report_spec.rb", "spec/reek/adapters/should_reek_of_spec.rb", "spec/reek/adapters/should_reek_only_of_spec.rb", "spec/reek/adapters/should_reek_spec.rb", "spec/reek/block_context_spec.rb", "spec/reek/class_context_spec.rb", "spec/reek/code_context_spec.rb", "spec/reek/code_parser_spec.rb", "spec/reek/config_spec.rb", "spec/reek/configuration_spec.rb", "spec/reek/if_context_spec.rb", "spec/reek/method_context_spec.rb", "spec/reek/module_context_spec.rb", "spec/reek/name_spec.rb", "spec/reek/object_refs_spec.rb", "spec/reek/object_source_spec.rb", "spec/reek/singleton_method_context_spec.rb", "spec/reek/smell_warning_spec.rb", "spec/reek/smells/attribute_spec.rb", "spec/reek/smells/behaves_like_variable_detector.rb", "spec/reek/smells/class_variable_spec.rb", "spec/reek/smells/control_couple_spec.rb", "spec/reek/smells/data_clump_spec.rb", "spec/reek/smells/duplication_spec.rb", "spec/reek/smells/feature_envy_spec.rb", "spec/reek/smells/large_class_spec.rb", "spec/reek/smells/long_method_spec.rb", "spec/reek/smells/long_parameter_list_spec.rb", "spec/reek/smells/nested_iterators_spec.rb", "spec/reek/smells/simulated_polymorphism_spec.rb", "spec/reek/smells/smell_detector_spec.rb", "spec/reek/smells/uncommunicative_name_spec.rb", "spec/reek/smells/utility_function_spec.rb", "spec/reek/sniffer_spec.rb", "spec/reek/stop_context_spec.rb", "spec/samples/all_but_one_masked/clean_one.rb", "spec/samples/all_but_one_masked/dirty.rb", "spec/samples/all_but_one_masked/masked.reek", "spec/samples/clean_due_to_masking/clean_one.rb", "spec/samples/clean_due_to_masking/clean_three.rb", "spec/samples/clean_due_to_masking/clean_two.rb", "spec/samples/clean_due_to_masking/dirty_one.rb", "spec/samples/clean_due_to_masking/dirty_two.rb", "spec/samples/clean_due_to_masking/masked.reek", "spec/samples/corrupt_config_file/corrupt.reek", "spec/samples/corrupt_config_file/dirty.rb", "spec/samples/empty_config_file/dirty.rb", "spec/samples/empty_config_file/empty.reek", "spec/samples/exceptions.reek", "spec/samples/inline.rb", "spec/samples/masked/dirty.rb", "spec/samples/masked/masked.reek", "spec/samples/mixed_results/clean_one.rb", "spec/samples/mixed_results/clean_three.rb", "spec/samples/mixed_results/clean_two.rb", "spec/samples/mixed_results/dirty_one.rb", "spec/samples/mixed_results/dirty_two.rb", "spec/samples/not_quite_masked/dirty.rb", "spec/samples/not_quite_masked/masked.reek", "spec/samples/optparse.rb", "spec/samples/overrides/masked/dirty.rb", "spec/samples/overrides/masked/lower.reek", "spec/samples/overrides/upper.reek", "spec/samples/redcloth.rb", "spec/samples/three_clean_files/clean_one.rb", "spec/samples/three_clean_files/clean_three.rb", "spec/samples/three_clean_files/clean_two.rb", "spec/samples/two_smelly_files/dirty_one.rb", "spec/samples/two_smelly_files/dirty_two.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/reek.rake", "tasks/test.rake"]
15
+ s.files = ["History.txt", "License.txt", "README.rdoc", "Rakefile", "bin/reek", "config/defaults.reek", "features/masking_smells.feature", "features/options.feature", "features/profile.feature", "features/rake_task.feature", "features/reports.feature", "features/samples.feature", "features/stdin.feature", "features/step_definitions/reek_steps.rb", "features/support/env.rb", "lib/reek.rb", "lib/reek/adapters/application.rb", "lib/reek/adapters/command_line.rb", "lib/reek/adapters/config_file.rb", "lib/reek/adapters/core_extras.rb", "lib/reek/adapters/rake_task.rb", "lib/reek/adapters/report.rb", "lib/reek/adapters/source.rb", "lib/reek/adapters/spec.rb", "lib/reek/block_context.rb", "lib/reek/class_context.rb", "lib/reek/code_context.rb", "lib/reek/code_parser.rb", "lib/reek/configuration.rb", "lib/reek/detector_stack.rb", "lib/reek/if_context.rb", "lib/reek/method_context.rb", "lib/reek/module_context.rb", "lib/reek/name.rb", "lib/reek/object_refs.rb", "lib/reek/sexp_formatter.rb", "lib/reek/singleton_method_context.rb", "lib/reek/smell_warning.rb", "lib/reek/smells/attribute.rb", "lib/reek/smells/class_variable.rb", "lib/reek/smells/control_couple.rb", "lib/reek/smells/data_clump.rb", "lib/reek/smells/duplication.rb", "lib/reek/smells/feature_envy.rb", "lib/reek/smells/large_class.rb", "lib/reek/smells/long_method.rb", "lib/reek/smells/long_parameter_list.rb", "lib/reek/smells/long_yield_list.rb", "lib/reek/smells/nested_iterators.rb", "lib/reek/smells/simulated_polymorphism.rb", "lib/reek/smells/smell_detector.rb", "lib/reek/smells/uncommunicative_name.rb", "lib/reek/smells/utility_function.rb", "lib/reek/sniffer.rb", "lib/reek/stop_context.rb", "lib/reek/tree_dresser.rb", "lib/reek/yield_call_context.rb", "reek.gemspec", "spec/reek/adapters/report_spec.rb", "spec/reek/adapters/should_reek_of_spec.rb", "spec/reek/adapters/should_reek_only_of_spec.rb", "spec/reek/adapters/should_reek_spec.rb", "spec/reek/block_context_spec.rb", "spec/reek/class_context_spec.rb", "spec/reek/code_context_spec.rb", "spec/reek/code_parser_spec.rb", "spec/reek/config_spec.rb", "spec/reek/configuration_spec.rb", "spec/reek/if_context_spec.rb", "spec/reek/method_context_spec.rb", "spec/reek/module_context_spec.rb", "spec/reek/name_spec.rb", "spec/reek/object_refs_spec.rb", "spec/reek/object_source_spec.rb", "spec/reek/singleton_method_context_spec.rb", "spec/reek/smell_warning_spec.rb", "spec/reek/smells/attribute_spec.rb", "spec/reek/smells/behaves_like_variable_detector.rb", "spec/reek/smells/class_variable_spec.rb", "spec/reek/smells/control_couple_spec.rb", "spec/reek/smells/data_clump_spec.rb", "spec/reek/smells/duplication_spec.rb", "spec/reek/smells/feature_envy_spec.rb", "spec/reek/smells/large_class_spec.rb", "spec/reek/smells/long_method_spec.rb", "spec/reek/smells/long_parameter_list_spec.rb", "spec/reek/smells/nested_iterators_spec.rb", "spec/reek/smells/simulated_polymorphism_spec.rb", "spec/reek/smells/smell_detector_spec.rb", "spec/reek/smells/uncommunicative_name_spec.rb", "spec/reek/smells/utility_function_spec.rb", "spec/reek/sniffer_spec.rb", "spec/reek/stop_context_spec.rb", "spec/samples/all_but_one_masked/clean_one.rb", "spec/samples/all_but_one_masked/dirty.rb", "spec/samples/all_but_one_masked/masked.reek", "spec/samples/clean_due_to_masking/clean_one.rb", "spec/samples/clean_due_to_masking/clean_three.rb", "spec/samples/clean_due_to_masking/clean_two.rb", "spec/samples/clean_due_to_masking/dirty_one.rb", "spec/samples/clean_due_to_masking/dirty_two.rb", "spec/samples/clean_due_to_masking/masked.reek", "spec/samples/corrupt_config_file/corrupt.reek", "spec/samples/corrupt_config_file/dirty.rb", "spec/samples/empty_config_file/dirty.rb", "spec/samples/empty_config_file/empty.reek", "spec/samples/exceptions.reek", "spec/samples/inline.rb", "spec/samples/masked/dirty.rb", "spec/samples/masked/masked.reek", "spec/samples/mixed_results/clean_one.rb", "spec/samples/mixed_results/clean_three.rb", "spec/samples/mixed_results/clean_two.rb", "spec/samples/mixed_results/dirty_one.rb", "spec/samples/mixed_results/dirty_two.rb", "spec/samples/not_quite_masked/dirty.rb", "spec/samples/not_quite_masked/masked.reek", "spec/samples/optparse.rb", "spec/samples/overrides/masked/dirty.rb", "spec/samples/overrides/masked/lower.reek", "spec/samples/overrides/upper.reek", "spec/samples/redcloth.rb", "spec/samples/three_clean_files/clean_one.rb", "spec/samples/three_clean_files/clean_three.rb", "spec/samples/three_clean_files/clean_two.rb", "spec/samples/two_smelly_files/dirty_one.rb", "spec/samples/two_smelly_files/dirty_two.rb", "spec/spec.opts", "spec/spec_helper.rb", "tasks/reek.rake", "tasks/test.rake"]
16
16
  s.homepage = %q{http://wiki.github.com/kevinrutherford/reek}
17
17
  s.post_install_message = %q{
18
18
  For more information on reek, see http://wiki.github.com/kevinrutherford/reek