rggen-core 0.19.0 → 0.23.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/exe/rggen +2 -2
  3. data/lib/rggen/core.rb +7 -4
  4. data/lib/rggen/core/base/component.rb +16 -7
  5. data/lib/rggen/core/base/component_factory.rb +12 -9
  6. data/lib/rggen/core/base/component_layer_extension.rb +194 -0
  7. data/lib/rggen/core/base/feature_layer_extension.rb +158 -0
  8. data/lib/rggen/core/builder/builder.rb +38 -52
  9. data/lib/rggen/core/builder/component_entry.rb +3 -2
  10. data/lib/rggen/core/builder/component_registry.rb +22 -17
  11. data/lib/rggen/core/builder/feature_registry.rb +6 -9
  12. data/lib/rggen/core/builder/input_component_registry.rb +43 -10
  13. data/lib/rggen/core/builder/layer.rb +132 -0
  14. data/lib/rggen/core/builder/loader_registry.rb +48 -0
  15. data/lib/rggen/core/builder/plugin_manager.rb +140 -0
  16. data/lib/rggen/core/configuration.rb +3 -2
  17. data/lib/rggen/core/configuration/component.rb +5 -0
  18. data/lib/rggen/core/configuration/component_factory.rb +1 -1
  19. data/lib/rggen/core/configuration/hash_loader.rb +4 -2
  20. data/lib/rggen/core/configuration/input_data.rb +15 -0
  21. data/lib/rggen/core/dsl.rb +3 -1
  22. data/lib/rggen/core/exceptions.rb +9 -4
  23. data/lib/rggen/core/generator.rb +3 -3
  24. data/lib/rggen/core/input_base/component_factory.rb +37 -6
  25. data/lib/rggen/core/input_base/feature.rb +3 -3
  26. data/lib/rggen/core/input_base/input_data.rb +13 -10
  27. data/lib/rggen/core/input_base/input_value_extractor.rb +34 -0
  28. data/lib/rggen/core/input_base/loader.rb +64 -21
  29. data/lib/rggen/core/input_base/yaml_loader.rb +5 -4
  30. data/lib/rggen/core/options.rb +18 -14
  31. data/lib/rggen/core/output_base/code_generator.rb +10 -23
  32. data/lib/rggen/core/output_base/component.rb +42 -39
  33. data/lib/rggen/core/output_base/component_factory.rb +4 -0
  34. data/lib/rggen/core/output_base/feature.rb +6 -7
  35. data/lib/rggen/core/printers.rb +11 -7
  36. data/lib/rggen/core/register_map.rb +6 -5
  37. data/lib/rggen/core/register_map/component.rb +4 -3
  38. data/lib/rggen/core/register_map/component_factory.rb +18 -1
  39. data/lib/rggen/core/register_map/feature.rb +2 -2
  40. data/lib/rggen/core/register_map/hash_loader.rb +61 -27
  41. data/lib/rggen/core/register_map/input_data.rb +30 -16
  42. data/lib/rggen/core/register_map/loader.rb +1 -1
  43. data/lib/rggen/core/register_map/ruby_loader.rb +1 -1
  44. data/lib/rggen/core/utility/attribute_setter.rb +4 -0
  45. data/lib/rggen/core/utility/code_utility.rb +8 -2
  46. data/lib/rggen/core/utility/error_utility.rb +33 -6
  47. data/lib/rggen/core/version.rb +2 -2
  48. metadata +10 -7
  49. data/lib/rggen/core/base/hierarchical_accessors.rb +0 -91
  50. data/lib/rggen/core/base/hierarchical_feature_accessors.rb +0 -83
  51. data/lib/rggen/core/builder/category.rb +0 -116
  52. data/lib/rggen/core/builder/plugins.rb +0 -77
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Builder
6
+ class LoaderRegistry
7
+ def initialize
8
+ @loaders = []
9
+ @extractors = []
10
+ @ignore_values = {}
11
+ end
12
+
13
+ def register_loader(loader)
14
+ register_loaders([loader])
15
+ end
16
+
17
+ def register_loaders(loaders)
18
+ @loaders.concat(Array(loaders))
19
+ end
20
+
21
+ def define_value_extractor(layers, value, &body)
22
+ @extractors <<
23
+ create_extractor(layers, value, &body)
24
+ end
25
+
26
+ def ignore_value(layers, value)
27
+ ignore_values(layers, [value])
28
+ end
29
+
30
+ def ignore_values(layers, values)
31
+ [layers].flatten.each do |layer|
32
+ (@ignore_values[layer] ||= []).concat(Array(values))
33
+ end
34
+ end
35
+
36
+ def create_loaders
37
+ @loaders.map { |loader| loader.new(@extractors, @ignore_values) }
38
+ end
39
+
40
+ private
41
+
42
+ def create_extractor(layers, value, &body)
43
+ Class.new(Core::InputBase::InputValueExtractor, &body).new(layers, value)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,140 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Builder
6
+ class Plugin
7
+ DEFAULT_PLUGIN_VERSION = '0.0.0'
8
+
9
+ def initialize(plugin_module, &block)
10
+ @plugin_module = plugin_module
11
+ @block = block
12
+ plugin_name # check if plugin name is given
13
+ end
14
+
15
+ def default_setup(builder)
16
+ @plugin_module.respond_to?(:default_setup) &&
17
+ @plugin_module.default_setup(builder)
18
+ end
19
+
20
+ def optional_setup(builder)
21
+ @block && @plugin_module.instance_exec(builder, &@block)
22
+ end
23
+
24
+ def plugin_name
25
+ if @plugin_module.const_defined?(:PLUGIN_NAME)
26
+ @plugin_module.const_get(:PLUGIN_NAME)
27
+ elsif @plugin_module.respond_to?(:plugin_name)
28
+ @plugin_module.plugin_name
29
+ else
30
+ raise Core::PluginError.new('no plugin name is given')
31
+ end
32
+ end
33
+
34
+ def version
35
+ if @plugin_module.const_defined?(:VERSION)
36
+ @plugin_module.const_get(:VERSION)
37
+ elsif @plugin_module.respond_to?(:version)
38
+ @plugin_module.version
39
+ else
40
+ DEFAULT_PLUGIN_VERSION
41
+ end
42
+ end
43
+
44
+ def version_info
45
+ "#{plugin_name} #{version}"
46
+ end
47
+ end
48
+
49
+ class PluginManager
50
+ def initialize(builder)
51
+ @builder = builder
52
+ @plugins = []
53
+ end
54
+
55
+ def load_plugin(setup_path_or_name)
56
+ setup_path_or_name = setup_path_or_name.to_s.strip
57
+ setup_path =
58
+ if setup_file_directly_given?(setup_path_or_name)
59
+ setup_path_or_name
60
+ else
61
+ get_setup_path(setup_path_or_name)
62
+ end
63
+ read_setup_file(setup_path, setup_path_or_name)
64
+ end
65
+
66
+ def load_plugins(plugins, no_default_plugins, activation = true)
67
+ RgGen.builder(@builder)
68
+ merge_plugins(plugins, no_default_plugins)
69
+ .each { |plugin| load_plugin(*plugin) }
70
+ activation && activate_plugins
71
+ end
72
+
73
+ def setup(plugin_module, &block)
74
+ @plugins << Plugin.new(plugin_module, &block)
75
+ end
76
+
77
+ def activate_plugins(**options)
78
+ options[:no_default_setup] ||
79
+ @plugins.each { |plugin| plugin.default_setup(@builder) }
80
+ options[:no_optional_setup] ||
81
+ @plugins.each { |plugin| plugin.optional_setup(@builder) }
82
+ end
83
+
84
+ def version_info
85
+ @plugins.map(&:version_info)
86
+ end
87
+
88
+ private
89
+
90
+ def setup_file_directly_given?(setup_path_or_name)
91
+ File.ext(setup_path_or_name) == 'rb' ||
92
+ File.basename(setup_path_or_name, '.*') == 'setup'
93
+ end
94
+
95
+ def get_setup_path(name)
96
+ base, sub_directory = name.split('/', 2)
97
+ base = base.sub(/^rggen[-_]/, '').tr('-', '_')
98
+ File.join(*[
99
+ 'rggen', base, sub_directory || '', 'setup'
100
+ ].reject(&:empty?))
101
+ end
102
+
103
+ def read_setup_file(setup_path, setup_path_or_name)
104
+ require setup_path
105
+ rescue ::LoadError
106
+ raise Core::PluginError.new([
107
+ "cannot load such plugin: #{setup_path_or_name}",
108
+ setup_path_or_name != setup_path && " (#{setup_path})" || ''
109
+ ].join)
110
+ end
111
+
112
+ def merge_plugins(plugins, no_default_plugins)
113
+ [
114
+ *default_plugins(no_default_plugins),
115
+ *plugins_from_env,
116
+ *plugins
117
+ ]
118
+ end
119
+
120
+ DEFAULT_PLUGSINS = 'rggen/setup'
121
+
122
+ def default_plugins(no_default_plugins)
123
+ load_default_plugins?(no_default_plugins) && DEFAULT_PLUGSINS || nil
124
+ end
125
+
126
+ def load_default_plugins?(no_default_plugins)
127
+ return false if no_default_plugins
128
+ return false if ENV.key?('RGGEN_NO_DEFAULT_PLUGINS')
129
+ return false if Gem.find_files(DEFAULT_PLUGSINS).empty?
130
+ true
131
+ end
132
+
133
+ def plugins_from_env
134
+ ENV['RGGEN_PLUGINS']
135
+ &.split(':')&.map(&:strip)&.reject(&:empty?)
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
@@ -10,8 +10,9 @@ module RgGen
10
10
  feature Feature, FeatureFactory
