r2-oas 0.4.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.
Files changed (136) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +99 -0
  3. data/GEMSPEC.md +20 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.ja.md +271 -0
  6. data/README.md +271 -0
  7. data/lib/r2-oas.rb +35 -0
  8. data/lib/r2-oas/app_configuration.rb +121 -0
  9. data/lib/r2-oas/app_configuration/deprecation.rb +28 -0
  10. data/lib/r2-oas/app_configuration/server.rb +35 -0
  11. data/lib/r2-oas/app_configuration/swagger.rb +35 -0
  12. data/lib/r2-oas/app_configuration/swagger/editor.rb +47 -0
  13. data/lib/r2-oas/app_configuration/swagger/ui.rb +45 -0
  14. data/lib/r2-oas/app_configuration/tool.rb +31 -0
  15. data/lib/r2-oas/app_configuration/tool/paths/stats.rb +43 -0
  16. data/lib/r2-oas/base.rb +48 -0
  17. data/lib/r2-oas/configuration.rb +121 -0
  18. data/lib/r2-oas/configuration/paths_config.rb +44 -0
  19. data/lib/r2-oas/deploy/client.rb +70 -0
  20. data/lib/r2-oas/deploy/swagger-ui/index.html.erb +60 -0
  21. data/lib/r2-oas/dynamic/schema/v3/object/from_routes/hookable_base_object.rb +100 -0
  22. data/lib/r2-oas/errors.rb +13 -0
  23. data/lib/r2-oas/hooks/global_hook.rb +20 -0
  24. data/lib/r2-oas/hooks/hook.rb +79 -0
  25. data/lib/r2-oas/hooks/repository.rb +15 -0
  26. data/lib/r2-oas/lib/core_ext/hash/deep_merge.rb +44 -0
  27. data/lib/r2-oas/lib/core_ext/object/blank.rb +135 -0
  28. data/lib/r2-oas/lib/three-way-merge/twm.rb +83 -0
  29. data/lib/r2-oas/logger/stdout_logger.rb +129 -0
  30. data/lib/r2-oas/pluggable_configuration.rb +36 -0
  31. data/lib/r2-oas/plugin/base.rb +44 -0
  32. data/lib/r2-oas/plugin/executor.rb +148 -0
  33. data/lib/r2-oas/plugin/hookable.rb +42 -0
  34. data/lib/r2-oas/plugin/public.rb +3 -0
  35. data/lib/r2-oas/plugin/transform/transform.rb +10 -0
  36. data/lib/r2-oas/plugin/transform/v3/transform.rb +20 -0
  37. data/lib/r2-oas/plugin/transform/v3/visitable.rb +37 -0
  38. data/lib/r2-oas/public.rb +5 -0
  39. data/lib/r2-oas/routing/adjustor.rb +44 -0
  40. data/lib/r2-oas/routing/base.rb +12 -0
  41. data/lib/r2-oas/routing/components/all.rb +5 -0
  42. data/lib/r2-oas/routing/components/base_component.rb +10 -0
  43. data/lib/r2-oas/routing/components/path_component.rb +67 -0
  44. data/lib/r2-oas/routing/components/request_component.rb +75 -0
  45. data/lib/r2-oas/routing/components/verb_component.rb +21 -0
  46. data/lib/r2-oas/routing/parser.rb +93 -0
  47. data/lib/r2-oas/schema/analyzer.rb +23 -0
  48. data/lib/r2-oas/schema/base.rb +11 -0
  49. data/lib/r2-oas/schema/builder.rb +23 -0
  50. data/lib/r2-oas/schema/cleaner.rb +23 -0
  51. data/lib/r2-oas/schema/editor.rb +146 -0
  52. data/lib/r2-oas/schema/generator.rb +23 -0
  53. data/lib/r2-oas/schema/manager/file/path_item_file_manager.rb +24 -0
  54. data/lib/r2-oas/schema/manager/file_manager.rb +26 -0
  55. data/lib/r2-oas/schema/monitor.rb +52 -0
  56. data/lib/r2-oas/schema/squeezer.rb +23 -0
  57. data/lib/r2-oas/schema/ui.rb +73 -0
  58. data/lib/r2-oas/schema/v3/analyzer.rb +58 -0
  59. data/lib/r2-oas/schema/v3/analyzer/base_analyzer.rb +71 -0
  60. data/lib/r2-oas/schema/v3/analyzer/components/object_analyzer.rb +38 -0
  61. data/lib/r2-oas/schema/v3/analyzer/components_analyzer.rb +30 -0
  62. data/lib/r2-oas/schema/v3/analyzer/path_analyzer.rb +116 -0
  63. data/lib/r2-oas/schema/v3/analyzer/tag_analyzer.rb +38 -0
  64. data/lib/r2-oas/schema/v3/base.rb +28 -0
  65. data/lib/r2-oas/schema/v3/builder.rb +28 -0
  66. data/lib/r2-oas/schema/v3/builder/base_builder.rb +72 -0
  67. data/lib/r2-oas/schema/v3/builder/doc_builder.rb +51 -0
  68. data/lib/r2-oas/schema/v3/cleaner.rb +19 -0
  69. data/lib/r2-oas/schema/v3/cleaner/base_cleaner.rb +30 -0
  70. data/lib/r2-oas/schema/v3/cleaner/components_cleaner.rb +42 -0
  71. data/lib/r2-oas/schema/v3/generator.rb +24 -0
  72. data/lib/r2-oas/schema/v3/generator/base_generator.rb +122 -0
  73. data/lib/r2-oas/schema/v3/generator/components/object_generator.rb +64 -0
  74. data/lib/r2-oas/schema/v3/generator/components/request_body_generator.rb +45 -0
  75. data/lib/r2-oas/schema/v3/generator/components_generator.rb +38 -0
  76. data/lib/r2-oas/schema/v3/generator/doc_generator.rb +115 -0
  77. data/lib/r2-oas/schema/v3/generator/path_generator.rb +78 -0
  78. data/lib/r2-oas/schema/v3/generator/schema_generator.rb +58 -0
  79. data/lib/r2-oas/schema/v3/manager/diff/base_array_diff_manager.rb +60 -0
  80. data/lib/r2-oas/schema/v3/manager/diff/base_diff_manager.rb +29 -0
  81. data/lib/r2-oas/schema/v3/manager/diff/base_hash_diff_manager.rb +95 -0
  82. data/lib/r2-oas/schema/v3/manager/diff/components_diff_manager.rb +19 -0
  83. data/lib/r2-oas/schema/v3/manager/diff/tag_diff_manager.rb +17 -0
  84. data/lib/r2-oas/schema/v3/manager/file/base_file_manager.rb +66 -0
  85. data/lib/r2-oas/schema/v3/manager/file/components_file_manager.rb +22 -0
  86. data/lib/r2-oas/schema/v3/manager/file/include_ref_base_file_manager.rb +89 -0
  87. data/lib/r2-oas/schema/v3/manager/file/path_item_file_manager.rb +22 -0
  88. data/lib/r2-oas/schema/v3/manager/file_manager.rb +12 -0
  89. data/lib/r2-oas/schema/v3/manager/pathname_manager.rb +78 -0
  90. data/lib/r2-oas/schema/v3/object/from_files/base_object.rb +62 -0
  91. data/lib/r2-oas/schema/v3/object/from_files/components/request_body_object.rb +103 -0
  92. data/lib/r2-oas/schema/v3/object/from_files/components/schema_object.rb +102 -0
  93. data/lib/r2-oas/schema/v3/object/from_files/components_object.rb +46 -0
  94. data/lib/r2-oas/schema/v3/object/from_files/external_document_object.rb +23 -0
  95. data/lib/r2-oas/schema/v3/object/from_files/info_object.rb +23 -0
  96. data/lib/r2-oas/schema/v3/object/from_files/openapi_object.rb +61 -0
  97. data/lib/r2-oas/schema/v3/object/from_files/path_item_object.rb +110 -0
  98. data/lib/r2-oas/schema/v3/object/from_files/paths_object.rb +33 -0
  99. data/lib/r2-oas/schema/v3/object/from_files/utils/all.rb +4 -0
  100. data/lib/r2-oas/schema/v3/object/from_files/utils/deep_methods.rb +27 -0
  101. data/lib/r2-oas/schema/v3/object/from_files/utils/refs.rb +151 -0
  102. data/lib/r2-oas/schema/v3/object/from_routes/base_object.rb +75 -0
  103. data/lib/r2-oas/schema/v3/object/from_routes/components/request_body_object.rb +96 -0
  104. data/lib/r2-oas/schema/v3/object/from_routes/components/schema_object.rb +59 -0
  105. data/lib/r2-oas/schema/v3/object/from_routes/components_object.rb +81 -0
  106. data/lib/r2-oas/schema/v3/object/from_routes/external_document_object.rb +28 -0
  107. data/lib/r2-oas/schema/v3/object/from_routes/info_object.rb +43 -0
  108. data/lib/r2-oas/schema/v3/object/from_routes/openapi_object.rb +59 -0
  109. data/lib/r2-oas/schema/v3/object/from_routes/path_item_object.rb +175 -0
  110. data/lib/r2-oas/schema/v3/object/from_routes/paths_object.rb +77 -0
  111. data/lib/r2-oas/schema/v3/object/from_routes/public.rb +9 -0
  112. data/lib/r2-oas/schema/v3/object/from_routes/server_object.rb +21 -0
  113. data/lib/r2-oas/schema/v3/object/from_routes/tag_object.rb +37 -0
  114. data/lib/r2-oas/schema/v3/object/store.rb +54 -0
  115. data/lib/r2-oas/schema/v3/squeezer.rb +29 -0
  116. data/lib/r2-oas/schema/v3/squeezer/base_squeezer.rb +37 -0
  117. data/lib/r2-oas/schema/v3/squeezer/path_squeezer.rb +28 -0
  118. data/lib/r2-oas/schema/v3/squeezer/tag_squeezer.rb +19 -0
  119. data/lib/r2-oas/shared/all.rb +4 -0
  120. data/lib/r2-oas/shared/callable.rb +17 -0
  121. data/lib/r2-oas/shared/sortable.rb +23 -0
  122. data/lib/r2-oas/store.rb +122 -0
  123. data/lib/r2-oas/support/deprecation.rb +24 -0
  124. data/lib/r2-oas/support/deprecation/behavior.rb +21 -0
  125. data/lib/r2-oas/support/deprecation/instance_delegator.rb +42 -0
  126. data/lib/r2-oas/support/deprecation/reporting.rb +91 -0
  127. data/lib/r2-oas/task.rb +11 -0
  128. data/lib/r2-oas/task_logging.rb +41 -0
  129. data/lib/r2-oas/tasks/common.rake +25 -0
  130. data/lib/r2-oas/tasks/main.rake +132 -0
  131. data/lib/r2-oas/tasks/tool.rake +86 -0
  132. data/lib/r2-oas/tool/paths/ls.rb +15 -0
  133. data/lib/r2-oas/tool/paths/stats.rb +84 -0
  134. data/lib/r2-oas/version.rb +5 -0
  135. data/r2-oas.gemspec +48 -0
  136. metadata +415 -0
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module R2OAS
4
+ module Schema
5
+ class PathItemFileManager
6
+ extend Forwardable
7
+
8
+ def_delegators :@manager, :skip_save?, :descendants_paths, :descendants_ref_paths
9
+
10
+ def initialize(path, path_type = :ref)
11
+ case ::R2OAS.version
12
+ when :v3
13
+ @manager = V3::PathItemFileManager.new(path, path_type)
14
+ else
15
+ raise "Do not support version: #{::R2OAS.version}"
16
+ end
17
+ end
18
+
19
+ class << self
20
+ alias build new
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'r2-oas/schema/v3/manager/file_manager'
4
+
5
+ module R2OAS
6
+ module Schema
7
+ class FileManager
8
+ extend Forwardable
9
+
10
+ def_delegators :@manager, :save, :delete
11
+
12
+ def initialize(path, path_type = :ref)
13
+ case ::R2OAS.version
14
+ when :v3
15
+ @manager = V3::FileManager.new(path, path_type)
16
+ else
17
+ raise "Do not support version: #{::R2OAS.version}"
18
+ end
19
+ end
20
+
21
+ class << self
22
+ alias build new
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal:true
2
+
3
+ require 'eventmachine'
4
+
5
+ # Scope Rails
6
+ module R2OAS
7
+ module Schema
8
+ class Monitor < Base
9
+ def initialize(before_schema_data, options)
10
+ super(options)
11
+ @before_schema_data = before_schema_data
12
+ end
13
+
14
+ def start
15
+ EM.run do
16
+ ensure_save_tmp_schema_file
17
+ signal_trap('INT')
18
+ signal_trap('TERM')
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ attr_accessor :unit_paths_file_path
25
+
26
+ def signal_trap(command)
27
+ Signal.trap(command) do
28
+ process_after_close_monitor
29
+ EM.stop
30
+ end
31
+ end
32
+
33
+ def process_after_close_monitor
34
+ options = { type: :edited }
35
+ @after_schema_data = fetch_after_schema_data
36
+ analyzer = Analyzer.new(@before_schema_data, @after_schema_data, options)
37
+ analyzer.analyze_docs
38
+ end
39
+
40
+ def ensure_save_tmp_schema_file
41
+ EM.add_periodic_timer(interval_to_save_edited_tmp_schema) do
42
+ @after_schema_data = fetch_after_schema_data
43
+ puts "\nwait for signal trap ..."
44
+ end
45
+ end
46
+
47
+ def fetch_after_schema_data
48
+ YAML.load_file(doc_save_file_path) || @after_schema_data
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+ require 'r2-oas/schema/v3/squeezer'
5
+
6
+ module R2OAS
7
+ module Schema
8
+ class Squeezer
9
+ extend Forwardable
10
+
11
+ def_delegators :@squeezer, :squeeze_docs
12
+
13
+ def initialize(schema_data, options = {})
14
+ case ::R2OAS.version
15
+ when :v3
16
+ @squeezer = V3::Squeezer.new(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,73 @@
1
+ # frozen_string_literal:true
2
+
3
+ require 'docker'
4
+ require 'eventmachine'
5
+ require 'watir'
6
+ require 'forwardable'
7
+
8
+ # Scope Rails
9
+ module R2OAS
10
+ module Schema
11
+ class UI < Base
12
+ extend Forwardable
13
+
14
+ alias swagger_json doc_save_file_path
15
+
16
+ def initialize(options = {})
17
+ super
18
+ @ui = swagger.ui
19
+ end
20
+
21
+ def start
22
+ EM.run do
23
+ container.start
24
+ open_browser
25
+ puts "\nwait for single trap ..."
26
+ signal_trap('INT')
27
+ signal_trap('TERM')
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ attr_accessor :unit_paths_file_path
34
+ def_delegators :@ui, :image, :port, :url, :exposed_port, :volume
35
+
36
+ def signal_trap(command)
37
+ Signal.trap(command) do
38
+ container.stop
39
+ container.remove
40
+ logger.info "container id: #{container.id} removed"
41
+
42
+ EM.stop
43
+ end
44
+ end
45
+
46
+ def open_browser
47
+ @browser ||= Watir::Browser.new
48
+ @browser.goto(url)
49
+ wait_for_loaded
50
+ end
51
+
52
+ def wait_for_loaded
53
+ Watir::Wait.until { @browser.body.present? }
54
+ end
55
+
56
+ # [Reference]
57
+ # https://www.tomduffield.com/files/presentations/the-nitty-gritty-of-the-docker-api.pdf
58
+ def container
59
+ @container ||= Docker::Container.create(
60
+ 'Image' => image,
61
+ 'ExposedPorts' => { exposed_port => {} },
62
+ 'HostConfig' => {
63
+ 'PortBindings' => {
64
+ exposed_port => [{ 'HostPort' => port }]
65
+ },
66
+ 'Binds' => ["#{swagger_json}:#{volume}"]
67
+ },
68
+ 'Volumes' => { volume => {} }
69
+ )
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'analyzer/base_analyzer'
4
+ require_relative 'analyzer/path_analyzer'
5
+ require_relative 'analyzer/tag_analyzer'
6
+ require_relative 'analyzer/components_analyzer'
7
+ require 'r2-oas/schema/v3/manager/file_manager'
8
+
9
+ module R2OAS
10
+ module Schema
11
+ module V3
12
+ class Analyzer < BaseAnalyzer
13
+ def initialize(before_schema_data, after_schema_data, options = {})
14
+ super
15
+ @path_analyzer = PathAnalyzer.new(@before_schema_data, @after_schema_data, options)
16
+ @tag_analyzer = TagAnalyzer.new(@after_schema_data, options)
17
+ @components_analyzer = ComponentsAnalyzer.new(@before_schema_data, @after_schema_data, options)
18
+ end
19
+
20
+ def analyze_docs
21
+ logger.info '[Analyze OAS file] start'
22
+ @after_schema_data.keys.each do |schema_name|
23
+ case schema_name
24
+ when 'paths'
25
+ logger.info '[Analyze OAS file (paths)] start'
26
+ @path_analyzer.analyze_docs
27
+ logger.info '[Analyze OAS file (paths)] end'
28
+ when 'tags'
29
+ logger.info '[Analyze OAS file (tags)] start'
30
+ @tag_analyzer.analyze_docs
31
+ logger.info '[Analyze OAS file (tags)] end'
32
+ when 'components'
33
+ logger.info '[Analyze OAS file (components)] start'
34
+ @components_analyzer.analyze_docs
35
+ logger.info '[Analyze OAS file (components)] end'
36
+ else
37
+ save_schema_when(schema_name)
38
+ end
39
+ end
40
+ logger.info '[Analyze OAS file] end'
41
+ end
42
+
43
+ private
44
+
45
+ def save_schema_when(schema_name)
46
+ file_manager = FileManager.new(schema_name, :relative)
47
+ data = @after_schema_data.slice(schema_name)
48
+ case @type
49
+ when :edited
50
+ file_manager.save_after_deep_merge(data)
51
+ when :existing
52
+ file_manager.save(data.to_yaml)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'r2-oas/schema/v3/base'
4
+
5
+ # Scope Rails
6
+ module R2OAS
7
+ module Schema
8
+ module V3
9
+ class BaseAnalyzer < Base
10
+ include Sortable
11
+
12
+ def initialize(before_schema_data, after_schema_data, options = {})
13
+ super(options)
14
+ @type = options[:type].presence
15
+ @before_schema_data = before_schema_data
16
+ @after_schema_data = after_schema_data.presence || create_after_schema_data
17
+ end
18
+
19
+ def analyze_docs
20
+ raise NoImplementError, 'Please implement in inherited class.'
21
+ end
22
+
23
+ def generate_from_existing_schema
24
+ raise NoImplementError, 'Please implement in inherited class.'
25
+ end
26
+
27
+ private
28
+
29
+ attr_accessor :existing_schema_file_path
30
+ attr_accessor :type
31
+
32
+ def create_after_schema_data
33
+ case @type
34
+ when :edited
35
+ {}
36
+ when :existing
37
+ if existing_schema_file_path.present?
38
+ create_after_schema_data_when_specify_path
39
+ else
40
+ create_after_schema_data_when_not_specify_path
41
+ end
42
+ end
43
+ end
44
+
45
+ def create_after_schema_data_when_not_specify_path
46
+ if FileTest.exists?(doc_save_file_path)
47
+ YAML.load_file(doc_save_file_path)
48
+ else
49
+ raise NoFileExistsError, "Do not exists file: #{doc_save_file_path}"
50
+ end
51
+ end
52
+
53
+ def create_after_schema_data_when_specify_path
54
+ extname = File.extname(existing_schema_file_path)
55
+ case extname
56
+ when /json/
57
+ File.open(existing_schema_file_path) do |file|
58
+ JSON.parse(file.read)
59
+ end
60
+ when /yaml/
61
+ YAML.load_file(existing_schema_file_path)
62
+ when /yml/
63
+ YAML.load_file(existing_schema_file_path)
64
+ else
65
+ raise NoImplementError, "Do not support extension: #{extname}"
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../base_analyzer'
4
+ require 'r2-oas/schema/v3/manager/file/components_file_manager'
5
+ require 'r2-oas/schema/v3/manager/diff/components_diff_manager'
6
+
7
+ # Scope Rails
8
+ module R2OAS
9
+ module Schema
10
+ module V3
11
+ module Components
12
+ class ObjectAnalyzer < BaseAnalyzer
13
+ def initialize(before_schema_data, after_schema_data, options = {})
14
+ super(before_schema_data, after_schema_data, options.except(:middle_category))
15
+ @major_category = 'components'
16
+ @middle_category = options[:middle_category]
17
+ end
18
+
19
+ def analyze_docs
20
+ diff_manager = ComponentsDiffManager.new(@before_schema_data, @after_schema_data, middle_category: @middle_category)
21
+ diff_manager.process_by_using_diff_data do |schema_name, is_removed, is_added, is_leftovers, after_edited_data|
22
+ file_manager = ComponentsFileManager.build("#/#{@major_category}/#{@middle_category}/#{schema_name}", :ref)
23
+ save_file_path = file_manager.save_file_path(type: :relative)
24
+
25
+ if is_removed && !is_added && !is_leftovers
26
+ file_manager.delete
27
+ logger.info " Delete schema file: \t#{save_file_path}"
28
+ else
29
+ file_manager.save(after_edited_data.to_yaml)
30
+ logger.info " Write schema file: \t#{save_file_path}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_analyzer'
4
+ require_relative 'components/object_analyzer'
5
+
6
+ # Scope Rails
7
+ module R2OAS
8
+ module Schema
9
+ module V3
10
+ class ComponentsAnalyzer < BaseAnalyzer
11
+ def initialize(before_schema_data, after_schema_data, options = {})
12
+ super
13
+ @options = options
14
+ end
15
+
16
+ def analyze_docs
17
+ support_components_objects.each do |object_name|
18
+ logger.info "[Analyze OAS file (components/#{object_name})] start"
19
+ Components::ObjectAnalyzer.new(
20
+ @before_schema_data,
21
+ @after_schema_data,
22
+ @options.merge(middle_category: object_name)
23
+ ).analyze_docs
24
+ logger.info "[Analyze OAS file (components/#{object_name})] end"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'base_analyzer'
4
+ require 'r2-oas/schema/v3/manager/file/path_item_file_manager'
5
+ require 'r2-oas/schema/v3/manager/file_manager'
6
+ require 'r2-oas/schema/v3/object/from_routes/tag_object'
7
+
8
+ # Scope Rails
9
+ module R2OAS
10
+ module Schema
11
+ module V3
12
+ class PathAnalyzer < BaseAnalyzer
13
+ VERB = %w[get put post delete options head patch trace].freeze
14
+ NOT_VERB = %w[$ref summary description servers parameters].freeze
15
+
16
+ def initialize(before_schema_data, after_schema_data, options = {})
17
+ super
18
+ @tags = []
19
+ end
20
+
21
+ def analyze_docs
22
+ sorted_schema = deep_sort(@after_schema_data, 'paths')
23
+ edited_paths_schema = sorted_schema['paths']
24
+
25
+ save_each_tags(edited_paths_schema) do |tag_name, result|
26
+ file_manager = PathItemFileManager.new("paths/#{tag_name}", :relative)
27
+ file_manager.save(result.to_yaml)
28
+ logger.info " Write schema file: \t#{file_manager.save_file_path(type: :relative)}"
29
+ end
30
+
31
+ # Automatically generated when there is no tag object in the read schema file
32
+ if generate_tag_file?
33
+ result = { 'tags' => V3::TagObject.new(@tags).to_doc }
34
+ file_manager = FileManager.new('tags', :relative)
35
+ file_manager.save(result.to_yaml)
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def generate_tag_file?
42
+ !@after_schema_data.keys.include?('tags')
43
+ end
44
+
45
+ def push_tags(tag_name)
46
+ @tags.push(tag_name) unless @tags.include?(tag_name)
47
+ end
48
+
49
+ def unit_paths_data_group_by_tags(unit_paths_data)
50
+ unit_paths_data.each_with_object({}) do |(path, data_when_path), result|
51
+ data_when_path.each do |verb_or_not, data_when_verb_or_not|
52
+ if VERB.include?(verb_or_not)
53
+ result = group_by_tags_when_verb(verb_or_not, data_when_verb_or_not, path, result)
54
+ elsif NOT_VERB.include?(verb_or_not)
55
+ result = group_by_tags_when_not_verb(verb_or_not, data_when_verb_or_not, path, result)
56
+ else
57
+ raise "Do not support path item object keys: #{verb_or_not}"
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ def group_by_tags_when_verb(verb, data_when_verb, path, result)
64
+ if !data_when_verb.is_a?(Array) && data_when_verb.key?('tags')
65
+ tag_name = data_when_verb['tags'].first
66
+ else
67
+ tag_name = 'unknown'
68
+ data_when_verb.deep_merge!(
69
+ 'tags' => [tag_name]
70
+ )
71
+ end
72
+
73
+ push_tags(tag_name)
74
+
75
+ result[tag_name] ||= {}
76
+ result[tag_name].deep_merge!(
77
+ 'paths' => {
78
+ path => {
79
+ verb => data_when_verb
80
+ }
81
+ }
82
+ )
83
+ result
84
+ end
85
+
86
+ # The following pseudo tag names are after reservation
87
+ # ・$ref
88
+ # ・summary
89
+ # ・description
90
+ # ・servers
91
+ # ・parameters
92
+ def group_by_tags_when_not_verb(not_verb, data_when_not_verb, path, result)
93
+ tag_name = not_verb
94
+
95
+ push_tags(tag_name)
96
+
97
+ result[tag_name] ||= {}
98
+ result[tag_name].deep_merge!(
99
+ 'paths' => {
100
+ path => {
101
+ not_verb => data_when_not_verb
102
+ }
103
+ }
104
+ )
105
+ result
106
+ end
107
+
108
+ def save_each_tags(unit_paths_data)
109
+ unit_paths_data_group_by_tags(unit_paths_data).each do |tag_name, result|
110
+ yield [tag_name, result] if block_given?
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end