appmap_swagger 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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