r2-oas 0.3.2 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +55 -1
  3. data/GEMSPEC.md +2 -2
  4. data/README.ja.md +73 -43
  5. data/README.md +75 -39
  6. data/lib/r2-oas.rb +4 -5
  7. data/lib/r2-oas/app_configuration.rb +17 -5
  8. data/lib/r2-oas/app_configuration/deprecation.rb +28 -0
  9. data/lib/r2-oas/configuration.rb +57 -11
  10. data/lib/r2-oas/configuration/paths_config.rb +6 -3
  11. data/lib/r2-oas/deploy/client.rb +1 -1
  12. data/lib/r2-oas/errors.rb +5 -0
  13. data/lib/r2-oas/helpers/file_helper.rb +68 -0
  14. data/lib/r2-oas/hooks/hook.rb +7 -5
  15. data/lib/r2-oas/lib/core_ext/all.rb +5 -0
  16. data/lib/r2-oas/lib/core_ext/string/filters.rb +29 -0
  17. data/lib/r2-oas/plugin/base.rb +44 -0
  18. data/lib/r2-oas/plugin/executor.rb +148 -0
  19. data/lib/r2-oas/plugin/hookable.rb +47 -0
  20. data/lib/r2-oas/plugin/public.rb +3 -0
  21. data/lib/r2-oas/plugin/transform/transform.rb +10 -0
  22. data/lib/r2-oas/plugin/transform/v3/transform.rb +20 -0
  23. data/lib/r2-oas/plugin/transform/v3/visitable.rb +37 -0
  24. data/lib/r2-oas/public.rb +3 -0
  25. data/lib/r2-oas/schema/base.rb +1 -1
  26. data/lib/r2-oas/schema/builder.rb +1 -1
  27. data/lib/r2-oas/schema/editor.rb +9 -2
  28. data/lib/r2-oas/schema/monitor.rb +1 -1
  29. data/lib/r2-oas/schema/ui.rb +1 -1
  30. data/lib/r2-oas/schema/v3/analyzer/path_analyzer.rb +1 -1
  31. data/lib/r2-oas/schema/v3/builder.rb +1 -1
  32. data/lib/r2-oas/schema/v3/builder/base_builder.rb +14 -2
  33. data/lib/r2-oas/schema/v3/builder/doc_builder.rb +10 -2
  34. data/lib/r2-oas/schema/v3/generator/base_generator.rb +7 -2
  35. data/lib/r2-oas/schema/v3/generator/doc_generator.rb +1 -1
  36. data/lib/r2-oas/schema/v3/manager/file/include_ref_base_file_manager.rb +3 -2
  37. data/lib/r2-oas/schema/v3/object/from_files/base_object.rb +62 -0
  38. data/lib/r2-oas/schema/v3/object/from_files/components/request_body_object.rb +103 -0
  39. data/lib/r2-oas/schema/v3/object/from_files/components/schema_object.rb +102 -0
  40. data/lib/r2-oas/schema/v3/object/from_files/components_object.rb +46 -0
  41. data/lib/r2-oas/schema/v3/object/from_files/external_document_object.rb +23 -0
  42. data/lib/r2-oas/schema/v3/object/from_files/info_object.rb +23 -0
  43. data/lib/r2-oas/schema/v3/object/from_files/openapi_object.rb +61 -0
  44. data/lib/r2-oas/schema/v3/object/from_files/path_item_object.rb +110 -0
  45. data/lib/r2-oas/schema/v3/object/from_files/paths_object.rb +33 -0
  46. data/lib/r2-oas/schema/v3/object/from_files/utils/all.rb +4 -0
  47. data/lib/r2-oas/schema/v3/object/from_files/utils/deep_methods.rb +27 -0
  48. data/lib/r2-oas/schema/v3/object/from_files/utils/refs.rb +151 -0
  49. data/lib/r2-oas/schema/v3/object/{public.rb → from_routes/all.rb} +0 -0
  50. data/lib/r2-oas/schema/v3/object/from_routes/base_object.rb +41 -0
  51. data/lib/r2-oas/schema/v3/object/{components → from_routes/components}/request_body_object.rb +19 -28
  52. data/lib/r2-oas/schema/v3/object/{components → from_routes/components}/schema_object.rb +12 -16
  53. data/lib/r2-oas/schema/v3/object/{components_object.rb → from_routes/components_object.rb} +19 -13
  54. data/lib/r2-oas/schema/v3/object/{external_document_object.rb → from_routes/external_document_object.rb} +9 -2
  55. data/lib/r2-oas/schema/v3/object/{info_object.rb → from_routes/info_object.rb} +9 -2
  56. data/lib/r2-oas/schema/v3/object/{openapi_object.rb → from_routes/openapi_object.rb} +16 -11
  57. data/lib/r2-oas/schema/v3/object/{path_item_object.rb → from_routes/path_item_object.rb} +8 -8
  58. data/lib/r2-oas/schema/v3/object/{paths_object.rb → from_routes/paths_object.rb} +13 -30
  59. data/lib/r2-oas/schema/v3/object/{server_object.rb → from_routes/server_object.rb} +0 -0
  60. data/lib/r2-oas/schema/v3/object/{tag_object.rb → from_routes/tag_object.rb} +2 -1
  61. data/lib/r2-oas/schema/v3/object/store.rb +54 -0
  62. data/lib/r2-oas/shared/all.rb +1 -0
  63. data/lib/r2-oas/shared/callable.rb +17 -0
  64. data/lib/r2-oas/store.rb +20 -16
  65. data/lib/r2-oas/support/deprecation.rb +26 -0
  66. data/lib/r2-oas/support/deprecation/behavior.rb +21 -0
  67. data/lib/r2-oas/support/deprecation/instance_delegator.rb +42 -0
  68. data/lib/r2-oas/support/deprecation/reporting.rb +91 -0
  69. data/lib/r2-oas/task.rb +1 -2
  70. data/lib/r2-oas/task_logging.rb +3 -7
  71. data/lib/r2-oas/tasks/common.rake +1 -2
  72. data/lib/r2-oas/tasks/main.rake +59 -9
  73. data/lib/r2-oas/version.rb +1 -1
  74. data/r2-oas.gemspec +2 -7
  75. metadata +55 -69
  76. data/.gitignore +0 -16
  77. data/.rspec +0 -3
  78. data/.rubocop.yml +0 -10
  79. data/.rubocop_todo.yml +0 -291
  80. data/.travis.yml +0 -26
  81. data/Appraisals +0 -13
  82. data/CODE_OF_CONDUCT.md +0 -74
  83. data/Gemfile +0 -12
  84. data/Rakefile +0 -8
  85. data/lib/r2-oas/app_configuration/tool.rb +0 -31
  86. data/lib/r2-oas/app_configuration/tool/paths/stats.rb +0 -43
  87. data/lib/r2-oas/pluggable_configuration.rb +0 -33
  88. data/lib/r2-oas/plugins/schema/v3/object/hookable_base_object.rb +0 -100
  89. data/lib/r2-oas/schema/v3/object/base_object.rb +0 -65
  90. data/lib/r2-oas/tasks/tool.rake +0 -83
  91. data/lib/r2-oas/tool/paths/ls.rb +0 -15
  92. data/lib/r2-oas/tool/paths/stats.rb +0 -84
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative 'app_configuration/server'
4
4
  require_relative 'app_configuration/swagger'
