rggen-core 0.20.0 → 0.24.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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +2 -1
- data/exe/rggen +2 -2
- data/lib/rggen/core.rb +9 -1
- data/lib/rggen/core/builder/builder.rb +30 -36
- data/lib/rggen/core/builder/component_registry.rb +8 -9
- data/lib/rggen/core/builder/feature_registry.rb +6 -9
- data/lib/rggen/core/builder/input_component_registry.rb +43 -10
- data/lib/rggen/core/builder/layer.rb +44 -29
- data/lib/rggen/core/builder/loader_registry.rb +48 -0
- data/lib/rggen/core/builder/plugin_manager.rb +122 -0
- data/lib/rggen/core/builder/plugin_spec.rb +83 -0
- data/lib/rggen/core/configuration.rb +5 -3
- data/lib/rggen/core/configuration/hash_loader.rb +4 -2
- data/lib/rggen/core/configuration/toml_loader.rb +18 -0
- data/lib/rggen/core/dsl.rb +3 -1
- data/lib/rggen/core/exceptions.rb +9 -4
- data/lib/rggen/core/facets.rb +0 -1
- data/lib/rggen/core/generator.rb +3 -3
- data/lib/rggen/core/input_base/feature.rb +2 -2
- data/lib/rggen/core/input_base/input_data.rb +8 -4
- data/lib/rggen/core/input_base/input_value_extractor.rb +34 -0
- data/lib/rggen/core/input_base/loader.rb +64 -20
- data/lib/rggen/core/input_base/toml_loader.rb +16 -0
- data/lib/rggen/core/input_base/yaml_loader.rb +12 -8
- data/lib/rggen/core/options.rb +18 -14
- data/lib/rggen/core/output_base/code_generator.rb +1 -1
- data/lib/rggen/core/plugin.rb +16 -0
- data/lib/rggen/core/printers.rb +11 -7
- data/lib/rggen/core/register_map.rb +6 -6
- data/lib/rggen/core/register_map/hash_loader.rb +58 -17
- data/lib/rggen/core/register_map/toml_loader.rb +18 -0
- data/lib/rggen/core/utility/attribute_setter.rb +5 -0
- data/lib/rggen/core/utility/error_utility.rb +33 -6
- data/lib/rggen/core/version.rb +2 -4
- metadata +32 -5
- data/lib/rggen/core/builder/plugins.rb +0 -79
@@ -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,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module Builder
|
6
|
+
class PluginRegistry
|
7
|
+
def initialize(plugin_module, &block)
|
8
|
+
@plugin_module = plugin_module
|
9
|
+
@block = block
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_setup(builder)
|
13
|
+
@plugin_module.plugin_spec.activate(builder)
|
14
|
+
end
|
15
|
+
|
16
|
+
def optional_setup(builder)
|
17
|
+
@block && @plugin_module.instance_exec(builder, &@block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def version_info
|
21
|
+
@plugin_module.plugin_spec.version_info
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class PluginManager
|
26
|
+
def initialize(builder)
|
27
|
+
@builder = builder
|
28
|
+
@plugins = []
|
29
|
+
end
|
30
|
+
|
31
|
+
def load_plugin(setup_path_or_name)
|
32
|
+
setup_path_or_name = setup_path_or_name.to_s.strip
|
33
|
+
setup_path =
|
34
|
+
if setup_file_directly_given?(setup_path_or_name)
|
35
|
+
setup_path_or_name
|
36
|
+
else
|
37
|
+
get_setup_path(setup_path_or_name)
|
38
|
+
end
|
39
|
+
read_setup_file(setup_path, setup_path_or_name)
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_plugins(plugins, no_default_plugins, activation = true)
|
43
|
+
RgGen.builder(@builder)
|
44
|
+
merge_plugins(plugins, no_default_plugins).each(&method(:load_plugin))
|
45
|
+
activation && activate_plugins
|
46
|
+
end
|
47
|
+
|
48
|
+
def register_plugin(plugin_module, &block)
|
49
|
+
plugin?(plugin_module) ||
|
50
|
+
(raise Core::PluginError.new('no plugin spec is given'))
|
51
|
+
@plugins << PluginRegistry.new(plugin_module, &block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def activate_plugins(**options)
|
55
|
+
options[:no_default_setup] ||
|
56
|
+
@plugins.each { |plugin| plugin.default_setup(@builder) }
|
57
|
+
options[:no_optional_setup] ||
|
58
|
+
@plugins.each { |plugin| plugin.optional_setup(@builder) }
|
59
|
+
end
|
60
|
+
|
61
|
+
def version_info
|
62
|
+
@plugins.map(&:version_info)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def setup_file_directly_given?(setup_path_or_name)
|
68
|
+
File.ext(setup_path_or_name) == 'rb' ||
|
69
|
+
File.basename(setup_path_or_name, '.*') == 'setup'
|
70
|
+
end
|
71
|
+
|
72
|
+
def get_setup_path(name)
|
73
|
+
base, sub_directory = name.split('/', 2)
|
74
|
+
base = base.sub(/^rggen[-_]/, '').tr('-', '_')
|
75
|
+
File.join(*['rggen', base, sub_directory, 'setup'].compact)
|
76
|
+
end
|
77
|
+
|
78
|
+
def read_setup_file(setup_path, setup_path_or_name)
|
79
|
+
require setup_path
|
80
|
+
rescue ::LoadError
|
81
|
+
message =
|
82
|
+
if setup_path_or_name == setup_path
|
83
|
+
"cannot load such plugin: #{setup_path_or_name}"
|
84
|
+
else
|
85
|
+
"cannot load such plugin: #{setup_path_or_name} (#{setup_path})"
|
86
|
+
end
|
87
|
+
raise Core::PluginError.new(message)
|
88
|
+
end
|
89
|
+
|
90
|
+
def merge_plugins(plugins, no_default_plugins)
|
91
|
+
[
|
92
|
+
*default_plugins(no_default_plugins),
|
93
|
+
*plugins_from_env,
|
94
|
+
*plugins
|
95
|
+
]
|
96
|
+
end
|
97
|
+
|
98
|
+
DEFAULT_PLUGSINS = 'rggen/setup'
|
99
|
+
|
100
|
+
def default_plugins(no_default_plugins)
|
101
|
+
load_default_plugins?(no_default_plugins) && DEFAULT_PLUGSINS || nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def load_default_plugins?(no_default_plugins)
|
105
|
+
return false if no_default_plugins
|
106
|
+
return false if ENV.key?('RGGEN_NO_DEFAULT_PLUGINS')
|
107
|
+
return false if Gem.find_files(DEFAULT_PLUGSINS).empty?
|
108
|
+
true
|
109
|
+
end
|
110
|
+
|
111
|
+
def plugins_from_env
|
112
|
+
ENV['RGGEN_PLUGINS']
|
113
|
+
&.split(':')&.map(&:strip)&.reject(&:empty?)
|
114
|
+
end
|
115
|
+
|
116
|
+
def plugin?(plugin_module)
|
117
|
+
plugin_module.respond_to?(:plugin_spec) && plugin_module.plugin_spec
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module Builder
|
6
|
+
class PluginSpec
|
7
|
+
def initialize(name, plugin_module)
|
8
|
+
@name = name
|
9
|
+
@plugin_module = plugin_module
|
10
|
+
@component_registrations = []
|
11
|
+
@loader_registrations = []
|
12
|
+
@files = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def version(value = nil)
|
16
|
+
@version = value if value
|
17
|
+
version_value
|
18
|
+
end
|
19
|
+
|
20
|
+
def version_info
|
21
|
+
"#{@name} #{version}"
|
22
|
+
end
|
23
|
+
|
24
|
+
def register_component(component, layers = nil, &body)
|
25
|
+
@component_registrations << [component, layers, body]
|
26
|
+
end
|
27
|
+
|
28
|
+
def register_loader(component, loader_type, loader)
|
29
|
+
@loader_registrations << [component, loader_type, loader]
|
30
|
+
end
|
31
|
+
|
32
|
+
def register_loaders(component, loader_type, loaders)
|
33
|
+
Array(loaders)
|
34
|
+
.each { |loader| register_loader(component, loader_type, loader) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def register_files(files)
|
38
|
+
root = File.dirname(caller_locations(1, 1).first.path)
|
39
|
+
files.each { |file| @files << File.join(root, file) }
|
40
|
+
end
|
41
|
+
|
42
|
+
alias_method :files, :register_files
|
43
|
+
|
44
|
+
def activate(builder)
|
45
|
+
activate_components(builder)
|
46
|
+
activate_loaders(builder)
|
47
|
+
load_files
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
DEFAULT_VERSION = '0.0.0'
|
53
|
+
|
54
|
+
def version_value
|
55
|
+
@version || const_version || DEFAULT_VERSION
|
56
|
+
end
|
57
|
+
|
58
|
+
def const_version
|
59
|
+
@plugin_module.const_defined?(:VERSION) &&
|
60
|
+
@plugin_module.const_get(:VERSION)
|
61
|
+
end
|
62
|
+
|
63
|
+
def activate_components(builder)
|
64
|
+
@component_registrations.each do |component, layers, body|
|
65
|
+
builder
|
66
|
+
.output_component_registry(component)
|
67
|
+
.register_component(layers, &body)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def activate_loaders(builder)
|
72
|
+
@loader_registrations.each do |component, loader_type, loader|
|
73
|
+
builder.register_loader(component, loader_type, loader)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def load_files
|
78
|
+
@files.each(&method(:require))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -5,13 +5,15 @@ module RgGen
|
|
5
5
|
module Configuration
|
6
6
|
def self.setup(builder)
|
7
7
|
builder.input_component_registry(:configuration) do
|
8
|
-
|
8
|
+
register_global_component do
|
9
9
|
component Component, ComponentFactory
|
10
10
|
feature Feature, FeatureFactory
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
register_loader :ruby, RubyLoader
|
14
|
+
register_loader :json, JSONLoader
|
15
|
+
register_loader :toml, TOMLLoader
|
16
|
+
register_loader :yaml, YAMLLoader
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -4,8 +4,10 @@ module RgGen
|
|
4
4
|
module Core
|
5
5
|
module Configuration
|
6
6
|
module HashLoader
|
7
|
-
|
8
|
-
|
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,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module Configuration
|
6
|
+
class TOMLLoader < Loader
|
7
|
+
include HashLoader
|
8
|
+
include InputBase::TOMLLoader
|
9
|
+
|
10
|
+
support_types [:toml]
|
11
|
+
|
12
|
+
def read_file(file)
|
13
|
+
load_toml(file)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/rggen/core/dsl.rb
CHANGED
@@ -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
|
-
:
|
23
|
+
:register_plugin,
|
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,
|
6
|
+
def initialize(message, location_info = nil, verbose_info = nil)
|
7
7
|
super(message)
|
8
8
|
@error_message = message
|
9
|
-
@
|
9
|
+
@location_info = location_info
|
10
|
+
@verbose_info = verbose_info
|
10
11
|
end
|
11
12
|
|
12
13
|
attr_reader :error_message
|
13
|
-
attr_reader :
|
14
|
+
attr_reader :location_info
|
15
|
+
attr_reader :verbose_info
|
14
16
|
|
15
17
|
def to_s
|
16
|
-
|
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
|
|
data/lib/rggen/core/facets.rb
CHANGED
data/lib/rggen/core/generator.rb
CHANGED
@@ -4,7 +4,7 @@ module RgGen
|
|
4
4
|
module Core
|
5
5
|
class Generator
|
6
6
|
def run(builder, options)
|
7
|
-
|
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
|
19
|
-
builder.
|
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)
|
@@ -149,8 +149,8 @@ module RgGen
|
|
149
149
|
end
|
150
150
|
|
151
151
|
def do_verify(scope)
|
152
|
-
|
153
|
-
|
152
|
+
self.class.verifiers&.[](scope)
|
153
|
+
&.each { |verifier| verifier.verify(self) }
|
154
154
|
(@verified ||= {})[scope] = true
|
155
155
|
end
|
156
156
|
|
@@ -51,9 +51,9 @@ module RgGen
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def load_file(file)
|
54
|
-
build_by_block(
|
55
|
-
|
56
|
-
|
54
|
+
build_by_block(instance_eval(<<~BODY, file, 1))
|
55
|
+
-> { #{File.binread(file)} } # -> { File.binread(file) }
|
56
|
+
BODY
|
57
57
|
end
|
58
58
|
|
59
59
|
private
|
@@ -79,7 +79,11 @@ module RgGen
|
|
79
79
|
|
80
80
|
def position_from_caller
|
81
81
|
locations = caller_locations(3, 2)
|
82
|
-
locations[0]
|
82
|
+
include_docile_path?(locations[0]) && locations[1] || locations[0]
|
83
|
+
end
|
84
|
+
|
85
|
+
def include_docile_path?(caller_location)
|
86
|
+
caller_location.path.include?('docile')
|
83
87
|
end
|
84
88
|
|
85
89
|
def create_child_data(layer, &block)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module InputBase
|
6
|
+
class InputValueExtractor
|
7
|
+
def initialize(target_layers, target_value)
|
8
|
+
@target_layers = Array(target_layers)
|
9
|
+
@target_value = target_value
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
attr_reader :extractor
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def extract(&body)
|
18
|
+
@extractor = body
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def target_value?(layer, value)
|
23
|
+
value == @target_value &&
|
24
|
+
(@target_layers.empty? || @target_layers.include?(layer))
|
25
|
+
end
|
26
|
+
|
27
|
+
def extract(input_data)
|
28
|
+
body = self.class.extractor
|
29
|
+
instance_exec(input_data, &body)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|