r2-oas 0.4.0

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