eager_eye 0.5.0 → 0.7.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 031e0f3547538856718932cd6121ac990ad8c11a43682ec076f68bb591943d55
4
- data.tar.gz: 433563980a743704c361304dff56866fe4cc9795a1d6f927cd0b4a8fc0367c8f
3
+ metadata.gz: a8d34dc13a536c66ca82e9495ba5e53b81c31f1e2764dea3ba8d64c434da69ec
4
+ data.tar.gz: d63753e0d80c366cc9b87fe6bcc5bc2f2ee1ba537e7363c2b6aadafffd5a4a05
5
5
  SHA512:
6
- metadata.gz: 5c9f874001fb0c71eb8c1858ef2739181482992b7455925afc696acfa1b7bebfa91888d305936ab6189f64ea1542afd7844b95c4ba453218d0c706d40d17304b
7
- data.tar.gz: 93750c566392f234cb5009d30873130182a4e80722b9f29402b662caacc0c961a31a8c109937c378f9a04b3d0f6e134326a0edeb0d138255debc2c9fb4ceb9a3
6
+ metadata.gz: bf3ff2ba24314b8b6e22385c82685d8909729f12ffc9d48531bd7fe4c6a1683e2aadb5692934ec300430dfdbc0cde795489e9a68a98072658a9452cd8e6e338b
7
+ data.tar.gz: fd73786c8c983b2bcc3d3860bf1036dc1525523dcce8ef06767760dfce57b813ee415679fa42cc7631830e8c4780f0bbbdecc61ae4563b964a983ada5c2c0d42
data/CHANGELOG.md CHANGED
@@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.7.0] - 2025-12-15
11
+
12
+ ### Added
13
+
14
+ - **Auto-fix Suggestions (Experimental)** - Automatic fix capabilities for simple issues
15
+ - `--suggest-fixes` flag to show auto-fix suggestions in diff format
16
+ - `--fix` flag to apply auto-fixes interactively
17
+ - `--fix --force` to apply all fixes without confirmation
18
+ - Fixer for `.count` → `.size` transformation in iterations
19
+ - Fixer for inline `.pluck(:id)` → `.select(:id)` transformation
20
+
21
+ ### Note
22
+
23
+ Auto-fix is experimental. Not all issues are auto-fixable. Always review changes and run your test suite after applying fixes.
24
+
25
+ ## [0.6.0] - 2025-12-15
26
+
27
+ ### Added
28
+
29
+ - **Inline Suppression Comments** - RuboCop-style comment directives for suppressing false positives
30
+ - `# eager_eye:disable DetectorName` - Disable for single line (inline) or start block
31
+ - `# eager_eye:disable-next-line DetectorName` - Disable only the next line
32
+ - `# eager_eye:disable-file DetectorName` - Disable for entire file (must be in first 5 lines)
33
+ - `# eager_eye:enable DetectorName` - End a disable block
34
+ - Support for multiple detectors: `# eager_eye:disable LoopAssociation, CountInIteration`
35
+ - Support for reason comments: `# eager_eye:disable DetectorName -- reason here`
36
+ - `all` keyword to disable all detectors at once
37
+ - Both CamelCase (`LoopAssociation`) and snake_case (`loop_association`) detector names accepted
38
+
39
+ ### Changed
40
+
41
+ - Updated README with inline suppression documentation
42
+ - Added `CommentParser` module for parsing suppression directives
43
+
10
44
  ## [0.5.0] - 2025-12-15
11
45
 
12
46
  ### Added
data/README.md CHANGED
@@ -272,6 +272,92 @@ Post.where(user_id: User.active.select(:id))
272
272
  | `pluck` + `where` | 2 | ~80KB for IDs | ~45ms |
273
273
  | `select` subquery | 1 | None | ~20ms |
274
274
 
