appmap_swagger 0.1.2 → 0.2.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 +4 -0
- data/README.md +46 -1
- data/appmap_swagger.gemspec +1 -0
- data/lib/appmap/swagger/rake_diff_task.rb +124 -0
- data/lib/appmap/swagger/rake_task.rb +2 -2
- data/lib/appmap/swagger/version.rb +1 -1
- data/lib/appmap_swagger.rb +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87efac78c319723b4cd01a2682c5980a06030b1dde8c70f5ee5fadfeea534d8d
|
4
|
+
data.tar.gz: ddb457dbee27c3520a2e277436e591423966419ac3d68579e1a235c699520e9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5ca916e54814cc605b3f47c0b98e47c8cac5753057f6046a4c213ef18171749f7abb078572ea4292b17b3280f0872f4ddef7532ce2b3ecd51de1cad962d35ecb
|
7
|
+
data.tar.gz: 7c0c5a9aa40124e6774e810e03b3aad9674cb6e58523ba08a0af914939b2dab5fa0c33d72b660edb2d3e0d614ab7cc1418e99febd68c4548186f61db653515a0
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,14 @@
|
|
2
2
|
|
3
3
|
This gem provides a Rake task called `swagger` that generates [Swagger 3](https://swagger.io/specification/) (aka OpenAPI) YAML from [AppMap](https://github.com/applandinc/appmap-ruby) data.
|
4
4
|
|
5
|
-
It depends on an NPM package called [@appland/appmap-swagger](https://www.npmjs.com/package/@appland/appmap-swagger), which does most of the heavy lifting of converting AppMaps to Swagger.
|
5
|
+
It depends on an NPM package called [@appland/appmap-swagger](https://www.npmjs.com/package/@appland/appmap-swagger), which does most of the heavy lifting of converting AppMaps to Swagger.
|
6
|
+
|
7
|
+
To the NPM package, this gem adds:
|
8
|
+
|
9
|
+
* A Rake task - Normally configured as `appmap:swagger`.
|
10
|
+
* Rails integration - For example, default configuration of the application name.
|
11
|
+
* Swagger "diff" - Smart comparison of the current revision Swagger YAML to a base revision.
|
12
|
+
|
6
13
|
|
7
14
|
# How it works
|
8
15
|
|
@@ -18,6 +25,12 @@ The Rake task `swagger`:
|
|
18
25
|
|
19
26
|
`openapi_stable.yaml` is ideal for use in code reviews, to see if (and how) web services have been changed.
|
20
27
|
|
28
|
+
The Rake task `swagger:diff`:
|
29
|
+
|
30
|
+
1. Computes a smart "diff" between the current revision Swagger and base revision.
|
31
|
+
2. Prints this diff in a user-friendly format, suitable for inclusion in a pull request or issue comment.
|
32
|
+
|
33
|
+
|
21
34
|
## Installation
|
22
35
|
|
23
36
|
Add this line to your application's Gemfile:
|
@@ -50,10 +63,42 @@ namespace :appmap do
|
|
50
63
|
# You may not have a VERSION file. Do what works best for you.
|
51
64
|
task.project_version = "v#{File.read(File.join(Rails.root, 'VERSION')).strip}"
|
52
65
|
end
|
66
|
+
|
67
|
+
AppMap::Swagger::RakeDiffTask.new(:'swagger:diff', [ :base, :swagger_file ]).tap do |task|
|
68
|
+
# Default base; can be overridden by the :base task argument
|
69
|
+
task.base = 'remotes/origin/main'
|
70
|
+
# Default swagger file; can be overridden by the :swagger_file task argument
|
71
|
+
task.swagger_file = 'swagger/openapi_stable.yaml'
|
72
|
+
end
|
53
73
|
end
|
54
74
|
end
|
55
75
|
```
|
56
76
|
|
77
|
+
## Example
|
78
|
+
|
79
|
+
```sh-session
|
80
|
+
$ ./bin/rake appmap:swagger:diff
|
81
|
+
changed @ info.version
|
82
|
+
old value : v0.22.0
|
83
|
+
new value : v0.22.1
|
84
|
+
|
85
|
+
added @ paths."/api/api_keys".delete.responses
|
86
|
+
added key : 200
|
87
|
+
added value : {"content"=>{"application/json"=>{}}}
|
88
|
+
|
89
|
+
removed @ paths."/scenarios/{id}".put.requestBody.content."application/json".schema.properties.scenario.properties
|
90
|
+
removed key : mapset
|
91
|
+
removed value : {"type"=>"string"}
|
92
|
+
|
93
|
+
removed @ paths."/scenarios/{scenario_id}/save_as".post.requestBody.content."application/json".schema.properties.save_as.properties
|
94
|
+
removed key : feature
|
95
|
+
removed value : {"type"=>"string"}
|
96
|
+
|
97
|
+
removed @ paths."/scenarios/{scenario_id}/save_as".post.requestBody.content."application/json".schema.properties.save_as.properties
|
98
|
+
removed key : feature_group
|
99
|
+
removed value : {"type"=>"string"}
|
100
|
+
```
|
101
|
+
|
57
102
|
## Incorporating the Swagger API and UI
|
58
103
|
|
59
104
|
Two other gems work great with `appmap:swagger`: `rswag-api` and `rswag-ui` from [rswag](https://github.com/rswag/rswag).
|
data/appmap_swagger.gemspec
CHANGED
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rake'
|
4
|
+
require 'rake/tasklib'
|
5
|
+
require 'hashdiff'
|
6
|
+
|
7
|
+
module AppMap
|
8
|
+
module Swagger
|
9
|
+
class RakeDiffTask < ::Rake::TaskLib
|
10
|
+
DEFAULT_BASE = 'remotes/origin/main'
|
11
|
+
DEFAULT_GIT = 'git'
|
12
|
+
DEFAULT_SWAGGER_FILE = 'swagger/openapi_stable.yaml'
|
13
|
+
|
14
|
+
attr_accessor :name, :git_command, :base, :swagger_file
|
15
|
+
|
16
|
+
Command = Struct.new(:git_command, :base, :swagger_file) do
|
17
|
+
def verbose
|
18
|
+
Rake.verbose == true
|
19
|
+
end
|
20
|
+
|
21
|
+
def perform
|
22
|
+
do_fail = lambda do |msg|
|
23
|
+
warn msg
|
24
|
+
exit $?.exitstatus || 1
|
25
|
+
end
|
26
|
+
|
27
|
+
return do_fail.(%Q('#{git_command}' not found; please install git)) unless system('git --version 2>&1 > /dev/null')
|
28
|
+
|
29
|
+
fetch_command = 'git fetch'
|
30
|
+
warn fetch_command if verbose
|
31
|
+
do_fail.(%Q(#{fetch_command} failed)) unless system(fetch_command)
|
32
|
+
|
33
|
+
show_command = %Q(git show #{base}:#{swagger_file})
|
34
|
+
warn show_command if verbose
|
35
|
+
base_content = `#{show_command}`
|
36
|
+
do_fail.(%Q(#{show_command} failed)) unless $?.exitstatus == 0
|
37
|
+
|
38
|
+
base_content = YAML.load(base_content)
|
39
|
+
head_content = YAML.load(File.read(swagger_file))
|
40
|
+
|
41
|
+
format_path = lambda do |tokens|
|
42
|
+
tokens.map do |token|
|
43
|
+
if token =~ /^[a-zA-Z0-9_-]+$/
|
44
|
+
token
|
45
|
+
else
|
46
|
+
%Q("#{token}")
|
47
|
+
end
|
48
|
+
end.join('.')
|
49
|
+
end
|
50
|
+
|
51
|
+
format_change = lambda do |entry|
|
52
|
+
path, old_v, new_v = entry
|
53
|
+
[
|
54
|
+
"changed @ #{format_path.call path.split('.')}",
|
55
|
+
"old value : #{old_v}",
|
56
|
+
"new value : #{new_v}"
|
57
|
+
].join("\n")
|
58
|
+
end
|
59
|
+
|
60
|
+
format_deletion = lambda do |entry|
|
61
|
+
path, old_v = entry
|
62
|
+
path_tokens = path.split('.')
|
63
|
+
removed_key = path_tokens.pop
|
64
|
+
[
|
65
|
+
"removed @ #{format_path.call path_tokens}",
|
66
|
+
"removed key : #{removed_key}",
|
67
|
+
"removed value : #{old_v}"
|
68
|
+
].join("\n")
|
69
|
+
end
|
70
|
+
|
71
|
+
format_addition = lambda do |entry|
|
72
|
+
path, new_v = entry
|
73
|
+
path_tokens = path.split('.')
|
74
|
+
added_key = path_tokens.pop
|
75
|
+
[
|
76
|
+
"added @ #{format_path.call path_tokens}",
|
77
|
+
"added key : #{added_key}",
|
78
|
+
"added value : #{new_v}"
|
79
|
+
].join("\n")
|
80
|
+
end
|
81
|
+
|
82
|
+
formatters = {
|
83
|
+
'~' => format_change,
|
84
|
+
'-' => format_deletion,
|
85
|
+
'+' => format_addition,
|
86
|
+
}
|
87
|
+
|
88
|
+
diff = Hashdiff.diff(base_content, head_content)
|
89
|
+
diff.each_with_index do |entry, index|
|
90
|
+
puts unless index == 0
|
91
|
+
warn YAML.dump(entry) if verbose
|
92
|
+
puts formatters[entry[0]].(entry[1..-1])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def initialize(*args, &task_block)
|
98
|
+
@name = args.shift || :'swagger:diff'
|
99
|
+
@git_command = DEFAULT_GIT
|
100
|
+
@base = DEFAULT_BASE
|
101
|
+
@swagger_file = DEFAULT_SWAGGER_FILE
|
102
|
+
|
103
|
+
define(args, &task_block)
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
# This bit of black magic - https://github.com/rspec/rspec-core/blob/main/lib/rspec/core/rake_task.rb#L110
|
109
|
+
def define(args, &task_block)
|
110
|
+
desc "Generate Swagger from AppMaps" unless ::Rake.application.last_description
|
111
|
+
|
112
|
+
task(name, *args) do |_, task_args|
|
113
|
+
RakeFileUtils.__send__(:verbose, Rake.verbose == true) do
|
114
|
+
task_block.call(*[self, task_args].slice(0, task_block.arity)) if task_block
|
115
|
+
Command.new(:git_command).tap do |cmd|
|
116
|
+
cmd.base = task_args[:base] || self.base
|
117
|
+
cmd.swagger_file = task_args[:swagger_file] || self.swagger_file
|
118
|
+
end.perform
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -43,12 +43,12 @@ module AppMap
|
|
43
43
|
FileUtils.mkdir_p output_dir
|
44
44
|
|
45
45
|
do_fail = lambda do |msg|
|
46
|
-
warn msg
|
46
|
+
warn msg
|
47
47
|
exit $?.exitstatus || 1
|
48
48
|
end
|
49
49
|
|
50
50
|
return do_fail.(%Q('node' not found; please install NodeJS)) unless system('node --version 2>&1 > /dev/null')
|
51
|
-
return do_fail.(%Q('#{swaggergen}' not found; please install appmap-swagger from NPM)) unless File.exists?(swaggergen)
|
51
|
+
return do_fail.(%Q('#{swaggergen}' not found; please install @appland/appmap-swagger from NPM)) unless File.exists?(swaggergen)
|
52
52
|
|
53
53
|
warn swagger_command.join(' ') if verbose
|
54
54
|
|
data/lib/appmap_swagger.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: appmap_swagger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kevin Gilpin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-04-
|
11
|
+
date: 2021-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: hashdiff
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: minitest
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,6 +112,7 @@ files:
|
|
98
112
|
- bin/console
|
99
113
|
- bin/setup
|
100
114
|
- lib/appmap/swagger/markdown_descriptions.rb
|
115
|
+
- lib/appmap/swagger/rake_diff_task.rb
|
101
116
|
- lib/appmap/swagger/rake_task.rb
|
102
117
|
- lib/appmap/swagger/stable.rb
|
103
118
|
- lib/appmap/swagger/version.rb
|