rggen-core 0.9.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 +7 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/LICENSE +21 -0
- data/README.md +46 -0
- data/exe/rggen +13 -0
- data/lib/rggen/core.rb +101 -0
- data/lib/rggen/core/base/component.rb +54 -0
- data/lib/rggen/core/base/component_factory.rb +84 -0
- data/lib/rggen/core/base/feature.rb +46 -0
- data/lib/rggen/core/base/feature_factory.rb +37 -0
- data/lib/rggen/core/base/hierarchical_accessors.rb +91 -0
- data/lib/rggen/core/base/hierarchical_feature_accessors.rb +83 -0
- data/lib/rggen/core/base/internal_struct.rb +21 -0
- data/lib/rggen/core/base/shared_context.rb +18 -0
- data/lib/rggen/core/builder.rb +13 -0
- data/lib/rggen/core/builder/builder.rb +150 -0
- data/lib/rggen/core/builder/category.rb +116 -0
- data/lib/rggen/core/builder/component_entry.rb +29 -0
- data/lib/rggen/core/builder/component_registry.rb +47 -0
- data/lib/rggen/core/builder/feature_registry.rb +126 -0
- data/lib/rggen/core/builder/input_component_registry.rb +35 -0
- data/lib/rggen/core/builder/list_feature_entry.rb +98 -0
- data/lib/rggen/core/builder/output_component_registry.rb +10 -0
- data/lib/rggen/core/builder/simple_feature_entry.rb +39 -0
- data/lib/rggen/core/cli.rb +29 -0
- data/lib/rggen/core/configuration.rb +19 -0
- data/lib/rggen/core/configuration/component.rb +10 -0
- data/lib/rggen/core/configuration/component_factory.rb +19 -0
- data/lib/rggen/core/configuration/error.rb +16 -0
- data/lib/rggen/core/configuration/feature.rb +13 -0
- data/lib/rggen/core/configuration/feature_factory.rb +11 -0
- data/lib/rggen/core/configuration/hash_loader.rb +15 -0
- data/lib/rggen/core/configuration/json_loader.rb +18 -0
- data/lib/rggen/core/configuration/loader.rb +11 -0
- data/lib/rggen/core/configuration/ruby_loader.rb +15 -0
- data/lib/rggen/core/configuration/yaml_loader.rb +18 -0
- data/lib/rggen/core/core_extensions/casecmp.rb +12 -0
- data/lib/rggen/core/core_extensions/forwardable.rb +12 -0
- data/lib/rggen/core/core_extensions/forwardable_workaround.rb +22 -0
- data/lib/rggen/core/core_extensions/object.rb +14 -0
- data/lib/rggen/core/dsl.rb +30 -0
- data/lib/rggen/core/exceptions.rb +29 -0
- data/lib/rggen/core/facets.rb +7 -0
- data/lib/rggen/core/generator.rb +51 -0
- data/lib/rggen/core/input_base/component.rb +30 -0
- data/lib/rggen/core/input_base/component_factory.rb +88 -0
- data/lib/rggen/core/input_base/feature.rb +130 -0
- data/lib/rggen/core/input_base/feature_factory.rb +80 -0
- data/lib/rggen/core/input_base/input_data.rb +98 -0
- data/lib/rggen/core/input_base/input_matcher.rb +79 -0
- data/lib/rggen/core/input_base/input_value.rb +34 -0
- data/lib/rggen/core/input_base/json_loader.rb +16 -0
- data/lib/rggen/core/input_base/loader.rb +44 -0
- data/lib/rggen/core/input_base/property.rb +76 -0
- data/lib/rggen/core/input_base/verifier.rb +41 -0
- data/lib/rggen/core/input_base/yaml_loader.rb +34 -0
- data/lib/rggen/core/options.rb +181 -0
- data/lib/rggen/core/output_base/code_generator.rb +59 -0
- data/lib/rggen/core/output_base/component.rb +100 -0
- data/lib/rggen/core/output_base/component_factory.rb +35 -0
- data/lib/rggen/core/output_base/erb_engine.rb +21 -0
- data/lib/rggen/core/output_base/feature.rb +147 -0
- data/lib/rggen/core/output_base/feature_factory.rb +13 -0
- data/lib/rggen/core/output_base/file_writer.rb +40 -0
- data/lib/rggen/core/output_base/template_engine.rb +27 -0
- data/lib/rggen/core/printers.rb +53 -0
- data/lib/rggen/core/register_map.rb +21 -0
- data/lib/rggen/core/register_map/component.rb +20 -0
- data/lib/rggen/core/register_map/component_factory.rb +19 -0
- data/lib/rggen/core/register_map/error.rb +16 -0
- data/lib/rggen/core/register_map/feature.rb +22 -0
- data/lib/rggen/core/register_map/feature_factory.rb +11 -0
- data/lib/rggen/core/register_map/hash_loader.rb +47 -0
- data/lib/rggen/core/register_map/input_data.rb +34 -0
- data/lib/rggen/core/register_map/json_loader.rb +18 -0
- data/lib/rggen/core/register_map/loader.rb +15 -0
- data/lib/rggen/core/register_map/ruby_loader.rb +15 -0
- data/lib/rggen/core/register_map/yaml_loader.rb +18 -0
- data/lib/rggen/core/utility/attribute_setter.rb +53 -0
- data/lib/rggen/core/utility/code_utility.rb +64 -0
- data/lib/rggen/core/utility/code_utility/code_block.rb +88 -0
- data/lib/rggen/core/utility/code_utility/line.rb +51 -0
- data/lib/rggen/core/utility/code_utility/source_file.rb +104 -0
- data/lib/rggen/core/utility/code_utility/structure_definition.rb +54 -0
- data/lib/rggen/core/utility/regexp_patterns.rb +38 -0
- data/lib/rggen/core/version.rb +10 -0
- metadata +188 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module Builder
|
6
|
+
class ComponentEntry
|
7
|
+
Entry = Struct.new(:target, :factory)
|
8
|
+
|
9
|
+
[:component, :feature].each do |entry_name|
|
10
|
+
define_method(entry_name) do |target, factory|
|
11
|
+
instance_variable_set("@#{__method__}", Entry.new(target, factory))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def feature_registry
|
16
|
+
return unless @feature
|
17
|
+
@feature_registry ||= FeatureRegistry.new(*@feature.values)
|
18
|
+
end
|
19
|
+
|
20
|
+
def build_factory
|
21
|
+
@component.factory.new do |f|
|
22
|
+
f.target_component(@component.target)
|
23
|
+
f.feature_factories(feature_registry&.build_factories)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module Builder
|
6
|
+
class ComponentRegistry
|
7
|
+
def initialize(name, builder)
|
8
|
+
@name = name
|
9
|
+
@builder = builder
|
10
|
+
@entries = []
|
11
|
+
end
|
12
|
+
|
13
|
+
def register_component(categories = nil, &block)
|
14
|
+
if categories
|
15
|
+
Array(categories).each do |category|
|
16
|
+
@entries << create_new_entry(category, block)
|
17
|
+
end
|
18
|
+
else
|
19
|
+
@entries << create_new_entry(nil, block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_factory
|
24
|
+
factories = @entries.map(&:build_factory)
|
25
|
+
factories.each_cons(2) { |(f0, f1)| f0.child_factory(f1) }
|
26
|
+
root_factory = factories.first
|
27
|
+
root_factory.root_factory
|
28
|
+
root_factory
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def create_new_entry(category, block)
|
34
|
+
entry = ComponentEntry.new
|
35
|
+
Docile.dsl_eval(entry, category, &block)
|
36
|
+
add_feature_registry(category, entry.feature_registry)
|
37
|
+
entry
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_feature_registry(category, feature_registry)
|
41
|
+
feature_registry || return
|
42
|
+
@builder.add_feature_registry(@name, category, feature_registry)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module Builder
|
6
|
+
class FeatureRegistry
|
7
|
+
def initialize(base_feature, factory)
|
8
|
+
@base_feature = base_feature
|
9
|
+
@factory = factory
|
10
|
+
@feature_entries = {}
|
11
|
+
@enabled_features = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def define_simple_feature(names, context = nil, &body)
|
15
|
+
Array(names)
|
16
|
+
.each { |name| create_new_entry(:simple, name, context, body) }
|
17
|
+
end
|
18
|
+
|
19
|
+
def define_list_feature(list_names, context = nil, &body)
|
20
|
+
Array(list_names)
|
21
|
+
.each { |name| create_new_entry(:list, name, context, body) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def define_list_item_feature(list_name, feature_names, context = nil, &body)
|
25
|
+
entry = @feature_entries[list_name]
|
26
|
+
entry&.match_entry_type?(:list) ||
|
27
|
+
(raise BuilderError.new("unknown list feature: #{list_name}"))
|
28
|
+
Array(feature_names)
|
29
|
+
.each { |name| entry.define_feature(name, context, &body) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def enable(feature_or_list_names, feature_names = nil)
|
33
|
+
if feature_names
|
34
|
+
@enabled_features[feature_or_list_names]
|
35
|
+
&.merge!(Array(feature_names))
|
36
|
+
else
|
37
|
+
Array(feature_or_list_names).each do |name|
|
38
|
+
@enabled_features[name] ||= []
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def enabled_features(list_name = nil)
|
44
|
+
if list_name
|
45
|
+
@enabled_features[list_name] || []
|
46
|
+
else
|
47
|
+
@enabled_features.keys
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def disable(feature_or_list_names = nil, feature_names = nil)
|
52
|
+
if feature_names
|
53
|
+
@enabled_features[feature_or_list_names]
|
54
|
+
&.delete_if { |key, _| Array(feature_names).include?(key) }
|
55
|
+
elsif feature_or_list_names
|
56
|
+
Array(feature_or_list_names)
|
57
|
+
.each(&@enabled_features.method(:delete))
|
58
|
+
else
|
59
|
+
@enabled_features.clear
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete(feature_or_list_names = nil, feature_names = nil)
|
64
|
+
if feature_names
|
65
|
+
@feature_entries[feature_or_list_names]&.delete(feature_names)
|
66
|
+
elsif feature_or_list_names
|
67
|
+
Array(feature_or_list_names)
|
68
|
+
.each(&@feature_entries.method(:delete))
|
69
|
+
else
|
70
|
+
@feature_entries.clear
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def simple_feature?(feature_name)
|
75
|
+
enabled_feature?(feature_name, :simple)
|
76
|
+
end
|
77
|
+
|
78
|
+
def list_feature?(list_name, feature_name = nil)
|
79
|
+
return false unless enabled_feature?(list_name, :list)
|
80
|
+
return true unless feature_name
|
81
|
+
enabled_list_item_feature?(list_name, feature_name)
|
82
|
+
end
|
83
|
+
|
84
|
+
def feature?(feature_or_list_name, feature_name = nil)
|
85
|
+
if feature_name
|
86
|
+
list_feature?(feature_or_list_name, feature_name)
|
87
|
+
else
|
88
|
+
simple_feature?(feature_or_list_name) ||
|
89
|
+
list_feature?(feature_or_list_name)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def build_factories
|
94
|
+
@enabled_features
|
95
|
+
.select { |n, _| @feature_entries.key?(n) }
|
96
|
+
.map { |n, f| [n, @feature_entries[n].build_factory(f)] }
|
97
|
+
.to_h
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
FEATURE_ENTRIES = {
|
103
|
+
simple: SimpleFeatureEntry, list: ListFeatureEntry
|
104
|
+
}.freeze
|
105
|
+
|
106
|
+
def create_new_entry(type, name, context, body)
|
107
|
+
entry = FEATURE_ENTRIES[type].new(self, name)
|
108
|
+
entry.setup(@base_feature, @factory, context, body)
|
109
|
+
@feature_entries[name] = entry
|
110
|
+
end
|
111
|
+
|
112
|
+
def enabled_feature?(name, entry_type)
|
113
|
+
return false unless @feature_entries[name]
|
114
|
+
&.match_entry_type?(entry_type)
|
115
|
+
@enabled_features.key?(name)
|
116
|
+
end
|
117
|
+
|
118
|
+
def enabled_list_item_feature?(list_name, feature_name)
|
119
|
+
return false unless @feature_entries[list_name]
|
120
|
+
.feature?(feature_name)
|
121
|
+
@enabled_features[list_name].include?(feature_name)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module Builder
|
6
|
+
class InputComponentRegistry < ComponentRegistry
|
7
|
+
def initialize(name, builder)
|
8
|
+
super
|
9
|
+
@loaders = []
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_setter :base_loader
|
13
|
+
|
14
|
+
def register_loader(loader)
|
15
|
+
@loaders << loader
|
16
|
+
end
|
17
|
+
|
18
|
+
def register_loaders(loaders)
|
19
|
+
@loaders.concat(Array(loaders))
|
20
|
+
end
|
21
|
+
|
22
|
+
def define_loader(&body)
|
23
|
+
loader = Class.new(@base_loader, &body)
|
24
|
+
register_loader(loader)
|
25
|
+
end
|
26
|
+
|
27
|
+
def build_factory
|
28
|
+
factory = super
|
29
|
+
factory.loaders(@loaders)
|
30
|
+
factory
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module Builder
|
6
|
+
class ListFeatureEntry
|
7
|
+
include Base::SharedContext
|
8
|
+
|
9
|
+
def initialize(registry, name)
|
10
|
+
@registry = registry
|
11
|
+
@name = name
|
12
|
+
@features = {}
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :registry
|
16
|
+
attr_reader :name
|
17
|
+
|
18
|
+
def setup(base_feature, base_factory, context, body)
|
19
|
+
@base_feature = Class.new(base_feature)
|
20
|
+
@factory = Class.new(base_factory)
|
21
|
+
context && attach_shared_context(context)
|
22
|
+
body && Docile.dsl_eval(self, @name, &body)
|
23
|
+
end
|
24
|
+
|
25
|
+
def match_entry_type?(entry_type)
|
26
|
+
entry_type == :list
|
27
|
+
end
|
28
|
+
|
29
|
+
def define_factory(&body)
|
30
|
+
@factory.class_exec(&body)
|
31
|
+
end
|
32
|
+
|
33
|
+
alias_method :factory, :define_factory
|
34
|
+
|
35
|
+
def build_factory(enabled_features)
|
36
|
+
@factory.new(@name) do |f|
|
37
|
+
f.target_features(target_features(enabled_features))
|
38
|
+
f.target_feature(@default_feature)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def define_base_feature(&body)
|
43
|
+
body && @base_feature.class_exec(&body)
|
44
|
+
end
|
45
|
+
|
46
|
+
alias_method :base_feature, :define_base_feature
|
47
|
+
|
48
|
+
def define_feature(feature_name, context = nil, &body)
|
49
|
+
@features[feature_name] ||= Class.new(@base_feature)
|
50
|
+
feature = @features[feature_name]
|
51
|
+
if context
|
52
|
+
feature.method_defined?(:shared_context) && (
|
53
|
+
raise BuilderError.new('shared context has already been set')
|
54
|
+
)
|
55
|
+
feature.attach_context(context)
|
56
|
+
end
|
57
|
+
body && feature.class_exec(feature_name, &body)
|
58
|
+
end
|
59
|
+
|
60
|
+
alias_method :feature, :define_feature
|
61
|
+
|
62
|
+
def define_default_feature(&body)
|
63
|
+
@default_feature ||= Class.new(@base_feature)
|
64
|
+
body && @default_feature.class_exec(&body)
|
65
|
+
end
|
66
|
+
|
67
|
+
alias_method :default_feature, :define_default_feature
|
68
|
+
|
69
|
+
def delete(features = nil)
|
70
|
+
if features
|
71
|
+
Array(features).each { |feature| @features.delete(feature) }
|
72
|
+
else
|
73
|
+
@features.clear
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def feature?(feature)
|
78
|
+
@features.key?(feature)
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def attach_shared_context(context)
|
84
|
+
[@factory, @base_feature, self].each do |target|
|
85
|
+
target.attach_context(context)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def target_features(enabled_features)
|
90
|
+
enabled_features
|
91
|
+
.select { |n| @features.key?(n) }
|
92
|
+
.map { |n| [n, @features[n]] }
|
93
|
+
.to_h
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module Builder
|
6
|
+
class SimpleFeatureEntry
|
7
|
+
def initialize(registry, name)
|
8
|
+
@registry = registry
|
9
|
+
@name = name
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_reader :registry
|
13
|
+
attr_reader :name
|
14
|
+
|
15
|
+
def setup(base_feature, factory, context, body)
|
16
|
+
@feature = define_feature(base_feature, context, body)
|
17
|
+
@factory = factory
|
18
|
+
end
|
19
|
+
|
20
|
+
def match_entry_type?(entry_type)
|
21
|
+
entry_type == :simple
|
22
|
+
end
|
23
|
+
|
24
|
+
def build_factory(_enabled_features)
|
25
|
+
@factory.new(@name) { |f| f.target_feature(@feature) }
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def define_feature(base, context, body)
|
31
|
+
feature = Class.new(base)
|
32
|
+
context && feature.attach_context(context)
|
33
|
+
body && feature.class_exec(@name, &body)
|
34
|
+
feature
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
class CLI
|
6
|
+
def initialize(builder = nil)
|
7
|
+
RgGen.builder(builder || Builder.create)
|
8
|
+
end
|
9
|
+
|
10
|
+
def run(args)
|
11
|
+
options = parse_options(args)
|
12
|
+
builder = RgGen.builder
|
13
|
+
runner(options).run(builder, options)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def parse_options(args)
|
19
|
+
options = Options.new
|
20
|
+
options.parse(args)
|
21
|
+
options
|
22
|
+
end
|
23
|
+
|
24
|
+
def runner(options)
|
25
|
+
options[:runner] || Generator.new
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RgGen
|
4
|
+
module Core
|
5
|
+
module Configuration
|
6
|
+
def self.setup(builder)
|
7
|
+
builder.input_component_registry(:configuration) do
|
8
|
+
register_component do
|
9
|
+
component Component, ComponentFactory
|
10
|
+
feature Feature, FeatureFactory
|
11
|
+
end
|
12
|
+
|
13
|
+
base_loader Loader
|
14
|
+
register_loaders [RubyLoader, JSONLoader, YAMLLoader]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|