coverband 6.1.4 → 6.1.8
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/.github/workflows/main.yml +27 -8
- data/.gitignore +3 -1
- data/.rubocop.yml +1 -1
- data/.standard.yml +1 -1
- data/Gemfile +4 -1
- data/Gemfile.rails7.0 +3 -0
- data/Gemfile.rails7.1 +4 -1
- data/{Gemfile.rails7 → Gemfile.rails7.2} +5 -2
- data/{Gemfile.rails6.0 → Gemfile.rails8.0} +5 -2
- data/README.md +161 -7
- data/Rakefile +1 -1
- data/agents.md +217 -0
- data/bin/coverband-mcp +42 -0
- data/changes.md +54 -3
- data/coverband.gemspec +5 -2
- data/lib/coverband/adapters/base.rb +21 -6
- data/lib/coverband/adapters/file_store.rb +1 -2
- data/lib/coverband/adapters/hash_redis_store.rb +3 -4
- data/lib/coverband/adapters/redis_store.rb +1 -2
- data/lib/coverband/adapters/web_service_store.rb +1 -2
- data/lib/coverband/collectors/abstract_tracker.rb +5 -5
- data/lib/coverband/collectors/delta.rb +4 -4
- data/lib/coverband/collectors/route_tracker.rb +2 -2
- data/lib/coverband/collectors/view_tracker.rb +33 -15
- data/lib/coverband/collectors/view_tracker_service.rb +1 -1
- data/lib/coverband/configuration.rb +57 -20
- data/lib/coverband/integrations/resque.rb +2 -2
- data/lib/coverband/mcp/http_handler.rb +118 -0
- data/lib/coverband/mcp/server.rb +116 -0
- data/lib/coverband/mcp/tools/get_coverage_summary.rb +41 -0
- data/lib/coverband/mcp/tools/get_dead_methods.rb +69 -0
- data/lib/coverband/mcp/tools/get_file_coverage.rb +74 -0
- data/lib/coverband/mcp/tools/get_route_tracker_data.rb +60 -0
- data/lib/coverband/mcp/tools/get_translation_tracker_data.rb +60 -0
- data/lib/coverband/mcp/tools/get_uncovered_files.rb +73 -0
- data/lib/coverband/mcp/tools/get_view_tracker_data.rb +60 -0
- data/lib/coverband/mcp.rb +27 -0
- data/lib/coverband/reporters/base.rb +3 -5
- data/lib/coverband/reporters/json_report.rb +7 -0
- data/lib/coverband/reporters/web.rb +17 -14
- data/lib/coverband/utils/absolute_file_converter.rb +37 -7
- data/lib/coverband/utils/dead_methods.rb +5 -1
- data/lib/coverband/utils/file_list.rb +15 -7
- data/lib/coverband/utils/html_formatter.rb +5 -2
- data/lib/coverband/utils/lines_classifier.rb +1 -1
- data/lib/coverband/utils/method_definition_scanner.rb +14 -2
- data/lib/coverband/utils/railtie.rb +1 -1
- data/lib/coverband/utils/relative_file_converter.rb +22 -7
- data/lib/coverband/utils/result.rb +2 -3
- data/lib/coverband/utils/source_file/line.rb +84 -0
- data/lib/coverband/utils/source_file.rb +35 -83
- data/lib/coverband/utils/tasks.rb +55 -6
- data/lib/coverband/version.rb +1 -1
- data/lib/coverband.rb +28 -2
- data/test/benchmarks/benchmark.rake +16 -18
- data/test/benchmarks/benchmark_delta.rb +54 -0
- data/test/benchmarks/benchmark_file_list.rb +58 -0
- data/test/benchmarks/benchmark_unused_keys.rb +52 -0
- data/test/coverband/collectors/coverage_test.rb +3 -7
- data/test/coverband/collectors/route_tracker_test.rb +3 -4
- data/test/coverband/collectors/translation_tracker_test.rb +1 -2
- data/test/coverband/collectors/view_tracker_test.rb +2 -2
- data/test/coverband/configuration_test.rb +0 -10
- data/test/coverband/file_store_integration_test.rb +72 -0
- data/test/coverband/file_store_redis_error_test.rb +56 -0
- data/test/coverband/github_issue_586_test.rb +46 -0
- data/test/coverband/initialization_timing_test.rb +71 -0
- data/test/coverband/integrations/rack_server_check_test.rb +6 -3
- data/test/coverband/mcp/http_handler_test.rb +159 -0
- data/test/coverband/mcp/security_test.rb +145 -0
- data/test/coverband/mcp/server_test.rb +125 -0
- data/test/coverband/mcp/tools/get_coverage_summary_test.rb +75 -0
- data/test/coverband/mcp/tools/get_dead_methods_test.rb +162 -0
- data/test/coverband/mcp/tools/get_file_coverage_test.rb +203 -0
- data/test/coverband/mcp/tools/get_route_tracker_data_test.rb +122 -0
- data/test/coverband/mcp/tools/get_translation_tracker_data_test.rb +122 -0
- data/test/coverband/mcp/tools/get_uncovered_files_test.rb +177 -0
- data/test/coverband/mcp/tools/get_view_tracker_data_test.rb +122 -0
- data/test/coverband/reporters/console_test.rb +1 -0
- data/test/coverband/reporters/json_test.rb +3 -3
- data/test/coverband/reporters/web_test.rb +5 -0
- data/test/coverband/track_key_test.rb +66 -0
- data/test/coverband/tracker_initialization_test.rb +75 -0
- data/test/coverband/user_environment_simulation_test.rb +75 -0
- data/test/coverband/utils/absolute_file_converter_test.rb +35 -0
- data/test/coverband/utils/dead_methods_test.rb +14 -2
- data/test/coverband/utils/lines_classifier_test.rb +1 -1
- data/test/coverband/utils/method_definition_scanner_test.rb +1 -1
- data/test/coverband/utils/relative_file_converter_test.rb +26 -0
- data/test/coverband/utils/result_test.rb +19 -0
- data/test/coverband/utils/{source_file_line_test.rb → source_file/line_test.rb} +1 -1
- data/test/dog.rb +5 -0
- data/test/forked/rails_full_stack_views_test.rb +1 -1
- data/test/integration/mcp_integration_test.rb +175 -0
- data/test/rails7_dummy/config/coverband.rb +13 -1
- data/test/rails7_dummy/config/coverband_missing_redis.rb +12 -1
- data/test/rails8_dummy/config/coverband.rb +3 -0
- data/test/rails8_dummy/config/coverband_missing_redis.rb +3 -0
- data/test/rails8_dummy/tmp/local_secret.txt +1 -0
- data/test/test_helper.rb +4 -8
- data/test/unique_files.rb +6 -2
- metadata +105 -59
- data/Gemfile.rails6.1 +0 -10
- data/test/rails4_dummy/config/application.rb +0 -15
- data/test/rails4_dummy/config/coverband.rb +0 -3
- data/test/rails4_dummy/config/coverband_missing_redis.rb +0 -3
- data/test/rails5_dummy/Rakefile +0 -6
- data/test/rails5_dummy/app/controllers/dummy_controller.rb +0 -5
- data/test/rails5_dummy/app/controllers/dummy_view_controller.rb +0 -16
- data/test/rails5_dummy/app/views/dummy_view/show.html.erb +0 -5
- data/test/rails5_dummy/app/views/dummy_view/show_haml.html.haml +0 -4
- data/test/rails5_dummy/app/views/dummy_view/show_slim.html.slim +0 -4
- data/test/rails5_dummy/config/application.rb +0 -14
- data/test/rails5_dummy/config/coverband.rb +0 -15
- data/test/rails5_dummy/config/coverband_missing_redis.rb +0 -14
- data/test/rails5_dummy/config/environment.rb +0 -2
- data/test/rails5_dummy/config/routes.rb +0 -7
- data/test/rails5_dummy/config.ru +0 -3
- data/test/rails5_dummy/tmp/.keep +0 -0
- data/test/rails6_dummy/Rakefile +0 -6
- data/test/rails6_dummy/app/controllers/dummy_controller.rb +0 -5
- data/test/rails6_dummy/app/controllers/dummy_view_controller.rb +0 -16
- data/test/rails6_dummy/app/views/dummy_view/show.html.erb +0 -5
- data/test/rails6_dummy/app/views/dummy_view/show_haml.html.haml +0 -4
- data/test/rails6_dummy/app/views/dummy_view/show_slim.html.slim +0 -4
- data/test/rails6_dummy/config/boot.rb +0 -3
- data/test/rails6_dummy/config/coverband.rb +0 -3
- data/test/rails6_dummy/config/coverband_missing_redis.rb +0 -3
- data/test/rails6_dummy/config/environment.rb +0 -5
- data/test/rails6_dummy/config/routes.rb +0 -7
- data/test/rails6_dummy/config/secrets.yml +0 -3
- data/test/rails6_dummy/config.ru +0 -4
- data/test/rails6_dummy/tmp/.keep +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/Rakefile +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/app/controllers/dummy_controller.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/app/controllers/dummy_view_controller.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/app/views/dummy_view/show.html.erb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/app/views/dummy_view/show_haml.html.haml +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/app/views/dummy_view/show_slim.html.slim +0 -0
- /data/test/{rails6_dummy → rails8_dummy}/config/application.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/config/boot.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/config/environment.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/config/routes.rb +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/config/secrets.yml +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/config.ru +0 -0
- /data/test/{rails4_dummy → rails8_dummy}/tmp/.keep +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: '01680ffc24d42fce1b45f90fff31a9d190b029af8a83b0a1405ed81d2785bc10'
|
|
4
|
+
data.tar.gz: 04daf91b9d7f64849d217075e71ff00d54cac2e64fd1b5c7fdd7e0b27943b56e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0de107048e072e97c1bded932a59ac9b6be2c6ac94b045118977aae38282a109772b183bed1b7ca99d7867d3fc694f326a53e2e93174bbf372e7f0ba16e8bd13
|
|
7
|
+
data.tar.gz: 57d8e1921056acb7f13e47b02caeb6207e635984a461c1952aafd0dbf4e445519d99ca8b369b60d11c3121b86da6f5f3d3d2a4e6aaf6d68fd2d3a8aa155d14fb
|
data/.github/workflows/main.yml
CHANGED
|
@@ -19,20 +19,39 @@ jobs:
|
|
|
19
19
|
# truffleruby,
|
|
20
20
|
# truffleruby-head,
|
|
21
21
|
# removing jruby again to flaky
|
|
22
|
-
gemfile: [ Gemfile.
|
|
22
|
+
gemfile: [ Gemfile.rails7.0, Gemfile.rails7.1, Gemfile.rails7.2, Gemfile.rails8.0 ]
|
|
23
23
|
# need to add support for multiple gemfiles
|
|
24
|
-
ruby: ["
|
|
24
|
+
ruby: ["3.1", "3.2", "3.3", "3.4", "4.0", "ruby-head"]
|
|
25
25
|
redis-version: [4, 5, 6, 7]
|
|
26
|
+
exclude:
|
|
27
|
+
# Rails 8 requires ruby 3.2+.
|
|
28
|
+
- gemfile: 'rails_8.0'
|
|
29
|
+
ruby: '3.1'
|
|
26
30
|
runs-on: ${{ matrix.os }}-latest
|
|
31
|
+
services:
|
|
32
|
+
redis:
|
|
33
|
+
image: redis:${{ matrix.redis-version }}
|
|
34
|
+
ports:
|
|
35
|
+
- 6379:6379
|
|
36
|
+
options: >-
|
|
37
|
+
--health-cmd "redis-cli ping"
|
|
38
|
+
--health-interval 10s
|
|
39
|
+
--health-timeout 5s
|
|
40
|
+
--health-retries 5
|
|
27
41
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
29
|
-
- uses: supercharge/redis-github-action@1.8.0
|
|
30
|
-
with:
|
|
31
|
-
redis-version: ${{ matrix.redis-version }}
|
|
42
|
+
- uses: actions/checkout@v6
|
|
32
43
|
- uses: ruby/setup-ruby@v1
|
|
33
44
|
with:
|
|
34
45
|
ruby-version: ${{ matrix.ruby }}
|
|
35
46
|
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
36
|
-
- run: bundle exec
|
|
37
|
-
- run: bundle exec rake
|
|
47
|
+
- run: bundle exec rake test:all
|
|
38
48
|
- run: "RUBYOPT='--enable=frozen-string-literal --debug=frozen-string-literal' bundle exec rake"
|
|
49
|
+
starndardrb:
|
|
50
|
+
runs-on: ubuntu-latest
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@v6
|
|
53
|
+
- uses: ruby/setup-ruby@v1
|
|
54
|
+
with:
|
|
55
|
+
ruby-version: 3.1
|
|
56
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
|
57
|
+
- run: bundle exec standardrb --format github
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.standard.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.rails7.0
CHANGED
data/Gemfile.rails7.1
CHANGED
|
@@ -4,7 +4,10 @@ source 'https://rubygems.org'
|
|
|
4
4
|
|
|
5
5
|
# Specify your gem's dependencies in coverband.gemspec
|
|
6
6
|
gemspec
|
|
7
|
-
gem 'rails', '~>7'
|
|
7
|
+
gem 'rails', '~>7.2.0'
|
|
8
8
|
gem "haml"
|
|
9
9
|
gem "slim"
|
|
10
|
-
gem "webrick"
|
|
10
|
+
gem "webrick"
|
|
11
|
+
|
|
12
|
+
# Required for Ruby 3.4+ (extracted from stdlib)
|
|
13
|
+
gem "cgi"
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
source
|
|
3
|
+
source 'https://rubygems.org'
|
|
4
4
|
|
|
5
5
|
# Specify your gem's dependencies in coverband.gemspec
|
|
6
6
|
gemspec
|
|
7
|
-
gem
|
|
7
|
+
gem 'rails', '~>8.0.0'
|
|
8
8
|
gem "haml"
|
|
9
9
|
gem "slim"
|
|
10
10
|
gem "webrick"
|
|
11
|
+
|
|
12
|
+
# Required for Ruby 3.4+ (extracted from stdlib)
|
|
13
|
+
gem "cgi"
|
data/README.md
CHANGED
|
@@ -116,6 +116,39 @@ The columns in the web UI are as follows:
|
|
|
116
116
|
When viewing an individual file, a line of code such as a class or method definition may appear green because it is eager loaded by the application, but still not be hit at all in runtime by actual users.
|
|
117
117
|
|
|
118
118
|

|
|
119
|
+
#### Coverage first seen and Last activity recorded
|
|
120
|
+
In the context of Coverband, a file is considered relevant for monitoring if it is located within certain specified project paths. Specifically, Coverband monitors all *.rb files located in the following paths:
|
|
121
|
+
|
|
122
|
+
- app/
|
|
123
|
+
|
|
124
|
+
- lib/
|
|
125
|
+
|
|
126
|
+
- config/
|
|
127
|
+
|
|
128
|
+
This applies as long as these files are not included in the list of exclusions defined in "config.ignore".
|
|
129
|
+
|
|
130
|
+
#### Coverage first seen
|
|
131
|
+
This attribute shows the exact date and time when Coverband first detected the file. This detection happens when:
|
|
132
|
+
|
|
133
|
+
- The file is loaded by Ruby (e.g., during application startup in Rails via autoload or require).
|
|
134
|
+
|
|
135
|
+
- The file becomes relevant for monitoring, even if no lines within it have been executed yet.
|
|
136
|
+
|
|
137
|
+
- By default, Coverband resets a file’s coverage data and updates its “Coverage first seen” timestamp whenever the file changes, ensuring the coverage reflects the file’s new state.
|
|
138
|
+
|
|
139
|
+
#### Last activity recorded
|
|
140
|
+
This attribute shows the most recent time when any line in the file was executed at runtime. It specifically reflects runtime execution and does not include the file’s load time.
|
|
141
|
+
|
|
142
|
+
- When any line in the file is executed at runtime (e.g., a method is called, a route is triggered, or a conditional is evaluated), Coverband updates the “Last activity recorded” timestamp.
|
|
143
|
+
|
|
144
|
+
- This only occurs when the file’s lines are actually executed. If a file is loaded but none of its lines are executed, the “Last activity recorded” timestamp will not be updated.
|
|
145
|
+
|
|
146
|
+
- It helps determine if a file is actively being used in the application. If a file has no recent activity, it may be a candidate for review or removal.
|
|
147
|
+
|
|
148
|
+
#### Example
|
|
149
|
+
- If a file has a “Coverage first seen” timestamp but no “Last activity recorded”, this indicates that the file is being loaded but no runtime activity is occurring (e.g., it contains unused methods or classes).
|
|
150
|
+
|
|
151
|
+
- If both attributes are populated and the “Last activity recorded” timestamp is recent, the file is actively used in the application.
|
|
119
152
|
|
|
120
153
|
### Mounting as a Rack App
|
|
121
154
|
|
|
@@ -305,12 +338,10 @@ Now that Coverband uses MD5 hashes there should be no reason to manually clear c
|
|
|
305
338
|
|
|
306
339
|
`rake coverband:clear`
|
|
307
340
|
|
|
308
|
-
This can also be done through the web if `config.web_enable_clear` is enabled.
|
|
309
|
-
|
|
310
|
-
**NOTE**: The previous task does not clear the trackers data (views, routes, translations, etc).
|
|
311
|
-
To clear trackers data, run
|
|
341
|
+
This will clear both the coverage and trackers data. It can also be done through the web if `config.web_enable_clear` is enabled.
|
|
312
342
|
|
|
313
|
-
`rake coverband:
|
|
343
|
+
To clear only coverage data, run `rake coverband:clear_coverage`.
|
|
344
|
+
To clear only trackers data, run `rake coverband:clear_tracker`.
|
|
314
345
|
|
|
315
346
|
### Adding Rake Tasks outside of Rails
|
|
316
347
|
|
|
@@ -375,6 +406,129 @@ A few folks have asked about what size of Redis is needed to run Coverband. I ha
|
|
|
375
406
|
|
|
376
407
|
# Newer Features
|
|
377
408
|
|
|
409
|
+
### MCP Server for AI Assistants
|
|
410
|
+
|
|
411
|
+
Coverband includes an optional MCP (Model Context Protocol) server that allows AI assistants like Claude to query your production coverage data directly. This enables AI-powered code analysis, dead code detection, and coverage insights.
|
|
412
|
+
|
|
413
|
+
#### Installation
|
|
414
|
+
|
|
415
|
+
Add the MCP gem to your Gemfile:
|
|
416
|
+
|
|
417
|
+
```ruby
|
|
418
|
+
gem 'mcp'
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
#### Available Tools
|
|
422
|
+
|
|
423
|
+
The MCP server provides the following tools:
|
|
424
|
+
|
|
425
|
+
| Tool | Description |
|
|
426
|
+
|------|-------------|
|
|
427
|
+
| `get_coverage_summary` | Get overall coverage statistics |
|
|
428
|
+
| `get_file_coverage` | Get detailed coverage for a specific file |
|
|
429
|
+
| `get_uncovered_files` | List files with no coverage data |
|
|
430
|
+
| `get_dead_methods` | Find methods that are never called |
|
|
431
|
+
| `get_view_tracker_data` | Get view/template usage data |
|
|
432
|
+
| `get_route_tracker_data` | Get route usage statistics |
|
|
433
|
+
| `get_translation_tracker_data` | Get translation key usage data |
|
|
434
|
+
|
|
435
|
+
#### Running the MCP Server
|
|
436
|
+
|
|
437
|
+
**Standalone (stdio transport):**
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
bundle exec coverband-mcp
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
**With a rake task:**
|
|
444
|
+
|
|
445
|
+
```bash
|
|
446
|
+
bundle exec rake coverband:mcp
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
**HTTP mode (for remote access):**
|
|
450
|
+
|
|
451
|
+
```bash
|
|
452
|
+
COVERBAND_MCP_HTTP=true COVERBAND_MCP_PORT=9023 bundle exec rake coverband:mcp
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
#### Configuring Claude Desktop
|
|
456
|
+
|
|
457
|
+
Add to your Claude Desktop configuration (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
|
458
|
+
|
|
459
|
+
**Option 1: Stdio transport (recommended for local development)**
|
|
460
|
+
|
|
461
|
+
```json
|
|
462
|
+
{
|
|
463
|
+
"mcpServers": {
|
|
464
|
+
"coverband": {
|
|
465
|
+
"command": "bundle",
|
|
466
|
+
"args": ["exec", "coverband-mcp"],
|
|
467
|
+
"cwd": "/path/to/your/rails/app"
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
**Option 2: HTTP transport (for remote access or shared servers)**
|
|
474
|
+
|
|
475
|
+
First, start the MCP server in HTTP mode:
|
|
476
|
+
|
|
477
|
+
```bash
|
|
478
|
+
COVERBAND_MCP_HTTP=true bundle exec rake coverband:mcp
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
Then configure Claude Desktop to connect via `mcp-remote`:
|
|
482
|
+
|
|
483
|
+
```json
|
|
484
|
+
{
|
|
485
|
+
"mcpServers": {
|
|
486
|
+
"coverband": {
|
|
487
|
+
"command": "npx",
|
|
488
|
+
"args": ["mcp-remote", "http://localhost:9023"]
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
#### Configuring Claude Code
|
|
495
|
+
|
|
496
|
+
Add a `.mcp.json` file to your project root:
|
|
497
|
+
|
|
498
|
+
**Option 1: Stdio transport (recommended)**
|
|
499
|
+
|
|
500
|
+
```json
|
|
501
|
+
{
|
|
502
|
+
"mcpServers": {
|
|
503
|
+
"coverband": {
|
|
504
|
+
"command": "bundle",
|
|
505
|
+
"args": ["exec", "coverband-mcp"]
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**Option 2: HTTP transport**
|
|
512
|
+
|
|
513
|
+
```json
|
|
514
|
+
{
|
|
515
|
+
"mcpServers": {
|
|
516
|
+
"coverband": {
|
|
517
|
+
"command": "npx",
|
|
518
|
+
"args": ["mcp-remote", "http://localhost:9023"]
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
#### Environment Variables
|
|
525
|
+
|
|
526
|
+
| Variable | Description | Default |
|
|
527
|
+
|----------|-------------|---------|
|
|
528
|
+
| `COVERBAND_MCP_HTTP` | Enable HTTP transport instead of stdio | `false` |
|
|
529
|
+
| `COVERBAND_MCP_PORT` | Port for HTTP server | `9023` |
|
|
530
|
+
| `COVERBAND_REDIS_URL` | Redis URL for coverage data | `localhost:6379` |
|
|
531
|
+
|
|
378
532
|
### Dead Method Scanning (ruby 2.6+)
|
|
379
533
|
|
|
380
534
|
Rake task that outputs dead methods based on current coverage data:
|
|
@@ -399,14 +553,14 @@ Outputs:
|
|
|
399
553
|
|
|
400
554
|
# Prerequisites
|
|
401
555
|
|
|
402
|
-
-
|
|
556
|
+
- Ruby 3.1+
|
|
403
557
|
- Coverband currently requires Redis for production usage
|
|
404
558
|
|
|
405
559
|
### Ruby and Rails Version Support
|
|
406
560
|
|
|
407
561
|
We will match Heroku & Ruby's support lifetime, supporting the last 3 major Ruby releases. For details see [supported runtimes](https://devcenter.heroku.com/articles/ruby-support#supported-runtimes).
|
|
408
562
|
|
|
409
|
-
For Rails, we will follow the policy of the [Rails team maintenance policy](https://guides.rubyonrails.org/maintenance_policy.html). We officially support the last two major release versions, while providing minimal support (major bugs / security fixes) for an additional version.
|
|
563
|
+
For Rails, we will follow the policy of the [Rails team maintenance policy](https://guides.rubyonrails.org/maintenance_policy.html). We officially support the last two major release versions, while providing minimal support (major bugs / security fixes) for an additional version. At the moment we primarily target Rails 7.0+.
|
|
410
564
|
|
|
411
565
|
### JRuby Support
|
|
412
566
|
|
data/Rakefile
CHANGED
data/agents.md
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# AI Agent Guidelines for Coverband Development
|
|
2
|
+
|
|
3
|
+
This document provides guidance for AI coding agents working on the Coverband project. Following these guidelines ensures code quality and consistency.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
Coverband is a Ruby gem that provides rack middleware to measure production code usage (LOC runtime usage). The project uses:
|
|
8
|
+
- **Ruby**: >= 3.1
|
|
9
|
+
- **Test Framework**: Minitest (version ~> 5.0)
|
|
10
|
+
- **Code Style**: StandardRB
|
|
11
|
+
- **CI/CD**: GitHub Actions
|
|
12
|
+
|
|
13
|
+
## Testing Requirements
|
|
14
|
+
|
|
15
|
+
### Running Tests
|
|
16
|
+
|
|
17
|
+
All code changes MUST pass the test suite before considering work complete. The project has multiple test targets:
|
|
18
|
+
|
|
19
|
+
#### Standard Test Suite
|
|
20
|
+
```bash
|
|
21
|
+
bundle exec rake test
|
|
22
|
+
```
|
|
23
|
+
This runs the main integration and unit tests located in:
|
|
24
|
+
- `test/integration/**/*_test.rb`
|
|
25
|
+
- `test/coverband/**/*_test.rb`
|
|
26
|
+
|
|
27
|
+
#### Forked Tests
|
|
28
|
+
```bash
|
|
29
|
+
bundle exec rake forked_tests
|
|
30
|
+
```
|
|
31
|
+
Runs tests that require forked processes (Rails integration tests):
|
|
32
|
+
- `test/forked/**/*_test.rb`
|
|
33
|
+
|
|
34
|
+
Note: Forked tests are not supported on JRuby.
|
|
35
|
+
|
|
36
|
+
#### Full Test Suite
|
|
37
|
+
```bash
|
|
38
|
+
bundle exec rake test:all
|
|
39
|
+
```
|
|
40
|
+
Runs all tests including benchmarks and memory tests.
|
|
41
|
+
|
|
42
|
+
#### Default Task
|
|
43
|
+
```bash
|
|
44
|
+
bundle exec rake
|
|
45
|
+
```
|
|
46
|
+
Equivalent to `bundle exec rake test`
|
|
47
|
+
|
|
48
|
+
### Test Framework Details
|
|
49
|
+
|
|
50
|
+
- Uses **Minitest** with **Mocha** for mocking
|
|
51
|
+
- Test files follow the pattern `*_test.rb`
|
|
52
|
+
- Rails integration tests use **Capybara** for browser testing
|
|
53
|
+
- Forked tests use `minitest-fork_executor` for parallel execution
|
|
54
|
+
|
|
55
|
+
### Test Configuration
|
|
56
|
+
|
|
57
|
+
Key test dependencies:
|
|
58
|
+
- `minitest ~> 5.0` (pinned for compatibility with minitest-fork_executor)
|
|
59
|
+
- `mocha` for mocking/stubbing
|
|
60
|
+
- `minitest-stub-const` for constant stubbing
|
|
61
|
+
- `capybara` for integration testing
|
|
62
|
+
- `rack-test` for Rack testing
|
|
63
|
+
|
|
64
|
+
## Code Style Requirements
|
|
65
|
+
|
|
66
|
+
### StandardRB
|
|
67
|
+
|
|
68
|
+
All code MUST pass StandardRB linting before considering work complete.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
bundle exec standardrb --format github
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Auto-fix Style Issues
|
|
75
|
+
```bash
|
|
76
|
+
bundle exec standardrb --fix
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Configuration
|
|
80
|
+
|
|
81
|
+
StandardRB configuration is in `.standard.yml`:
|
|
82
|
+
- Ruby version: 3.1
|
|
83
|
+
- Parallel execution enabled
|
|
84
|
+
- Some rules are disabled for compatibility with older Ruby versions
|
|
85
|
+
- Test files have relaxed rules (see `.standard.yml` for specifics)
|
|
86
|
+
|
|
87
|
+
### Common Style Requirements
|
|
88
|
+
|
|
89
|
+
1. **Module Inclusions**: Add an empty line after `extend` or `include` statements
|
|
90
|
+
2. **Frozen String Literals**: All Ruby files should start with `# frozen_string_literal: true`
|
|
91
|
+
3. **Line Length**: Follow StandardRB defaults (no manual line length configuration needed)
|
|
92
|
+
|
|
93
|
+
## AI Agent Workflow
|
|
94
|
+
|
|
95
|
+
When making code changes, follow this workflow:
|
|
96
|
+
|
|
97
|
+
### 1. Make Code Changes
|
|
98
|
+
Implement the requested feature or bug fix.
|
|
99
|
+
|
|
100
|
+
### 2. Run Tests
|
|
101
|
+
```bash
|
|
102
|
+
bundle exec rake test
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
If working on Rails integration or forked features:
|
|
106
|
+
```bash
|
|
107
|
+
bundle exec rake test:all
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 3. Fix Any Test Failures
|
|
111
|
+
- Read test output carefully
|
|
112
|
+
- Fix issues in the code
|
|
113
|
+
- Re-run tests until all pass
|
|
114
|
+
|
|
115
|
+
### 4. Check Code Style
|
|
116
|
+
```bash
|
|
117
|
+
bundle exec standardrb --format github
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 5. Auto-fix Style Issues (if any)
|
|
121
|
+
```bash
|
|
122
|
+
bundle exec standardrb --fix
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 6. Verify Everything Passes
|
|
126
|
+
```bash
|
|
127
|
+
bundle exec rake test
|
|
128
|
+
bundle exec standardrb --format github
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### 7. Only Then Consider Work Complete
|
|
132
|
+
Do NOT mark work as complete or hand back to the user until:
|
|
133
|
+
- ✅ All tests pass
|
|
134
|
+
- ✅ StandardRB reports no violations
|
|
135
|
+
|
|
136
|
+
## Common Issues and Solutions
|
|
137
|
+
|
|
138
|
+
### Mocha Configuration
|
|
139
|
+
- Use only Mocha 3.x compatible configuration options
|
|
140
|
+
- Valid options: `stubbing_method_unnecessarily`, `stubbing_non_public_method`
|
|
141
|
+
- Invalid options (removed): `stubbing_method_on_nil`, `stubbing_method_on_non_mock_object`, `stubbing_non_existent_method`
|
|
142
|
+
|
|
143
|
+
### Rails Constant Checks
|
|
144
|
+
When checking if Rails is defined:
|
|
145
|
+
```ruby
|
|
146
|
+
# ✅ Correct
|
|
147
|
+
if defined?(Rails) && Rails.respond_to?(:version)
|
|
148
|
+
# ...
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# ❌ Wrong (doesn't protect against undefined constant)
|
|
152
|
+
if Rails&.respond_to?(:version)
|
|
153
|
+
# ...
|
|
154
|
+
end
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Minitest Version
|
|
158
|
+
- Must use Minitest ~> 5.0 for compatibility with `minitest-fork_executor`
|
|
159
|
+
- Minitest 6.0+ is not compatible with the fork executor
|
|
160
|
+
|
|
161
|
+
## CI/CD
|
|
162
|
+
|
|
163
|
+
The project uses GitHub Actions for CI. On every push/PR:
|
|
164
|
+
1. Tests run against multiple Ruby versions (3.1, 3.2, 3.3, 3.4, ruby-head)
|
|
165
|
+
2. Tests run against multiple Rails versions (7.0, 7.1, 7.2, 8.0)
|
|
166
|
+
3. Tests run against multiple Redis versions (4, 5, 6, 7)
|
|
167
|
+
4. StandardRB runs separately to check code style
|
|
168
|
+
|
|
169
|
+
Your local testing should match CI requirements:
|
|
170
|
+
- All tests must pass
|
|
171
|
+
- StandardRB must report no violations
|
|
172
|
+
|
|
173
|
+
## Additional Notes
|
|
174
|
+
|
|
175
|
+
- The project uses Redis as the default storage backend
|
|
176
|
+
- Rails 8.0 requires Ruby 3.2+
|
|
177
|
+
- Test coverage data is stored in `/tmp` during tests
|
|
178
|
+
- Use `test_helper.rb` for common test setup
|
|
179
|
+
- Use `rails_test_helper.rb` for Rails-specific test setup
|
|
180
|
+
|
|
181
|
+
## Example Complete Workflow
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# 1. Make changes to code
|
|
185
|
+
vim lib/coverband/some_file.rb
|
|
186
|
+
|
|
187
|
+
# 2. Run tests
|
|
188
|
+
bundle exec rake test
|
|
189
|
+
|
|
190
|
+
# 3. Fix any failures, re-run until passing
|
|
191
|
+
bundle exec rake test
|
|
192
|
+
|
|
193
|
+
# 4. Check style
|
|
194
|
+
bundle exec standardrb --format github
|
|
195
|
+
|
|
196
|
+
# 5. Auto-fix any style issues
|
|
197
|
+
bundle exec standardrb --fix
|
|
198
|
+
|
|
199
|
+
# 6. Final verification
|
|
200
|
+
bundle exec rake test
|
|
201
|
+
bundle exec standardrb --format github
|
|
202
|
+
|
|
203
|
+
# 7. All green? Work is complete! ✅
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Quick Reference
|
|
207
|
+
|
|
208
|
+
| Command | Purpose |
|
|
209
|
+
|---------|---------|
|
|
210
|
+
| `bundle exec rake` | Run main test suite (default) |
|
|
211
|
+
| `bundle exec rake test` | Run main test suite |
|
|
212
|
+
| `bundle exec rake forked_tests` | Run forked/Rails integration tests |
|
|
213
|
+
| `bundle exec rake test:all` | Run all tests including benchmarks |
|
|
214
|
+
| `bundle exec standardrb --format github` | Check code style |
|
|
215
|
+
| `bundle exec standardrb --fix` | Auto-fix style issues |
|
|
216
|
+
|
|
217
|
+
Remember: **Tests and style checks must pass before work is considered complete!**
|
data/bin/coverband-mcp
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require "bundler/setup"
|
|
5
|
+
require "coverband/mcp"
|
|
6
|
+
|
|
7
|
+
# Ensure Coverband is configured
|
|
8
|
+
Coverband.configure unless Coverband.configured?
|
|
9
|
+
|
|
10
|
+
# Security check and warning
|
|
11
|
+
unless Coverband.configuration.mcp_enabled?
|
|
12
|
+
puts "❌ ERROR: MCP is not enabled for security reasons."
|
|
13
|
+
puts "To enable MCP access, configure Coverband with:"
|
|
14
|
+
puts
|
|
15
|
+
puts "Coverband.configure do |config|"
|
|
16
|
+
puts " config.mcp_enabled = true"
|
|
17
|
+
puts " config.mcp_password = 'your-secure-password' # Recommended"
|
|
18
|
+
puts " config.mcp_allowed_environments = %w[development staging production] # As needed"
|
|
19
|
+
puts "end"
|
|
20
|
+
puts
|
|
21
|
+
puts "Or set environment variables:"
|
|
22
|
+
puts " COVERBAND_MCP_PASSWORD=your-secure-password"
|
|
23
|
+
puts
|
|
24
|
+
puts "Current environment: #{(defined?(Rails) && Rails.respond_to?(:env) && Rails.env) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"}"
|
|
25
|
+
exit 1
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Display security status
|
|
29
|
+
puts "🔐 SECURITY STATUS:"
|
|
30
|
+
if Coverband.configuration.mcp_password
|
|
31
|
+
puts " ✅ Authentication: Enabled (password protected)"
|
|
32
|
+
else
|
|
33
|
+
puts " ⚠️ Authentication: DISABLED - Consider setting mcp_password for production use"
|
|
34
|
+
end
|
|
35
|
+
env = (defined?(Rails) && Rails.respond_to?(:env) && Rails.env) || ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
|
|
36
|
+
puts " 📍 Environment: #{env}"
|
|
37
|
+
puts " 🌍 Allowed environments: #{Coverband.configuration.mcp_allowed_environments.join(", ")}"
|
|
38
|
+
puts
|
|
39
|
+
|
|
40
|
+
# Start the MCP server with stdio transport
|
|
41
|
+
server = Coverband::MCP::Server.new
|
|
42
|
+
server.run_stdio
|