275
+ ## Inline Suppression
276
+
277
+ Suppress false positives using inline comments (RuboCop-style):
278
+
279
+ ```ruby
280
+ # Disable for single line
281
+ user.posts.count # eager_eye:disable CountInIteration
282
+
283
+ # Disable for next line
284
+ # eager_eye:disable-next-line LoopAssociation
285
+ @users.each { |u| u.profile }
286
+
287
+ # Disable block
288
+ # eager_eye:disable LoopAssociation, SerializerNesting
289
+ @users.each do |user|
290
+ user.posts.each { |p| p.author }
291
+ end
292
+ # eager_eye:enable LoopAssociation, SerializerNesting
293
+
294
+ # Disable entire file (must be in first 5 lines)
295
+ # eager_eye:disable-file CustomMethodQuery
296
+
297
+ # With reason
298
+ user.posts.count # eager_eye:disable CountInIteration -- using counter_cache
299
+
300
+ # Disable all detectors
301
+ # eager_eye:disable all
302
+ ```
303
+
304
+ ### Available Detector Names
305
+
306
+ Both CamelCase and snake_case formats are accepted:
307
+
308
+ | Detector | CamelCase | snake_case |
309
+ |----------|-----------|------------|
310
+ | Loop Association | `LoopAssociation` | `loop_association` |
311
+ | Serializer Nesting | `SerializerNesting` | `serializer_nesting` |
312
+ | Missing Counter Cache | `MissingCounterCache` | `missing_counter_cache` |
313
+ | Custom Method Query | `CustomMethodQuery` | `custom_method_query` |
314
+ | Count in Iteration | `CountInIteration` | `count_in_iteration` |
315
+ | Callback Query | `CallbackQuery` | `callback_query` |
316
+ | Pluck to Array | `PluckToArray` | `pluck_to_array` |
317
+ | All Detectors | `all` | `all` |
318
+
319
+ ## Auto-fix (Experimental)
320
+
321
+ EagerEye can automatically fix some simple issues:
322
+
323
+ ```bash
324
+ # Show fix suggestions
325
+ eager_eye --suggest-fixes
326
+
327
+ # Apply fixes interactively
328
+ eager_eye --fix
329
+
330
+ # Apply all fixes without confirmation
331
+ eager_eye --fix --force
332
+ ```
333
+
334
+ ### Currently Supported Auto-fixes
335
+
336
+ | Issue | Fix |
337
+ |-------|-----|
338
+ | `.count` in iteration | → `.size` |
339
+ | `.pluck(:id)` inline | → `.select(:id)` |
340
+
341
+ ### Example
342
+
343
+ ```
344
+ $ eager_eye --suggest-fixes
345
+
346
+ app/controllers/posts_controller.rb:
347
+ Line 15:
348
+ - user.posts.count
349
+ + user.posts.size
350
+
351
+ $ eager_eye --fix
352
+ app/controllers/posts_controller.rb:15
353
+ - user.posts.count
354
+ + user.posts.size
355
+ Apply this fix? [y/n/q] y
356
+ Applied
357
+ ```
358
+
359
+ > **Warning:** Auto-fix is experimental. Always review changes and run your test suite after applying fixes.
360
+
275
361
  ## Configuration
276
362
 
277
363
  ### Config File (.eager_eye.yml)
@@ -58,8 +58,16 @@ module EagerEye
58
58
  ast = parse_source(source)
59
59
  return unless ast
60
60
 
61
+ comment_parser = CommentParser.new(source)
62
+
61
63
  enabled_detectors.each do |detector|
62
64
  file_issues = detector.detect(ast, file_path)
65
+
66
+ # Filter suppressed issues
67
+ file_issues.reject! do |issue|
68
+ comment_parser.disabled_at?(issue.line_number, issue.detector)
69
+ end
70
+
63
71
  @issues.concat(file_issues)
64
72
  end
65
73
  rescue Errno::ENOENT, Errno::EACCES => e