5
- require_relative 'app_configuration/tool'
5
+ require_relative 'app_configuration/deprecation'
6
6
 
7
7
  module R2OAS
8
8
  module AppConfiguration
@@ -42,10 +42,14 @@ module R2OAS
42
42
  DEFAULT_HTTP_METHODS_WHEN_GENERATE_REQUEST_BODY = %w[post patch put]
43
43
  DEFAULT_IGNORED_HTTP_STATUSES_WHEN_GENERATE_COMPONENT_SCHEMA = %w[204 404]
44
44
  # rubocop:enable Style/MutableConstant
45
- DEFAULT_TOOL = Tool.new
46
45
  # :dot or :underbar
47
- DEFAULT_NAMESPACE_TYPE = :underbar
46
+ DEFAULT_NAMESPACE_TYPE = :dot
48
47
  DEFAULT_DEPLOY_DIR_PATH = './deploy_docs'
48
+ EDFAULT_PLUGINS = [].freeze
49
+ DEFAULT_LOCAL_PLUGINS_DIR_NAME = 'plugins'
50
+ DEFAULT_LOCAL_TASKS_DIR_NAME = 'tasks'
51
+ DEFAULT_OUTPUT_PATH = './oas_docs/dist/oas_doc.yml'
52
+ DEFAULT_DEPRECATION = Deprecation.new
49
53
 
