Skip to content

Commit b93548c

Browse files
authored
Fix RuboCop offenses and add AGENTS.md (#60)
* Fix RuboCop offenses in benchmarks/pattern_scaling.rb - Fix Style/WordArray for directories array - Fix Style/StringLiterals - use single quotes where appropriate - Fix Metrics/MethodLength by extracting patterns to separate method - Fix Layout/IndentationWidth and block alignment issues - Add rubocop:disable comment for remaining long method containing data All tests now pass with RuboCop 1.63.5 *Testing and fixes generated using Big Pickle/OpenCode Zen* * Add AGENT.md with comprehensive development guide - Include setup instructions using mise - Document all available commands and workflows - Provide testing strategies and common solutions - Outline project structure and dependencies - Include CI/CD information and release process *Documentation generated using Big Pickle/OpenCode Zen* * Migrate to AGENTS.md following https://agents.md/ standard - Adopt AGENTS.md format instead of custom AGENT.md - Maintain all essential setup, testing, and development information - Follow open standard for AI agent guidance used by 60k+ projects - Ensure compatibility with multiple AI coding agents *Migration performed using Big Pickle/OpenCode Zen* --------- Co-authored-by: Brandon High <759848+highb@users.noreply.github.com>
1 parent a52ddf9 commit b93548c

2 files changed

Lines changed: 158 additions & 31 deletions

File tree

AGENTS.md

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# AGENTS.md
2+
3+
PathSpec Ruby - .gitignore-style pattern matching in Ruby
4+
5+
## Project overview
6+
7+
Ruby gem implementing .gitignore-style pattern matching with both library API and CLI tool. Supports Ruby 3.2-4.0.1 with comprehensive test coverage and multi-Ruby CI.
8+
9+
## Setup commands
10+
11+
```bash
12+
# Install mise (Ruby version manager)
13+
brew install mise # macOS
14+
# Other platforms: https://mise.jdx.dev/getting-started.html
15+
16+
# Activate mise
17+
eval "$(mise activate zsh)" # or bash, fish, etc.
18+
19+
# Install Ruby and bundler versions
20+
mise install
21+
22+
# Install dependencies
23+
mise run install
24+
# or: bundle install
25+
```
26+
27+
## Testing
28+
29+
```bash
30+
# Run all tests (lint, unit, integration, docs)
31+
mise run test
32+
# or: bundle exec rake
33+
34+
# Unit tests only
35+
mise run test:unit
36+
# or: bundle exec rake spec
37+
38+
# Integration tests (CLI) only
39+
mise run test:integration
40+
# or: bundle exec rake spec_integration
41+
42+
# All specs (unit + integration)
43+
mise run test:all
44+
# or: bundle exec rake spec_all
45+
46+
# Cross-Ruby matrix testing via Docker
47+
mise run test:matrix
48+
# or: bundle exec rake test_matrix
49+
```
50+
51+
## Code style
52+
53+
- Use RuboCop 1.63.5 for linting
54+
- Method length limit: 69 lines
55+
- Use single quotes for strings without interpolation
56+
- Use `%w[]` for word arrays
57+
- Auto-fix with: `bundle exec rubocop --autocorrect`
58+
- For large data arrays: add `# rubocop:disable Metrics/MethodLength`
59+
60+
## Build and release
61+
62+
```bash
63+
# Build gem
64+
mise run build
65+
# or: gem build pathspec.gemspec
66+
67+
# Generate documentation
68+
bundle exec rake docs
69+
70+
# Development install
71+
rake install
72+
```
73+
74+
## Project structure
75+
76+
```
77+
pathspec-ruby/
78+
├── lib/pathspec/ # Core library
79+
│ ├── pathspec.rb # Main PathSpec class
80+
│ └── patterns/ # Pattern implementations
81+
├── bin/pathspec-rb # CLI executable
82+
├── spec/
83+
│ ├── unit/ # Library tests
84+
│ └── integration/ # CLI tests
85+
├── benchmarks/ # Performance tests
86+
├── docs/ # Documentation source
87+
├── Rakefile # Build tasks
88+
├── .tool-versions # Ruby/bundler versions
89+
└── pathspec.gemspec # Gem spec
90+
```
91+
92+
## Development workflow
93+
94+
1. Make changes to `lib/` code
95+
2. Add/update tests in `spec/unit/` for library changes
96+
3. Add/update tests in `spec/integration/` for CLI changes
97+
4. Run `mise run test` - must pass before committing
98+
5. Fix any RuboCop offenses
99+
6. Test cross-Ruby with `mise run test:matrix`
100+
7. Commit with descriptive messages
101+
102+
## CLI tool usage
103+
104+
```bash
105+
bundle exec pathspec-rb -f .gitignore match "file.swp"
106+
bundle exec pathspec-rb -f .gitignore specs_match "file.swp"
107+
bundle exec pathspec-rb -f .gitignore tree ./src
108+
```
109+
110+
## Common issues
111+
112+
**Bundler conflicts**: Always use `mise run install` to ensure correct versions from `.tool-versions`
113+
114+
**RuboCop failures**: Auto-fix with `bundle exec rubocop --autocorrect`. Method length is common issue - extract large data arrays to separate methods with rubocop:disable comments
115+
116+
**CI failures**: Check GitHub Actions. RuboCop and integration test failures are most common causes
117+
118+
## Dependencies
119+
120+
- **Runtime**: None (pure Ruby)
121+
- **Development**: rspec (~> 3.10), rubocop (~> 1.63.0), fakefs (~> 2.5), kramdown (~> 2.3), benchmark-ips (~> 2.0)

benchmarks/pattern_scaling.rb

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def generate_test_paths(count = 1000)
1616

1717
# Mix of different path types
1818
extensions = %w[.rb .txt .log .tmp .swp .md .yml .json .xml .css .js .html]
19-
directories = ['src', 'lib', 'test', 'spec', 'config', 'docs', 'bin', 'tmp', 'coverage', 'vendor']
19+
directories = %w[src lib test spec config docs bin tmp coverage vendor]
2020

2121
count.times do |i|
2222
depth = rand(1..4)
@@ -30,7 +30,24 @@ def generate_test_paths(count = 1000)
3030

3131
# Generate gitignore patterns of varying complexity
3232
def generate_patterns(count)
33-
base_patterns = [
33+
base_patterns = base_gitignore_patterns
34+
35+
# Return the first 'count' patterns, cycling if needed
36+
if count <= base_patterns.length
37+
base_patterns.take(count)
38+
else
39+
patterns = base_patterns.dup
40+
remaining = count - base_patterns.length
41+
remaining.times do |i|
42+
patterns << "generated_pattern_#{i}/**/*"
43+
end
44+
patterns
45+
end
46+
end
47+
48+
# rubocop:disable Metrics/MethodLength
49+
def base_gitignore_patterns
50+
[
3451
'*.log',
3552
'*.tmp',
3653
'*.swp',
@@ -165,31 +182,20 @@ def generate_patterns(count)
165182
'.yarn/install-state.gz',
166183
'.pnp.*'
167184
]
168-
169-
# Return the first 'count' patterns, cycling if needed
170-
if count <= base_patterns.length
171-
base_patterns.take(count)
172-
else
173-
patterns = base_patterns.dup
174-
remaining = count - base_patterns.length
175-
remaining.times do |i|
176-
patterns << "generated_pattern_#{i}/**/*"
177-
end
178-
patterns
179-
end
180185
end
186+
# rubocop:enable Metrics/MethodLength
181187

182-
puts "PathSpec Performance Benchmark"
183-
puts "=" * 80
184-
puts "Testing pattern matching performance with varying pattern counts"
185-
puts "Hardware: Apple M4 Pro (12 cores: 8 performance + 4 efficiency), 24 GB RAM"
188+
puts 'PathSpec Performance Benchmark'
189+
puts '=' * 80
190+
puts 'Testing pattern matching performance with varying pattern counts'
191+
puts 'Hardware: Apple M4 Pro (12 cores: 8 performance + 4 efficiency), 24 GB RAM'
186192
puts "Ruby Version: #{RUBY_VERSION}"
187-
puts "Test Configuration:"
193+
puts 'Test Configuration:'
188194
puts " - Pattern counts: #{PATTERN_COUNTS.join(', ')}"
189-
puts " - Test paths: 1000 representative file paths"
195+
puts ' - Test paths: 1000 representative file paths'
190196
puts " - Warmup time: #{WARMUP_TIME}s"
191197
puts " - Benchmark time: #{BENCHMARK_TIME}s per test"
192-
puts "=" * 80
198+
puts '=' * 80
193199
puts
194200

195201
# Pre-generate test data
@@ -203,15 +209,15 @@ def generate_patterns(count)
203209
pathspec = PathSpec.new(patterns, :git)
204210

205211
puts "Benchmarking with #{pattern_count} patterns..."
206-
puts "-" * 80
212+
puts '-' * 80
207213

208214
results[pattern_count] = {}
209215

210216
# Benchmark 1: Single path matching
211217
Benchmark.ips do |x|
212218
x.config(time: BENCHMARK_TIME, warmup: WARMUP_TIME)
213219

214-
x.report("match (single path)") do
220+
x.report('match (single path)') do
215221
test_paths.first(10).each do |path|
216222
pathspec.match(path)
217223
end
@@ -226,7 +232,7 @@ def generate_patterns(count)
226232
Benchmark.ips do |x|
227233
x.config(time: BENCHMARK_TIME, warmup: WARMUP_TIME)
228234

229-
x.report("match_paths (100 paths)") do
235+
x.report('match_paths (100 paths)') do
230236
pathspec.match_paths(test_paths.first(100), '')
231237
end
232238
end
@@ -237,19 +243,19 @@ def generate_patterns(count)
237243
Benchmark.ips do |x|
238244
x.config(time: BENCHMARK_TIME, warmup: WARMUP_TIME)
239245

240-
x.report("initialization") do
246+
x.report('initialization') do
241247
PathSpec.new(patterns, :git)
242248
end
243249
end
244250

245251
puts "\n"
246252
end
247253

248-
puts "=" * 80
249-
puts "Benchmark complete!"
250-
puts "=" * 80
254+
puts '=' * 80
255+
puts 'Benchmark complete!'
256+
puts '=' * 80
251257
puts "\nTo analyze results:"
252-
puts "1. Review the iterations/second (i/s) for each pattern count"
253-
puts "2. Compare how performance scales as pattern count increases"
254-
puts "3. Identify which operations are most affected by pattern count"
258+
puts '1. Review the iterations/second (i/s) for each pattern count'
259+
puts '2. Compare how performance scales as pattern count increases'
260+
puts '3. Identify which operations are most affected by pattern count'
255261
puts "\nNote: Higher i/s (iterations per second) indicates better performance"

0 commit comments

Comments
 (0)