@@ -0,0 +1,93 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EagerEye
4
+ class AutoFixer
5
+ def initialize(issues, interactive: true)
6
+ @issues = issues
7
+ @interactive = interactive
8
+ @files_cache = {}
9
+ end
10
+
11
+ def run
12
+ fixes = collect_fixes
13
+ return puts "No auto-fixable issues found." if fixes.empty?
14
+
15
+ if @interactive
16
+ apply_interactively(fixes)
17
+ else
18
+ apply_all(fixes)
19
+ end
20
+ end
21
+
22
+ def suggest
23
+ fixes = collect_fixes
24
+ return puts "No auto-fixable issues found." if fixes.empty?
25
+
26
+ fixes.group_by { |f| f[:file] }.each do |file, file_fixes|
27
+ puts "\n#{file}:"
28
+ file_fixes.each do |fix|
29
+ puts " Line #{fix[:line]}:"
30
+ puts " - #{fix[:original]}"
31
+ puts " + #{fix[:fixed]}"
32
+ end
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def collect_fixes
39
+ @issues.filter_map do |issue|
40
+ source = read_file(issue.file_path)
41
+ fixer = FixerRegistry.fixer_for(issue, source)
42
+ next unless fixer&.fixable?
43
+
44
+ fixer.diff
45
+ end.compact
46
+ end
47
+
48
+ def read_file(path)
49
+ @files_cache[path] ||= File.read(path)
50
+ end
51
+
52
+ def apply_interactively(fixes)
53
+ fixes.each do |fix|
54
+ puts "\n#{fix[:file]}:#{fix[:line]}"
55
+ puts " - #{fix[:original]}"
56
+ puts " + #{fix[:fixed]}"
57
+ print "Apply this fix? [y/n/q] "
58
+
59
+ response = $stdin.gets&.chomp&.downcase
60
+ case response
61
+ when "y"
62
+ apply_fix(fix)
63
+ puts " Applied"
64
+ when "q"
65
+ puts "Aborted."
66
+ break
67
+ else
68
+ puts " Skipped"
69
+ end
70
+ end
71
+ end
72
+
73
+ def apply_all(fixes)
74
+ # Group by file to minimize file operations
75
+ fixes.group_by { |f| f[:file] }.each do |file, file_fixes|
76
+ lines = File.readlines(file)
77
+
78
+ file_fixes.sort_by { |f| -f[:line] }.each do |fix|
79
+ lines[fix[:line] - 1] = "#{fix[:fixed]}\n"
80
+ end
81
+
82
+ File.write(file, lines.join)
83
+ puts "Fixed #{file_fixes.size} issue(s) in #{file}"
84
+ end
85
+ end
86
+
87
+ def apply_fix(fix)
88
+ lines = File.readlines(fix[:file])
89
+ lines[fix[:line] - 1] = "#{fix[:fixed]}\n"
90
+ File.write(fix[:file], lines.join)
91
+ end
92
+ end
93
+ end
data/lib/eager_eye/cli.rb CHANGED
@@ -16,6 +16,19 @@ module EagerEye
16
16
  return 0 if options[:help] || options[:version]
17
17
 
18
18
  issues = analyze
19
+
20
+ if options[:suggest_fixes]
21
+ fixer = AutoFixer.new(issues)
22
+ fixer.suggest
23
+ return 0
24
+ end
25
+
26
+ if options[:fix]
27
+ fixer = AutoFixer.new(issues, interactive: !options[:force])
28
+ fixer.run
29
+ return 0
30
+ end
31
+
19
32
  output_report(issues)
20
33
  exit_code(issues)
21
34
  end
@@ -31,7 +44,10 @@ module EagerEye
31
44
  fail_on_issues: true,
32
45
  colorize: $stdout.tty?,
33
46
  help: false,
34
- version: false
47
+ version: false,
48
+ suggest_fixes: false,
49
+ fix: false,
50
+ force: false
35
51
  }
36
52
  end
37
53
 
@@ -50,35 +66,66 @@ module EagerEye
50
66
  opts.separator ""
51
67
  opts.separator "Options:"
52
68
 
53
- opts.on("-f", "--format FORMAT", %i[console json], "Output format (console, json)") do |format|
54
- options[:format] = format
55
- end
69
+ add_output_options(opts)
70
+ add_filter_options(opts)
71
+ add_behavior_options(opts)
72
+ add_info_options(opts)
73
+ add_fix_options(opts)
74
+ end
75
+ end
56
76
 
57
- opts.on("-e", "--exclude PATTERN", "Exclude files matching pattern (can be used multiple times)") do |pattern|
58
- options[:exclude] << pattern
59
- end
77
+ def add_output_options(opts)
78
+ opts.on("-f", "--format FORMAT", %i[console json], "Output format (console, json)") do |format|
79
+ options[:format] = format
80
+ end
60
81
 
61
- opts.on("-o", "--only DETECTORS", "Run only specified detectors (comma-separated)") do |detectors|
62
- options[:only] = detectors.split(",").map(&:strip).map(&:to_sym)
63
- end
82
+ opts.on("--no-color", "Disable colored output") do
83
+ options[:colorize] = false
84
+ end
85
+ end
64
86
 
65
- opts.on("--no-fail", "Exit with 0 even if issues found") do
66
- options[:fail_on_issues] = false
67
- end
87
+ def add_filter_options(opts)
88
+ opts.on("-e", "--exclude PATTERN", "Exclude files matching pattern") do |pattern|
89
+ options[:exclude] << pattern
90
+ end
68
91
 
