swagcov 0.2.1 → 0.2.5

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: 326ccddda2c92236e815bc06b7a29f64b5b4a1d59a796f000c5c424b91b1f7cd
4
- data.tar.gz: 557e962da1fb3232dd7ed29e05597a88771c9ce1f34fd35ec39b5140c901ed65
3
+ metadata.gz: 820849bdcc13ddb85e1ff404bcc881dbe8f8154090bb6111d0afbdbdd286ce4f
4
+ data.tar.gz: 90de5bb3a335673d58524344dd871182e06c1eb3185192a92026be5be0ce372e
5
5
  SHA512:
6
- metadata.gz: f6c067ae52cb5e3609e0cab96e08b3e016438bbf7ed04281bd2ce024e2af0bd47e601aa3ba85dca61b1c973dca495431b635be1b24d8ef7dbf8fbcf7f5218d90
7
- data.tar.gz: 8caf8633ab01634c0fa42a38edc44f07127f4bd984792144562b7274ba46f31a9e0af52828ce8221f678c61866e9b7c6ccbb5ffe14935c9b2b0e9f0668c7ef1b
6
+ metadata.gz: b49673a8bfca29bb64ece42acc8c1a85f34339b4aa643036c72f4c1849e6e061a933c6471df2502da4e5ba4676c4f75cec559518c87242c7a3a31d6c0e817000
7
+ data.tar.gz: 1b60f5d474d4be3c5c51a6180cb0343b380bca69a4fa99fe0c55063e7037a4f1134d3cbd284a411aa2a9b6ef257898df55facdf99b8827fe2fde3c069c8222be
data/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Swagcov
2
- See coverage report for openapi docs for Rails Routes.
2
+ [![Gem Version](https://img.shields.io/gem/v/swagcov)](https://rubygems.org/gems/swagcov)
3
+ ![Gem Downloads](https://img.shields.io/gem/dt/swagcov)
4
+ [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop-hq/rubocop)
5
+ [![GitHub License](https://img.shields.io/github/license/smridge/swagcov.svg)](https://github.com/smridge/swagcov/blob/main/LICENSE)
6
+
7
+ See OpenAPI documentation coverage report for Rails Routes.
3
8
 
4
9
  ## Installation
5
10
  Add this line to your application's Gemfile:
@@ -34,7 +39,6 @@ Create a `.swagcov.yml` in root of your Rails application.
34
39
  paths:
35
40
  ignore:
36
41
  - /v1/foobar/:token
37
- - /sidekiq
38
42
  ```
39
43
 
40
44
  - Example `.swagcov.yml` Config File:
@@ -49,7 +53,6 @@ Create a `.swagcov.yml` in root of your Rails application.
49
53
  - ^/v1
50
54
  ignore:
51
55
  - /v1/foobar/:token
52
- - /sidekiq
53
56
  ```
54
57
 
55
58
  Execute:
@@ -57,6 +60,44 @@ Execute:
57
60
  bundle exec rake swagcov
58
61
  ```
59
62
 
63
+ ## Example configurations and output from running `bundle exec rake swagcov` from the root of your Rails Application:
64
+ - All Routes (minimal configuration):
65
+ ```yml
66
+ docs:
67
+ paths:
68
+ - swagger.yaml
69
+ ```
70
+ <img src="https://raw.githubusercontent.com/smridge/swagcov/main/images/all-endpoints.png">
71
+
72
+
73
+ - With `only` endpoint configuration:
74
+ ```yml
75
+ docs:
76
+ paths:
77
+ - swagger.yaml
78
+
79
+ routes:
80
+ paths:
81
+ only:
82
+ - ^/v2
83
+ ```
84
+ <img src="https://raw.githubusercontent.com/smridge/swagcov/main/images/only-endpoints.png">
85
+
86
+ - With `ignore` and `only` endpoint configurations:
87
+ ```yml
88
+ docs:
89
+ paths:
90
+ - swagger/v1/swagger.yaml
91
+
92
+ routes:
93
+ paths:
94
+ only:
95
+ - ^/v2
96
+ ignore:
97
+ - /v2/users
98
+ ```
99
+ <img src="https://raw.githubusercontent.com/smridge/swagcov/main/images/ignore-and-only-endpoints.png">
100
+
60
101
  ## Development
61
102
  ```shell
62
103
  git clone git@github.com:smridge/swagcov.git
@@ -72,18 +113,34 @@ gem "swagcov", path: "../swagcov"
72
113
  bundle
73
114
  ```
74
115
 
116
+ Run Tests
117
+ ```
118
+ bundle exec rspec spec --exclude-pattern spec/sandbox_5_2/**/*_spec.rb
119
+ ```
120
+
121
+ ### Test via Sandbox Application
122
+ For Rails 5
123
+ - `cd spec/sandbox_5_2/`
124
+ - Run tests: `bundle exec rspec spec`
125
+ - Run `bundle exec rake swagcov`
126
+ - This will run against any changes made to your branch.
127
+
75
128
  ## Publish (internal)
76
129
  > Note: Publishing a new version of this gem is only meant for maintainers.
77
130
  - Ensure you have access to publish on [rubygems](https://rubygems.org/gems/swagcov).
78
131
  - Update [CHANGELOG](https://github.com/smridge/swagcov/blob/main/CHANGELOG.md).
79
132
  - Update [`VERSION`](https://github.com/smridge/swagcov/blob/main/lib/swagcov/version.rb).
133
+ - Commit changes to `main` branch locally.
80
134
  - Run: `rake release`
81
135
  - 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).
82
136
 
83
137
  ## TODO
84
138
  - Add specs
85
139
  - Test against different rails versions
140
+ - Create Sandbox App for Rails 6
86
141
  - Add autogeneration of ignore paths
142
+ - Add `CONTRIBUTING.md`
143
+ - Add GitHub Actions for specs/linting
87
144
 
88
145
  ## Credit
89
146
  To [@lonelyelk](https://github.com/lonelyelk) for initial development!
@@ -2,29 +2,50 @@
2
2
 
3
3
  module Swagcov
4
4
  class Coverage
5
- def initialize
5
+ attr_reader :total, :covered, :ignored, :routes_not_covered, :routes_covered, :routes_ignored
6
+
7
+ def initialize dotfile: Swagcov::Dotfile.new, routes: ::Rails.application.routes.routes
6
8
  @total = 0
7
9
  @covered = 0
8
10
  @ignored = 0
9
11
  @routes_not_covered = []
10
12
  @routes_covered = []
11
13
  @routes_ignored = []
14
+ @dotfile = dotfile
15
+ @routes = routes
12
16
  end
13
17
 
14
18
  def report
15
- Rails.application.routes.routes.each do |route|
19
+ collect_coverage
20
+ routes_output(@routes_covered, "green")
21
+ routes_output(@routes_ignored, "yellow")
22
+ routes_output(@routes_not_covered, "red")
23
+
24
+ final_output
25
+
26
+ exit @total - @covered
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :dotfile
32
+
33
+ def collect_coverage
34
+ @routes.each do |route|
16
35
  path = route.path.spec.to_s.sub(/\(\.:format\)$/, "")
17
36
 
18
- if ignore_path?(path)
37
+ next if third_party_route?(route, path)
38
+
39
+ if dotfile.ignore_path?(path)
19
40
  @ignored += 1
20
41
  @routes_ignored << { verb: route.verb, path: path, status: "ignored" }
21
42
  next
22
43
  end
23
44
 
24
- next if only_path_mismatch?(path)
45
+ next if dotfile.only_path_mismatch?(path)
25
46
 
26
47
  @total += 1
27
- regex = Regexp.new("#{path.gsub(%r{:[^/]+}, '\\{[^/]+\\}')}(\\.[^/]+)?$")
48
+ regex = Regexp.new("^#{path.gsub(%r{:[^/]+}, '\\{[^/]+\\}')}(\\.[^/]+)?$")
28
49
  matching_keys = docs_paths.keys.select { |k| regex.match?(k) }
29
50
 
30
51
  if (doc = docs_paths.dig(matching_keys.first, route.verb.downcase))
@@ -34,57 +55,33 @@ module Swagcov
34
55
  @routes_not_covered << { verb: route.verb, path: path, status: "none" }
35
56
  end
36
57
  end
37
-
38
- routes_output(@routes_covered, "green")
39
- routes_output(@routes_ignored, "yellow")
40
- routes_output(@routes_not_covered, "red")
41
-
42
- final_output
43
-
44
- exit @total - @covered
45
- end
46
-
47
- def dotfile
48
- @dotfile ||= YAML.load_file(Rails.root.join(".swagcov.yml"))
49
58
  end
50
59
 
51
60
  def docs_paths
52
- @docs_paths ||= Dir.glob(dotfile["docs"]["paths"]).reduce({}) do |acc, docspath|
61
+ @docs_paths ||= Dir.glob(dotfile.doc_paths).reduce({}) do |acc, docspath|
53
62
  acc.merge(YAML.load_file(docspath)["paths"])
54
63
  end
55
64
  end
56
65
 
57
- private
58
-
59
- def ignore_path? path
60
- ignored_regex&.match?(path)
61
- end
62
-
63
- def ignored_regex
64
- @ignored_regex ||= path_config_regex(dotfile.dig("routes", "paths", "ignore"))
65
- end
66
-
67
- def only_path_mismatch? path
68
- only_regex && !only_regex.match?(path)
69
- end
70
-
71
- def only_regex
72
- @only_regex ||= path_config_regex(dotfile.dig("routes", "paths", "only"))
73
- end
74
-
75
- def path_config_regex path_config
76
- return unless path_config
66
+ def third_party_route? route, path
67
+ # https://github.com/rails/rails/blob/48f3c3e201b57a4832314b2c957a3b303e89bfea/actionpack/lib/action_dispatch/routing/inspector.rb#L105-L107
68
+ # Skips route paths like ["/rails/info/properties", "/rails/info", "/rails/mailers"]
69
+ route.internal ||
77
70
 
78
- config = path_config.map { |path| path.first == "^" ? path : "#{path}$" }
71
+ # Skips routes like "/sidekiq"
72
+ route.verb.blank? ||
79
73
 
80
- /#{config.join('|')}/
74
+ # Exclude routes that are part of the rails gem that you would not write documentation for
75
+ # https://github.com/rails/rails/tree/main/activestorage/app/controllers/active_storage
76
+ # https://github.com/rails/rails/tree/main/actionmailbox/app/controllers/action_mailbox
77
+ path.include?("/active_storage/") || path.include?("/action_mailbox/")
81
78
  end
82
79
 
83
80
  def routes_output routes, status_color
84
81
  routes.each do |route|
85
82
  $stdout.puts(
86
83
  format(
87
- "%<verb>10s %<path>-90s %<status>s",
84
+ "%<verb>10s %<path>-90s %<status>s",
88
85
  { verb: route[:verb], path: route[:path], status: route[:status].send(status_color) }
89
86
  )
90
87
  )
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Swagcov
4
+ class BadConfigurationError < RuntimeError
5
+ end
6
+
7
+ class Dotfile
8
+ DEFAULT_CONFIG_FILE_NAME = ".swagcov.yml"
9
+
10
+ def initialize pathname: Rails.root.join(DEFAULT_CONFIG_FILE_NAME)
11
+ raise BadConfigurationError, "Missing config file (#{DEFAULT_CONFIG_FILE_NAME})" unless pathname.exist?
12
+
13
+ @dotfile = YAML.load_file(pathname)
14
+ raise BadConfigurationError, "Invalid config file (#{DEFAULT_CONFIG_FILE_NAME})" unless valid?
15
+ end
16
+
17
+ def ignore_path? path
18
+ ignored_regex&.match?(path)
19
+ end
20
+
21
+ def only_path_mismatch? path
22
+ only_regex && !only_regex.match?(path)
23
+ end
24
+
25
+ def doc_paths
26
+ dotfile.dig("docs", "paths")
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :dotfile
32
+
33
+ def ignored_regex
34
+ @ignored_regex ||= path_config_regex(dotfile.dig("routes", "paths", "ignore"))
35
+ end
36
+
37
+ def only_regex
38
+ @only_regex ||= path_config_regex(dotfile.dig("routes", "paths", "only"))
39
+ end
40
+
41
+ def path_config_regex path_config
42
+ return unless path_config
43
+
44
+ config = path_config.map { |path| path.first == "^" ? path : "^#{path}$" }
45
+
46
+ /#{config.join('|')}/
47
+ end
48
+
49
+ def valid?
50
+ dotfile && doc_paths
51
+ end
52
+ end
53
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Swagcov
4
- VERSION = "0.2.1"
4
+ VERSION = "0.2.5"
5
5
  end
data/lib/swagcov.rb CHANGED
@@ -4,6 +4,7 @@ require "swagcov/version"
4
4
 
5
5
  if defined?(Rails)
6
6
  require "swagcov/railtie"
7
+ require "swagcov/dotfile"
7
8
  require "swagcov/coverage"
8
9
  end
9
10
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swagcov
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sarah Ridge
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-21 00:00:00.000000000 Z
11
+ date: 2021-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry-byebug
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rspec
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -66,6 +80,20 @@ dependencies:
66
80
  - - ">="
67
81
  - !ruby/object:Gem::Version
68
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
69
97
  description:
70
98
  email:
71
99
  - sarahmarie@hey.com
@@ -79,6 +107,7 @@ files:
79
107
  - lib/swagcov.rb
80
108
  - lib/swagcov/core_ext/string.rb
81
109
  - lib/swagcov/coverage.rb
110
+ - lib/swagcov/dotfile.rb
82
111
  - lib/swagcov/railtie.rb
83
112
  - lib/swagcov/version.rb
84
113
  - lib/tasks/swagcove.rake