swagcov 0.10.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f7e8120c6da2d859ae0712f523ee0586e9e800c842594ef89c7fdaed3a28ee0
4
- data.tar.gz: c884efd95e1dc61fba493ba731633087baf546612a00a83489f3d4abc7c38cff
3
+ metadata.gz: 142f669b882f17b5a640aa9cd72b0cc12019cda4e4bc48d9fea5d432fcfff505
4
+ data.tar.gz: 5eac1740f216095d93ec1d0f69553eab305aa60ac8e8fb3935a9d75446db05ea
5
5
  SHA512:
6
- metadata.gz: d000402186ba36251cbdc689374979e863dce7b23f154837eba4e177bc484de337bf4928cc8d547bd71d20b7db323ab08cc378590871b2502c72a2398b8749e6
7
- data.tar.gz: 74144d434fd8ba835564b3fc92a9a63b318b74c438390213a9cd62cfba0705666464d3363d3d732eff05b46ddacb9105547352310ffeb7e166e5a5834efccba3
6
+ metadata.gz: 283c6d98acb19f7184ba06ef95a184fcb2844062647699a934ffd5ecb1f4f1c34f47df7cd5ede1aae39a4277f84c3237aed655e4268094921b48ac34ef0f1b73
7
+ data.tar.gz: 6107ded5f46b2472d38dc4a454ff01bb8da7dcbddc1668b22858031e38a8c3097781b32c794dfbd064a9e13e19d426482d06c1c9935059725069e94255b76cdd
data/CHANGELOG.md CHANGED
@@ -2,9 +2,25 @@
2
2
  ## main (unreleased)
3
3
  -
4
4
 