11
11
  end
12
12
 
13
- base_loader Loader
14
- register_loaders [RubyLoader, JSONLoader, YAMLLoader]
13
+ register_loader :ruby, RubyLoader
14
+ register_loader :yaml, YAMLLoader
15
+ register_loader :json, JSONLoader
15
16
  end
16
17
  end
17
18
  end
@@ -4,6 +4,11 @@ module RgGen
4
4
  module Core
5
5
  module Configuration
6
6
  class Component < InputBase::Component
7
+ private
8
+
9
+ def post_initialize
10
+ need_no_children
11
+ end
7
12
  end
8
13
  end
9
14
  end
@@ -7,7 +7,7 @@ module RgGen
7
7
  private
8
8
 
9
9
  def create_input_data(&block)
10
- InputBase::InputData.new(valid_value_lists, &block)
10
+ InputData.new(valid_value_lists, &block)
11
11
  end
12
12
  end
13
13
  end
@@ -4,8 +4,10 @@ module RgGen
4
4
  module Core
5
5
  module Configuration
6
6
  module HashLoader
7
- def format(read_data, file)
8
- input_data.values(Hash(read_data), file)
7
+ private
8
+
9
+ def format_layer_data(read_data, _layer, file)
10
+ Hash(read_data)
9
11
  rescue TypeError => e
