rggen-core 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|