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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a33cef0212a7370171c60f0fc5729a7e5a68c7051647ff0abede311c6532a448
4
- data.tar.gz: fb9b3b10b5cd1faa4128367174336682e328e87b7d6e5326081ff6c67bb336c2
3
+ metadata.gz: 87efac78c319723b4cd01a2682c5980a06030b1dde8c70f5ee5fadfeea534d8d
4
+ data.tar.gz: ddb457dbee27c3520a2e277436e591423966419ac3d68579e1a235c699520e9a
5
5
  SHA512:
6
- metadata.gz: 41e31f98cde40c9cc6d0b7f7385d715aa7b5af0f24ecfca9ed22fce3bc62aad18395ab9cb3460745b376ea1b27323847c8b9fbf3026452214cdd02923ada29cd
7
- data.tar.gz: e61e353925c1b5e1dc4d923133707335f4ccc94d49a7df83cf45e1637c657bae71fd11e5831e7cfb3c6f648d5e01c531879bbb1d5c78824eddf0bed38c88735a
6
+ metadata.gz: 5ca916e54814cc605b3f47c0b98e47c8cac5753057f6046a4c213ef18171749f7abb078572ea4292b17b3280f0872f4ddef7532ce2b3ecd51de1cad962d35ecb
7
+ data.tar.gz: 7c0c5a9aa40124e6774e810e03b3aad9674cb6e58523ba08a0af914939b2dab5fa0c33d72b660edb2d3e0d614ab7cc1418e99febd68c4548186f61db653515a0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # v0.2.0
2
+
3
+ * Add `swagger:diff` task.
4
+
1
5
  # v0.1.2
2
6
 
3
7
  * Fix `verbose` behavior, and respect the `rake -v` flag.
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. This gem adds the Rake task and some niceties such as Rails integration.
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).
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency 'rdoc'
29
29
  spec.add_dependency 'reverse_markdown'
30
30
  spec.add_dependency 'activesupport'
31
+ spec.add_dependency 'hashdiff'
31
32
 
32
33
  spec.add_development_dependency 'minitest'
33
34
  end
@@ -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 if verbose
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
 
@@ -1,5 +1,5 @@
1
1
  module AppMap
2
2
  module Swagger
3
- VERSION = "0.1.2"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
@@ -1,2 +1,3 @@
1
1
  require 'appmap/swagger/version'
2
2
  require 'appmap/swagger/rake_task'
3
+ require 'appmap/swagger/rake_diff_task'
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.1.2
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-02 00:00:00.000000000 Z
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