swagcov 0.6.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 +4 -4
- data/CHANGELOG.md +56 -31
- data/README.md +9 -1
- data/lib/swagcov/command/generate_dotfile.rb +45 -0
- data/lib/swagcov/command/generate_todo_file.rb +52 -0
- data/lib/swagcov/command/report_coverage.rb +20 -0
- data/lib/swagcov/coverage.rb +6 -71
- data/lib/swagcov/dotfile.rb +23 -14
- data/lib/swagcov/formatter/console.rb +78 -0
- data/lib/swagcov/openapi_files.rb +1 -1
- data/lib/swagcov/version.rb +1 -1
- data/lib/swagcov.rb +13 -2
- data/lib/tasks/swagcov/generate_todo.rake +8 -0
- data/lib/tasks/swagcov/install.rake +1 -1
- data/lib/tasks/swagcov.rake +1 -1
- metadata +8 -4
- data/lib/swagcov/install.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1df02b05f23038aacedc8a990a47012d27f90f64f7185c689507face26acd8c4
|
4
|
+
data.tar.gz: 8d2e127ed1b1de208ef87fe6a8920fe505fbdceade1f430300b26e2bb6441d19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4faad26270ff8aceddad224fdb26b6fcd8c86eb0d1c2a75c8bff082aa829187a5d571b7aff037b4a8c5bc907c26c446d55a5807420b111f18abc5c7b475a445c
|
7
|
+
data.tar.gz: a8bbfa8964e97929d4e190353729e399e9f0bf59d78acef28084699e902be2689bf8e7bf2a2ea3289f10114040c10112204c0954da319da4c38971c6ea7f0c5e
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,30 @@
|
|
2
2
|
## main (unreleased)
|
3
3
|
-
|
4
4
|
|
5
|
+
## 0.7.0 (2025-04-18)
|
6
|
+
### Enhancement
|
7
|
+
- Add support for Ruby 3.5 ([#98](https://github.com/smridge/swagcov/pull/98))
|
8
|
+
- Add rake task for auto-generation of `.swagcov_todo.yml` file ([#93](https://github.com/smridge/swagcov/pull/93), [#96](https://github.com/smridge/swagcov/pull/96))
|
9
|
+
```shell
|
10
|
+
bundle exec rake swagcov:generate_todo
|
11
|
+
```
|
12
|
+
|
13
|
+
### Refactor
|
14
|
+
- Add `Swagcov.project_root` method ([#86](https://github.com/smridge/swagcov/pull/86))
|
15
|
+
- Separate coverage collection and output ([#83](https://github.com/smridge/swagcov/pull/83))
|
16
|
+
- Replace ActiveSupport string method with ruby string method ([#85](https://github.com/smridge/swagcov/pull/85))
|
17
|
+
- Replace `Swagcov::Coverage.new.report` with `Swagcov::Command::ReportCoverage.new.run` ([#89](https://github.com/smridge/swagcov/pull/89))
|
18
|
+
- Rename `Swagcov::Install` to `Swagcov::Command::GenerateDotfile` ([#88](https://github.com/smridge/swagcov/pull/88))
|
19
|
+
- Refactor `GenerateDotfile` to be consistent with `GenerateTodoFile` ([#97](https://github.com/smridge/swagcov/pull/97))
|
20
|
+
|
21
|
+
### Fix
|
22
|
+
- Add exit code to install task + update messaging ([#87](https://github.com/smridge/swagcov/pull/87))
|
23
|
+
- Ignored path verb matching when duplicate path keys are present ([#92](https://github.com/smridge/swagcov/pull/92))
|
24
|
+
- Fix exit code error handling ([#95](https://github.com/smridge/swagcov/pull/95))
|
25
|
+
|
26
|
+
### Development
|
27
|
+
- Add irb console for local development ([#94](https://github.com/smridge/swagcov/pull/94))
|
28
|
+
|
5
29
|
## 0.6.0 (2025-04-09)
|
6
30
|
### Fix
|
7
31
|
- Grammatical number for endpoint(s) count output ([#78](https://github.com/smridge/swagcov/pull/78))
|
@@ -15,23 +39,23 @@
|
|
15
39
|
- Improve path matching processing for `ignore` and `only` routes ([#65](https://github.com/smridge/swagcov/pull/65))
|
16
40
|
|
17
41
|
### Code Coverage
|
18
|
-
|
42
|
+
- Add test coverage reporting ([#68](https://github.com/smridge/swagcov/pull/68), [#69](https://github.com/smridge/swagcov/pull/69))
|
19
43
|
|
20
44
|
## 0.5.0 (2025-03-26)
|
21
45
|
### Enhancement
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
46
|
+
- Add rake task for configuration installation ([#59](https://github.com/smridge/swagcov/pull/59))
|
47
|
+
```shell
|
48
|
+
bundle exec rake swagcov:install
|
49
|
+
```
|
50
|
+
- Extend `ignore` routes configuration to exclude only specific actions ([#60](https://github.com/smridge/swagcov/pull/60))
|
51
|
+
```yml
|
52
|
+
routes:
|
53
|
+
paths:
|
54
|
+
ignore:
|
55
|
+
- /v2/users # existing configuration that ignores all associated actions (verbs)
|
56
|
+
- /v2/users/:id: # new option to extend to specific actions
|
57
|
+
- GET
|
58
|
+
```
|
35
59
|
|
36
60
|
## 0.4.1 (2025-03-18)
|
37
61
|
### Fix
|
@@ -45,48 +69,49 @@
|
|
45
69
|
|
46
70
|
## 0.3.0 (2022-02-21)
|
47
71
|
### Enhancement
|
48
|
-
|
72
|
+
- Raise specific `Swagcov::BadConfigurationError` for malformed yaml files ([#23](https://github.com/smridge/swagcov/pull/23))
|
49
73
|
|
50
74
|
### Security
|
51
|
-
|
75
|
+
- Require Multi-Factor Authentication for RubyGems privileged operations ([#16](https://github.com/smridge/swagcov/pull/16))
|
52
76
|
|
53
77
|
### Code Coverage
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
78
|
+
- Add Sandbox Application and specs for Rails 5.1 ([#20](https://github.com/smridge/swagcov/pull/20))
|
79
|
+
- Add specs for Rails 5.2 ([#7](https://github.com/smridge/swagcov/pull/7)), ([#14](https://github.com/smridge/swagcov/pull/14))
|
80
|
+
- Add Sandbox Application and specs for Rails 6.0 ([#17](https://github.com/smridge/swagcov/pull/17))
|
81
|
+
- Add Sandbox Application and specs for Rails 6.1 ([#22](https://github.com/smridge/swagcov/pull/22))
|
82
|
+
- Add GitHub Actions to run specs ([#18](https://github.com/smridge/swagcov/pull/18))
|
83
|
+
- Add GitHub CodeQL ([#13](https://github.com/smridge/swagcov/pull/13))
|
60
84
|
|
61
85
|
### Refactor
|
62
|
-
|
63
|
-
|
86
|
+
- Move `SystemExit` to rake task for easier testing ([#24](https://github.com/smridge/swagcov/pull/24))
|
87
|
+
- Reduce complexity when matching routes ([#15](https://github.com/smridge/swagcov/pull/15))
|
64
88
|
|
65
89
|
## 0.2.5 (2021-09-14)
|
66
90
|
### Fix
|
67
|
-
|
91
|
+
- Matching routes against swagger paths. Previously, partial paths could result in a match ([#12](https://github.com/smridge/swagcov/pull/12))
|
68
92
|
|
69
93
|
## 0.2.4 (2021-04-30)
|
70
94
|
### Fix
|
71
|
-
|
95
|
+
- If a route path does not start with "^" match the entire path ([#5](https://github.com/smridge/swagcov/pull/5))
|
96
|
+
|
72
97
|
### Enhancement
|
73
|
-
|
98
|
+
- Raise specific `Swagcov::BadConfigurationError` error if bad or missing configuration ([#5](https://github.com/smridge/swagcov/pull/5))
|
74
99
|
|
75
100
|
## 0.2.3 (2021-04-23)
|
76
101
|
### Fix
|
77
|
-
|
102
|
+
- Exclude ActiveStorage and ActionMailer routes ([#3](https://github.com/smridge/swagcov/pull/3))
|
78
103
|
|
79
104
|
## 0.2.2 (2021-04-22)
|
80
105
|
### Fix
|
81
|
-
|
106
|
+
- Exclude Rails Internal Routes and Mounted Applications ([#2](https://github.com/smridge/swagcov/pull/2))
|
82
107
|
|
83
108
|
## 0.2.1 (2021-04-21)
|
84
109
|
### Fix
|
85
|
-
|
110
|
+
- Exceptions caused by missing dependency for strings. ([#1](https://github.com/smridge/swagcov/pull/1))
|
86
111
|
|
87
112
|
## 0.2.0 (2021-04-20)
|
88
113
|
### Enhancement
|
89
|
-
|
114
|
+
- Add Exit status to easily build a pass/fail into build pipeline
|
90
115
|
|
91
116
|
## 0.1.0 (2021-02-24)
|
92
117
|
- Create Rake Task for checking documentation coverage (rails only)
|
data/README.md
CHANGED
@@ -15,6 +15,12 @@ See OpenAPI documentation coverage report for Rails Routes.
|
|
15
15
|
- See overview of different endpoints covered, missing and what you choose to ignore.
|
16
16
|
- Add pass/fail to your build pipeline when missing Documentation Coverage.
|
17
17
|
|
18
|
+
| `rake task` | `rails console` | Description |
|
19
|
+
| :--- | :--- | :--- |
|
20
|
+
| `rake swagcov` | `Swagcov::Command::ReportCoverage.new.run` | Check documentation coverage |
|
21
|
+
| `rake swagcov:install` | `Swagcov::Command::GenerateDotfile.new.run` | Install required `.swagcov.yml` config file |
|
22
|
+
| `rake swagcov:generate_todo` | `Swagcov::Command::GenerateTodoFile.new.run` | Generate `.swagcov_todo.yml` |
|
23
|
+
|
18
24
|
## Ruby and Rails Version Support
|
19
25
|
Versioning support from a test coverage perspective, see [tests.yml](/.github/workflows/tests.yml) for detail
|
20
26
|
| `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` |
|
@@ -27,6 +33,7 @@ Versioning support from a test coverage perspective, see [tests.yml](/.github/wo
|
|
27
33
|
| `3.2` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
28
34
|
| `3.3` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
29
35
|
| `3.4` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
36
|
+
| `3.5` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
30
37
|
|
31
38
|
## Installation
|
32
39
|
Add this line to your application's Gemfile:
|
@@ -88,7 +95,8 @@ Execute:
|
|
88
95
|
bundle exec rake swagcov
|
89
96
|
```
|
90
97
|
|
91
|
-
|
98
|
+
## Examples
|
99
|
+
Configurations and output from running `bundle exec rake swagcov` from the root of your Rails Application
|
92
100
|
- All Routes (minimal configuration):
|
93
101
|
```yml
|
94
102
|
docs:
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Swagcov
|
4
|
+
module Command
|
5
|
+
class GenerateDotfile
|
6
|
+
attr_reader :dotfile
|
7
|
+
|
8
|
+
def initialize basename: ::Swagcov::Dotfile::DEFAULT_CONFIG_FILE_NAME
|
9
|
+
@dotfile = ::Swagcov.project_root.join(basename)
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
if ::File.exist?(@dotfile)
|
14
|
+
$stdout.puts "#{@dotfile.basename} already exists at #{@dotfile.dirname}"
|
15
|
+
return ::Swagcov::STATUS_ERROR
|
16
|
+
end
|
17
|
+
|
18
|
+
::File.write(
|
19
|
+
dotfile,
|
20
|
+
<<~YAML
|
21
|
+
## Required field:
|
22
|
+
# List your OpenAPI documentation files
|
23
|
+
docs:
|
24
|
+
paths:
|
25
|
+
- swagger.yaml
|
26
|
+
|
27
|
+
## Optional fields:
|
28
|
+
# routes:
|
29
|
+
# paths:
|
30
|
+
# only:
|
31
|
+
# - ^/v2 # only track v2 endpoints
|
32
|
+
# ignore:
|
33
|
+
# - /v2/users # do not track certain endpoints
|
34
|
+
# - /v2/users/:id: # ignore only certain actions (verbs)
|
35
|
+
# - GET
|
36
|
+
YAML
|
37
|
+
)
|
38
|
+
|
39
|
+
$stdout.puts "created #{@dotfile.basename} at #{@dotfile.dirname}"
|
40
|
+
|
41
|
+
::Swagcov::STATUS_SUCCESS
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Swagcov
|
4
|
+
module Command
|
5
|
+
class GenerateTodoFile
|
6
|
+
def initialize basename: ::Swagcov::Dotfile::TODO_CONFIG_FILE_NAME,
|
7
|
+
data: ::Swagcov::Coverage.new(dotfile: ::Swagcov::Dotfile.new(skip_todo: true)).collect[:uncovered]
|
8
|
+
@dotfile = ::Swagcov.project_root.join(basename)
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
::File.write(
|
14
|
+
@dotfile,
|
15
|
+
<<~YAML
|
16
|
+
# This configuration was auto generated
|
17
|
+
# The intent is to remove these route configurations as documentation is added
|
18
|
+
#{routes_yaml}
|
19
|
+
YAML
|
20
|
+
)
|
21
|
+
|
22
|
+
$stdout.puts "created #{@dotfile.basename} at #{@dotfile.dirname}"
|
23
|
+
|
24
|
+
::Swagcov::STATUS_SUCCESS
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def routes_yaml
|
30
|
+
return if routes.empty?
|
31
|
+
|
32
|
+
{
|
33
|
+
"routes" => {
|
34
|
+
"paths" => {
|
35
|
+
"ignore" => routes
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}.to_yaml.strip
|
39
|
+
end
|
40
|
+
|
41
|
+
def routes
|
42
|
+
hash = {}
|
43
|
+
|
44
|
+
@data.each do |route|
|
45
|
+
hash[route[:path]] ? hash[route[:path]] << route[:verb] : hash[route[:path]] = [route[:verb]]
|
46
|
+
end
|
47
|
+
|
48
|
+
@routes ||= hash.map { |key, value| { key => value } }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Swagcov
|
4
|
+
module Command
|
5
|
+
class ReportCoverage
|
6
|
+
def initialize data: nil
|
7
|
+
@data = data
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
data = @data || ::Swagcov::Coverage.new.collect
|
12
|
+
|
13
|
+
::Swagcov::Formatter::Console.new(data: data).run
|
14
|
+
rescue ::Swagcov::Errors::BadConfiguration => e
|
15
|
+
warn "#{e.class}: #{e.message}"
|
16
|
+
::Swagcov::STATUS_ERROR
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/swagcov/coverage.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Swagcov
|
4
4
|
class Coverage
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :dotfile
|
6
6
|
|
7
7
|
def initialize dotfile: ::Swagcov::Dotfile.new, routes: ::Rails.application.routes.routes
|
8
8
|
@dotfile = dotfile
|
@@ -18,22 +18,7 @@ module Swagcov
|
|
18
18
|
}
|
19
19
|
end
|
20
20
|
|
21
|
-
def
|
22
|
-
collect_coverage
|
23
|
-
routes_output(@data[:covered], "green")
|
24
|
-
routes_output(@data[:ignored], "yellow")
|
25
|
-
routes_output(@data[:uncovered], "red")
|
26
|
-
|
27
|
-
final_output
|
28
|
-
|
29
|
-
@data[:uncovered_count]
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
attr_reader :dotfile
|
35
|
-
|
36
|
-
def collect_coverage
|
21
|
+
def collect
|
37
22
|
openapi_files = ::Swagcov::OpenapiFiles.new(filepaths: dotfile.docs_config)
|
38
23
|
rails_version = ::Rails::VERSION::STRING
|
39
24
|
|
@@ -58,8 +43,12 @@ module Swagcov
|
|
58
43
|
update_data(:uncovered, verb, path, "none")
|
59
44
|
end
|
60
45
|
end
|
46
|
+
|
47
|
+
@data
|
61
48
|
end
|
62
49
|
|
50
|
+
private
|
51
|
+
|
63
52
|
def third_party_route? route, path, rails_version
|
64
53
|
# https://github.com/rails/rails/blob/48f3c3e201b57a4832314b2c957a3b303e89bfea/actionpack/lib/action_dispatch/routing/inspector.rb#L105-L107
|
65
54
|
# Skips route paths like ["/rails/info/properties", "/rails/info", "/rails/mailers"]
|
@@ -86,59 +75,5 @@ module Swagcov
|
|
86
75
|
@data[:"#{key}_count"] += 1
|
87
76
|
@data[key] << { verb: verb, path: path, status: status }
|
88
77
|
end
|
89
|
-
|
90
|
-
def routes_output routes, status_color
|
91
|
-
routes.each do |route|
|
92
|
-
$stdout.puts(
|
93
|
-
format(
|
94
|
-
"%<verb>10s %<path>-#{min_width(:path) + 1}s %<status>s",
|
95
|
-
{ verb: route[:verb], path: route[:path], status: route[:status].send(status_color) }
|
96
|
-
)
|
97
|
-
)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
def min_width key
|
102
|
-
strings =
|
103
|
-
@data[:covered].map { |hash| hash[key] } +
|
104
|
-
@data[:ignored].map { |hash| hash[key] } +
|
105
|
-
@data[:uncovered].map { |hash| hash[key] }
|
106
|
-
|
107
|
-
strings.max_by(&:length).size
|
108
|
-
end
|
109
|
-
|
110
|
-
def final_output
|
111
|
-
$stdout.puts
|
112
|
-
$stdout.puts(
|
113
|
-
format(
|
114
|
-
"OpenAPI documentation coverage %<percentage>.2f%% (%<covered>d/%<total>d)",
|
115
|
-
{
|
116
|
-
percentage: 100.0 * @data[:covered_count] / @data[:total_count],
|
117
|
-
covered: @data[:covered_count],
|
118
|
-
total: @data[:total_count]
|
119
|
-
}
|
120
|
-
)
|
121
|
-
)
|
122
|
-
|
123
|
-
count_output
|
124
|
-
end
|
125
|
-
|
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"]
|
134
|
-
|
135
|
-
$stdout.puts(
|
136
|
-
format(
|
137
|
-
"%<status>s #{key} #{count == 1 ? 'endpoint' : 'endpoints'}",
|
138
|
-
{ status: count.to_s.send(color) }
|
139
|
-
)
|
140
|
-
)
|
141
|
-
end
|
142
|
-
end
|
143
78
|
end
|
144
79
|
end
|
data/lib/swagcov/dotfile.rb
CHANGED
@@ -3,12 +3,14 @@
|
|
3
3
|
module Swagcov
|
4
4
|
class Dotfile
|
5
5
|
DEFAULT_CONFIG_FILE_NAME = ".swagcov.yml"
|
6
|
+
TODO_CONFIG_FILE_NAME = ".swagcov_todo.yml"
|
6
7
|
|
7
|
-
def initialize
|
8
|
-
@dotfile = load_yaml(
|
8
|
+
def initialize basename: DEFAULT_CONFIG_FILE_NAME, todo_basename: TODO_CONFIG_FILE_NAME, skip_todo: false
|
9
|
+
@dotfile = load_yaml(basename, required: true)
|
9
10
|
|
10
11
|
raise ::Swagcov::Errors::BadConfiguration, "Invalid config file (#{DEFAULT_CONFIG_FILE_NAME})" unless valid?
|
11
12
|
|
13
|
+
@todo_file = load_yaml(todo_basename) unless skip_todo
|
12
14
|
@ignored_regex = path_config_regex(ignored_config)
|
13
15
|
@only_regex = path_config_regex(only_config)
|
14
16
|
end
|
@@ -18,11 +20,12 @@ module Swagcov
|
|
18
20
|
|
19
21
|
ignore_all_path_actions = @ignored_regex.match?(path)
|
20
22
|
|
21
|
-
ignored_verbs =
|
23
|
+
ignored_verbs =
|
24
|
+
@ignored_config.select { |config| config[path]&.is_a?(::Array) }.map(&:values).flatten.map(&:downcase)
|
22
25
|
|
23
|
-
return ignore_all_path_actions
|
26
|
+
return ignore_all_path_actions if ignored_verbs.empty?
|
24
27
|
|
25
|
-
ignored_verbs.
|
28
|
+
ignored_verbs.any?(verb.downcase)
|
26
29
|
end
|
27
30
|
|
28
31
|
def only_path_mismatch? path
|
@@ -34,7 +37,11 @@ module Swagcov
|
|
34
37
|
end
|
35
38
|
|
36
39
|
def ignored_config
|
37
|
-
|
40
|
+
dotfile_routes = dotfile.dig("routes", "paths", "ignore").to_a
|
41
|
+
todo_routes = todo_file ? todo_file.dig("routes", "paths", "ignore").to_a : []
|
42
|
+
routes = dotfile_routes + todo_routes
|
43
|
+
|
44
|
+
@ignored_config ||= routes.empty? ? nil : routes
|
38
45
|
end
|
39
46
|
|
40
47
|
def only_config
|
@@ -43,16 +50,18 @@ module Swagcov
|
|
43
50
|
|
44
51
|
private
|
45
52
|
|
46
|
-
attr_reader :dotfile
|
53
|
+
attr_reader :dotfile, :todo_file
|
54
|
+
|
55
|
+
def load_yaml basename, required: false
|
56
|
+
pathname = ::Swagcov.project_root.join(basename)
|
57
|
+
|
58
|
+
raise ::Swagcov::Errors::BadConfiguration, "Missing config file (#{basename})" if !pathname.exist? && required
|
47
59
|
|
48
|
-
|
49
|
-
unless pathname.exist?
|
50
|
-
raise ::Swagcov::Errors::BadConfiguration, "Missing config file (#{DEFAULT_CONFIG_FILE_NAME})"
|
51
|
-
end
|
60
|
+
return unless pathname.exist?
|
52
61
|
|
53
62
|
::YAML.load_file(pathname)
|
54
|
-
rescue Psych::SyntaxError
|
55
|
-
raise ::Swagcov::Errors::BadConfiguration, "
|
63
|
+
rescue ::Psych::SyntaxError
|
64
|
+
raise ::Swagcov::Errors::BadConfiguration, "Malformed config file (#{basename})"
|
56
65
|
end
|
57
66
|
|
58
67
|
def path_config_regex path_config
|
@@ -63,7 +72,7 @@ module Swagcov
|
|
63
72
|
if path.is_a?(::Hash)
|
64
73
|
"^#{path.keys.first}$"
|
65
74
|
else
|
66
|
-
path.
|
75
|
+
path.chr == "^" ? path : "^#{path}$"
|
67
76
|
end
|
68
77
|
end
|
69
78
|
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Swagcov
|
4
|
+
module Formatter
|
5
|
+
class Console
|
6
|
+
attr_reader :data
|
7
|
+
|
8
|
+
def initialize data: ::Swagcov::Coverage.new.collect
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
routes_output(data[:covered], "green")
|
14
|
+
routes_output(data[:ignored], "yellow")
|
15
|
+
routes_output(data[:uncovered], "red")
|
16
|
+
final_output
|
17
|
+
|
18
|
+
data[:uncovered_count].zero? ? ::Swagcov::STATUS_SUCCESS : ::Swagcov::STATUS_OFFENSES
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def routes_output routes, status_color
|
24
|
+
routes.each do |route|
|
25
|
+
$stdout.puts(
|
26
|
+
format(
|
27
|
+
"%<verb>10s %<path>-#{min_width(:path) + 1}s %<status>s",
|
28
|
+
{ verb: route[:verb], path: route[:path], status: route[:status].send(status_color) }
|
29
|
+
)
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def min_width key
|
35
|
+
strings =
|
36
|
+
data[:covered].map { |hash| hash[key] } +
|
37
|
+
data[:ignored].map { |hash| hash[key] } +
|
38
|
+
data[:uncovered].map { |hash| hash[key] }
|
39
|
+
|
40
|
+
strings.max_by(&:length).size
|
41
|
+
end
|
42
|
+
|
43
|
+
def final_output
|
44
|
+
$stdout.puts
|
45
|
+
$stdout.puts(
|
46
|
+
format(
|
47
|
+
"OpenAPI documentation coverage %<percentage>.2f%% (%<covered>d/%<total>d)",
|
48
|
+
{
|
49
|
+
percentage: 100.0 * data[:covered_count] / data[:total_count],
|
50
|
+
covered: data[:covered_count],
|
51
|
+
total: data[:total_count]
|
52
|
+
}
|
53
|
+
)
|
54
|
+
)
|
55
|
+
|
56
|
+
count_output
|
57
|
+
end
|
58
|
+
|
59
|
+
def count_output
|
60
|
+
{
|
61
|
+
ignored: "yellow",
|
62
|
+
total: "blue",
|
63
|
+
covered: "green",
|
64
|
+
uncovered: "red"
|
65
|
+
}.each do |key, color|
|
66
|
+
count = data[:"#{key}_count"]
|
67
|
+
|
68
|
+
$stdout.puts(
|
69
|
+
format(
|
70
|
+
"%<status>s #{key} #{count == 1 ? 'endpoint' : 'endpoints'}",
|
71
|
+
{ status: count.to_s.send(color) }
|
72
|
+
)
|
73
|
+
)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -28,7 +28,7 @@ module Swagcov
|
|
28
28
|
def load_yaml filepath
|
29
29
|
::YAML.load_file(filepath)["paths"]
|
30
30
|
rescue ::Psych::SyntaxError
|
31
|
-
raise ::Swagcov::Errors::BadConfiguration, "
|
31
|
+
raise ::Swagcov::Errors::BadConfiguration, "Malformed openapi file (#{filepath})"
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
data/lib/swagcov/version.rb
CHANGED
data/lib/swagcov.rb
CHANGED
@@ -1,16 +1,27 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "rails"
|
4
|
-
require "active_support/core_ext"
|
5
4
|
|
5
|
+
require "swagcov/command/generate_dotfile"
|
6
|
+
require "swagcov/command/generate_todo_file"
|
7
|
+
require "swagcov/command/report_coverage"
|
6
8
|
require "swagcov/core_ext/string"
|
9
|
+
require "swagcov/formatter/console"
|
7
10
|
require "swagcov/coverage"
|
8
11
|
require "swagcov/dotfile"
|
9
12
|
require "swagcov/errors"
|
10
|
-
require "swagcov/install"
|
11
13
|
require "swagcov/openapi_files"
|
12
14
|
require "swagcov/railtie"
|
13
15
|
require "swagcov/version"
|
14
16
|
|
15
17
|
module Swagcov
|
18
|
+
module_function
|
19
|
+
|
20
|
+
STATUS_SUCCESS = 0
|
21
|
+
STATUS_OFFENSES = 1
|
22
|
+
STATUS_ERROR = 2
|
23
|
+
|
24
|
+
def project_root
|
25
|
+
::Rails.root || ::Pathname.new(::FileUtils.pwd)
|
26
|
+
end
|
16
27
|
end
|
data/lib/tasks/swagcov.rake
CHANGED
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.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sarah Ridge
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: rails
|
@@ -34,15 +34,19 @@ files:
|
|
34
34
|
- README.md
|
35
35
|
- Rakefile
|
36
36
|
- lib/swagcov.rb
|
37
|
+
- lib/swagcov/command/generate_dotfile.rb
|
38
|
+
- lib/swagcov/command/generate_todo_file.rb
|
39
|
+
- lib/swagcov/command/report_coverage.rb
|
37
40
|
- lib/swagcov/core_ext/string.rb
|
38
41
|
- lib/swagcov/coverage.rb
|
39
42
|
- lib/swagcov/dotfile.rb
|
40
43
|
- lib/swagcov/errors.rb
|
41
|
-
- lib/swagcov/
|
44
|
+
- lib/swagcov/formatter/console.rb
|
42
45
|
- lib/swagcov/openapi_files.rb
|
43
46
|
- lib/swagcov/railtie.rb
|
44
47
|
- lib/swagcov/version.rb
|
45
48
|
- lib/tasks/swagcov.rake
|
49
|
+
- lib/tasks/swagcov/generate_todo.rake
|
46
50
|
- lib/tasks/swagcov/install.rake
|
47
51
|
homepage: https://github.com/smridge/swagcov
|
48
52
|
licenses:
|
@@ -67,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
71
|
- !ruby/object:Gem::Version
|
68
72
|
version: '0'
|
69
73
|
requirements: []
|
70
|
-
rubygems_version: 3.6.
|
74
|
+
rubygems_version: 3.6.8
|
71
75
|
specification_version: 4
|
72
76
|
summary: OpenAPI documentation coverage for Rails Routes
|
73
77
|
test_files: []
|
data/lib/swagcov/install.rb
DELETED
@@ -1,41 +0,0 @@
|
|
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
|