10
12
  raise Core::LoadError.new(e.message, file)
11
13
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ class InputData < InputBase::InputData
7
+ def initialize(valid_value_lists, &block)
8
+ super(nil, valid_value_lists, &block)
9
+ end
10
+
11
+ undef_method :child
12
+ end
13
+ end
14
+ end
15
+ end
@@ -15,11 +15,13 @@ module RgGen
15
15
  :define_simple_feature,
16
16
  :define_list_feature,
17
17
  :define_list_item_feature,
18
+ :define_value_extractor,
18
19
  :enable,
19
20
  :disable_all,
20
21
  :disable,
21
22
  :delete,
22
- :setup
23
+ :setup,
24
+ :load_plugin
23
25
  ].each do |method_name|
24
26
  def_delegator :'RgGen.builder', method_name
25
27
  end
@@ -3,23 +3,28 @@
3
3
  module RgGen
4
4
  module Core
5
5
  class RgGenError < StandardError
6
- def initialize(message, additional_info = nil)
6
+ def initialize(message, location_info = nil, verbose_info = nil)
7
7
  super(message)
8
8
  @error_message = message
9
- @additional_info = additional_info
9
+ @location_info = location_info
10
+ @verbose_info = verbose_info
10
11
  end
11
12
 
12
13
  attr_reader :error_message
13
- attr_reader :additional_info
14
+ attr_reader :location_info
15
+ attr_reader :verbose_info
14
16
 
15
17
  def to_s
16
- additional_info ? "#{super} -- #{additional_info}" : super
18
+ location_info && "#{super} -- #{location_info}" || super
17
19
  end
18
20
  end
19
21
 
20
22
  class BuilderError < RgGenError
21
23
  end
22
24
 
25
+ class PluginError < RgGenError
26
+ end
27
+
23
28
  class RuntimeError < RgGenError
24
29
  end
25
30
 
@@ -4,7 +4,7 @@ module RgGen
4
4
  module Core
5
5
  class Generator
6
6
  def run(builder, options)
7
- load_setup_file(builder, options[:setup])
7
+ load_plugins(builder, options)
8
8
  load_configuration(builder, options[:configuration])
9
9
  load_register_map(builder, options.register_map_files)
10
10
  write_files(builder, options)
@@ -15,8 +15,8 @@ module RgGen
15
15
  attr_reader :configuration
16
16
  attr_reader :register_map
17
17
 
18
- def load_setup_file(builder, file)
19
- builder.load_setup_file(file)
18
+ def load_plugins(builder, options)
19
+ builder.load_plugins(options[:plugins], options[:no_default_plugins])
20
20
  end
21
21
 
22
22
  def load_configuration(builder, file)
@@ -4,6 +4,20 @@ module RgGen
4
4
  module Core
5
5
  module InputBase
6
6
  class ComponentFactory < Base::ComponentFactory
7
+ class << self
8
+ def enable_no_children_error
9
+ @enable_no_children_error = true
10
+ end
11
+
12
+ def disable_no_children_error
13
+ @enable_no_children_error = false
14
+ end
15
+
16
+ def enable_no_children_error?
17
+ @enable_no_children_error.nil? || @enable_no_children_error
18
+ end
19
+ end
20
+
7
21
  attr_setter :loaders
8
22
 