50
54
  PUBLIC_VALID_OPTIONS_KEYS = %i[
51
55
  version
@@ -61,9 +65,13 @@ module R2OAS
61
65
  http_statuses_when_http_method
62
66
  http_methods_when_generate_request_body
63
67
  ignored_http_statuses_when_generate_component_schema
64
- tool
65
68
  namespace_type
66
69
  deploy_dir_path
70
+ plugins
71
+ local_plugins_dir_name
72
+ local_tasks_dir_name
73
+ output_path
74
+ deprecation
67
75
  ].freeze
68
76
 
69
77
  UNPUBLIC_VALID_OPTIONS_KEYS = %i[
@@ -95,11 +103,15 @@ module R2OAS
95
103
  target.interval_to_save_edited_tmp_schema = DEFAULT_INTERVAL_TO_SAVE_EDITED_TMP_SCHEMA
96
104
  target.swagger = DEFAULT_SWAGGER
97
105
  target.http_statuses_when_http_method = DEFAULT_HTTP_STATUSES_WHEN_HTTP_METHOD
98
- target.tool = DEFAULT_TOOL
99
106
  target.http_methods_when_generate_request_body = DEFAULT_HTTP_METHODS_WHEN_GENERATE_REQUEST_BODY
100
107
  target.ignored_http_statuses_when_generate_component_schema = DEFAULT_IGNORED_HTTP_STATUSES_WHEN_GENERATE_COMPONENT_SCHEMA
101
108
  target.namespace_type = DEFAULT_NAMESPACE_TYPE
102
109
  target.deploy_dir_path = DEFAULT_DEPLOY_DIR_PATH
110
+ target.plugins = EDFAULT_PLUGINS
111
+ target.local_plugins_dir_name = DEFAULT_LOCAL_PLUGINS_DIR_NAME
112
+ target.local_tasks_dir_name = DEFAULT_LOCAL_TASKS_DIR_NAME
113
+ target.output_path = DEFAULT_OUTPUT_PATH
114
+ target.deprecation = DEFAULT_DEPRECATION
103
115
  end
104
116
  end
105
117
  end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'r2-oas/support/deprecation'
4
+
5
+ module R2OAS
6
+ module AppConfiguration
7
+ class Deprecation
8
+ DEFAULT_SILENCED = ::R2OAS::Deprecation.silenced
9
+
10
+ attr_reader :silenced
11
+
12
+ def silenced=(value)
13
+ @silenced = !!value
14
+ ::R2OAS::Deprecation.silenced = !!value
15
+ end
16
+
17
+ def initialize
18
+ set_default
19
+ end
20
+
21
+ private
22
+
23
+ def set_default
24
+ self.silenced = DEFAULT_SILENCED
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,16 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'fileutils'
4
+
3
5
  require_relative 'app_configuration'
4
- require_relative 'pluggable_configuration'
5
6
  require_relative 'configuration/paths_config'
6
7
  require_relative 'logger/stdout_logger'
8
+ require_relative 'support/deprecation'
9
+ require_relative 'helpers/file_helper'
7
10
 
8
11
  module R2OAS
9
12
  module Configuration
10
13
  extend AppConfiguration
11
- extend PluggableConfiguration
14
+ include Helpers::FileHelper
12
15
 
13
- PUBLIC_VALID_OPTIONS_KEYS = AppConfiguration::VALID_OPTIONS_KEYS + PluggableConfiguration::VALID_OPTIONS_KEYS
16
+ PUBLIC_VALID_OPTIONS_KEYS = AppConfiguration::VALID_OPTIONS_KEYS
14
17
 
15
18
  UNPUBLIC_VALID_OPTIONS_KEYS = %i[
16
19
  paths_config
@@ -23,11 +26,11 @@ module R2OAS
23
26
 
24
27
  def self.extended(base)
25
28
  base.send :set_default_for_configuration, base
26
- base.send :set_default_for_pluggable, base
27
29
  end
28
30
 
29
31
  def configure
30
32
  yield self if block_given?
33
+ load_local_plugins
31
34
  end
32
35
 
33
36
  def options
@@ -50,20 +53,63 @@ module R2OAS
50
53
  end
51
54
  end
52
55
 
53
- def pluggable_configuration_options
54
- PluggableConfiguration::VALID_OPTIONS_KEYS.inject({}) do |option, key|
55
- option.merge!(key => send(key))
56
+ def load_tasks
57
+ load_local_tasks
58
+ end
59
+
60
+ def init
61
+ old_stdout = $stdout
62
+ $stdout = StringIO.new
63
+
64
+ plugins_path = File.expand_path("#{root_dir_path}/#{local_plugins_dir_name}")
65
+ plugins_helpers_path = "#{plugins_path}/helpers"
66
+ tasks_path = File.expand_path("#{root_dir_path}/#{local_tasks_dir_name}")
67
+ tasks_helpers_path = "#{tasks_path}/helpers"
68
+
69
+ gitkeep_plugins_path = "#{plugins_path}/.gitkeep"
70
+ gitkeep_plugins_helpers_path = "#{plugins_helpers_path}/.gitkeep"
71
+ gitkeep_tasks_path = "#{tasks_path}/.gitkeep"
72
+ gitkeep_tasks_helpers_path = "#{tasks_helpers_path}/.gitkeep"
73
+
74
+ paths_config.create_dot_paths(false)
75
+ mkdir_p_dir_or_skip(plugins_helpers_path)
76
+ mkdir_p_dir_or_skip(tasks_helpers_path)
77
+ write_file_or_skip(gitkeep_plugins_path, '')
78
+ write_file_or_skip(gitkeep_plugins_helpers_path, '')
79
+ write_file_or_skip(gitkeep_tasks_path, '')
80
+ write_file_or_skip(gitkeep_tasks_helpers_path, '')
81
+
82
+ if $stdout.string.present?
83
+ STDOUT.puts $stdout.string
84
+ else
85
+ STDOUT.puts "Already Initialized existing oas_docs in #{root_dir_path}"
56
86
  end
87
+
88
+ $stdout = old_stdout
89
+ end
90
+
91
+ def output_dir_path
92
+ output_path.to_s.split('/').slice(0..-2).join('/')
57
93
  end
58
94
 
59
95
  private
60
96
 
61
- def set_default_for_configuration(target)
62
- AppConfiguration.set_default(target)
97
+ def load_local_tasks
98
+ tasks_path = File.expand_path("#{root_dir_path}/#{local_tasks_dir_name}")
99
+ Dir.glob("#{tasks_path}/**/*.rake").sort.each do |file|
100
+ load file if FileTest.exists?(file)
101
+ end
63
102
  end
64
103
 
65
- def set_default_for_pluggable(target)
66
- PluggableConfiguration.set_default(target)
104
+ def load_local_plugins
105
+ plugins_path = File.expand_path("#{root_dir_path}/#{local_plugins_dir_name}")
106
+ Dir.glob("#{plugins_path}/**/*.rb").sort.each do |file|
107
+ require file if FileTest.exists?(file)
108
+ end
109
+ end
110
+
111
+ def set_default_for_configuration(target)
112
+ AppConfiguration.set_default(target)
67
113
  end
68
114
  end
69
115
  end
@@ -1,10 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'r2-oas/schema/manager/file/path_item_file_manager'
4
+ require 'r2-oas/helpers/file_helper'
4
5
 
5
6
  module R2OAS
6
7
  module Configuration
7
8
  class PathsConfig
9
+ include Helpers::FileHelper
10
+
8
11
  def initialize(root_dir_path, schema_save_dir_name)
9
12
  @root_dir_path = root_dir_path
10
13
  @schema_save_dir_path = "#{root_dir_path}/#{schema_save_dir_name}"
@@ -25,11 +28,11 @@ module R2OAS
25
28
  end.uniq.compact.reject(&:empty?)
26
29
  end
27
30
 
28
- def create_dot_paths
31
+ def create_dot_paths(silent = true)
29
32
  abs_root_path = File.expand_path(@root_dir_path)
30
33
 
31
- FileUtils.mkdir_p(abs_root_path) unless FileTest.exists?(abs_root_path)
32
- File.write(abs_paths_path, '') unless FileTest.exists?(abs_paths_path)
34
+ mkdir_p_dir_or_skip(abs_root_path, silent)
35
+ write_file_or_skip(abs_paths_path, '', silent)
33
36
  end
34
37
 
35
38
  def many_components_file_paths
@@ -46,7 +46,7 @@ module R2OAS
46
46
 
47
47
  def copy_oas_doc_file
48
48
  swagger_file_path = File.expand_path(Rails.root.join(deploy_dir_path, doc_save_file_name), __FILE__)
49
- oas_doc_file_path = File.expand_path("#{root_dir_path}/#{doc_save_file_name}")
49
+ oas_doc_file_path = File.expand_path(output_path)
50
50
  FileUtils.cp_r(oas_doc_file_path, swagger_file_path)
51
51
  end
52
52
 
@@ -5,4 +5,9 @@ module R2OAS
5
5
  class NoFileExistsError < StandardError; end
6
6
  class NoSupportError < StandardError; end
7
7
  class ChecksumError < StandardError; end
8
+ class PluginNameError < StandardError; end
9
+ class PluginDuplicationError < StandardError; end
10
+ class PluginLoadError < StandardError; end
11
+ class DepulicateSchemaNameError < StandardError; end
12
+ class RefInvalidAssignment < StandardError; end
8
13
  end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+
5
+ # https :/ / keyesberry.hatenadiary.org / entry / 20101107 / p1
6
+ #
7
+ # Text attributes
8
+ # 0 All attributes off
9
+ # 1 Bold on
10
+ # 4 Underscore (on monochrome display adapter only)
11
+ # 5 Blink on
12
+ # 7 Reverse video on
13
+ # 8 Concealed on
14
+
15
+ # Foreground colors
16
+ # 30 Black
17
+ # 31 Red
18
+ # 32 Green
19
+ # 33 Yellow
20
+ # 34 Blue
21
+ # 35 Magenta
22
+ # 36 Cyan
23
+ # 37 White
24
+
25
+ # Background colors
26
+ # 40 Black
27
+ # 41 Red
28
+ # 42 Green
29
+ # 43 Yellow
30
+ # 44 Blue
31
+ # 45 Magenta
32
+ # 46 Cyan
33
+ # 47 White
34
+ module R2OAS
35
+ module Helpers
36
+ module FileHelper
37
+ def write_file_or_skip(file_path, data, silent = false)
38
+ unless FileTest.exists?(file_path)
39
+ File.write(file_path, data)
40
+ puts "#{space}#{bold('create')}\t#{relative(file_path)}" unless silent
41
+ end
42
+ end
43
+
44
+ def mkdir_p_dir_or_skip(dir_path, silent = false)
45
+ unless FileTest.exists?(dir_path)
46
+ FileUtils.mkdir_p(dir_path)
47
+ puts "#{space}#{bold('create')}\t#{relative(dir_path)}" unless silent
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def relative(path)
54
+ current_dir_pathname = Pathname.new(Dir.pwd)
55
+ target_path = Pathname.new(path)
56
+ target_path.relative_path_from(current_dir_pathname)
57
+ end
58
+
59
+ def bold(str)
60
+ "\e[1m#{str}\e[0m"
61
+ end
62
+
63
+ def space
64
+ ' '
65
+ end
66
+ end
67
+ end
68
+ end
@@ -12,19 +12,21 @@ module R2OAS
12
12
  class << self
13
13
  attr_accessor :repository
14
14
 
15
- def register(target_class)
15
+ def register(type, target_class)
16
16
  @repository ||= {}
17
+ @repository[type] ||= {}
18
+ @type = type
17
19
  @hooks ||= {}
18
- @repository[target_class] = Repository.new(target_class)
20
+ @repository[type][target_class] = Repository.new(target_class)
19
21
  self
20
22
  end
21
23
 
22
24
  def on(on, callback, target_class, once = false)
23
- target_repository = @repository[target_class]
25
+ target_repository = @repository[@type][target_class]
24
26
  uid = target_repository.last_hook_id + 1
25
27
  target_repository.last_hook_id = uid
26
28
 
27
- @repository[target_class].global_hooks_data[on] ||= []
29
+ target_repository.global_hooks_data[on] ||= []
28
30
  global_hook = GlobalHook.new(callback, once, uid, target_class)
29
31
 
30
32
  target_repository.global_hooks_data[on].push(global_hook)
@@ -34,7 +36,7 @@ module R2OAS
34
36
 
35
37
  # MEMO: Do not Use
36
38
  def off(uid, target_class)
37
- target_repository = @repository[target_class]
39
+ target_repository = @repository[@type][target_class]
38
40
  result = uid
39
41
 
40
42
  target_repository.global_hooks_data.each do |on|
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'hash/deep_merge'
4
+ require_relative 'object/blank'
5
+ require_relative 'string/filters'
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copy from https://github.com/rails/rails/blob/45b609c9964242f5c169d913c612eedce2a47397/activesupport/lib/active_support/core_ext/string/filters.rb#L11
4
+
5
+ class String
6
+ # Returns the string, first removing all whitespace on both ends of
7
+ # the string, and then changing remaining consecutive whitespace
8
+ # groups into one space each.
9
+ #
10
+ # Note that it handles both ASCII and Unicode whitespace.
11
+ #
12
+ # %{ Multi-line
13
+ # string }.squish # => "Multi-line string"
14
+ # " foo bar \n \t boo".squish # => "foo bar boo"
15
+ def squish
16
+ dup.squish!
17
+ end
18
+
19
+ # Performs a destructive squish. See String#squish.
20
+ # str = " foo bar \n \t boo"
21
+ # str.squish! # => "foo bar boo"
22
+ # str # => "foo bar boo"
23
+ def squish!
24
+ gsub!(/\A[[:space:]]+/, '')
25
+ gsub!(/[[:space:]]+\z/, '')
26
+ gsub!(/[[:space:]]+/, ' ')
27
+ self
28
+ end
29
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'r2-oas/base'
4
+ require 'r2-oas/hooks/hook'
5
+ require_relative 'hookable'
6
+
7
+ module R2OAS
8
+ module Plugin
9
+ class Base < ::R2OAS::Base
10
+ extend ::R2OAS::Plugin::Hookable
11
+
12
+ class << self
13
+ attr_accessor :plugin_name, :type, :opts
14
+
15
+ def setup(&block)
16
+ return unless block_given?
17
+
18
+ callback = proc { |*args| block.call(*args) }
19
+ on(:setup, callback)
20
+ end
21
+
22
+ def teardown(&block)
23
+ return unless block_given?
24
+
25
+ callback = proc { |*args| block.call(*args) }
26
+ on(:teardown, callback)
27
+ end
28
+
29
+ def execute_setup(*args)
30
+ execute_hook(:setup, *args)
31
+ end
32
+
33
+ def execute_teardown(*args)
34
+ execute_hook(:teardown, *args)
35
+ end
36
+
37
+ def inherited(base)
38
+ super
39
+ base.opts = {}
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,148 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'hookable'
4
+ require 'r2-oas/errors'
5
+
6
+ module R2OAS
7
+ module Plugin
8
+ class Executor
9
+ extend ::R2OAS::Plugin::Hookable
10
+
11
+ def initialize(plugins, opts)
12
+ @plugins = plugins
13
+ @use_plugin = !!opts[:use_plugin]
14
+ end
15
+
16
+ def execute_transform_plugins(hook_method, *args)
17
+ return unless @use_plugin
18
+ return unless @plugins.present?
19
+
20
+ @plugin_map ||= self.class.plugin_map(@plugins)
21
+
22
+ self.class.execute_transform_plugins(@plugin_map, hook_method, *args)
23
+ end
24
+
25
+ class << self
26
+ attr_accessor :plugin_map
27
+
28
+ def execute_transform_plugins(plugin_map, hook_method, *args)
29
+ execute_plugins(plugin_map, :transform, hook_method, *args)
30
+ end
31
+
32
+ def execute_plugins(plugin_map, type, hook_method, *args)
33
+ return unless plugin_map.present?
34
+
35
+ plugins_info = plugin_map[type.to_sym][hook_method.to_sym]
36
+
37
+ return if plugins_info.nil?
38
+
39
+ plugins_info.each do |info|
40
+ opts = info[:plugin_opts]
41
+ klass = info[:plugin_klass]
42
+ klass.send(:opts=, opts) if opts.present?
43
+ klass.send(info[:execute_hook_method], *args)
44
+ end
45
+ end
46
+
47
+ # e.g.)
48
+ # {
49
+ # transform: {
50
+ # setup: [
51
+ # { plugin_name: 'r2oas-transform-plugin-sample1', plugin_klass: Sample1Plugin, hook_method: :setup },
52
+ # { plugin_name: 'r2oas-transform-plugin-sample2', plugin_klass: Sample2Plugin, hook_method: :setup },
53
+ # ],
54
+ # info: [
55
+ # { plugin_name: 'r2oas-transform-plugin-sample1', plugin_klass: Sample1Plugin, hook_method: :info },
56
+ # ]
57
+ # }
58
+ # }
59
+ #
60
+ def plugin_map(plugins)
61
+ @plugin_map ||= {}
62
+ return @plugin_map if @plugin_map.present?
63
+
64
+ @will_plugins = []
65
+
66
+ use_plugins_info = create_use_plugins_info(plugins)
67
+
68
+ loaded_plugins_hooks_map = hooks_map.each_with_object({}) do |(klass, repo), result|
69
+ # MEMO:
70
+ # klass may be DynamicSchema or Plugin or Other Class
71
+ next unless klass.respond_to?(:plugin_name)
72
+ # Plugins that are loaded but not used
73
+ next unless use_plugins_info.keys.include?(klass.plugin_name)
74
+
75
+ result[klass.plugin_name] = { klass: klass, repo: repo }
76
+ end
77
+
78
+ unknown_plugins = use_plugins_info.keys - loaded_plugins_hooks_map.keys
79
+
80
+ raise R2OAS::PluginLoadError, "The '#{unknown_plugins.join(', ')}' plugin doesn't exist or can't be loaded" if unknown_plugins.present?
81
+
82
+ loaded_plugins_hooks_map.each do |plugin_name, info|
83
+ plugin_klass = info[:klass]
84
+ repo = info[:repo]
85
+
86
+ repo.global_hooks_data.each do |hook_method, callbacks|
87
+ callbacks.each do
88
+ plugin_type = plugin_klass.type
89
+
90
+ data = {
91
+ plugin_name: plugin_name,
92
+ plugin_klass: plugin_klass,
93
+ plugin_opts: use_plugins_info[plugin_name],
94
+ execute_hook_method: "execute_#{hook_method}"
95
+ }
96
+
97
+ if @plugin_map[plugin_type].present?
98
+ if @plugin_map[plugin_type][hook_method].present?
99
+ @plugin_map[plugin_type][hook_method].push(data)
100
+ else
101
+ @plugin_map[plugin_type][hook_method] = [data]
102
+ end
103
+ else
104
+ @plugin_map[plugin_type] = {}
105
+ @plugin_map[plugin_type][hook_method] = [data]
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ @plugin_map
112
+ end
113
+
114
+ def create_use_plugins_info(plugins)
115
+ will_use_plugins = []
116
+ result = {}
117
+
118
+ plugins.each do |plugin_info|
119
+ case plugin_info
120
+ when Array
121
+ plugin_name = plugin_info[0]
122
+ plugin_opts = plugin_info[1]
123
+
124
+ raise PluginNameError, 'Missing plugin name' if plugin_name.blank?
125
+
126
+ result[plugin_name] = plugin_opts
127
+ when String
128
+ plugin_name = plugin_info
129
+ plugin_opts = nil
130
+
131
+ result[plugin_name] = plugin_opts
132
+ else
133
+ raise NoSupportError, "The plugin loading format '#{plugin_info.class}' is incorrect"
134
+ end
135
+
136
+ if will_use_plugins.include?(plugin_name)
137
+ raise PluginDuplicationError, "Plugin: duplicate '#{plugin_name}'"
138
+ else
139
+ will_use_plugins.push(plugin_name)
140
+ end
141
+ end
142
+
143
+ result
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end