appmap 0.51.2 → 0.54.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/.travis.yml +3 -1
- data/CHANGELOG.md +40 -0
- data/Rakefile +21 -5
- data/appmap.gemspec +8 -7
- data/exe/appmap-agent-init +19 -0
- data/exe/appmap-inspect +7 -0
- data/lib/appmap.rb +29 -119
- data/lib/appmap/agent.rb +115 -0
- data/lib/appmap/class_map.rb +2 -2
- data/lib/appmap/command/agent_setup/init.rb +44 -0
- data/lib/appmap/command/inspect.rb +27 -0
- data/lib/appmap/command_error.rb +13 -0
- data/lib/appmap/config.rb +13 -4
- data/lib/appmap/handler/net_http.rb +2 -1
- data/lib/appmap/handler/rails/request_handler.rb +2 -1
- data/lib/appmap/metadata.rb +4 -2
- data/lib/appmap/minitest.rb +2 -0
- data/lib/appmap/node_cli.rb +59 -0
- data/lib/appmap/railtie.rb +2 -2
- data/lib/appmap/rspec.rb +5 -3
- data/lib/appmap/service/guesser.rb +2 -9
- data/lib/appmap/swagger.rb +2 -0
- data/lib/appmap/swagger/configuration.rb +70 -0
- data/lib/appmap/swagger/markdown_descriptions.rb +43 -0
- data/lib/appmap/swagger/rake_tasks.rb +43 -0
- data/lib/appmap/swagger/stable.rb +37 -0
- data/lib/appmap/util.rb +31 -2
- data/lib/appmap/version.rb +1 -1
- data/package.json +5 -7
- data/spec/config_spec.rb +0 -1
- data/spec/fixtures/hook/.gitignore +2 -0
- data/spec/fixtures/hook/app/controllers/api/api_keys_controller.rb +1 -0
- data/spec/fixtures/hook/app/controllers/organizations_controller.rb +1 -0
- data/spec/fixtures/hook/app/models/api_key.rb +1 -0
- data/spec/fixtures/hook/app/models/configuration.rb +1 -0
- data/spec/fixtures/hook/app/models/show.rb +1 -0
- data/spec/fixtures/hook/app/models/user.rb +1 -0
- data/spec/fixtures/hook/revoke_api_key.appmap.json +847 -0
- data/spec/fixtures/hook/spec/api_spec.rb +1 -0
- data/spec/fixtures/hook/spec/user_spec.rb +1 -0
- data/spec/fixtures/hook/user_page_scenario.appmap.json +1722 -0
- data/spec/fixtures/rails5_users_app/config/environments/test.rb +3 -0
- data/spec/fixtures/rails5_users_app/docker-compose.yml +1 -1
- data/spec/fixtures/rails6_users_app/Dockerfile +9 -1
- data/spec/fixtures/rails6_users_app/appmap.yml +3 -1
- data/spec/fixtures/rails6_users_app/config/environments/test.rb +3 -0
- data/spec/fixtures/rails6_users_app/docker-compose.yml +1 -1
- data/spec/fixtures/rails6_users_app/lib/tasks/appmap.rake +13 -0
- data/spec/{abstract_controller_base_spec.rb → rails_recording_spec.rb} +2 -21
- data/spec/rails_spec_helper.rb +22 -0
- data/spec/swagger/swagger_spec.rb +47 -0
- data/test/{cli_test.rb → agent_setup_init_test.rb} +4 -4
- data/test/fixtures/gem_test/Gemfile +1 -0
- data/test/gem_test.rb +1 -0
- data/test/inspect_cli_test.rb +12 -0
- data/yarn.lock +477 -0
- metadata +39 -63
- data/exe/appmap-agent-setup +0 -47
- data/lib/appmap/algorithm/prune_class_map.rb +0 -67
- data/lib/appmap/algorithm/stats.rb +0 -91
- data/lib/appmap/command/init.rb +0 -42
- data/lib/appmap/command/record.rb +0 -38
- data/lib/appmap/command/stats.rb +0 -14
- data/lore/pages/2019-05-21-install-and-record/index.pug +0 -51
- data/lore/pages/2019-05-21-install-and-record/install_example_appmap.png +0 -0
- data/lore/pages/2019-05-21-install-and-record/metadata.yml +0 -5
- data/lore/pages/layout.pug +0 -66
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.css +0 -1912
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.css.map +0 -1
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.min.css +0 -7
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-grid.min.css.map +0 -1
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.css +0 -331
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.css.map +0 -1
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.min.css +0 -8
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap-reboot.min.css.map +0 -1
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.css +0 -9030
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.css.map +0 -1
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.min.css +0 -7
- data/lore/public/lib/bootstrap-4.1.3/css/bootstrap.min.css.map +0 -1
- data/lore/public/stylesheets/style.css +0 -8
- data/package-lock.json +0 -1064
data/lib/appmap/class_map.rb
CHANGED
@@ -111,7 +111,7 @@ module AppMap
|
|
111
111
|
end
|
112
112
|
|
113
113
|
comment = method.comment
|
114
|
-
function_info[:comment] = comment unless
|
114
|
+
function_info[:comment] = comment unless Util.blank?(comment)
|
115
115
|
|
116
116
|
function_info[:labels] = parse_labels(comment) + (method.labels || [])
|
117
117
|
object_infos << function_info
|
@@ -119,7 +119,7 @@ module AppMap
|
|
119
119
|
parent = root
|
120
120
|
object_infos.each do |info|
|
121
121
|
parent = find_or_create parent.children, info do
|
122
|
-
Types.const_get(info[:type]
|
122
|
+
Types.const_get(Util.classify(info[:type])).new(info[:name].to_s).tap do |type|
|
123
123
|
info.keys.tap do |keys|
|
124
124
|
keys.delete(:name)
|
125
125
|
keys.delete(:type)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'appmap/service/guesser'
|
5
|
+
require 'appmap/util'
|
6
|
+
|
7
|
+
module AppMap
|
8
|
+
module Command
|
9
|
+
module AgentSetup
|
10
|
+
InitStruct = Struct.new(:config_file)
|
11
|
+
|
12
|
+
class Init < InitStruct
|
13
|
+
def perform
|
14
|
+
if File.exist?(config_file)
|
15
|
+
puts AppMap::Util.color(%(The AppMap config file #{config_file} already exists.), :magenta)
|
16
|
+
return
|
17
|
+
end
|
18
|
+
|
19
|
+
ensure_directory_exists
|
20
|
+
|
21
|
+
config = {
|
22
|
+
'name' => Service::Guesser.guess_name,
|
23
|
+
'packages' => Service::Guesser.guess_paths.map { |path| { 'path' => path } }
|
24
|
+
}
|
25
|
+
content = YAML.dump(config).gsub("---\n", '')
|
26
|
+
|
27
|
+
File.write(config_file, content)
|
28
|
+
puts AppMap::Util.color(
|
29
|
+
%(The following AppMap config file #{config_file} has been created:),
|
30
|
+
:green
|
31
|
+
)
|
32
|
+
puts content
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def ensure_directory_exists
|
38
|
+
dirname = File.dirname(config_file)
|
39
|
+
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'appmap/version'
|
2
|
+
require 'appmap/config'
|
3
|
+
require 'appmap/node_cli'
|
4
|
+
|
5
|
+
module AppMap
|
6
|
+
module Command
|
7
|
+
class Inspect < AppMap::NodeCLI
|
8
|
+
class << self
|
9
|
+
def run
|
10
|
+
command = Inspect.new(verbose: ENV['DEBUG'] == 'true')
|
11
|
+
command.inspect(ARGV)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def inspect(arguments)
|
16
|
+
detect_nodejs
|
17
|
+
index_appmaps
|
18
|
+
|
19
|
+
arguments.unshift 'inspect'
|
20
|
+
arguments.unshift APPMAP_JS
|
21
|
+
arguments.unshift 'node'
|
22
|
+
|
23
|
+
exec(*arguments)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module AppMap
|
2
|
+
# Raised when a system / shell command fails.
|
3
|
+
class CommandError < StandardError
|
4
|
+
attr_reader :command, :msg
|
5
|
+
|
6
|
+
def initialize(command, msg = nil)
|
7
|
+
super [ "Command failed: #{command}", msg ].compact.join('; ')
|
8
|
+
|
9
|
+
@command = command
|
10
|
+
@msg = msg
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/appmap/config.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'yaml'
|
4
|
+
require 'appmap/util'
|
4
5
|
require 'appmap/handler/net_http'
|
5
6
|
require 'appmap/handler/rails/template'
|
6
7
|
require 'appmap/service/guesser'
|
8
|
+
require 'appmap/swagger/configuration'
|
7
9
|
|
8
10
|
module AppMap
|
9
11
|
class Config
|
@@ -54,7 +56,7 @@ module AppMap
|
|
54
56
|
if path
|
55
57
|
Package.new(path, gem, package_name, exclude, labels, shallow)
|
56
58
|
else
|
57
|
-
|
59
|
+
AppMap::Util.startup_message "#{gem} is not available in the bundle"
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
@@ -80,8 +82,8 @@ module AppMap
|
|
80
82
|
package_name: package_name,
|
81
83
|
gem: gem,
|
82
84
|
handler_class: handler_class.name,
|
83
|
-
exclude:
|
84
|
-
labels:
|
85
|
+
exclude: Util.blank?(exclude) ? nil : exclude,
|
86
|
+
labels: Util.blank?(labels) ? nil : labels,
|
85
87
|
shallow: shallow
|
86
88
|
}.compact
|
87
89
|
end
|
@@ -225,15 +227,17 @@ module AppMap
|
|
225
227
|
'JSON::Ext::Generator::State' => TargetMethods.new(:generate, Package.build_from_path('json', package_name: 'json', labels: %w[format.json.generate])),
|
226
228
|
}.freeze
|
227
229
|
|
228
|
-
attr_reader :name, :appmap_dir, :packages, :exclude, :hooked_methods, :builtin_hooks
|
230
|
+
attr_reader :name, :appmap_dir, :packages, :exclude, :swagger_config, :hooked_methods, :builtin_hooks
|
229
231
|
|
230
232
|
def initialize(name,
|
231
233
|
packages: [],
|
234
|
+
swagger_config: Swagger::Configuration.new,
|
232
235
|
exclude: [],
|
233
236
|
functions: [])
|
234
237
|
@name = name
|
235
238
|
@appmap_dir = AppMap::DEFAULT_APPMAP_DIR
|
236
239
|
@packages = packages
|
240
|
+
@swagger_config = swagger_config
|
237
241
|
@hook_paths = Set.new(packages.map(&:path))
|
238
242
|
@exclude = exclude
|
239
243
|
@builtin_hooks = BUILTIN_HOOKS
|
@@ -350,6 +354,11 @@ module AppMap
|
|
350
354
|
end
|
351
355
|
end
|
352
356
|
|
357
|
+
if config_data['swagger']
|
358
|
+
swagger_config = Swagger::Configuration.load(config_data['swagger'])
|
359
|
+
config_params[:swagger_config] = swagger_config
|
360
|
+
end
|
361
|
+
|
353
362
|
Config.new name, config_params
|
354
363
|
end
|
355
364
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'appmap/event'
|
4
|
+
require 'appmap/util'
|
4
5
|
|
5
6
|
module AppMap
|
6
7
|
module Handler
|
@@ -38,7 +39,7 @@ module AppMap
|
|
38
39
|
headers: headers
|
39
40
|
}.compact
|
40
41
|
|
41
|
-
unless
|
42
|
+
unless Util.blank?(params)
|
42
43
|
h[:message] = params.keys.map do |key|
|
43
44
|
val = params[key]
|
44
45
|
{
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'appmap/event'
|
4
4
|
require 'appmap/hook'
|
5
|
+
require 'appmap/util'
|
5
6
|
|
6
7
|
module AppMap
|
7
8
|
module Handler
|
@@ -40,7 +41,7 @@ module AppMap
|
|
40
41
|
headers: headers,
|
41
42
|
}.compact
|
42
43
|
|
43
|
-
unless
|
44
|
+
unless Util.blank?(params)
|
44
45
|
h[:message] = params.keys.map do |key|
|
45
46
|
val = params[key]
|
46
47
|
{
|
data/lib/appmap/metadata.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'appmap/util'
|
4
|
+
|
3
5
|
module AppMap
|
4
6
|
module Metadata
|
5
7
|
class << self
|
@@ -40,9 +42,9 @@ module AppMap
|
|
40
42
|
git_sha = `git rev-parse HEAD`.strip
|
41
43
|
git_status = `git status -s`.split("\n").map(&:strip)
|
42
44
|
git_last_annotated_tag = `git describe --abbrev=0 2>/dev/null`.strip
|
43
|
-
git_last_annotated_tag = nil if
|
45
|
+
git_last_annotated_tag = nil if Util.blank?(git_last_annotated_tag)
|
44
46
|
git_last_tag = `git describe --abbrev=0 --tags 2>/dev/null`.strip
|
45
|
-
git_last_tag = nil if
|
47
|
+
git_last_tag = nil if Util.blank?(git_last_tag)
|
46
48
|
git_commits_since_last_annotated_tag = `git describe`.strip =~ /-(\d+)-(\w+)$/[1] rescue 0 if git_last_annotated_tag
|
47
49
|
git_commits_since_last_tag = `git describe --tags`.strip =~ /-(\d+)-(\w+)$/[1] rescue 0 if git_last_tag
|
48
50
|
|
data/lib/appmap/minitest.rb
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'open3'
|
2
|
+
require 'shellwords'
|
3
|
+
require 'appmap/util'
|
4
|
+
require 'appmap/command_error'
|
5
|
+
|
6
|
+
module AppMap
|
7
|
+
# Utilities for invoking the +@appland/appmap+ CLI.
|
8
|
+
class NodeCLI
|
9
|
+
APPMAP_JS = Pathname.new(__dir__).join('../../node_modules/@appland/cli/src/cli.js').expand_path.to_s
|
10
|
+
|
11
|
+
attr_reader :verbose
|
12
|
+
# Directory to scan for AppMaps.
|
13
|
+
attr_accessor :appmap_dir
|
14
|
+
|
15
|
+
def initialize(verbose: false, appmap_dir: AppMap::DEFAULT_APPMAP_DIR)
|
16
|
+
@verbose = verbose
|
17
|
+
@appmap_dir = appmap_dir
|
18
|
+
|
19
|
+
detect_nodejs
|
20
|
+
end
|
21
|
+
|
22
|
+
def detect_nodejs
|
23
|
+
do_fail('node', 'please install NodeJS') unless system('node --version 2>&1 > /dev/null')
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def index_appmaps
|
28
|
+
command [ 'index', '--appmap-dir', appmap_dir ]
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def command(command, options = {})
|
33
|
+
command.unshift << '--verbose' if verbose
|
34
|
+
command.unshift APPMAP_JS
|
35
|
+
command.unshift 'node'
|
36
|
+
|
37
|
+
warn command.join(' ') if verbose
|
38
|
+
stdout, stderr, status = Open3.capture3({ 'NODE_OPTIONS' => '--trace-warnings' }, *command.map(&:shellescape), options)
|
39
|
+
stdout_msg = stdout.split("\n").map {|line| "stdout: #{line}"}.join("\n") unless Util.blank?(stdout)
|
40
|
+
stderr_msg = stderr.split("\n").map {|line| "stderr: #{line}"}.join("\n") unless Util.blank?(stderr)
|
41
|
+
if verbose
|
42
|
+
warn stdout_msg if stdout_msg
|
43
|
+
warn stderr_msg if stderr_msg
|
44
|
+
end
|
45
|
+
unless status.exitstatus == 0
|
46
|
+
raise CommandError.new(command, [ stdout_msg, stderr_msg ].compact.join("\n"))
|
47
|
+
end
|
48
|
+
[ stdout, stderr ]
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
def do_fail(command, msg)
|
54
|
+
command = command.join(' ') if command.is_a?(Array)
|
55
|
+
warn [ command, msg ].join('; ') if verbose
|
56
|
+
raise CommandError.new(command, msg)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/appmap/railtie.rb
CHANGED
@@ -5,8 +5,8 @@ module AppMap
|
|
5
5
|
class Railtie < ::Rails::Railtie
|
6
6
|
initializer 'appmap.remote_recording' do
|
7
7
|
require 'appmap/middleware/remote_recording'
|
8
|
-
Rails.application.config.middleware.
|
9
|
-
|
8
|
+
Rails.application.config.middleware.insert_before \
|
9
|
+
ActionDispatch::Executor,
|
10
10
|
AppMap::Middleware::RemoteRecording
|
11
11
|
end
|
12
12
|
|
data/lib/appmap/rspec.rb
CHANGED
@@ -62,8 +62,10 @@ module AppMap
|
|
62
62
|
example_group_parent = \
|
63
63
|
if example_group.respond_to?(:module_parent)
|
64
64
|
example_group.module_parent
|
65
|
-
|
65
|
+
elsif example_group.respond_to?(:parent)
|
66
66
|
example_group.parent
|
67
|
+
elsif example_group.respond_to?(:parent_groups)
|
68
|
+
example_group.parent_groups.first
|
67
69
|
end
|
68
70
|
|
69
71
|
example_group_parent != example_group ? ScopeExampleGroup.new(example_group_parent) : nil
|
@@ -109,13 +111,13 @@ module AppMap
|
|
109
111
|
|
110
112
|
description = []
|
111
113
|
scope = ScopeExample.new(example)
|
112
|
-
|
113
114
|
while scope
|
114
115
|
description << scope.description
|
115
116
|
scope = scope.parent
|
116
117
|
end
|
117
118
|
|
118
|
-
description.reject!(&:nil?)
|
119
|
+
description.reject!(&:nil?)
|
120
|
+
description.reject!(&Util.method(:blank?))
|
119
121
|
default_description = description.last
|
120
122
|
description.reverse!
|
121
123
|
|
@@ -6,15 +6,8 @@ module AppMap
|
|
6
6
|
POSSIBLE_PATHS = %w[app/controllers app/models lib]
|
7
7
|
class << self
|
8
8
|
def guess_name
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
repo_name = `git config --get remote.origin.url`.strip
|
13
|
-
repo_name.split('/').last.split('.').first unless repo_name == ''
|
14
|
-
end
|
15
|
-
dirname = -> { Dir.pwd.split('/').last }
|
16
|
-
|
17
|
-
reponame.() || dirname.()
|
9
|
+
return Pathname.new(`git rev-parse --show-toplevel`.strip).basename.to_s if File.directory?('.git')
|
10
|
+
Dir.pwd.split('/').last
|
18
11
|
end
|
19
12
|
|
20
13
|
def guess_paths
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module AppMap
|
4
|
+
module Swagger
|
5
|
+
class Configuration
|
6
|
+
DEFAULT_VERSION = '1.0'
|
7
|
+
DEFAULT_OUTPUT_DIR = 'swagger'
|
8
|
+
DEFAULT_DESCRIPTION = 'Generate Swagger from AppMaps'
|
9
|
+
|
10
|
+
attr_accessor :project_version,
|
11
|
+
:output_dir,
|
12
|
+
:description
|
13
|
+
attr_writer :project_name, :template
|
14
|
+
|
15
|
+
class << self
|
16
|
+
def load(config_data)
|
17
|
+
Configuration.new.tap do |config|
|
18
|
+
config_data.each do |k,v|
|
19
|
+
config.send "#{k}=", v
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@project_name = nil
|
27
|
+
@project_version = DEFAULT_VERSION
|
28
|
+
@output_dir = DEFAULT_OUTPUT_DIR
|
29
|
+
@description = DEFAULT_DESCRIPTION
|
30
|
+
end
|
31
|
+
|
32
|
+
def project_name
|
33
|
+
@project_name || default_project_name
|
34
|
+
end
|
35
|
+
|
36
|
+
def template
|
37
|
+
@template || default_template
|
38
|
+
end
|
39
|
+
|
40
|
+
def default_template
|
41
|
+
YAML.load <<~TEMPLATE
|
42
|
+
openapi: 3.0.1
|
43
|
+
info:
|
44
|
+
title: #{project_name}
|
45
|
+
version: #{project_version}
|
46
|
+
paths:
|
47
|
+
components:
|
48
|
+
servers:
|
49
|
+
- url: http://{defaultHost}
|
50
|
+
variables:
|
51
|
+
defaultHost:
|
52
|
+
default: localhost:3000
|
53
|
+
TEMPLATE
|
54
|
+
end
|
55
|
+
|
56
|
+
def default_project_name
|
57
|
+
# https://www.rubydoc.info/docs/rails/Module#module_parent_name-instance_method
|
58
|
+
module_parent_name = ->(cls) { cls.name =~ /::[^:]+\Z/ ? $`.freeze : nil }
|
59
|
+
|
60
|
+
# Lazy-evaluate this so that Rails.application will be defined.
|
61
|
+
# If this code runs too early in the lifecycle, Rails.application is nil.
|
62
|
+
if defined?(::Rails)
|
63
|
+
[module_parent_name.(::Rails.application.class).humanize.titleize, "API"].join(" ")
|
64
|
+
else
|
65
|
+
"MyProject API"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rdoc'
|
2
|
+
require 'reverse_markdown'
|
3
|
+
|
4
|
+
module AppMap
|
5
|
+
module Swagger
|
6
|
+
# Transform description fields into Markdown.
|
7
|
+
class MarkdownDescriptions
|
8
|
+
def initialize(swagger_yaml)
|
9
|
+
@swagger_yaml = swagger_yaml
|
10
|
+
end
|
11
|
+
|
12
|
+
def converter
|
13
|
+
method(:rdoc_to_markdown)
|
14
|
+
end
|
15
|
+
|
16
|
+
def perform
|
17
|
+
to_markdown = lambda do |obj|
|
18
|
+
return obj.each(&to_markdown) if obj.is_a?(Array)
|
19
|
+
return unless obj.is_a?(Hash)
|
20
|
+
|
21
|
+
description = obj['description']
|
22
|
+
obj['description'] = converter.(description) if description
|
23
|
+
|
24
|
+
obj.reject { |k,v| k == 'properties' }.each_value(&to_markdown)
|
25
|
+
|
26
|
+
obj
|
27
|
+
end
|
28
|
+
|
29
|
+
to_markdown.(Util.deep_dup(@swagger_yaml))
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def rdoc_to_markdown(comment)
|
35
|
+
# Strip tags
|
36
|
+
comment = comment.split("\n").reject { |line| line =~ /^\s*@/ }.join("\n")
|
37
|
+
converter = ::RDoc::Markup::ToHtml.new(::RDoc::Options.new)
|
38
|
+
html = converter.convert(comment).strip
|
39
|
+
::ReverseMarkdown.convert(html).strip
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|