swagcov 0.4.1 → 0.6.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 +4 -4
- data/CHANGELOG.md +92 -0
- data/README.md +31 -46
- data/lib/swagcov/coverage.rb +65 -53
- data/lib/swagcov/dotfile.rb +39 -22
- data/lib/swagcov/errors.rb +8 -0
- data/lib/swagcov/install.rb +41 -0
- data/lib/swagcov/openapi_files.rb +5 -5
- data/lib/swagcov/version.rb +3 -1
- data/lib/swagcov.rb +9 -8
- data/lib/tasks/swagcov/install.rake +8 -0
- metadata +9 -5
- /data/lib/tasks/{swagcove.rake → swagcov.rake} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba29f88b400a4b44a37ee42725f70a5a97aa8ec9186de531ea13de33e8fec205
|
4
|
+
data.tar.gz: 6651caaa48d8fa61bd90f1598cfd3d78b8d6612ca6f14f76360ef8d85a256828
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86b8e97506c580b7981090803aa41a609d1c1396613a57da1faf7c66864c40ac0337675fa009a5c48311ceff89bf8e6f1eb683d098a0153525a71d95cdb9c124
|
7
|
+
data.tar.gz: e62b2919cb26ff819d28abf200fce58d23b7f509b47200114ce6f69bc23d086fb2399b21be6e0363a6a15102f845d6ad5dc003e5fb36f175ab1c87947b21a68a
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# CHANGELOG
|
2
|
+
## main (unreleased)
|
3
|
+
-
|
4
|
+
|
5
|
+
## 0.6.0 (2025-04-09)
|
6
|
+
### Fix
|
7
|
+
- Grammatical number for endpoint(s) count output ([#78](https://github.com/smridge/swagcov/pull/78))
|
8
|
+
|
9
|
+
### Enhancement
|
10
|
+
- Add support for Rails 4.2 ([#72](https://github.com/smridge/swagcov/pull/72))
|
11
|
+
|
12
|
+
### Refactor
|
13
|
+
- `BREAKING CHANGE`: `Swagcov::BadConfigurationError` is now `Swagcov::Errors::BadConfiguration` ([#74](https://github.com/smridge/swagcov/pull/74))
|
14
|
+
- `BREAKING CHANGE`: `Swagcov::VERSION` is now `Swagcov::Version::STRING` ([#77](https://github.com/smridge/swagcov/pull/77))
|
15
|
+
- Improve path matching processing for `ignore` and `only` routes ([#65](https://github.com/smridge/swagcov/pull/65))
|
16
|
+
|
17
|
+
### Code Coverage
|
18
|
+
- Add test coverage reporting ([#68](https://github.com/smridge/swagcov/pull/68), [#69](https://github.com/smridge/swagcov/pull/69))
|
19
|
+
|
20
|
+
## 0.5.0 (2025-03-26)
|
21
|
+
### Enhancement
|
22
|
+
- Add rake task for configuration installation ([#59](https://github.com/smridge/swagcov/pull/59))
|
23
|
+
```shell
|
24
|
+
bundle exec rake swagcov:install
|
25
|
+
```
|
26
|
+
- Extend `ignore` routes configuration to exclude only specific actions ([#60](https://github.com/smridge/swagcov/pull/60))
|
27
|
+
```yml
|
28
|
+
routes:
|
29
|
+
paths:
|
30
|
+
ignore:
|
31
|
+
- /v2/users # existing configuration that ignores all associated actions (verbs)
|
32
|
+
- /v2/users/:id: # new option to extend to specific actions
|
33
|
+
- GET
|
34
|
+
```
|
35
|
+
|
36
|
+
## 0.4.1 (2025-03-18)
|
37
|
+
### Fix
|
38
|
+
- Output width for better layout alignment ([#48](https://github.com/smridge/swagcov/pull/48))
|
39
|
+
|
40
|
+
### Code Coverage
|
41
|
+
- Added official support for ruby 3.3 and 3.4 and rails 7.1, 7.2, 8.0. See [tests.yml](/.github/workflows/tests.yml) for detail
|
42
|
+
|
43
|
+
## 0.4.0 (2022-08-11)
|
44
|
+
- Improve OpenAPI file processing ([#26](https://github.com/smridge/swagcov/pull/26))
|
45
|
+
|
46
|
+
## 0.3.0 (2022-02-21)
|
47
|
+
### Enhancement
|
48
|
+
- Raise specific `Swagcov::BadConfigurationError` for malinformed yaml files ([#23](https://github.com/smridge/swagcov/pull/23))
|
49
|
+
|
50
|
+
### Security
|
51
|
+
- Require Multi-Factor Authentication for RubyGems privileged operations ([#16](https://github.com/smridge/swagcov/pull/16))
|
52
|
+
|
53
|
+
### Code Coverage
|
54
|
+
- Add Sandbox Application and specs for Rails 5.1 ([#20](https://github.com/smridge/swagcov/pull/20))
|
55
|
+
- Add specs for Rails 5.2 ([#7](https://github.com/smridge/swagcov/pull/7)), ([#14](https://github.com/smridge/swagcov/pull/14))
|
56
|
+
- Add Sandbox Application and specs for Rails 6.0 ([#17](https://github.com/smridge/swagcov/pull/17))
|
57
|
+
- Add Sandbox Application and specs for Rails 6.1 ([#22](https://github.com/smridge/swagcov/pull/22))
|
58
|
+
- Add GitHub Actions to run specs ([#18](https://github.com/smridge/swagcov/pull/18))
|
59
|
+
- Add GitHub CodeQL ([#13](https://github.com/smridge/swagcov/pull/13))
|
60
|
+
|
61
|
+
### Refactor
|
62
|
+
- Move `SystemExit` to rake task for easier testing ([#24](https://github.com/smridge/swagcov/pull/24))
|
63
|
+
- Reduce complexity when matching routes ([#15](https://github.com/smridge/swagcov/pull/15))
|
64
|
+
|
65
|
+
## 0.2.5 (2021-09-14)
|
66
|
+
### Fix
|
67
|
+
- Matching routes against swagger paths. Previously, partial paths could result in a match ([#12](https://github.com/smridge/swagcov/pull/12))
|
68
|
+
|
69
|
+
## 0.2.4 (2021-04-30)
|
70
|
+
### Fix
|
71
|
+
- If a route path does not start with "^" match the entire path ([#5](https://github.com/smridge/swagcov/pull/5))
|
72
|
+
### Enhancement
|
73
|
+
- Raise specific `Swagcov::BadConfigurationError` error if bad or missing configuration ([#5](https://github.com/smridge/swagcov/pull/5))
|
74
|
+
|
75
|
+
## 0.2.3 (2021-04-23)
|
76
|
+
### Fix
|
77
|
+
- Exclude ActiveStorage and ActionMailer routes ([#3](https://github.com/smridge/swagcov/pull/3))
|
78
|
+
|
79
|
+
## 0.2.2 (2021-04-22)
|
80
|
+
### Fix
|
81
|
+
- Exclude Rails Internal Routes and Mounted Applications ([#2](https://github.com/smridge/swagcov/pull/2))
|
82
|
+
|
83
|
+
## 0.2.1 (2021-04-21)
|
84
|
+
### Fix
|
85
|
+
- Exceptions caused by missing dependency for strings. ([#1](https://github.com/smridge/swagcov/pull/1))
|
86
|
+
|
87
|
+
## 0.2.0 (2021-04-20)
|
88
|
+
### Enhancement
|
89
|
+
- Add Exit status to easily build a pass/fail into build pipeline
|
90
|
+
|
91
|
+
## 0.1.0 (2021-02-24)
|
92
|
+
- Create Rake Task for checking documentation coverage (rails only)
|
data/README.md
CHANGED
@@ -4,12 +4,30 @@
|
|
4
4
|
[](https://github.com/rubocop-hq/rubocop)
|
5
5
|
[](https://github.com/smridge/swagcov/blob/main/LICENSE)
|
6
6
|
|
7
|
+

|
8
|
+

|
9
|
+

|
10
|
+
[](https://coveralls.io/github/smridge/swagcov?branch=main)
|
11
|
+
|
7
12
|
See OpenAPI documentation coverage report for Rails Routes.
|
8
13
|
|
9
14
|
## Usages
|
10
15
|
- See overview of different endpoints covered, missing and what you choose to ignore.
|
11
16
|
- Add pass/fail to your build pipeline when missing Documentation Coverage.
|
12
17
|
|
18
|
+
## Ruby and Rails Version Support
|
19
|
+
Versioning support from a test coverage perspective, see [tests.yml](/.github/workflows/tests.yml) for detail
|
20
|
+
| `ruby -v` | `rails 4.2` | `rails 5.0` | `rails 5.1` | `rails 5.2` | `rails 6.0` | `rails 6.1` | `rails 7.0` | `rails 7.1` | `rails 7.2` | `rails 8.0` |
|
21
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
22
|
+
| `2.5` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
23
|
+
| `2.6` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
|
24
|
+
| `2.7` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
|
25
|
+
| `3.0` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
|
26
|
+
| `3.1` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
|
27
|
+
| `3.2` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
28
|
+
| `3.3` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
29
|
+
| `3.4` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
30
|
+
|
13
31
|
## Installation
|
14
32
|
Add this line to your application's Gemfile:
|
15
33
|
```ruby
|
@@ -21,7 +39,11 @@ Execute:
|
|
21
39
|
bundle
|
22
40
|
```
|
23
41
|
|
24
|
-
Create a `.swagcov.yml` in root of your Rails application.
|
42
|
+
Create a `.swagcov.yml` in root of your Rails application. Alternatively, run:
|
43
|
+
```shell
|
44
|
+
bundle exec rake swagcov:install
|
45
|
+
```
|
46
|
+
|
25
47
|
- Add the paths of your `openapi` yml files (**required**):
|
26
48
|
```yml
|
27
49
|
docs:
|
@@ -57,6 +79,8 @@ Create a `.swagcov.yml` in root of your Rails application.
|
|
57
79
|
- ^/v1
|
58
80
|
ignore:
|
59
81
|
- /v1/foobar/:token
|
82
|
+
- /v1/foobar:
|
83
|
+
- GET
|
60
84
|
```
|
61
85
|
|
62
86
|
Execute:
|
@@ -99,57 +123,18 @@ bundle exec rake swagcov
|
|
99
123
|
- ^/v2
|
100
124
|
ignore:
|
101
125
|
- /v2/users
|
126
|
+
- /v2/users/:id:
|
127
|
+
- GET
|
102
128
|
```
|
103
129
|
<img src="https://raw.githubusercontent.com/smridge/swagcov/main/images/ignore-and-only-endpoints.png">
|
104
130
|
|
105
|
-
##
|
106
|
-
|
107
|
-
git clone git@github.com:smridge/swagcov.git
|
108
|
-
```
|
109
|
-
|
110
|
-
Add this line to your application's Gemfile:
|
111
|
-
```ruby
|
112
|
-
# Use the relative path from your application, to the swagcov folder
|
113
|
-
gem "swagcov", path: "../swagcov"
|
114
|
-
```
|
115
|
-
|
116
|
-
```shell
|
117
|
-
bundle
|
118
|
-
```
|
119
|
-
|
120
|
-
Run Tests
|
121
|
-
```
|
122
|
-
bundle exec rspec spec --exclude-pattern spec/sandbox_**/**/*_spec.rb
|
123
|
-
```
|
131
|
+
## Contributing
|
132
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for detail
|
124
133
|
|
125
|
-
###
|
126
|
-
- Go to any sandbox application within the `spec` directory
|
127
|
-
- For example, `cd spec/sandbox_5_2/`
|
128
|
-
- Install the ruby version specified in `.ruby-version` file
|
129
|
-
- Install gems: `bundle install`
|
130
|
-
- Run tests: `bundle exec rspec spec`
|
131
|
-
- Run `bundle exec rake swagcov`
|
132
|
-
- This will run against any changes made to your branch.
|
133
|
-
|
134
|
-
## Publish (internal)
|
135
|
-
> Note: Publishing a new version of this gem is only meant for maintainers.
|
136
|
-
- Ensure you have access to publish on [rubygems](https://rubygems.org/gems/swagcov).
|
137
|
-
- Update [CHANGELOG](https://github.com/smridge/swagcov/blob/main/CHANGELOG.md).
|
138
|
-
- Update [`VERSION`](https://github.com/smridge/swagcov/blob/main/lib/swagcov/version.rb).
|
139
|
-
- Run `bundle update` for each sandbox application to reflect new swagcov version in each `Gemfile.lock`
|
140
|
-
- Open a Pull Request to ensure all specs pass, then merge to `main`.
|
141
|
-
- Checkout the latest `main` on your machine.
|
142
|
-
- Run: `rake release`
|
143
|
-
- This command builds the gem, creates a tag and publishes to rubygems, see [bundler docs](https://bundler.io/guides/creating_gem.html#releasing-the-gem).
|
144
|
-
|
145
|
-
## TODO
|
146
|
-
- Add autogeneration of ignore paths
|
147
|
-
- Add `CONTRIBUTING.md`
|
148
|
-
|
149
|
-
## Credit
|
134
|
+
### Credit
|
150
135
|
To [@lonelyelk](https://github.com/lonelyelk) for initial development!
|
151
136
|
|
152
|
-
|
137
|
+
### Contributors
|
153
138
|
<a href="https://github.com/smridge/swagcov/graphs/contributors">
|
154
139
|
<img src="https://contrib.rocks/image?repo=smridge/swagcov" />
|
155
140
|
</a>
|
data/lib/swagcov/coverage.rb
CHANGED
@@ -2,28 +2,31 @@
|
|
2
2
|
|
3
3
|
module Swagcov
|
4
4
|
class Coverage
|
5
|
-
attr_reader :
|
6
|
-
|
7
|
-
def initialize dotfile: Swagcov::Dotfile.new, routes: ::Rails.application.routes.routes
|
8
|
-
@total = 0
|
9
|
-
@covered = 0
|
10
|
-
@ignored = 0
|
11
|
-
@routes_not_covered = []
|
12
|
-
@routes_covered = []
|
13
|
-
@routes_ignored = []
|
5
|
+
attr_reader :data
|
6
|
+
|
7
|
+
def initialize dotfile: ::Swagcov::Dotfile.new, routes: ::Rails.application.routes.routes
|
14
8
|
@dotfile = dotfile
|
15
9
|
@routes = routes
|
10
|
+
@data = {
|
11
|
+
covered: [],
|
12
|
+
ignored: [],
|
13
|
+
uncovered: [],
|
14
|
+
total_count: 0,
|
15
|
+
covered_count: 0,
|
16
|
+
ignored_count: 0,
|
17
|
+
uncovered_count: 0
|
18
|
+
}
|
16
19
|
end
|
17
20
|
|
18
21
|
def report
|
19
22
|
collect_coverage
|
20
|
-
routes_output(@
|
21
|
-
routes_output(@
|
22
|
-
routes_output(@
|
23
|
+
routes_output(@data[:covered], "green")
|
24
|
+
routes_output(@data[:ignored], "yellow")
|
25
|
+
routes_output(@data[:uncovered], "red")
|
23
26
|
|
24
27
|
final_output
|
25
28
|
|
26
|
-
@
|
29
|
+
@data[:uncovered_count]
|
27
30
|
end
|
28
31
|
|
29
32
|
private
|
@@ -31,36 +34,36 @@ module Swagcov
|
|
31
34
|
attr_reader :dotfile
|
32
35
|
|
33
36
|
def collect_coverage
|
34
|
-
openapi_files = ::Swagcov::OpenapiFiles.new(filepaths: dotfile.
|
37
|
+
openapi_files = ::Swagcov::OpenapiFiles.new(filepaths: dotfile.docs_config)
|
38
|
+
rails_version = ::Rails::VERSION::STRING
|
35
39
|
|
36
40
|
@routes.each do |route|
|
37
41
|
path = route.path.spec.to_s.chomp("(.:format)")
|
42
|
+
verb = rails_version > "5" ? route.verb : route.verb.inspect.gsub(%r{[$^/]}, "")
|
38
43
|
|
39
|
-
next if third_party_route?(route, path)
|
44
|
+
next if third_party_route?(route, path, rails_version)
|
40
45
|
|
41
|
-
if dotfile.ignore_path?(path)
|
42
|
-
|
43
|
-
@routes_ignored << { verb: route.verb, path: path, status: "ignored" }
|
46
|
+
if dotfile.ignore_path?(path, verb: verb)
|
47
|
+
update_data(:ignored, verb, path, "ignored")
|
44
48
|
next
|
45
49
|
end
|
46
50
|
|
47
51
|
next if dotfile.only_path_mismatch?(path)
|
48
52
|
|
49
|
-
@
|
53
|
+
@data[:total_count] += 1
|
50
54
|
|
51
|
-
if (response_keys = openapi_files.find_response_keys(path: path, route_verb:
|
52
|
-
|
53
|
-
@routes_covered << { verb: route.verb, path: path, status: response_keys.join(" ") }
|
55
|
+
if (response_keys = openapi_files.find_response_keys(path: path, route_verb: verb))
|
56
|
+
update_data(:covered, verb, path, response_keys.join(" "))
|
54
57
|
else
|
55
|
-
|
58
|
+
update_data(:uncovered, verb, path, "none")
|
56
59
|
end
|
57
60
|
end
|
58
61
|
end
|
59
62
|
|
60
|
-
def third_party_route? route, path
|
63
|
+
def third_party_route? route, path, rails_version
|
61
64
|
# https://github.com/rails/rails/blob/48f3c3e201b57a4832314b2c957a3b303e89bfea/actionpack/lib/action_dispatch/routing/inspector.rb#L105-L107
|
62
65
|
# Skips route paths like ["/rails/info/properties", "/rails/info", "/rails/mailers"]
|
63
|
-
route
|
66
|
+
internal_rails_route?(route, rails_version) ||
|
64
67
|
|
65
68
|
# Skips routes like "/sidekiq"
|
66
69
|
route.verb.blank? ||
|
@@ -71,6 +74,19 @@ module Swagcov
|
|
71
74
|
path.include?("/active_storage/") || path.include?("/action_mailbox/")
|
72
75
|
end
|
73
76
|
|
77
|
+
def internal_rails_route? route, rails_version
|
78
|
+
if rails_version > "5"
|
79
|
+
route.internal
|
80
|
+
else
|
81
|
+
::ActionDispatch::Routing::RouteWrapper.new(route).internal?
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def update_data key, verb, path, status
|
86
|
+
@data[:"#{key}_count"] += 1
|
87
|
+
@data[key] << { verb: verb, path: path, status: status }
|
88
|
+
end
|
89
|
+
|
74
90
|
def routes_output routes, status_color
|
75
91
|
routes.each do |route|
|
76
92
|
$stdout.puts(
|
@@ -84,9 +100,9 @@ module Swagcov
|
|
84
100
|
|
85
101
|
def min_width key
|
86
102
|
strings =
|
87
|
-
@
|
88
|
-
@
|
89
|
-
@
|
103
|
+
@data[:covered].map { |hash| hash[key] } +
|
104
|
+
@data[:ignored].map { |hash| hash[key] } +
|
105
|
+
@data[:uncovered].map { |hash| hash[key] }
|
90
106
|
|
91
107
|
strings.max_by(&:length).size
|
92
108
|
end
|
@@ -96,37 +112,33 @@ module Swagcov
|
|
96
112
|
$stdout.puts(
|
97
113
|
format(
|
98
114
|
"OpenAPI documentation coverage %<percentage>.2f%% (%<covered>d/%<total>d)",
|
99
|
-
{
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
format(
|
105
|
-
"%<total>s endpoints ignored",
|
106
|
-
{ total: @ignored.to_s.yellow }
|
115
|
+
{
|
116
|
+
percentage: 100.0 * @data[:covered_count] / @data[:total_count],
|
117
|
+
covered: @data[:covered_count],
|
118
|
+
total: @data[:total_count]
|
119
|
+
}
|
107
120
|
)
|
108
121
|
)
|
109
122
|
|
110
|
-
|
111
|
-
|
112
|
-
"%<total>s endpoints checked",
|
113
|
-
{ total: @total.to_s.blue }
|
114
|
-
)
|
115
|
-
)
|
123
|
+
count_output
|
124
|
+
end
|
116
125
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
126
|
+
def count_output
|
127
|
+
{
|
128
|
+
ignored: "yellow",
|
129
|
+
total: "blue",
|
130
|
+
covered: "green",
|
131
|
+
uncovered: "red"
|
132
|
+
}.each do |key, color|
|
133
|
+
count = @data[:"#{key}_count"]
|
123
134
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
135
|
+
$stdout.puts(
|
136
|
+
format(
|
137
|
+
"%<status>s #{key} #{count == 1 ? 'endpoint' : 'endpoints'}",
|
138
|
+
{ status: count.to_s.send(color) }
|
139
|
+
)
|
128
140
|
)
|
129
|
-
|
141
|
+
end
|
130
142
|
end
|
131
143
|
end
|
132
144
|
end
|
data/lib/swagcov/dotfile.rb
CHANGED
@@ -1,28 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Swagcov
|
4
|
-
class BadConfigurationError < RuntimeError
|
5
|
-
end
|
6
|
-
|
7
4
|
class Dotfile
|
8
5
|
DEFAULT_CONFIG_FILE_NAME = ".swagcov.yml"
|
9
6
|
|
10
7
|
def initialize pathname: ::Rails.root.join(DEFAULT_CONFIG_FILE_NAME)
|
11
8
|
@dotfile = load_yaml(pathname)
|
12
9
|
|
13
|
-
raise
|
10
|
+
raise ::Swagcov::Errors::BadConfiguration, "Invalid config file (#{DEFAULT_CONFIG_FILE_NAME})" unless valid?
|
11
|
+
|
12
|
+
@ignored_regex = path_config_regex(ignored_config)
|
13
|
+
@only_regex = path_config_regex(only_config)
|
14
14
|
end
|
15
15
|
|
16
|
-
def ignore_path? path
|
17
|
-
|
16
|
+
def ignore_path? path, verb:
|
17
|
+
return false unless @ignored_config
|
18
|
+
|
19
|
+
ignore_all_path_actions = @ignored_regex.match?(path)
|
20
|
+
|
21
|
+
ignored_verbs = @ignored_config.find { |config| config[path] }
|
22
|
+
|
23
|
+
return ignore_all_path_actions unless ignored_verbs.is_a?(::Hash)
|
24
|
+
|
25
|
+
ignored_verbs.values.flatten.map(&:downcase).any?(verb.downcase)
|
18
26
|
end
|
19
27
|
|
20
28
|
def only_path_mismatch? path
|
21
|
-
|
29
|
+
@only_config && !@only_regex.match?(path)
|
22
30
|
end
|
23
31
|
|
24
|
-
def
|
25
|
-
dotfile.dig("docs", "paths")
|
32
|
+
def docs_config
|
33
|
+
@docs_config ||= dotfile.dig("docs", "paths")
|
34
|
+
end
|
35
|
+
|
36
|
+
def ignored_config
|
37
|
+
@ignored_config ||= dotfile.dig("routes", "paths", "ignore")
|
38
|
+
end
|
39
|
+
|
40
|
+
def only_config
|
41
|
+
@only_config ||= dotfile.dig("routes", "paths", "only")
|
26
42
|
end
|
27
43
|
|
28
44
|
private
|
@@ -30,31 +46,32 @@ module Swagcov
|
|
30
46
|
attr_reader :dotfile
|
31
47
|
|
32
48
|
def load_yaml pathname
|
33
|
-
|
49
|
+
unless pathname.exist?
|
50
|
+
raise ::Swagcov::Errors::BadConfiguration, "Missing config file (#{DEFAULT_CONFIG_FILE_NAME})"
|
51
|
+
end
|
34
52
|
|
35
|
-
YAML.load_file(pathname)
|
53
|
+
::YAML.load_file(pathname)
|
36
54
|
rescue Psych::SyntaxError
|
37
|
-
raise
|
38
|
-
end
|
39
|
-
|
40
|
-
def ignored_regex
|
41
|
-
@ignored_regex ||= path_config_regex(dotfile.dig("routes", "paths", "ignore"))
|
42
|
-
end
|
43
|
-
|
44
|
-
def only_regex
|
45
|
-
@only_regex ||= path_config_regex(dotfile.dig("routes", "paths", "only"))
|
55
|
+
raise ::Swagcov::Errors::BadConfiguration, "Malinformed config file (#{DEFAULT_CONFIG_FILE_NAME})"
|
46
56
|
end
|
47
57
|
|
48
58
|
def path_config_regex path_config
|
49
59
|
return unless path_config
|
50
60
|
|
51
|
-
config =
|
61
|
+
config =
|
62
|
+
path_config.map do |path|
|
63
|
+
if path.is_a?(::Hash)
|
64
|
+
"^#{path.keys.first}$"
|
65
|
+
else
|
66
|
+
path.first == "^" ? path : "^#{path}$"
|
67
|
+
end
|
68
|
+
end
|
52
69
|
|
53
70
|
/#{config.join('|')}/
|
54
71
|
end
|
55
72
|
|
56
73
|
def valid?
|
57
|
-
dotfile &&
|
74
|
+
dotfile && docs_config
|
58
75
|
end
|
59
76
|
end
|
60
77
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Swagcov
|
4
|
+
class Install
|
5
|
+
attr_reader :dotfile
|
6
|
+
|
7
|
+
def initialize pathname: ::Rails.root.join(::Swagcov::Dotfile::DEFAULT_CONFIG_FILE_NAME).to_s
|
8
|
+
@dotfile = pathname
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate_dotfile
|
12
|
+
if ::File.exist?(dotfile)
|
13
|
+
$stdout.puts "#{dotfile} already exists"
|
14
|
+
return
|
15
|
+
end
|
16
|
+
|
17
|
+
::File.write(
|
18
|
+
dotfile,
|
19
|
+
<<~YAML
|
20
|
+
## Required field:
|
21
|
+
# List your OpenAPI documentation files
|
22
|
+
docs:
|
23
|
+
paths:
|
24
|
+
- swagger.yaml
|
25
|
+
|
26
|
+
## Optional fields:
|
27
|
+
# routes:
|
28
|
+
# paths:
|
29
|
+
# only:
|
30
|
+
# - ^/v2 # only track v2 endpoints
|
31
|
+
# ignore:
|
32
|
+
# - /v2/users # do not track certain endpoints
|
33
|
+
# - /v2/users/:id: # ignore only certain actions (verbs)
|
34
|
+
# - GET
|
35
|
+
YAML
|
36
|
+
)
|
37
|
+
|
38
|
+
$stdout.puts "created #{::Swagcov::Dotfile::DEFAULT_CONFIG_FILE_NAME}"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -9,7 +9,7 @@ module Swagcov
|
|
9
9
|
|
10
10
|
def find_response_keys path:, route_verb:
|
11
11
|
# replace :id with {id}
|
12
|
-
regex = Regexp.new("^#{path.gsub(%r{:[^/]+}, '\\{[^/]+\\}')}?$")
|
12
|
+
regex = ::Regexp.new("^#{path.gsub(%r{:[^/]+}, '\\{[^/]+\\}')}?$")
|
13
13
|
|
14
14
|
matching_paths_key = @openapi_paths.keys.grep(regex).first
|
15
15
|
matching_request_method_key = @openapi_paths.dig(matching_paths_key, route_verb.downcase)
|
@@ -20,15 +20,15 @@ module Swagcov
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def load_yamls
|
23
|
-
Dir.glob(@filepaths).reduce({}) do |hash, filepath|
|
23
|
+
::Dir.glob(@filepaths).reduce({}) do |hash, filepath|
|
24
24
|
hash.merge(load_yaml(filepath))
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
def load_yaml filepath
|
29
|
-
YAML.load_file(filepath)["paths"]
|
30
|
-
rescue Psych::SyntaxError
|
31
|
-
raise
|
29
|
+
::YAML.load_file(filepath)["paths"]
|
30
|
+
rescue ::Psych::SyntaxError
|
31
|
+
raise ::Swagcov::Errors::BadConfiguration, "Malinformed openapi file (#{filepath})"
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
data/lib/swagcov/version.rb
CHANGED
data/lib/swagcov.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
4
|
-
|
5
|
-
if defined?(Rails)
|
6
|
-
require "swagcov/railtie"
|
7
|
-
require "swagcov/dotfile"
|
8
|
-
require "swagcov/coverage"
|
9
|
-
require "swagcov/openapi_files"
|
10
|
-
end
|
3
|
+
require "rails"
|
4
|
+
require "active_support/core_ext"
|
11
5
|
|
12
6
|
require "swagcov/core_ext/string"
|
7
|
+
require "swagcov/coverage"
|
8
|
+
require "swagcov/dotfile"
|
9
|
+
require "swagcov/errors"
|
10
|
+
require "swagcov/install"
|
11
|
+
require "swagcov/openapi_files"
|
12
|
+
require "swagcov/railtie"
|
13
|
+
require "swagcov/version"
|
13
14
|
|
14
15
|
module Swagcov
|
15
16
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: swagcov
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sarah Ridge
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-
|
10
|
+
date: 2025-04-09 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rails
|
@@ -15,20 +15,21 @@ dependencies:
|
|
15
15
|
requirements:
|
16
16
|
- - ">="
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: '
|
18
|
+
version: '4.2'
|
19
19
|
type: :runtime
|
20
20
|
prerelease: false
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
22
22
|
requirements:
|
23
23
|
- - ">="
|
24
24
|
- !ruby/object:Gem::Version
|
25
|
-
version: '
|
25
|
+
version: '4.2'
|
26
26
|
email:
|
27
27
|
- sarahmarie@hey.com
|
28
28
|
executables: []
|
29
29
|
extensions: []
|
30
30
|
extra_rdoc_files: []
|
31
31
|
files:
|
32
|
+
- CHANGELOG.md
|
32
33
|
- LICENSE
|
33
34
|
- README.md
|
34
35
|
- Rakefile
|
@@ -36,10 +37,13 @@ files:
|
|
36
37
|
- lib/swagcov/core_ext/string.rb
|
37
38
|
- lib/swagcov/coverage.rb
|
38
39
|
- lib/swagcov/dotfile.rb
|
40
|
+
- lib/swagcov/errors.rb
|
41
|
+
- lib/swagcov/install.rb
|
39
42
|
- lib/swagcov/openapi_files.rb
|
40
43
|
- lib/swagcov/railtie.rb
|
41
44
|
- lib/swagcov/version.rb
|
42
|
-
- lib/tasks/
|
45
|
+
- lib/tasks/swagcov.rake
|
46
|
+
- lib/tasks/swagcov/install.rake
|
43
47
|
homepage: https://github.com/smridge/swagcov
|
44
48
|
licenses:
|
45
49
|
- MIT
|
File without changes
|