69
- opts.on("--no-color", "Disable colored output") do
70
- options[:colorize] = false
71
- end
92
+ opts.on("-o", "--only DETECTORS", "Run only specified detectors (comma-separated)") do |detectors|
93
+ options[:only] = detectors.split(",").map(&:strip).map(&:to_sym)
94
+ end
95
+ end
72
96
 
73
- opts.on("-v", "--version", "Show version") do
74
- puts "EagerEye #{EagerEye::VERSION}"
75
- options[:version] = true
76
- end
97
+ def add_behavior_options(opts)
98
+ opts.on("--no-fail", "Exit with 0 even if issues found") do
99
+ options[:fail_on_issues] = false
100
+ end
101
+ end
102
+
103
+ def add_info_options(opts)
104
+ opts.on("-v", "--version", "Show version") do
105
+ puts "EagerEye #{EagerEye::VERSION}"
106
+ options[:version] = true
107
+ end
108
+
109
+ opts.on("-h", "--help", "Show this help message") do
110
+ puts opts
111
+ options[:help] = true
112
+ end
113
+ end
114
+
115
+ def add_fix_options(opts)
116
+ opts.separator ""
117
+ opts.separator "Auto-fix options (experimental):"
118
+
119
+ opts.on("--suggest-fixes", "Show auto-fix suggestions") do
120
+ options[:suggest_fixes] = true
121
+ end
122
+
123
+ opts.on("--fix", "Apply auto-fixes interactively") do
124
+ options[:fix] = true
125
+ end
77
126
 
78
- opts.on("-h", "--help", "Show this help message") do
79
- puts opts
80
- options[:help] = true
81
- end
127
+ opts.on("--force", "Apply fixes without confirmation (use with --fix)") do
128
+ options[:force] = true
82
129
  end
83
130
  end
