rggen-core 0.19.0 → 0.23.1

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 (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