9
23
  private
@@ -27,8 +41,13 @@ module RgGen
27
41
  end
28
42
 
29
43
  def find_loader(file)
30
- loader = loaders.find { |l| l.support?(file) }
31
- loader || (raise Core::LoadError.new('unsupported file type', file))
44
+ loaders.find { |l| l.support?(file) } ||
45
+ (raise Core::LoadError.new('unsupported file type', file))
46
+ end
47
+
48
+ def valid_value_lists
49
+ component_factories
50
+ .transform_values(&->(f) { f.valid_value_list })
32
51
  end
33
52
 
34
53
  def create_input_data(&block)
@@ -58,9 +77,23 @@ module RgGen
58
77
  end
59
78
 
60
79
  def post_build(component)
80
+ exist_no_children?(component) &&
81
+ raise_no_children_error(component)
61
82
  component.verify(:component)
62
83
  end
63
84
 
85
+ def exist_no_children?(component)
86
+ enable_no_children_error? &&
87
+ component.need_children? && component.children.empty?
88
+ end
89
+
90
+ def enable_no_children_error?
91
+ self.class.enable_no_children_error?
92
+ end
93
+
94
+ def raise_no_children_error(_component)
95
+ end
96
+
64
97
  def finalize(component)
65
98
  component.verify(:all)
66
99
  end
@@ -77,10 +110,8 @@ module RgGen
77
110
 
78
111
  protected
79
112
 
80
- def valid_value_lists
81
- list = [Array(active_feature_factories&.keys)]
82
- list.concat(Array(child_factory&.valid_value_lists))
83
- list
113
+ def valid_value_list
114
+ Array(active_feature_factories&.keys)
84
115
  end
85
116
  end
86
117
  end
@@ -80,9 +80,9 @@ module RgGen
80
80
  end
81
81
 
82
82
  def export_verifiers(subclass)
83
- copied_verifiers =
84
- @verifiers.map { |scope, blocks| [scope, blocks.dup] }.to_h
85
- subclass.instance_variable_set(:@verifiers, copied_verifiers)
83
+ subclass.instance_variable_set(
84
+ :@verifiers, @verifiers.transform_values(&:dup)
85
+ )
86
86
  end
87
87
  end
88
88
 
@@ -4,7 +4,8 @@ module RgGen
4
4
  module Core
5
5
  module InputBase
6
6
  class InputData
7
- def initialize(valid_value_lists)
7
+ def initialize(layer, valid_value_lists)
8
+ @layer = layer
8
9
  @valid_value_lists = valid_value_lists
9
10
  @values = Hash.new(NAValue)
10
11
  @children = []
@@ -12,6 +13,8 @@ module RgGen
12
13
  block_given? && yield(self)
13
14
  end
14
15
 
16
+ attr_reader :layer
17
+
15
18
  def value(value_name, value, position = nil)
16
19
  symbolized_name = value_name.to_sym
17
20
  return unless valid_value?(symbolized_name)
@@ -24,8 +27,8 @@ module RgGen
24
27
  end
25
28
  end
26
29
 
27
- def []=(value_name, position = nil, value)
28
- value(value_name, value, position)
30
+ def []=(value_name, position_or_value, value = nil)
31
+ value(value_name, value || position_or_value, position_or_value)
29
32
  end
30
33
 
31
34
  def [](value_name)
@@ -39,8 +42,8 @@ module RgGen
39
42
 
40
43
  attr_reader :children
41
44
 
42
- def child(value_list = nil, &block)
43
- create_child_data do |child_data|
45
+ def child(layer, value_list = nil, &block)
46
+ create_child_data(layer) do |child_data|
44
47
  child_data.build_by_block(block)
45
48
  child_data.values(value_list)
46
49
  @children << child_data
@@ -56,11 +59,11 @@ module RgGen
56
59
  private
57
60
 
58
61
  def valid_value?(value_name)
59
- @valid_value_lists.first.include?(value_name)
62
+ @valid_value_lists[layer].include?(value_name)
60
63
  end
61
64
 
62
65
  def define_setter_methods
63
- @valid_value_lists.first.each(&method(:define_setter_method))
66
+ @valid_value_lists[layer].each(&method(:define_setter_method))
64
67
  end
65
68
 
66
69
  def define_setter_method(value_name)
@@ -79,12 +82,12 @@ module RgGen
79
82
  locations[0].path.include?('docile') ? locations[1] : locations[0]
80
83
  end
81
84
 
82
- def create_child_data(&block)
83
- child_data_class.new(@valid_value_lists[1..-1], &block)
85
+ def create_child_data(layer, &block)
86
+ child_data_class.new(layer, @valid_value_lists, &block)
84
87
  end
85
88
 
86
89
  def child_data_class
87
- InputData
90
+ self.class
88
91
  end
89
92
 
90
93
  protected