84
131
 
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EagerEye
4
+ class CommentParser
5
+ DISABLE_PATTERN = /eager_eye:disable(?:-next-line|-file)?\s+(.+?)(?:\s+--|$)/i
6
+ ENABLE_PATTERN = /eager_eye:enable\s+(.+?)(?:\s+--|$)/i
7
+ INLINE_DISABLE_PATTERN = /eager_eye:disable\s+(.+?)(?:\s+--|$)/i
8
+ FILE_DISABLE_PATTERN = /eager_eye:disable-file\s+(.+?)(?:\s+--|$)/i
9
+ NEXT_LINE_PATTERN = /eager_eye:disable-next-line\s+(.+?)(?:\s+--|$)/i
10
+ BLOCK_DISABLE_PATTERN = /eager_eye:disable\s+(.+?)(?:\s+--|$)/i
11
+
12
+ def initialize(source_code)
13
+ @source_code = source_code
14
+ @lines = source_code.lines
15
+ @disabled_ranges = Hash.new { |h, k| h[k] = [] }
16
+ @file_disabled = Set.new
17
+ @current_disabled = Set.new
18
+ parse_comments
19
+ end
20
+
21
+ def disabled_at?(line_number, detector_name)
22
+ return true if @file_disabled.include?(detector_name.to_s)
23
+ return true if @file_disabled.include?("all")
24
+
25
+ detector = detector_name.to_s
26
+ @disabled_ranges[detector].any? { |range| range.cover?(line_number) } ||
27
+ @disabled_ranges["all"].any? { |range| range.cover?(line_number) }
28
+ end
29
+
30
+ private
31
+
32
+ def parse_comments
33
+ @lines.each_with_index do |line, index|
34
+ line_num = index + 1
35
+ process_line(line, line_num)
36
+ end
37
+
38
+ close_unclosed_blocks
39
+ end
40
+
41
+ def process_line(line, line_num)
42
+ directive = detect_directive(line, line_num)
43
+ apply_directive(directive, line_num) if directive
44
+ end
45
+
46
+ def detect_directive(line, line_num)
47
+ detect_file_directive(line, line_num) ||
48
+ detect_next_line_directive(line) ||
49
+ detect_block_directive(line) ||
50
+ detect_enable_directive(line) ||
51
+ detect_inline_directive(line)
52
+ end
53
+
54
+ def detect_file_directive(line, line_num)
55
+ return unless line_num <= 5 && line =~ FILE_DISABLE_PATTERN
56
+
57
+ { type: :file, detectors: parse_detector_names(::Regexp.last_match(1)) }
58
+ end
59
+
60
+ def detect_next_line_directive(line)
61
+ return unless line =~ NEXT_LINE_PATTERN
62
+
63
+ { type: :next_line, detectors: parse_detector_names(::Regexp.last_match(1)) }
64
+ end
65
+
66
+ def detect_block_directive(line)
67
+ return unless line =~ BLOCK_DISABLE_PATTERN && !inline_disable?(line)
68
+
69
+ { type: :block_start, detectors: parse_detector_names(::Regexp.last_match(1)) }
70
+ end
71
+
72
+ def detect_enable_directive(line)
73
+ return unless line =~ ENABLE_PATTERN
74
+
75
+ { type: :block_end, detectors: parse_detector_names(::Regexp.last_match(1)) }
76
+ end
77
+
78
+ def detect_inline_directive(line)
79
+ return unless line =~ INLINE_DISABLE_PATTERN
80
+
81
+ { type: :inline, detectors: parse_detector_names(::Regexp.last_match(1)) }
82
+ end
83
+
84
+ def apply_directive(directive, line_num)
85
+ case directive[:type]
86
+ when :file then apply_file_disable(directive[:detectors])
87
+ when :next_line then apply_next_line_disable(directive[:detectors], line_num)
88
+ when :block_start then apply_block_start(directive[:detectors], line_num)
89
+ when :block_end then apply_block_end(directive[:detectors], line_num)
90
+ when :inline then apply_inline_disable(directive[:detectors], line_num)
91
+ end
92
+ end
93
+
94
+ def apply_file_disable(detectors)
95
+ @file_disabled.merge(detectors)
96
+ end
97
+
98
+ def apply_next_line_disable(detectors, line_num)
99
+ next_line = line_num + 1
100
+ detectors.each { |d| @disabled_ranges[d] << (next_line..next_line) }
101
+ end
102
+
103
+ def apply_block_start(detectors, line_num)
104
+ detectors.each { |d| @current_disabled << { detector: d, start: line_num } }
105
+ end
106
+
107
+ def apply_block_end(detectors, line_num)
108
+ detectors.each do |d|
109
+ entry = @current_disabled.find { |e| e[:detector] == d }
110
+ next unless entry
111
+
112
+ @disabled_ranges[d] << (entry[:start]..line_num)
113
+ @current_disabled.delete(entry)
114
+ end
115
+ end
116
+
117
+ def apply_inline_disable(detectors, line_num)
118
+ detectors.each { |d| @disabled_ranges[d] << (line_num..line_num) }
119
+ end
120
+
121
+ def close_unclosed_blocks
122
+ @current_disabled.each do |entry|
123
+ @disabled_ranges[entry[:detector]] << (entry[:start]..@lines.size)
124
+ end
125
+ end
126
+
127
+ def inline_disable?(line)
128
+ code_part = line.split("#").first
129
+ code_part && !code_part.strip.empty?
130
+ end
131
+
132
+ def parse_detector_names(str)
133
+ str.split(/[,\s]+/).map(&:strip).reject(&:empty?).map do |name|
134
+ normalize_detector_name(name)
135
+ end
136
+ end
137
+
138
+ def normalize_detector_name(name)
139
+ name.gsub(/([A-Z])/) { "_#{::Regexp.last_match(1).downcase}" }
140
+ .sub(/^_/, "")
141
+ .downcase
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EagerEye
4
+ class FixerRegistry
5
+ FIXERS = {
6
+ count_in_iteration: Fixers::CountToSize,
7
+ pluck_to_array: Fixers::PluckToSelect
8
+ }.freeze
9
+
10
+ def self.fixer_for(issue, source_code)
11
+ fixer_class = FIXERS[issue.detector]
12
+ return nil unless fixer_class
13
+
14
+ fixer_class.new(issue, source_code)
15
+ end
16
+
17
+ def self.fixable?(issue, source_code)
18
+ fixer = fixer_for(issue, source_code)
19
+ fixer&.fixable? || false
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EagerEye
4
+ module Fixers
5
+ class Base
6
+ attr_reader :issue, :source_lines
7
+
8
+ def initialize(issue, source_code)
9
+ @issue = issue
10
+ @source_code = source_code
11
+ @source_lines = source_code.lines
12
+ end
13
+
14
+ def fixable?
15
+ false
16
+ end
17
+
18
+ def fix
19
+ raise NotImplementedError
20
+ end
21
+
22
+ def diff
23
+ return nil unless fixable?
24
+
25
+ original_line = @source_lines[issue.line_number - 1]
26
+ fixed_line = fixed_content
27
+ return nil if original_line == fixed_line
28
+
29
+ {
30
+ file: issue.file_path,
31
+ line: issue.line_number,
32
+ original: original_line.chomp,
33
+ fixed: fixed_line.chomp
34
+ }
35
+ end
36
+
37
+ protected
38
+
39
+ def fixed_content
40
+ raise NotImplementedError
41
+ end
42
+
43
+ def line_content
44
+ @source_lines[issue.line_number - 1]
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EagerEye
4
+ module Fixers
5
+ class CountToSize < Base
6
+ def fixable?
7
+ issue.detector == :count_in_iteration &&
8
+ line_content&.include?(".count")
9
+ end
10
+
11
+ protected
12
+
13
+ def fixed_content
14
+ line_content.gsub(/\.count\b/, ".size")
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EagerEye
4
+ module Fixers
5
+ class PluckToSelect < Base
6
+ # This fixer only works for single-line pluck + where patterns
7
+ # Two-line patterns are too complex to fix automatically
8
+
9
+ def fixable?
10
+ issue.detector == :pluck_to_array &&
11
+ single_line_pattern?
12
+ end
13
+
14
+ protected
15
+
16
+ def fixed_content
17
+ # Model.where(col: OtherModel.pluck(:id)) -> Model.where(col: OtherModel.select(:id))
18
+ line_content.gsub(/\.pluck\((:\w+)\)/, '.select(\1)')
19
+ end
20
+
21
+ private
22
+
23
+ def single_line_pattern?
24
+ return false unless line_content
25
+
26
+ line_content.include?(".pluck(") && line_content.include?(".where(")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EagerEye
4
- VERSION = "0.5.0"
4
+ VERSION = "0.7.0"
5
5
  end
