eager_eye 1.0.8 → 1.0.9
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 +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +41 -1
- data/lib/eager_eye/comment_parser.rb +38 -20
- data/lib/eager_eye/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 44b2f46a77bcc0bb742c6d169cebb7be6b9a8b722b64044b153397fcf7686872
|
|
4
|
+
data.tar.gz: 25a589c3401fe25248b6fe429e0255e5d2d9ada9b50bd7bbf467ada161e0ca95
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2ea1baa8c98a5362527e991d3712c0a3c0d821307a99e1b8b1a9a0ac76fbff5d4adcf4f4cd512990971956fcc3bd61ef97fb8c047d0b44609e4bd55ca385bfb4
|
|
7
|
+
data.tar.gz: 8d1590b243420e3ea3534290f15725a0aa70f3ea537aa7da05cd4648521fe284718965d27e4b00ac77ea277d4ca400107e49a18a7759780dd532c560ef1b91b3
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.0.9] - 2025-12-26
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Inline Suppression Comments** - Suppress specific warnings with RuboCop-style inline comments
|
|
15
|
+
- `# eager_eye:disable-next-line` - Suppress next line
|
|
16
|
+
- `# eager_eye:disable CallbackQuery` - Suppress specific detector inline
|
|
17
|
+
- `# eager_eye:disable-block` / `# eager_eye:enable-block` - Suppress block of code
|
|
18
|
+
- `# eager_eye:disable-file DetectorName` - Suppress entire file
|
|
19
|
+
- Supports both CamelCase and snake_case detector names
|
|
20
|
+
- Can disable all detectors with `all` keyword
|
|
21
|
+
|
|
22
|
+
### Improved
|
|
23
|
+
|
|
24
|
+
- Enhanced README with table of contents and better organization
|
|
25
|
+
- Improved code readability and documentation structure
|
|
26
|
+
- Updated version badge to v1.0.9
|
|
27
|
+
|
|
10
28
|
## [1.0.8] - 2025-12-25
|
|
11
29
|
|
|
12
30
|
### Added
|
data/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://github.com/hamzagedikkaya/eager_eye/actions/workflows/main.yml"><img src="https://github.com/hamzagedikkaya/eager_eye/actions/workflows/main.yml/badge.svg" alt="CI"></a>
|
|
13
|
-
<a href="https://rubygems.org/gems/eager_eye"><img src="https://img.shields.io/badge/gem-v1.0.
|
|
13
|
+
<a href="https://rubygems.org/gems/eager_eye"><img src="https://img.shields.io/badge/gem-v1.0.9-red.svg" alt="Gem Version"></a>
|
|
14
14
|
<a href="https://github.com/hamzagedikkaya/eager_eye"><img src="https://img.shields.io/badge/coverage-95%25-brightgreen.svg" alt="Coverage"></a>
|
|
15
15
|
<a href="https://www.ruby-lang.org/"><img src="https://img.shields.io/badge/ruby-%3E%3D%203.1-ruby.svg" alt="Ruby"></a>
|
|
16
16
|
<a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT"></a>
|
|
@@ -23,6 +23,24 @@
|
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
+
## Table of Contents
|
|
27
|
+
- [Why EagerEye?](#why-eagereye)
|
|
28
|
+
- [Features](#features)
|
|
29
|
+
- [Installation](#installation)
|
|
30
|
+
- [Quick Start](#quick-start)
|
|
31
|
+
- [Detected Issues](#detected-issues)
|
|
32
|
+
- [Inline Suppression](#inline-suppression)
|
|
33
|
+
- [Auto-fix](#auto-fix-experimental)
|
|
34
|
+
- [RSpec Integration](#rspec-integration)
|
|
35
|
+
- [Configuration](#configuration)
|
|
36
|
+
- [CI Integration](#ci-integration)
|
|
37
|
+
- [CLI Reference](#cli-reference)
|
|
38
|
+
- [Output Formats](#output-formats)
|
|
39
|
+
- [Limitations](#limitations)
|
|
40
|
+
- [VS Code Extension](#vs-code-extension)
|
|
41
|
+
- [Development](#development)
|
|
42
|
+
- [Contributing](#contributing)
|
|
43
|
+
|
|
26
44
|
## Why EagerEye?
|
|
27
45
|
|
|
28
46
|
Unlike runtime tools like Bullet, EagerEye:
|
|
@@ -41,6 +59,28 @@ Unlike runtime tools like Bullet, EagerEye:
|
|
|
41
59
|
| CI integration | Native | Requires tests |
|
|
42
60
|
| False positive rate | Higher | Lower |
|
|
43
61
|
|
|
62
|
+
## Features
|
|
63
|
+
|
|
64
|
+
✨ **Detects 7 types of N+1 problems:**
|
|
65
|
+
- Loop associations (queries in iterations)
|
|
66
|
+
- Serializer nesting issues
|
|
67
|
+
- Missing counter caches
|
|
68
|
+
- Custom method queries (invisible to Bullet)
|
|
69
|
+
- Count in iteration patterns
|
|
70
|
+
- Callback query N+1s
|
|
71
|
+
- Pluck to array misuse
|
|
72
|
+
|
|
73
|
+
🔧 **Developer-friendly:**
|
|
74
|
+
- Inline suppression (like RuboCop)
|
|
75
|
+
- Auto-fix support (experimental)
|
|
76
|
+
- JSON/Console output formats
|
|
77
|
+
- RSpec integration
|
|
78
|
+
|
|
79
|
+
🚀 **CI-ready:**
|
|
80
|
+
- No test suite required
|
|
81
|
+
- GitHub Actions examples included
|
|
82
|
+
- Severity levels and filtering
|
|
83
|
+
|
|
44
84
|
## Installation
|
|
45
85
|
|
|
46
86
|
Add to your Gemfile:
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
module EagerEye
|
|
4
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
5
|
FILE_DISABLE_PATTERN = /eager_eye:disable-file\s+(.+?)(?:\s+--|$)/i
|
|
9
|
-
NEXT_LINE_PATTERN = /eager_eye:disable-next-line
|
|
10
|
-
|
|
6
|
+
NEXT_LINE_PATTERN = /eager_eye:disable-next-line(?:\s+(.+?))?(?:\s+--|$)/i
|
|
7
|
+
BLOCK_START_PATTERN = /eager_eye:disable-block(?:\s+(.+?))?(?:\s+--|$)/i
|
|
8
|
+
BLOCK_END_PATTERN = /eager_eye:enable-block(?:\s+(.+?))?(?:\s+--|$)/i
|
|
9
|
+
INLINE_DISABLE_PATTERN = /eager_eye:disable\s+(.+?)(?:\s+--|$)/i
|
|
10
|
+
ENABLE_PATTERN = /eager_eye:enable(?:\s+(.+?))?(?:\s+--|$)/i
|
|
11
11
|
|
|
12
12
|
def initialize(source_code)
|
|
13
13
|
@source_code = source_code.encode("UTF-8", invalid: :replace, undef: :replace)
|
|
@@ -46,39 +46,50 @@ module EagerEye
|
|
|
46
46
|
def detect_directive(line, line_num)
|
|
47
47
|
detect_file_directive(line, line_num) ||
|
|
48
48
|
detect_next_line_directive(line) ||
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
detect_inline_directive(line)
|
|
49
|
+
detect_block_end_directive(line) ||
|
|
50
|
+
detect_block_or_inline_directive(line)
|
|
52
51
|
end
|
|
53
52
|
|
|
54
53
|
def detect_file_directive(line, line_num)
|
|
55
54
|
return unless line_num <= 5 && line =~ FILE_DISABLE_PATTERN
|
|
56
55
|
|
|
57
|
-
|
|
56
|
+
detectors = parse_detector_names(::Regexp.last_match(1) || "all")
|
|
57
|
+
{ type: :file, detectors: detectors }
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def detect_next_line_directive(line)
|
|
61
61
|
return unless line =~ NEXT_LINE_PATTERN
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
detectors = parse_detector_names(::Regexp.last_match(1) || "all")
|
|
64
|
+
{ type: :next_line, detectors: detectors }
|
|
64
65
|
end
|
|
65
66
|
|
|
66
|
-
def
|
|
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)
|
|
67
|
+
def detect_block_end_directive(line)
|
|
73
68
|
return unless line =~ ENABLE_PATTERN
|
|
74
69
|
|
|
75
|
-
|
|
70
|
+
detectors = parse_detector_names(::Regexp.last_match(1) || "all")
|
|
71
|
+
{ type: :block_end, detectors: detectors }
|
|
76
72
|
end
|
|
77
73
|
|
|
78
|
-
def
|
|
74
|
+
def detect_block_or_inline_directive(line)
|
|
75
|
+
# Check for eager_eye:disable-block explicitly
|
|
76
|
+
if line =~ BLOCK_START_PATTERN && !code_before_comment?(line)
|
|
77
|
+
detectors = parse_detector_names(::Regexp.last_match(1) || "all")
|
|
78
|
+
return { type: :block_start, detectors: detectors }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Check for eager_eye:disable (either inline or block start)
|
|
79
82
|
return unless line =~ INLINE_DISABLE_PATTERN
|
|
80
83
|
|
|
81
|
-
|
|
84
|
+
detectors = parse_detector_names(::Regexp.last_match(1) || "all")
|
|
85
|
+
|
|
86
|
+
# If there's code before the comment, it's inline (same line only)
|
|
87
|
+
if code_before_comment?(line)
|
|
88
|
+
{ type: :inline, detectors: detectors }
|
|
89
|
+
else
|
|
90
|
+
# No code before comment, so it's a block start
|
|
91
|
+
{ type: :block_start, detectors: detectors }
|
|
92
|
+
end
|
|
82
93
|
end
|
|
83
94
|
|
|
84
95
|
def apply_directive(directive, line_num)
|
|
@@ -129,7 +140,14 @@ module EagerEye
|
|
|
129
140
|
code_part && !code_part.strip.empty?
|
|
130
141
|
end
|
|
131
142
|
|
|
143
|
+
def code_before_comment?(line)
|
|
144
|
+
code_part = line.split("#").first
|
|
145
|
+
code_part && !code_part.strip.empty?
|
|
146
|
+
end
|
|
147
|
+
|
|
132
148
|
def parse_detector_names(str)
|
|
149
|
+
return ["all"] if str.nil? || str.strip.empty?
|
|
150
|
+
|
|
133
151
|
str.split(/[,\s]+/).map(&:strip).reject(&:empty?).map do |name|
|
|
134
152
|
normalize_detector_name(name)
|
|
135
153
|
end
|
data/lib/eager_eye/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: eager_eye
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.0.
|
|
4
|
+
version: 1.0.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- hamzagedikkaya
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-12-
|
|
11
|
+
date: 2025-12-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: ast
|