r2-oas 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/ISSUE_TEMPLATE.md +12 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +12 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +7 -0
- data/.rubocop_todo.yml +224 -0
- data/.travis.yml +22 -0
- data/CHANGELOG.md +3 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +207 -0
- data/LICENSE.txt +21 -0
- data/README.ja.md +585 -0
- data/README.md +582 -0
- data/Rakefile +8 -0
- data/bin/console +12 -0
- data/bin/setup +8 -0
- data/docs/HOW_TO_ANALYZE_DOCS.md +875 -0
- data/docs/HOW_TO_CLEAN_DOCS.md +19 -0
- data/docs/HOW_TO_DEPLOY_SWAGGER_DOC.md +839 -0
- data/docs/HOW_TO_DISPLAY_PATHS_LIST.md +28 -0
- data/docs/HOW_TO_DISPLAY_PATHS_STATS.md +53 -0
- data/docs/HOW_TO_GENERATE_DOCS.md +256 -0
- data/docs/HOW_TO_MONITOR_SWAGGER_DOC.md +219 -0
- data/docs/HOW_TO_START_SWAGGER_EDITOR.md +218 -0
- data/docs/HOW_TO_START_SWAGGER_UI.md +262 -0
- data/docs/HOW_TO_USE_HOOK_WHEN_GENERATE_DOC.md +244 -0
- data/docs/HOW_TO_USE_SCHEMA_NAMESPACE.md +176 -0
- data/docs/HOW_TO_USE_TAG_NAMESPACE.md +176 -0
- data/docs/versions/v3.md +155 -0
- data/lib/r2-oas.rb +36 -0
- data/lib/r2-oas/app_configuration.rb +102 -0
- data/lib/r2-oas/app_configuration/server.rb +35 -0
- data/lib/r2-oas/app_configuration/swagger.rb +35 -0
- data/lib/r2-oas/app_configuration/swagger/editor.rb +47 -0
- data/lib/r2-oas/app_configuration/swagger/ui.rb +45 -0
- data/lib/r2-oas/app_configuration/tool.rb +31 -0
- data/lib/r2-oas/app_configuration/tool/paths/stats.rb +43 -0
- data/lib/r2-oas/base.rb +48 -0
- data/lib/r2-oas/configuration.rb +69 -0
- data/lib/r2-oas/configuration/paths_config.rb +44 -0
- data/lib/r2-oas/deploy/client.rb +43 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/favicon-16x16.png +0 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/favicon-32x32.png +0 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/oauth2-redirect.html +68 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui-bundle.js +134 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui-bundle.js.map +1 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui-standalone-preset.js +22 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui-standalone-preset.js.map +1 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui.css +4 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui.css.map +1 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui.js +9 -0
- data/lib/r2-oas/deploy/swagger-ui/dist/swagger-ui.js.map +1 -0
- data/lib/r2-oas/deploy/swagger-ui/index.html.erb +60 -0
- data/lib/r2-oas/errors.rb +7 -0
- data/lib/r2-oas/hooks/global_hook.rb +20 -0
- data/lib/r2-oas/hooks/hook.rb +77 -0
- data/lib/r2-oas/hooks/repository.rb +15 -0
- data/lib/r2-oas/logger/stdout_logger.rb +129 -0
- data/lib/r2-oas/pluggable_configuration.rb +33 -0
- data/lib/r2-oas/plugins/schema/v3/object/hookable_base_object.rb +100 -0
- data/lib/r2-oas/routing/adjustor.rb +44 -0
- data/lib/r2-oas/routing/base.rb +12 -0
- data/lib/r2-oas/routing/components/all.rb +5 -0
- data/lib/r2-oas/routing/components/base_component.rb +10 -0
- data/lib/r2-oas/routing/components/path_component.rb +67 -0
- data/lib/r2-oas/routing/components/request_component.rb +75 -0
- data/lib/r2-oas/routing/components/verb_component.rb +21 -0
- data/lib/r2-oas/routing/parser.rb +93 -0
- data/lib/r2-oas/schema/analyzer.rb +23 -0
- data/lib/r2-oas/schema/base.rb +11 -0
- data/lib/r2-oas/schema/cleaner.rb +23 -0
- data/lib/r2-oas/schema/editor.rb +120 -0
- data/lib/r2-oas/schema/generator.rb +23 -0
- data/lib/r2-oas/schema/manager/file/path_item_file_manager.rb +24 -0
- data/lib/r2-oas/schema/monitor.rb +52 -0
- data/lib/r2-oas/schema/squeezer.rb +23 -0
- data/lib/r2-oas/schema/ui.rb +74 -0
- data/lib/r2-oas/schema/v3/analyzer.rb +58 -0
- data/lib/r2-oas/schema/v3/analyzer/base_analyzer.rb +76 -0
- data/lib/r2-oas/schema/v3/analyzer/components/object_analyzer.rb +38 -0
- data/lib/r2-oas/schema/v3/analyzer/components_analyzer.rb +30 -0
- data/lib/r2-oas/schema/v3/analyzer/path_analyzer.rb +116 -0
- data/lib/r2-oas/schema/v3/analyzer/tag_analyzer.rb +38 -0
- data/lib/r2-oas/schema/v3/base.rb +28 -0
- data/lib/r2-oas/schema/v3/cleaner.rb +19 -0
- data/lib/r2-oas/schema/v3/cleaner/base_cleaner.rb +30 -0
- data/lib/r2-oas/schema/v3/cleaner/components_cleaner.rb +42 -0
- data/lib/r2-oas/schema/v3/generator.rb +28 -0
- data/lib/r2-oas/schema/v3/generator/base_generator.rb +88 -0
- data/lib/r2-oas/schema/v3/generator/components/object_generator.rb +83 -0
- data/lib/r2-oas/schema/v3/generator/components/request_body_generator.rb +45 -0
- data/lib/r2-oas/schema/v3/generator/components_generator.rb +38 -0
- data/lib/r2-oas/schema/v3/generator/doc_generator.rb +49 -0
- data/lib/r2-oas/schema/v3/generator/path_generator.rb +90 -0
- data/lib/r2-oas/schema/v3/generator/schema_generator.rb +78 -0
- data/lib/r2-oas/schema/v3/manager/diff/base_array_diff_manager.rb +60 -0
- data/lib/r2-oas/schema/v3/manager/diff/base_diff_manager.rb +29 -0
- data/lib/r2-oas/schema/v3/manager/diff/base_hash_diff_manager.rb +95 -0
- data/lib/r2-oas/schema/v3/manager/diff/components_diff_manager.rb +19 -0
- data/lib/r2-oas/schema/v3/manager/diff/tag_diff_manager.rb +17 -0
- data/lib/r2-oas/schema/v3/manager/file/base_file_manager.rb +60 -0
- data/lib/r2-oas/schema/v3/manager/file/components_file_manager.rb +22 -0
- data/lib/r2-oas/schema/v3/manager/file/include_ref_base_file_manager.rb +88 -0
- data/lib/r2-oas/schema/v3/manager/file/path_item_file_manager.rb +22 -0
- data/lib/r2-oas/schema/v3/manager/file_manager.rb +12 -0
- data/lib/r2-oas/schema/v3/manager/pathname_manager.rb +73 -0
- data/lib/r2-oas/schema/v3/object/base_object.rb +65 -0
- data/lib/r2-oas/schema/v3/object/components/request_body_object.rb +92 -0
- data/lib/r2-oas/schema/v3/object/components/schema_object.rb +55 -0
- data/lib/r2-oas/schema/v3/object/components_object.rb +81 -0
- data/lib/r2-oas/schema/v3/object/external_document_object.rb +19 -0
- data/lib/r2-oas/schema/v3/object/info_object.rb +34 -0
- data/lib/r2-oas/schema/v3/object/openapi_object.rb +58 -0
- data/lib/r2-oas/schema/v3/object/path_item_object.rb +167 -0
- data/lib/r2-oas/schema/v3/object/paths_object.rb +74 -0
- data/lib/r2-oas/schema/v3/object/public.rb +9 -0
- data/lib/r2-oas/schema/v3/object/server_object.rb +21 -0
- data/lib/r2-oas/schema/v3/object/tag_object.rb +36 -0
- data/lib/r2-oas/schema/v3/squeezer.rb +29 -0
- data/lib/r2-oas/schema/v3/squeezer/base_squeezer.rb +37 -0
- data/lib/r2-oas/schema/v3/squeezer/path_squeezer.rb +28 -0
- data/lib/r2-oas/schema/v3/squeezer/tag_squeezer.rb +19 -0
- data/lib/r2-oas/shared/all.rb +3 -0
- data/lib/r2-oas/shared/sortable.rb +23 -0
- data/lib/r2-oas/task.rb +11 -0
- data/lib/r2-oas/task_logging.rb +39 -0
- data/lib/r2-oas/tasks/common.rake +26 -0
- data/lib/r2-oas/tasks/main.rake +117 -0
- data/lib/r2-oas/tasks/tool.rake +79 -0
- data/lib/r2-oas/tool/paths/ls.rb +15 -0
- data/lib/r2-oas/tool/paths/stats.rb +84 -0
- data/lib/r2-oas/version.rb +5 -0
- data/r2-oas.gemspec +56 -0
- metadata +373 -0
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base'
|
4
|
+
require_relative 'components/all'
|
5
|
+
|
6
|
+
module R2OAS
|
7
|
+
module Routing
|
8
|
+
class Adjustor < Base
|
9
|
+
VALID_KEYS = %i[route name verb path reqs].freeze
|
10
|
+
|
11
|
+
def initialize(route_data)
|
12
|
+
valid_route_data?(route_data)
|
13
|
+
@route_data = route_data
|
14
|
+
@route = route_data[:route]
|
15
|
+
@path_comp = PathComponent.new(route_data[:path])
|
16
|
+
@request_comp = RequestComponent.new(route_data[:reqs], @route.engine?)
|
17
|
+
@verb_comp = VerbComponent.new(route_data[:verb])
|
18
|
+
@verbs = @verb_comp.verbs
|
19
|
+
end
|
20
|
+
|
21
|
+
def routes_els
|
22
|
+
@verbs.each_with_object([]) do |verb, result|
|
23
|
+
route_el = {}
|
24
|
+
route_el[:path] = @path_comp.symbol_to_brace
|
25
|
+
route_el[:data] = {
|
26
|
+
verb: verb,
|
27
|
+
path: @path_comp.symbol_to_brace,
|
28
|
+
tag_name: @request_comp.to_tag_name,
|
29
|
+
schema_name: @request_comp.to_schema_name,
|
30
|
+
format_name: @request_comp.to_format_name,
|
31
|
+
required_parameters: @path_comp.path_parameters_data
|
32
|
+
}
|
33
|
+
result.push route_el
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def valid_route_data?(route_data)
|
40
|
+
raise 'Invalid params' unless route_data.keys.eql?(VALID_KEYS)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_component'
|
4
|
+
|
5
|
+
module R2OAS
|
6
|
+
module Routing
|
7
|
+
class PathComponent < BaseComponent
|
8
|
+
FORMAT_PATH_PARAMETER_REGEXP = /\(.+\)/.freeze
|
9
|
+
SYMBOL_PATH_PARAMETER_REGEXP = /:(.\w+)/.freeze
|
10
|
+
BRACE_PATH_PARAMETER_REGEXP = /\{(.\w+)\}/.freeze
|
11
|
+
|
12
|
+
def initialize(path)
|
13
|
+
super()
|
14
|
+
@path = path
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
without_format.to_s
|
19
|
+
end
|
20
|
+
|
21
|
+
def symbol_to_brace
|
22
|
+
return without_format unless exist_path_parameters?
|
23
|
+
|
24
|
+
path_parameters.each_with_object(without_format) do |path_parameter, result|
|
25
|
+
result.gsub!(":#{path_parameter}", "{#{path_parameter}}")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def path_parameters_data
|
30
|
+
return {} unless exist_path_parameters?
|
31
|
+
|
32
|
+
path_parameters.each_with_object({}) do |path_parameter, data|
|
33
|
+
type = (path_parameter =~ /id/ ? 'integer' : 'string')
|
34
|
+
data.merge!(
|
35
|
+
"#{path_parameter}": {
|
36
|
+
type: type
|
37
|
+
}
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def path_excluded_path_parameters
|
43
|
+
excluded_path_parameters = path_parameters.each_with_object(symbol_to_brace) do |path_parameter, result|
|
44
|
+
result.gsub!("{#{path_parameter}}", '')
|
45
|
+
end
|
46
|
+
excluded_path_parameters.split('/').delete_if(&:empty?).join('/')
|
47
|
+
end
|
48
|
+
|
49
|
+
def exist_path_parameters?
|
50
|
+
path_parameters.present?
|
51
|
+
end
|
52
|
+
|
53
|
+
def path_parameters
|
54
|
+
result = without_format.scan(SYMBOL_PATH_PARAMETER_REGEXP) + without_format.scan(BRACE_PATH_PARAMETER_REGEXP)
|
55
|
+
result.flatten
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# e.x.) "/tasks(.:format)" => "/tasks"
|
61
|
+
# e.x.) "/:model_name/:id/show_in_app(.:format)" => "/{model_name}/{id}/show_in_app"
|
62
|
+
def without_format
|
63
|
+
@path.gsub(FORMAT_PATH_PARAMETER_REGEXP, '')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_component'
|
4
|
+
|
5
|
+
module R2OAS
|
6
|
+
module Routing
|
7
|
+
class RequestComponent < BaseComponent
|
8
|
+
def initialize(request, is_route_engine)
|
9
|
+
super()
|
10
|
+
@request = request
|
11
|
+
@is_route_engine = is_route_engine
|
12
|
+
end
|
13
|
+
|
14
|
+
# e.x.) "tasks#index" => "task"
|
15
|
+
# e.x.) "RailsAdmin::Engine" => "rails_amin/engine"
|
16
|
+
def to_tag_name
|
17
|
+
tag_name = if @is_route_engine
|
18
|
+
@request.gsub('::', '/').underscore
|
19
|
+
else
|
20
|
+
@request.split('#').first.singularize
|
21
|
+
end
|
22
|
+
|
23
|
+
tag_name = tag_name.split('/').last unless use_tag_namespace
|
24
|
+
|
25
|
+
tag_name
|
26
|
+
end
|
27
|
+
|
28
|
+
def to_schema_name
|
29
|
+
if @is_route_engine
|
30
|
+
schema_name = @request.split('::').map(&:camelcase).join(ns_div)
|
31
|
+
else
|
32
|
+
# e.x.) @request = "api/v2/posts#index {:format=>:json}"
|
33
|
+
# e.x.) path = "api/v2/post"
|
34
|
+
path = @request.split('#').first.singularize
|
35
|
+
schema_name = path.split('/').map(&:camelcase).join(ns_div)
|
36
|
+
end
|
37
|
+
|
38
|
+
if use_schema_namespace
|
39
|
+
schema_name_only = schema_name.split(ns_div).last
|
40
|
+
namespace = adjust_namespace(schema_name.split(ns_div)[0..-2].join(ns_div))
|
41
|
+
|
42
|
+
if namespace.present?
|
43
|
+
[namespace, schema_name_only].join(ns_div)
|
44
|
+
else
|
45
|
+
schema_name_only
|
46
|
+
end
|
47
|
+
else
|
48
|
+
schema_name.split(ns_div).last
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# e.x.) "tasks#index { :format => ":json" }"
|
53
|
+
def to_format_name
|
54
|
+
result = ''
|
55
|
+
@request.match(/{\:format=>:(?<format_name>.*)}/) do |md|
|
56
|
+
result = md[:format_name] if md[:format_name]
|
57
|
+
end
|
58
|
+
result
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def adjust_namespace(namespace)
|
64
|
+
case namespace_type
|
65
|
+
when :dot
|
66
|
+
namespace.downcase
|
67
|
+
when :underbar
|
68
|
+
namespace
|
69
|
+
else
|
70
|
+
raise "Do not support #{namespace_type}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'base_component'
|
4
|
+
|
5
|
+
module R2OAS
|
6
|
+
module Routing
|
7
|
+
class VerbComponent < BaseComponent
|
8
|
+
def initialize(verb)
|
9
|
+
super()
|
10
|
+
@verb = verb
|
11
|
+
end
|
12
|
+
|
13
|
+
# e.x.) "" => ["get"]
|
14
|
+
# e.x.) "POST" => ["post"]
|
15
|
+
# e.x.) "GET|POST" => ["get","post"]
|
16
|
+
def verbs
|
17
|
+
(@verb.downcase.presence || 'get').split('|')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'adjustor'
|
4
|
+
require_relative 'base'
|
5
|
+
|
6
|
+
module R2OAS
|
7
|
+
module Routing
|
8
|
+
class Parser
|
9
|
+
# routes should be Rails.application.routes.routes
|
10
|
+
def initialize(routes)
|
11
|
+
@_routes = routes
|
12
|
+
@_engines = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
def routes_data
|
16
|
+
data = []
|
17
|
+
normalized_routes do |route_els|
|
18
|
+
data.push *route_els
|
19
|
+
end
|
20
|
+
data
|
21
|
+
end
|
22
|
+
|
23
|
+
def tags_data
|
24
|
+
data = []
|
25
|
+
normalized_routes do |route_els|
|
26
|
+
route_els.each do |route_el|
|
27
|
+
tag_name = route_el[:data][:tag_name]
|
28
|
+
data.push tag_name unless data.include?(tag_name)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
data
|
32
|
+
end
|
33
|
+
|
34
|
+
def schemas_data
|
35
|
+
data = []
|
36
|
+
normalized_routes do |route_els|
|
37
|
+
route_els.each do |route_el|
|
38
|
+
schema_name = route_el[:data][:schema_name]
|
39
|
+
data.push schema_name unless data.include?(schema_name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
data
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
attr_accessor :_routes, :_engines
|
48
|
+
|
49
|
+
def normalized_routes(&block)
|
50
|
+
collect_routes(_routes).each_with_object([]) do |route_data, _arr|
|
51
|
+
routes_els = Adjustor.new(route_data).routes_els
|
52
|
+
block.call(routes_els) if block_given?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# copy from:
|
57
|
+
# https://github.com/rails/rails/blob/v4.2.1/actionpack/lib/action_dispatch/routing/inspector.rb#L114-L140
|
58
|
+
# https://github.com/rails/rails/blob/v5.2.3/actionpack/lib/action_dispatch/routing/inspector.rb
|
59
|
+
def collect_routes(routes)
|
60
|
+
result = routes.collect do |route|
|
61
|
+
ActionDispatch::Routing::RouteWrapper.new(route)
|
62
|
+
end.reject(&:internal?).collect do |route|
|
63
|
+
collect_engine_routes(route)
|
64
|
+
|
65
|
+
# delete json_regexp after copy
|
66
|
+
{ route: route,
|
67
|
+
name: route.name,
|
68
|
+
verb: route.verb,
|
69
|
+
path: route.path,
|
70
|
+
reqs: route.reqs }
|
71
|
+
end
|
72
|
+
|
73
|
+
# Push Rails Engine Routes Data
|
74
|
+
_engines.each do |_engine_name, engine_route_data|
|
75
|
+
result.push(*engine_route_data)
|
76
|
+
end
|
77
|
+
|
78
|
+
result
|
79
|
+
end
|
80
|
+
|
81
|
+
# copy from:
|
82
|
+
# https://github.com/rails/rails/blob/v4.2.1/actionpack/lib/action_dispatch/routing/inspector.rb#L114-L140
|
83
|
+
def collect_engine_routes(route)
|
84
|
+
name = route.endpoint
|
85
|
+
return unless route.engine?
|
86
|
+
return if _engines[name]
|
87
|
+
|
88
|
+
routes = route.rack_app.routes
|
89
|
+
_engines[name] = collect_routes(routes.routes) if routes.is_a?(ActionDispatch::Routing::RouteSet)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
require 'r2-oas/schema/v3/analyzer'
|
5
|
+
|
6
|
+
module R2OAS
|
7
|
+
module Schema
|
8
|
+
class Analyzer
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def_delegators :@analyzer, :analyze_docs
|
12
|
+
|
13
|
+
def initialize(before_schema_data, after_schema_data, options = {})
|
14
|
+
case ::R2OAS.version
|
15
|
+
when :v3
|
16
|
+
@analyzer = V3::Analyzer.new(before_schema_data, after_schema_data, options)
|
17
|
+
else
|
18
|
+
raise NoImplementError, "Do not support version: #{::R2OAS.version}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
require 'r2-oas/schema/v3/cleaner'
|
5
|
+
|
6
|
+
module R2OAS
|
7
|
+
module Schema
|
8
|
+
class Cleaner
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def_delegators :@cleaner, :clean_docs
|
12
|
+
|
13
|
+
def initialize(options = {})
|
14
|
+
case ::R2OAS.version
|
15
|
+
when :v3
|
16
|
+
@cleaner = V3::Cleaner.new(options)
|
17
|
+
else
|
18
|
+
raise NoImplementError, "Do not support version: #{::R2OAS.version}"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal:true
|
2
|
+
|
3
|
+
require 'docker'
|
4
|
+
require 'eventmachine'
|
5
|
+
require 'watir'
|
6
|
+
require 'tempfile'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'shell'
|
9
|
+
require 'forwardable'
|
10
|
+
|
11
|
+
# Can't use ActiveSupport::Autroload
|
12
|
+
# ThreadError: can't be called from trap context
|
13
|
+
require 'r2-oas/schema/analyzer'
|
14
|
+
require_relative 'base'
|
15
|
+
|
16
|
+
# Scope Rails
|
17
|
+
module R2OAS
|
18
|
+
module Schema
|
19
|
+
class Editor < Base
|
20
|
+
extend Forwardable
|
21
|
+
|
22
|
+
TMP_FILE_NAME = 'edited_schema'
|
23
|
+
|
24
|
+
attr_accessor :edited_schema
|
25
|
+
|
26
|
+
def initialize(before_schema_data, options)
|
27
|
+
super(options)
|
28
|
+
@editor = swagger.editor
|
29
|
+
@before_schema_data = before_schema_data
|
30
|
+
end
|
31
|
+
|
32
|
+
def start
|
33
|
+
EM.run do
|
34
|
+
container.start
|
35
|
+
open_browser_and_set_schema
|
36
|
+
ensure_save_tmp_schema_file
|
37
|
+
signal_trap('INT')
|
38
|
+
signal_trap('TERM')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_accessor :unit_paths_file_path
|
45
|
+
def_delegators :@editor, :storage_key, :image, :port, :url, :exposed_port
|
46
|
+
|
47
|
+
def signal_trap(command)
|
48
|
+
Signal.trap(command) do
|
49
|
+
if @browser.exists?
|
50
|
+
process_after_close_browser
|
51
|
+
container.stop
|
52
|
+
container.remove
|
53
|
+
logger.info "container id: #{container.id} removed"
|
54
|
+
else
|
55
|
+
process_after_close_browser
|
56
|
+
container.remove
|
57
|
+
logger.info "container id: #{container.id} removed"
|
58
|
+
end
|
59
|
+
|
60
|
+
EM.stop
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def process_after_close_browser
|
65
|
+
fetch_edited_schema_from_browser
|
66
|
+
|
67
|
+
options = { type: :edited }
|
68
|
+
save_edited_schema
|
69
|
+
conv_after_schema_data = YAML.load(@after_schema_data)
|
70
|
+
analyzer = Analyzer.new(@before_schema_data, conv_after_schema_data, options)
|
71
|
+
analyzer.analyze_docs
|
72
|
+
end
|
73
|
+
|
74
|
+
def ensure_save_tmp_schema_file
|
75
|
+
EM.add_periodic_timer(interval_to_save_edited_tmp_schema) do
|
76
|
+
if @browser.exists?
|
77
|
+
@after_schema_data = @browser.driver.local_storage[storage_key] || @after_schema_data
|
78
|
+
save_edited_schema
|
79
|
+
puts "\nwait for signal trap ..."
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def fetch_edited_schema_from_browser
|
85
|
+
@after_schema_data = @browser.driver.local_storage[storage_key] if @browser.exists?
|
86
|
+
end
|
87
|
+
|
88
|
+
def save_edited_schema
|
89
|
+
File.write(doc_save_file_path, @after_schema_data)
|
90
|
+
end
|
91
|
+
|
92
|
+
def open_browser_and_set_schema
|
93
|
+
capabilities = { 'chromeOptions' => { 'w3c' => false } }
|
94
|
+
@browser ||= Watir::Browser.new(:chrome, capabilities)
|
95
|
+
@browser.goto(url)
|
96
|
+
if wait_for_loaded
|
97
|
+
schema_doc_from_local = YAML.load_file(doc_save_file_path)
|
98
|
+
@browser.driver.local_storage[storage_key] = schema_doc_from_local.to_yaml
|
99
|
+
@browser.refresh
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def wait_for_loaded
|
104
|
+
Watir::Wait.until { @browser.body.present? }
|
105
|
+
end
|
106
|
+
|
107
|
+
def container
|
108
|
+
@container ||= Docker::Container.create(
|
109
|
+
'Image' => image,
|
110
|
+
'ExposedPorts' => { exposed_port => {} },
|
111
|
+
'HostConfig' => {
|
112
|
+
'PortBindings' => {
|
113
|
+
exposed_port => [{ 'HostPort' => port }]
|
114
|
+
}
|
115
|
+
}
|
116
|
+
)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|