5
+ ## 1.0.0 (2025-05-19)
6
+ ### Refactor
7
+ - Default Environment Variable approach ([#143](https://github.com/smridge/swagcov/pull/143))
8
+ - `swagcov` is considered tested and stable for a version 1.0.0 release, see [README](/README.md) for documentation
9
+
10
+ ## 0.11.0 (2025-05-13)
11
+ ### Enhancement
12
+ - Add swagcov `version` option ([#134](https://github.com/smridge/swagcov/pull/134))
13
+ ```
14
+ swagcov -v
15
+ rake swagcov -- -v
16
+ ```
17
+
18
+ ### Refactor
19
+ - Reduce `Metrics/AbcSize` for better maintainability ([#138](https://github.com/smridge/swagcov/pull/138), [#139](https://github.com/smridge/swagcov/pull/139), [#140](https://github.com/smridge/swagcov/pull/140))
20
+
5
21
  ## 0.10.0 (2025-05-08)
6
22
  ### Enhancement
7
- - Added executable for streamlined command line usage ([#120](https://github.com/smridge/swagcov/pull/120))
23
+ - Add executable for streamlined command line usage ([#120](https://github.com/smridge/swagcov/pull/120))
8
24
  - The below options are now available:
9
25
  ```
10
26
  swagcov
@@ -13,7 +29,7 @@
13
29
  swagcov --help
14
30
  ```
15
31
  - **Note**: This is experimental as it may not work for all use cases. Use `rake swagcov` as a fallback
16
- - Added command line options to the existing `rake swagcov` task ([#121](https://github.com/smridge/swagcov/pull/121), [#122](https://github.com/smridge/swagcov/pull/122), [#123](https://github.com/smridge/swagcov/pull/123))
32
+ - Add command line options to the existing `rake swagcov` task ([#121](https://github.com/smridge/swagcov/pull/121), [#122](https://github.com/smridge/swagcov/pull/122), [#123](https://github.com/smridge/swagcov/pull/123))
17
33
  - The below options are now available:
18
34
  ```
19
35
  rake swagcov
data/README.md CHANGED
@@ -15,104 +15,149 @@ 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
- **Check OpenAPI documentation coverage for Rails Route endpoints**
19
- | `executable ` | `rake task ` | `rails console ` |
20
- | :--- | :--- | :--- |
21
- | `swagcov` | `rake swagcov` | `Swagcov::Command::ReportCoverage.new.run` |
22
-
23
- **Generate required `.swagcov.yml` config file**
24
- | `executable ` | `rake task ` | `rails console ` |
25
- | :--- | :--- | :--- |
26
- | `swagcov --init` | `rake swagcov -- --init` | `Swagcov::Command::GenerateDotfile.new.run` |
27
-
28
-
29
- **Generate optional `.swagcov_todo.yml` config file**
30
- | `executable ` | `rake task ` | `rails console ` |
31
- | :--- | :--- | :--- |
32
- | `swagcov --todo` | `rake swagcov -- --todo` | `Swagcov::Command::GenerateTodoFile.new.run` |
33
-
34
- **See command line usage options**
35
- | `executable ` | `rake task ` | `rails console ` |
36
- | :--- | :--- | :--- |
37
- | `swagcov --help` | `rake swagcov -- --help` | n/a |
18
+ ### Usage Options
19
+ `swagcov` can be used with a few different approachs.
20
+ The approaches below are listed in the following order:
21
+ - via executable
22
+ - via rake task
23
+ - via rails console
24
+
25
+ #### View OpenAPI documentation coverage report for Rails Route endpoints
26
+ - `swagcov`
27
+ - `rake swagcov`
28
+ - `Swagcov::Runner.new.run`
29
+
30
+ #### Generate required `.swagcov.yml` config file
31
+ - `swagcov --init`
32
+ - `rake swagcov -- --init`
33
+ - `Swagcov::Runner.new(args: ["--init"]).run`
34
+
35
+ #### Generate optional `.swagcov_todo.yml` config file
36
+ - `swagcov --todo`
37
+ - `rake swagcov -- --todo`
38
+ - `Swagcov::Runner.new(args: ["--todo"]).run`
39
+
40
+ #### View `swagcov` version
41
+ - `swagcov -v`
42
+ - `rake swagcov -- -v`
43
+ - `Swagcov::Runner.new(args: ["-v"]).run`
44
+
45
+ #### View command line usage options
46
+ - `swagcov --help`
47
+ - `rake swagcov -- --help`
48
+ - `Swagcov::Runner.new(args: ["--help"]).run`
49
+
50
+ ### Environment Variables
51
+ The following default environment variables are automatically set (and can optionally be changed to your needs)
52
+ | Key | Value |
53
+ | :--- | :--- |
54
+ | `SWAGCOV_DOTFILE` | `.swagcov.yml` |
55
+ | `SWAGCOV_TODOFILE` | `.swagcov_todo.yml` |
56
+
57
+ For example `SWAGCOV_DOTFILE=".openapi_coverage_config.yml" bundle exec swagcov`
58
+
59
+ ### Exit Codes
60
+ `swagcov` exits with the following status codes:
61
+ - `0` - (`success`) if no missing documentation coverage is detected
62
+ - `1` - (`offenses`) if missing documentation coverage is detected
63
+ - `2` - (`error`) if abnormal termination due to invalid configuration, cli options, or an internal error
38
64
 
39
65
  ## Ruby and Rails Version Support
40
66
  Versioning support from a test coverage perspective, see [tests.yml](/.github/workflows/tests.yml) for detail
41
67
  | `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` |
42
- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
43
- | `2.5` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
44
- | `2.6` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
45
- | `2.7` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
46
- | `3.0` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
47
- | `3.1` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
48
- | `3.2` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
49
- | `3.3` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
50
- | `3.4` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
51
- | `3.5` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
68
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
69
+ | `2.5` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
70
+ | `2.6` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ |
71
+ | `2.7` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
72
+ | `3.0` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ |
73
+ | `3.1` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ |
74
+ | `3.2` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
75
+ | `3.3` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
76
+ | `3.4` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
77
+ | `3.5` | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
52
78
 
53
79
  ## Installation
54
- Add this line to your application's Gemfile:
55
- ```ruby
56
- gem "swagcov"
57
- ```
58
-
59
- Execute:
60
- ```shell
61
- bundle
62
- ```
63
-
64
- Create a `.swagcov.yml` in root of your Rails application. Alternatively, run:
65
- ```shell
66
- bundle exec rake swagcov:install
67
- ```
68
-
69
- - Add the paths of your OpenAPI `.yml` and/or `.json` files (**required**):
70
- ```yml
71
- docs:
72
- paths:
73
- - swagger.yaml
74
- - swagger.json
80
+ - Add this line to your application's Gemfile:
81
+ ```ruby
82
+ gem "swagcov"
75
83
  ```
76
84
 
77
- - Add `only` routes (**optional**) :
78
- ```yml
79
- routes:
80
- paths:
81
- only:
82
- - ^/v1
83
- ```
85
+ - Execute `bundle install` to install the gem
84
86
 
85
- - Add `ignore` routes (**optional**) :
86
- ```yml
87
- routes:
88
- paths:
89
- ignore:
90
- - /v1/foobar/:token
87
+ - Generate the required `.swagcov.yml` configuration file in the root of your Rails application by executing one of the following commands:
88
+ ```
89
+ bundle exec swagcov --init
90
+ bundle exec rake swagcov -- --init
91
91
  ```
92
92
 
93
- - Full Example `.swagcov.yml` Config File:
94
- ```yml
93
+ You should now see the following file to configure to your needs:
94
+ ```yaml
95
+ ## Required field:
96
+ # List your OpenAPI documentation file(s) (accepts json or yaml)
95
97
  docs:
96
98
  paths:
97
99
  - swagger.yaml
100
+ - swagger.json
98
101
 
99
- routes:
100
- paths:
101
- only:
102
- - ^/v1
103
- ignore:
104
- - /v1/foobar/:token
105
- - /v1/foobar:
106
- - GET
102
+ ## Optional fields:
103
+ # routes:
104
+ # paths:
105
+ # only:
106
+ # - ^/v2 # only track v2 endpoints
107
+ # ignore:
108
+ # - /v2/users # do not track certain endpoints
109
+ # - /v2/users/:id: # ignore only certain actions (verbs)
110
+ # - GET
107
111
  ```
108
112
 
109
- Execute:
110
- ```shell
111
- bundle exec rake swagcov
112
- ```
113
+ - Execute one of the following commands:
114
+ ```
115
+ bundle exec swagcov
116
+ bundle exec rake swagcov
117
+ ```
118
+
119
+ Example Output:
120
+ ```
121
+ GET /articles 200
122
+ PATCH /articles/:id 200
123
+ DELETE /articles/:id 204
124
+ GET /users 200
125
+ POST /users 201
126
+ GET /users/:id 200
127
+ PUT /users/:id 200
128
+ DELETE /users/:id 204
129
+ GET /v1/articles 200
130
+ POST /v1/articles 201
131
+ GET /v1/articles/:id 200
132
+ PATCH /v1/articles/:id 200
133
+ PUT /v1/articles/:id 200
134
+ DELETE /v1/articles/:id 204
135
+ GET /v2/articles 200
136
+ POST /v2/articles 201
137
+ PATCH /v2/articles/:id 200
138
+ DELETE /v2/articles/:id 204
139
+ GET /v2/articles/:id ignored
140
+ PUT /v2/articles/:id ignored
141
+ POST /articles none
142
+ GET /articles/:id none
143
+ PUT /articles/:id none
144
+ PATCH /users/:id none
145
+
146
+ OpenAPI documentation coverage 81.82% (18/22)
147
+ 2 ignored endpoints
148
+ 22 total endpoints
149
+ 18 covered endpoints
150
+ 4 uncovered endpoints
151
+ ```
152
+
153
+ - Optionally generate a `.swagcov_todo.yml` config file acting as a TODO list
154
+ ```
155
+ bundle exec swagcov --todo
156
+ bundle exec rake swagcov -- --todo
157
+ ```
113
158
 
114
159
  ## Examples
115
- Configurations and output from running `bundle exec rake swagcov` from the root of your Rails Application
160
+ Configurations and output from running `swagcov` / `rake swagcov` from the root of your Rails Application
116
161
  - All Routes (minimal configuration):
117
162
  ```yml
118
163
  docs:
@@ -5,7 +5,7 @@ module Swagcov
5
5
  class GenerateDotfile
6
6
  attr_reader :dotfile
7
7
 
8
- def initialize basename: ::Swagcov::Dotfile::DEFAULT_CONFIG_FILE_NAME
8
+ def initialize basename: ::Swagcov::DOTFILE
9
9
  @dotfile = ::Swagcov.project_root.join(basename)
10
10
  end
11
11
 
@@ -3,7 +3,7 @@
3
3
  module Swagcov
4
4
  module Command
5
5
  class GenerateTodoFile
6
- def initialize basename: ::Swagcov::Dotfile::TODO_CONFIG_FILE_NAME,
6
+ def initialize basename: ::Swagcov::TODOFILE,
7
7
  data: ::Swagcov::Coverage.new(dotfile: ::Swagcov::Dotfile.new(skip_todo: true)).collect[:uncovered]
8
8
  @dotfile = ::Swagcov.project_root.join(basename)
9
9
  @data = data
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Swagcov
4
+ module Command
5
+ class ReportVersion
6
+ def run
7
+ $stdout.puts ::Swagcov::Version::STRING
8
+
9
+ ::Swagcov::STATUS_SUCCESS
10
+ end
11
+ end
12
+ end
13
+ end
@@ -2,11 +2,11 @@
2
2
 
3
3
  module Swagcov
4
4
  class Coverage
5
- attr_reader :dotfile
6
-
7
5
  def initialize dotfile: ::Swagcov::Dotfile.new, routes: ::Swagcov.project_routes
8
6
  @dotfile = dotfile
7
+ @openapi_files = ::Swagcov::OpenapiFiles.new(filepaths: @dotfile.docs_config)
9
8
  @routes = routes
9
+ @rails_version = ::Rails::VERSION::STRING
10
10
  @data = {
11
11
  covered: [],
12
12
  ignored: [],
@@ -19,14 +19,11 @@ module Swagcov
19
19
  end
20
20
 
21
21
  def collect
22
- openapi_files = ::Swagcov::OpenapiFiles.new(filepaths: dotfile.docs_config)
23
- rails_version = ::Rails::VERSION::STRING
24
-
25
22
  @routes.each do |route|
26
- path = route.path.spec.to_s.chomp("(.:format)")
27
- verb = rails_version > "5" ? route.verb : route.verb.inspect.gsub(%r{[$^/]}, "")
23
+ path = route_path(route)
24
+ verb = route_verb(route)
28
25
 
29
- next if third_party_route?(route, path, rails_version)
26
+ next if third_party_route?(route, path)
30
27
 
31
28
  if dotfile.ignore_path?(path, verb: verb)
32
29
  update_data(:ignored, verb, path, "ignored")
@@ -49,10 +46,20 @@ module Swagcov
49
46
 
50
47
  private
51
48
 
52
- def third_party_route? route, path, rails_version
49
+ attr_reader :dotfile, :openapi_files, :rails_version
50
+
51
+ def route_path route
52
+ route.path.spec.to_s.chomp("(.:format)")
53
+ end
54
+
55
+ def route_verb route
56
+ rails_version > "5" ? route.verb : route.verb.inspect.gsub(%r{[$^/]}, "")
57
+ end
58
+
59
+ def third_party_route? route, path
53
60
  # https://github.com/rails/rails/blob/48f3c3e201b57a4832314b2c957a3b303e89bfea/actionpack/lib/action_dispatch/routing/inspector.rb#L105-L107
54
61
  # Skips route paths like ["/rails/info/properties", "/rails/info", "/rails/mailers"]
55
- internal_rails_route?(route, rails_version) ||
62
+ internal_rails_route?(route) ||
56
63
 
57
64
  # Skips routes like "/sidekiq"
58
65
  route.verb.blank? ||
@@ -63,7 +70,7 @@ module Swagcov
63
70
  path.include?("/active_storage/") || path.include?("/action_mailbox/")
64
71
  end
65
72
 
66
- def internal_rails_route? route, rails_version
73
+ def internal_rails_route? route
67
74
  if rails_version > "5"
68
75
  route.internal
69
76
  else
@@ -2,13 +2,10 @@
2
2
 
3
3
  module Swagcov
4
4
  class Dotfile
5
- DEFAULT_CONFIG_FILE_NAME = ::ENV.fetch("SWAGCOV_DOTFILE", ".swagcov.yml")
6
- TODO_CONFIG_FILE_NAME = ::ENV.fetch("SWAGCOV_TODOFILE", ".swagcov_todo.yml")
7
-
8
- def initialize basename: DEFAULT_CONFIG_FILE_NAME, todo_basename: TODO_CONFIG_FILE_NAME, skip_todo: false
5
+ def initialize basename: ::Swagcov::DOTFILE, todo_basename: ::Swagcov::TODOFILE, skip_todo: false
9
6
  @dotfile = load_yaml(basename, required: true)
10
7
 
11
- raise ::Swagcov::Errors::BadConfiguration, "Invalid config file (#{DEFAULT_CONFIG_FILE_NAME})" unless valid?
8
+ raise ::Swagcov::Errors::BadConfiguration, "Invalid config file (#{::Swagcov::DOTFILE})" unless valid?
12
9
 
13
10
  @todo_file = load_yaml(todo_basename) unless skip_todo
14
11
  @ignored_regex = path_config_regex(ignored_config)
@@ -33,10 +33,9 @@ module Swagcov
33
33
  end
34
34
 
35
35
  def min_path_width
36
- strings =
37
- data[:covered].map { |hash| hash[:path] } +
38
- data[:ignored].map { |hash| hash[:path] } +
39
- data[:uncovered].map { |hash| hash[:path] }
36
+ strings = []
37
+
38
+ %i[covered ignored uncovered].each { |key| data[key].each { |hash| strings << hash[:path] } }
40
39
 
41
40
  @min_path_width ||= strings.max_by(&:length)&.size.to_i + 1
42
41
  end
@@ -25,6 +25,10 @@ module Swagcov
25
25
  opts.on("-t", "--todo", "Generate optional .swagcov_todo.yml config file") do |opt|
26
26
  options[:todo] = opt
27
27
  end
28
+
29
+ opts.on("-v", "--version", "Display version") do |opt|
30
+ options[:version] = opt
31
+ end
28
32
  end.parse!(@args)
29
33
 
30
34
  options
@@ -10,9 +10,17 @@ module Swagcov
10
10
  end
11
11
 
12
12
  def run
13
- exit ::Swagcov::Command::GenerateDotfile.new.run if options[:init]
14
- exit ::Swagcov::Command::GenerateTodoFile.new.run if options[:todo]
15
- exit ::Swagcov::Command::ReportCoverage.new.run
13
+ exit runner
14
+ end
15
+
16
+ private
17
+
18
+ def runner
19
+ return ::Swagcov::Command::GenerateDotfile.new.run if options[:init]
20
+ return ::Swagcov::Command::GenerateTodoFile.new.run if options[:todo]
21
+ return ::Swagcov::Command::ReportVersion.new.run if options[:version]
22
+
23
+ ::Swagcov::Command::ReportCoverage.new.run
16
24
  end
17
25
  end
18
26
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Swagcov
4
4
  module Version
5
- STRING = "0.10.0"
5
+ STRING = "1.0.0"
6
6
  end
7
7
  end
data/lib/swagcov.rb CHANGED
@@ -5,6 +5,7 @@ require "rails"
5
5
  require "swagcov/command/generate_dotfile"
6
6
  require "swagcov/command/generate_todo_file"
7
7
  require "swagcov/command/report_coverage"
8
+ require "swagcov/command/report_version"
8
9
  require "swagcov/core_ext/string"
9
10
  require "swagcov/formatter/console"
10
11
  require "swagcov/coverage"
@@ -23,6 +24,9 @@ module Swagcov
23
24
  STATUS_OFFENSES = 1
24
25
  STATUS_ERROR = 2
25
26
 
27
+ DOTFILE = ENV["SWAGCOV_DOTFILE"] ||= ".swagcov.yml"
28
+ TODOFILE = ENV["SWAGCOV_TODOFILE"] ||= ".swagcov_todo.yml"
29
+
26
30
  def project_root
27
31
  ::Rails.root || ::Pathname.new(::FileUtils.pwd)
28
32
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swagcov
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sarah Ridge
@@ -38,6 +38,7 @@ files:
38
38
  - lib/swagcov/command/generate_dotfile.rb
39
39
  - lib/swagcov/command/generate_todo_file.rb
40
40
  - lib/swagcov/command/report_coverage.rb
41
+ - lib/swagcov/command/report_version.rb
41
42
  - lib/swagcov/core_ext/string.rb
42
43
  - lib/swagcov/coverage.rb
43
44
  - lib/swagcov/dotfile.rb
@@ -72,7 +73,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
73
  - !ruby/object:Gem::Version
73
74
  version: '0'
74
75
  requirements: []
75
- rubygems_version: 3.6.8
76
+ rubygems_version: 3.6.9
76
77
  specification_version: 4
77
78
  summary: OpenAPI documentation coverage report for Rails Route endpoints
78
79
  test_files: []