data/lib/eager_eye.rb CHANGED
@@ -11,7 +11,13 @@ require_relative "eager_eye/detectors/custom_method_query"
11
11
  require_relative "eager_eye/detectors/count_in_iteration"
12
12
  require_relative "eager_eye/detectors/callback_query"
13
13
  require_relative "eager_eye/detectors/pluck_to_array"
14
+ require_relative "eager_eye/comment_parser"
14
15
  require_relative "eager_eye/analyzer"
16
+ require_relative "eager_eye/fixers/base"
17
+ require_relative "eager_eye/fixers/count_to_size"
18
+ require_relative "eager_eye/fixers/pluck_to_select"
19
+ require_relative "eager_eye/fixer_registry"
20
+ require_relative "eager_eye/auto_fixer"
15
21
  require_relative "eager_eye/reporters/base"
16
22
  require_relative "eager_eye/reporters/console"
17
23
  require_relative "eager_eye/reporters/json"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eager_eye
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - hamzagedikkaya
@@ -58,7 +58,9 @@ files:
58
58
  - exe/eager_eye
59
59
  - lib/eager_eye.rb
60
60
  - lib/eager_eye/analyzer.rb
61
+ - lib/eager_eye/auto_fixer.rb
61
62
  - lib/eager_eye/cli.rb
63
+ - lib/eager_eye/comment_parser.rb
62
64
  - lib/eager_eye/configuration.rb
63
65
  - lib/eager_eye/detectors/base.rb
64
66
  - lib/eager_eye/detectors/callback_query.rb
@@ -68,6 +70,10 @@ files:
68
70
  - lib/eager_eye/detectors/missing_counter_cache.rb
69
71
  - lib/eager_eye/detectors/pluck_to_array.rb
70
72
  - lib/eager_eye/detectors/serializer_nesting.rb
73
+ - lib/eager_eye/fixer_registry.rb
74
+ - lib/eager_eye/fixers/base.rb
75
+ - lib/eager_eye/fixers/count_to_size.rb
76
+ - lib/eager_eye/fixers/pluck_to_select.rb
71
77
  - lib/eager_eye/generators/install_generator.rb
72
78
  - lib/eager_eye/issue.rb
73
79
  - lib/eager_eye/railtie.rb