rggen-core 0.24.0 → 0.26.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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +1 -1
  4. data/lib/rggen/core/base/component.rb +5 -6
  5. data/lib/rggen/core/base/component_factory.rb +9 -6
  6. data/lib/rggen/core/builder/builder.rb +6 -8
  7. data/lib/rggen/core/builder/component_registry.rb +1 -1
  8. data/lib/rggen/core/builder/feature_registry.rb +11 -8
  9. data/lib/rggen/core/builder/list_feature_entry.rb +5 -9
  10. data/lib/rggen/core/builder/loader_registry.rb +1 -2
  11. data/lib/rggen/core/builder/plugin_manager.rb +71 -31
  12. data/lib/rggen/core/builder/simple_feature_entry.rb +4 -4
  13. data/lib/rggen/core/core_extensions/object.rb +4 -4
  14. data/lib/rggen/core/facets.rb +2 -0
  15. data/lib/rggen/core/input_base/component.rb +12 -0
  16. data/lib/rggen/core/input_base/component_factory.rb +1 -0
  17. data/lib/rggen/core/input_base/feature.rb +20 -6
  18. data/lib/rggen/core/input_base/input_data.rb +17 -16
  19. data/lib/rggen/core/input_base/input_matcher.rb +5 -5
  20. data/lib/rggen/core/input_base/loader.rb +18 -20
  21. data/lib/rggen/core/input_base/property.rb +17 -11
  22. data/lib/rggen/core/input_base/yaml_loader.rb +6 -36
  23. data/lib/rggen/core/options.rb +2 -2
  24. data/lib/rggen/core/output_base/code_generator.rb +4 -5
  25. data/lib/rggen/core/output_base/document_component_factory.rb +10 -0
  26. data/lib/rggen/core/output_base/feature.rb +15 -11
  27. data/lib/rggen/core/output_base/file_writer.rb +2 -2
  28. data/lib/rggen/core/output_base/source_file_component_factory.rb +15 -0
  29. data/lib/rggen/core/output_base/template_engine.rb +4 -5
  30. data/lib/rggen/core/register_map/hash_loader.rb +11 -13
  31. data/lib/rggen/core/utility/code_utility/code_block.rb +11 -5
  32. data/lib/rggen/core/version.rb +1 -1
  33. data/lib/rggen/core.rb +2 -1
  34. metadata +8 -6
  35. data/lib/rggen/core/base/proxy_call.rb +0 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 040113a3bef96502aae386b3aa7dafcca07af29d8881b41bfc6e17b3e0769885
4
- data.tar.gz: 4392f0ae0bc1cd8d7422606eea73f11dffe293e29cc39250c5fd3479581dc349
3
+ metadata.gz: fe3a65999b49b800216dea110ca47e81c71cf4fe0a65626f50526be374647713
4
+ data.tar.gz: 160dbda800f4fef46bbe18ef34810851082d09271eb7754b6b4508eb4f56c8fd
5
5
  SHA512:
6
- metadata.gz: c77e46129bc726cb7afee6b21b3b31e2a692ee3fa2d99aade8eb6f6a3d1082e4f3fab1c83ff4f20afead532c521dfea6f23c8c6762a0b54ed9ab9cfbf013b484
7
- data.tar.gz: c20b96a0be7b1f15cae6cc8b1512d05b83d8f06cb3407b34fe1731221065de3467522bdabfd74b2b5336fcc96b245a9eff191629ff58c61635b8ca77af511be1
6
+ metadata.gz: eae55af6cdaa6eff67f15ef508dcd32af950d72f18621d0b8769011957c9c6a72c9f3c41557d197a0c1e9fec25ecaff34364f3518cd04c12f22bdb6ee8efa6af
7
+ data.tar.gz: 3d030a72ade1067dbb7450ff30ef4cffc3d97430e73a4ea96f9fb310a5cb633e314f1a9b280d4c4e615b1fce2ace5f5456f2881bd76a18fa05cef60420989ada
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017-2021 Taichi Ishitani
3
+ Copyright (c) 2017-2022 Taichi Ishitani
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -44,7 +44,7 @@ Feedbacks, bug reports, questions and etc. are wellcome! You can post them by us
44
44
 
45
45
  ## Copyright & License
46
46
 
47
- Copyright © 2017-2021 Taichi Ishitani. RgGen::Core is licensed under the [MIT License](https://opensource.org/licenses/MIT), see [LICENSE](LICENSE) for futher details.
47
+ Copyright © 2017-2022 Taichi Ishitani. RgGen::Core is licensed under the [MIT License](https://opensource.org/licenses/MIT), see [LICENSE](LICENSE) for futher details.
48
48
 
49
49
  ## Code of Conduct
50
50
 
@@ -70,15 +70,14 @@ module RgGen
70
70
 
71
71
  def define_proxy_calls(receiver, methods)
72
72
  Array(methods)
73
- .map(&:to_sym)
74
73
  .each { |method| define_proxy_call(receiver, method) }
75
74
  end
76
75
 
77
- def define_proxy_call(receiver, method)
78
- @proxy_calls ||= {}
79
- @proxy_calls[method] = ProxyCall.new(receiver, method)
80
- define_singleton_method(method) do |*args, &block|
81
- @proxy_calls[__method__].call(*args, &block)
76
+ def define_proxy_call(receiver, method_name)
77
+ (@proxy_receivers ||= {})[method_name.to_sym] = receiver
78
+ define_singleton_method(method_name) do |*args, &block|
79
+ name = __method__
80
+ @proxy_receivers[name].__send__(name, *args, &block)
82
81
  end
83
82
  end
84
83
  end
@@ -27,7 +27,7 @@ module RgGen
27
27
  if root_factory?
28
28
  [nil, preprocess(args)]
29
29
  else
30
- [args.first, preprocess(args[1..-1])]
30
+ [args.first, preprocess(args[1..])]
31
31
  end
32
32
  create_component(parent, sources) do |component|
33
33
  build_component(parent, component, sources)
@@ -43,11 +43,15 @@ module RgGen
43
43
 
44
44
  def create_component(parent, sources, &block)
45
45
  actual_sources = Array(select_actual_sources(*sources))
46
- @target_component
47
- .new(parent, component_name, layer, *actual_sources, &block)
46
+ create_component?(*actual_sources) &&
47
+ @target_component.new(parent, component_name, layer, *actual_sources, &block)
48
48
  end
49
49
 
50
- def select_actual_sources(*sources)
50
+ def select_actual_sources(*_sources)
51
+ end
52
+
53
+ def create_component?(*_sources)
54
+ true
51
55
  end
52
56
 
53
57
  def build_component(parent, component, sources)
@@ -88,8 +92,7 @@ module RgGen
88
92
  end
89
93
 
90
94
  def create_child(component, *args)
91
- factory = find_child_factory(*args)
92
- factory.create(component, *args)
95
+ find_child_factory(*args).create(component, *args)
93
96
  end
94
97
  end
95
98
  end
@@ -43,9 +43,8 @@ module RgGen
43
43
  else
44
44
  @layers.values
45
45
  end
46
- target_layers.each do |layer|
47
- layer.add_feature_registry(name, registry)
48
- end
46
+ target_layers
47
+ .each { |layer| layer.add_feature_registry(name, registry) }
49
48
  end
50
49
 
51
50
  [
@@ -79,8 +78,7 @@ module RgGen
79
78
  if targets.empty?
80
79
  @component_registries[type]
81
80
  else
82
- @component_registries[type]
83
- .select { |name, _| targets.include?(name) }
81
+ @component_registries[type].slice(*targets)
84
82
  end
85
83
  registries.each_value.map(&:build_factory)
86
84
  end
@@ -130,9 +128,9 @@ module RgGen
130
128
 
131
129
  def component_registry(type, name, &body)
132
130
  registries = @component_registries[type]
133
- klass = COMPONENT_REGISTRIES[type]
134
- registries.key?(name) || (registries[name] = klass.new(name, self))
135
- block_given? && Docile.dsl_eval(registries[name], &body) || registries[name]
131
+ registries.key?(name) ||
132
+ (registries[name] = COMPONENT_REGISTRIES[type].new(name, self))
133
+ body && Docile.dsl_eval(registries[name], &body) || registries[name]
136
134
  end
137
135
  end
138
136
  end
@@ -42,7 +42,7 @@ module RgGen
42
42
  factories =
43
43
  @entries
44
44
  .map(&:build_factory)
45
- .map { |f| [f.layer, f] }.to_h
45
+ .to_h { |f| [f.layer, f] }
46
46
  factories.each_value { |f| f.component_factories factories }
47
47
  factories.values
48
48
  end
@@ -12,11 +12,11 @@ module RgGen
12
12
  end
13
13
 
14
14
  def define_simple_feature(name, context = nil, &body)
15
- create_new_entry(:simple, name, context, body)
15
+ create_new_entry(:simple, name, context, &body)
16
16
  end
17
17
 
18
18
  def define_list_feature(list_name, context = nil, &body)
19
- create_new_entry(:list, list_name, context, body)
19
+ create_new_entry(:list, list_name, context, &body)
20
20
  end
21
21
 
22
22
  def define_list_item_feature(list_name, feature_name, context = nil, &body)
@@ -88,10 +88,9 @@ module RgGen
88
88
  end
89
89
 
90
90
  def build_factories
91
- @enabled_features
92
- .select { |n, _| @feature_entries.key?(n) }
93
- .map { |n, f| [n, @feature_entries[n].build_factory(f)] }
94
- .to_h
91
+ @feature_entries
92
+ .slice(*@enabled_features.keys)
93
+ .transform_values(&method(:build_factory))
95
94
  end
96
95
 
97
96
  private
@@ -100,9 +99,9 @@ module RgGen
100
99
  simple: SimpleFeatureEntry, list: ListFeatureEntry
101
100
  }.freeze
102
101
 
103
- def create_new_entry(type, name, context, body)
102
+ def create_new_entry(type, name, context, &body)
104
103
  entry = FEATURE_ENTRIES[type].new(self, name)
105
- entry.setup(@base_feature, @factory, context, body)
104
+ entry.setup(@base_feature, @factory, context, &body)
106
105
  @feature_entries[name] = entry
107
106
  end
108
107
 
@@ -117,6 +116,10 @@ module RgGen
117
116
  .feature?(feature_name)
118
117
  @enabled_features[list_name].include?(feature_name)
119
118
  end
119
+
120
+ def build_factory(entry)
121
+ entry.build_factory(@enabled_features[entry.name])
122
+ end
120
123
  end
121
124
  end
122
125
  end
@@ -15,11 +15,11 @@ module RgGen
15
15
  attr_reader :registry
16
16
  attr_reader :name
17
17
 
18
- def setup(base_feature, base_factory, context, body)
18
+ def setup(base_feature, base_factory, context, &body)
19
19
  @base_feature = Class.new(base_feature)
20
20
  @factory = Class.new(base_factory)
21
21
  context && attach_shared_context(context)
22
- body && Docile.dsl_eval(self, @name, &body)
22
+ block_given? && Docile.dsl_eval(self, @name, &body)
23
23
  end
24
24
 
25
25
  def match_entry_type?(entry_type)
@@ -49,9 +49,8 @@ module RgGen
49
49
  @features[feature_name] ||= Class.new(@base_feature)
50
50
  feature = @features[feature_name]
51
51
  if context
52
- feature.method_defined?(:shared_context) && (
53
- raise BuilderError.new('shared context has already been set')
54
- )
52
+ feature.method_defined?(:shared_context) &&
53
+ (raise BuilderError.new('shared context has already been set'))
55
54
  feature.attach_context(context)
56
55
  end
57
56
  body && feature.class_exec(feature_name, &body)
@@ -87,10 +86,7 @@ module RgGen
87
86
  end
88
87
 
89
88
  def target_features(enabled_features)
90
- enabled_features
91
- .select { |n| @features.key?(n) }
92
- .map { |n| [n, @features[n]] }
93
- .to_h
89
+ @features.slice(*enabled_features)
94
90
  end
95
91
  end
96
92
  end
@@ -19,8 +19,7 @@ module RgGen
19
19
  end
20
20
 
21
21
  def define_value_extractor(layers, value, &body)
22
- @extractors <<
23
- create_extractor(layers, value, &body)
22
+ @extractors << create_extractor(layers, value, &body)
24
23
  end
25
24
 
26
25
  def ignore_value(layers, value)
@@ -22,26 +22,80 @@ module RgGen
22
22
  end
23
23
  end
24
24
 
25
+ class PluginInfo
26
+ attr_reader :name
27
+ attr_reader :setup_path
28
+ attr_reader :gem_name
29
+ attr_reader :version
30
+
31
+ def parse(setup_path_or_name, version)
32
+ setup_path_or_name = setup_path_or_name.to_s.strip
33
+ @name, @setup_path, @gem_name, @version =
34
+ if setup_file_directly_given?(setup_path_or_name)
35
+ [nil, setup_path_or_name, *find_plugin_gem(setup_path_or_name)]
36
+ else
37
+ [
38
+ setup_path_or_name, get_setup_path(setup_path_or_name),
39
+ extract_gem_name(setup_path_or_name), version
40
+ ]
41
+ end
42
+ self
43
+ end
44
+
45
+ def to_s
46
+ if name && version
47
+ "#{name} (#{version})"
48
+ elsif name
49
+ name
50
+ else
51
+ setup_path
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def setup_file_directly_given?(setup_path_or_name)
58
+ File.ext(setup_path_or_name) == 'rb' ||
59
+ File.basename(setup_path_or_name, '.*') == 'setup'
60
+ end
61
+
62
+ def find_plugin_gem(setup_path)
63
+ gemspec =
64
+ Gem::Specification
65
+ .each.find { |spec| match_gemspec?(spec, setup_path) }
66
+ gemspec && [gemspec.name, gemspec.version]
67
+ end
68
+
69
+ def match_gemspec?(gemspec, setup_path)
70
+ gemspec.full_require_paths.any?(&setup_path.method(:start_with?))
71
+ end
72
+
73
+ def extract_gem_name(plugin_name)
74
+ plugin_name.split('/', 2).first
75
+ end
76
+
77
+ def get_setup_path(plugin_name)
78
+ base, sub_directory = plugin_name.split('/', 2)
79
+ base = base.sub(/^rggen[-_]/, '').tr('-', '_')
80
+ File.join(*['rggen', base, sub_directory, 'setup'].compact)
81
+ end
82
+ end
83
+
25
84
  class PluginManager
26
85
  def initialize(builder)
27
86
  @builder = builder
28
87
  @plugins = []
29
88
  end
30
89
 
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)
90
+ def load_plugin(setup_path_or_name, version = nil)
91
+ info = PluginInfo.new.parse(setup_path_or_name, version)
92
+ read_setup_file(info)
40
93
  end
41
94
 
42
95
  def load_plugins(plugins, no_default_plugins, activation = true)
43
96
  RgGen.builder(@builder)
44
- merge_plugins(plugins, no_default_plugins).each(&method(:load_plugin))
97
+ merge_plugins(plugins, no_default_plugins)
98
+ .each { |plugin| load_plugin(*plugin) }
45
99
  activation && activate_plugins
46
100
  end
47
101
 
@@ -64,27 +118,11 @@ module RgGen
64
118
 
65
119
  private
66
120
 
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
121
+ def read_setup_file(info)
122
+ info.gem_name && gem(info.gem_name, info.version)
123
+ require info.setup_path
80
124
  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)
125
+ raise Core::PluginError.new("cannot load such plugin: #{info}")
88
126
  end
89
127
 
90
128
  def merge_plugins(plugins, no_default_plugins)
@@ -110,7 +148,9 @@ module RgGen
110
148
 
111
149
  def plugins_from_env
112
150
  ENV['RGGEN_PLUGINS']
113
- &.split(':')&.map(&:strip)&.reject(&:empty?)
151
+ &.split(':')
152
+ &.reject(&:blank?)
153
+ &.map { |entry| entry.split(',', 2) }
114
154
  end
115
155
 
116
156
  def plugin?(plugin_module)
@@ -12,8 +12,8 @@ module RgGen
12
12
  attr_reader :registry
13
13
  attr_reader :name
14
14
 
15
- def setup(base_feature, factory, context, body)
16
- @feature = define_feature(base_feature, context, body)
15
+ def setup(base_feature, factory, context, &body)
16
+ @feature = define_feature(base_feature, context, &body)
17
17
  @factory = factory
18
18
  end
19
19
 
@@ -27,10 +27,10 @@ module RgGen
27
27
 
28
28
  private
29
29
 
30
- def define_feature(base, context, body)
30
+ def define_feature(base, context, &body)
31
31
  feature = Class.new(base)
32
32
  context && feature.attach_context(context)
33
- body && feature.class_exec(@name, &body)
33
+ block_given? && feature.class_exec(@name, &body)
34
34
  feature
35
35
  end
36
36
  end
@@ -2,10 +2,10 @@
2
2
 
3
3
  class Object
4
4
  def export_instance_variable(variable, to)
5
- return unless instance_variable_defined?(variable)
6
- v = instance_variable_get(variable)
7
- v = yield(v) if block_given?
8
- to.instance_variable_set(variable, v)
5
+ instance_variable_defined?(variable) &&
6
+ instance_variable_get(variable)
7
+ .yield_self { |v| block_given? ? yield(v) : v }
8
+ .yield_self { |v| to.instance_variable_set(variable, v) }
9
9
  end
10
10
 
11
11
  def singleton_exec(*args, &block)
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'facets/array/merge'
4
4
  require 'facets/file/ext'
5
+ require 'facets/hash/except' if RUBY_VERSION < '3.0.0'
6
+ require 'facets/kernel/blank'
5
7
  require 'facets/pathname/to_path'
6
8
  require 'facets/module/attr_setter'
7
9
  require 'facets/module/lastname'
@@ -9,10 +9,22 @@ module RgGen
9
9
  define_proxy_calls(feature, feature.properties)
10
10
  end
11
11
 
12
+ def document_only
13
+ @document_only = true
14
+ end
15
+
16
+ def document_only?
17
+ instance_variable_defined?(:@document_only) && @document_only
18
+ end
19
+
12
20
  def properties
13
21
  features.flat_map(&:properties)
14
22
  end
15
23
 
24
+ def post_build
25
+ features.each(&:post_build)
26
+ end
27
+
16
28
  def verify(scope)
17
29
  features.each { |feature| feature.verify(scope) }
18
30
  children.each { |child| child.verify(scope) } if scope == :all
@@ -79,6 +79,7 @@ module RgGen
79
79
  def post_build(component)
80
80
  exist_no_children?(component) &&
81
81
  raise_no_children_error(component)
82
+ component.post_build
82
83
  component.verify(:component)
83
84
  end
84
85
 
@@ -34,6 +34,13 @@ module RgGen
34
34
 
35
35
  attr_reader :builders
36
36
 
37
+ def post_build(&block)
38
+ @post_builders ||= []
39
+ @post_builders << block
40
+ end
41
+
42
+ attr_reader :post_builders
43
+
37
44
  def active_feature?
38
45
  !passive_feature?
39
46
  end
@@ -68,6 +75,7 @@ module RgGen
68
75
  export_instance_variable(:@properties, subclass, &:dup)
69
76
  export_instance_variable(:@ignore_empty_value, subclass)
70
77
  export_instance_variable(:@builders, subclass, &:dup)
78
+ export_instance_variable(:@post_builders, subclass, &:dup)
71
79
  export_instance_variable(:@input_matcher, subclass)
72
80
  export_instance_variable(:@printables, subclass, &:dup)
73
81
  export_verifiers(subclass) if @verifiers
@@ -95,6 +103,12 @@ module RgGen
95
103
  self.class.builders && do_build(args)
96
104
  end
97
105
 
106
+ def post_build
107
+ self.class.post_builders&.each do |post_builder|
108
+ instance_exec(&post_builder)
109
+ end
110
+ end
111
+
98
112
  def verify(scope)
99
113
  verified?(scope) || do_verify(scope)
100
114
  end
@@ -102,7 +116,7 @@ module RgGen
102
116
  def printables
103
117
  helper
104
118
  .printables
105
- &.map { |name, body| [name, printable(name, body)] }
119
+ &.map { |name, body| [name, printable(name, &body)] }
106
120
  end
107
121
 
108
122
  def printable?
@@ -119,10 +133,10 @@ module RgGen
119
133
 
120
134
  def do_build(args)
121
135
  @position = args.last.position
122
- args = [*args[0..-2], args.last.value]
123
- match_automatically? && match_pattern(args.last)
136
+ value = args.last.value
137
+ match_automatically? && match_pattern(value)
124
138
  Array(self.class.builders)
125
- .each { |builder| instance_exec(*args, &builder) }
139
+ .each { |builder| instance_exec(*args[0..-2], value, &builder) }
126
140
  end
127
141
 
128
142
  attr_reader :position
@@ -154,8 +168,8 @@ module RgGen
154
168
  (@verified ||= {})[scope] = true
155
169
  end
156
170
 
157
- def printable(name, body)
158
- body ? instance_exec(&body) : __send__(name)
171
+ def printable(name, &body)
172
+ block_given? ? instance_exec(&body) : __send__(name)
159
173
  end
160
174
  end
161
175
  end
@@ -17,14 +17,8 @@ module RgGen
17
17
 
18
18
  def value(value_name, value, position = nil)
19
19
  symbolized_name = value_name.to_sym
20
- return unless valid_value?(symbolized_name)
21
- @values[symbolized_name] =
22
- case value
23
- when InputValue
24
- value
25
- else
26
- InputValue.new(value, position)
27
- end
20
+ valid_value?(symbolized_name) &&
21
+ assign_value(symbolized_name, value, position)
28
22
  end
29
23
 
30
24
  def []=(value_name, position_or_value, value = nil)
@@ -44,16 +38,14 @@ module RgGen
44
38
 
45
39
  def child(layer, value_list = nil, &block)
46
40
  create_child_data(layer) do |child_data|
47
- child_data.build_by_block(block)
41
+ child_data.build_by_block(&block)
48
42
  child_data.values(value_list)
49
43
  @children << child_data
50
44
  end
51
45
  end
52
46
 
53
47
  def load_file(file)
54
- build_by_block(instance_eval(<<~BODY, file, 1))
55
- -> { #{File.binread(file)} } # -> { File.binread(file) }
56
- BODY
48
+ build_by_block { instance_eval(File.binread(file), file, 1) }
57
49
  end
58
50
 
59
51
  private
@@ -62,6 +54,16 @@ module RgGen
62
54
  @valid_value_lists[layer].include?(value_name)
63
55
  end
64
56
 
57
+ def assign_value(value_name, value, position)
58
+ @values[value_name] =
59
+ case value
60
+ when InputValue
61
+ value
62
+ else
63
+ InputValue.new(value, position)
64
+ end
65
+ end
66
+
65
67
  def define_setter_methods
66
68
  @valid_value_lists[layer].each(&method(:define_setter_method))
67
69
  end
@@ -73,8 +75,7 @@ module RgGen
73
75
  end
74
76
 
75
77
  def value_setter(value_name, value, position)
76
- position ||= position_from_caller
77
- value(value_name, value, position)
78
+ value(value_name, value, position || position_from_caller)
78
79
  end
79
80
 
80
81
  def position_from_caller
@@ -96,8 +97,8 @@ module RgGen
96
97
 
97
98
  protected
98
99
 
99
- def build_by_block(block)
100
- block && Docile.dsl_eval(self, &block)
100
+ def build_by_block(&block)
101
+ block_given? && Docile.dsl_eval(self, &block)
101
102
  end
102
103
  end
103
104
  end
@@ -11,9 +11,10 @@ module RgGen
11
11
  end
12
12
 
13
13
  def match(rhs)
14
- rhs = rhs.to_s
15
- rhs = delete_blanks(rhs) if ignore_blanks?
16
- match_patterns(rhs)
14
+ rhs
15
+ .to_s
16
+ .yield_self { |s| ignore_blanks? && delete_blanks(s) || s }
17
+ .yield_self(&method(:match_patterns))
17
18
  end
18
19
 
19
20
  def match_automatically?
@@ -64,8 +65,7 @@ module RgGen
64
65
  index, match_data =
65
66
  @patterns
66
67
  .transform_values { |pattern| pattern.match(rhs) }
67
- .compact
68
- .max_by { |_, m| m[0].length }
68
+ .max_by { |_, m| m && m[0].length || 0 }
69
69
  match_data && [convert_match_data(match_data), index]
70
70
  end
71
71
 
@@ -42,44 +42,42 @@ module RgGen
42
42
  end
43
43
 
44
44
  def format_sub_layer(read_data, input_data, layer, file)
45
- format_sub_layer_data(read_data, layer, file)
46
- &.flat_map { |sub_layer, data_array| [sub_layer].product(data_array) }
47
- &.each do |(sub_layer, data)|
48
- format(data, input_data.child(sub_layer), sub_layer, file)
49
- end
45
+ format_sub_layer_data(read_data, layer, file)&.each do |(sub_layer, data)|
46
+ format(data, input_data.child(sub_layer), sub_layer, file)
47
+ end
50
48
  end
51
49
 
52
50
  def format_layer_data(_read_data, _layer, _file)
53
51
  end
54
52
 
55
53
  def format_layer_data_by_extractors(read_data, layer)
56
- layer_data = {}
57
- valid_values(layer).each do |value|
58
- @extractors
59
- .select { |extractor| extractor.target_value?(layer, value) }
60
- .each do |extractor|
61
- extract_value(read_data, extractor, layer_data, value)
62
- end
63
- end
54
+ layer_data =
55
+ valid_values(layer)
56
+ .map { |value_name| extract_value(read_data, layer, value_name) }
57
+ .compact.to_h
64
58
  layer_data.empty? ? nil : layer_data
65
59
  end
66
60
 
67
- def extract_value(read_data, extractor, layer_data, value)
68
- data = extractor.extract(read_data)
69
- data && (layer_data[value] = data)
61
+ def extract_value(read_data, layer, value_name)
62
+ value =
63
+ @extractors
64
+ .select { |extractor| extractor.target_value?(layer, value_name) }
65
+ .map { |extractor| extractor.extract(read_data) }
66
+ .compact.last
67
+ value && [value_name, value]
70
68
  end
71
69
 
72
70
  def filter_layer_data(layer_data, layer)
73
- layer_data
74
- .select { |key, _| valid_values(layer).include?(key) }
71
+ layer_data.slice(*valid_values(layer))
75
72
  end
76
73
 
77
74
  def format_sub_layer_data(_read_data, _layer, _file)
78
75
  end
79
76
 
80
77
  def valid_values(layer)
81
- @valid_value_lists[layer]
82
- .reject { |value| @ignore_values[layer]&.include?(value) }
78
+ list = @valid_value_lists[layer]
79
+ ignore_values = @ignore_values[layer]
80
+ ignore_values && (list - ignore_values) || list
83
81
  end
84
82
  end
85
83
  end
@@ -5,13 +5,18 @@ module RgGen
5
5
  module InputBase
6
6
  class Property
7
7
  def self.define(feature, name, **options, &body)
8
- new(name, options, body).define(feature)
8
+ new(name, options, &body).define(feature)
9
9
  end
10
10
 
11
- def initialize(name, options, body)
11
+ def initialize(name, options, &body)
12
12
  @name = name
13
13
  @options = options
14
- @costom_property = create_costom_property(@options[:body] || body)
14
+ @costom_property =
15
+ if options[:body]
16
+ create_costom_property(&options[:body])
17
+ elsif block_given?
18
+ create_costom_property(&body)
19
+ end
15
20
  end
16
21
 
17
22
  attr_reader :name
@@ -19,15 +24,15 @@ module RgGen
19
24
  def define(feature)
20
25
  feature.class_exec(self) do |property|
21
26
  define_method(property.name) do |*args, &block|
22
- property.evaluate(self, args, block)
27
+ property.evaluate(self, args, &block)
23
28
  end
24
29
  end
25
30
  end
26
31
 
27
- def evaluate(feature, args, block)
32
+ def evaluate(feature, args, &block)
28
33
  feature.verify(@options[:verify]) if @options.key?(:verify)
29
34
  if proxy_property?
30
- proxy_property(feature, args, block)
35
+ proxy_property(feature, args, &block)
31
36
  else
32
37
  default_property(feature)
33
38
  end
@@ -35,7 +40,7 @@ module RgGen
35
40
 
36
41
  private
37
42
 
38
- def create_costom_property(body)
43
+ def create_costom_property(&body)
39
44
  body && Module.new.module_eval do
40
45
  define_method(:__costom_property__, &body)
41
46
  instance_method(:__costom_property__)
@@ -50,7 +55,7 @@ module RgGen
50
55
  ].any?
51
56
  end
52
57
 
53
- def proxy_property(feature, args, block)
58
+ def proxy_property(feature, args, &block)
54
59
  receiver, method =
55
60
  if @costom_property
56
61
  [@costom_property.bind(feature), :call]
@@ -63,7 +68,7 @@ module RgGen
63
68
  end
64
69
 
65
70
  def default_property(feature)
66
- varible_name = "@#{@name[-1] == '?' ? @name[0..-2] : @name}"
71
+ varible_name = "@#{@name.to_s.delete_suffix('?')}"
67
72
  if feature.instance_variable_defined?(varible_name)
68
73
  feature.instance_variable_get(varible_name)
69
74
  elsif @options.key?(:initial)
@@ -74,8 +79,9 @@ module RgGen
74
79
  end
75
80
 
76
81
  def set_initial_value(feature, varible_name)
77
- value = evaluate_default_initial_value(feature, @options[:initial])
78
- feature.instance_variable_set(varible_name, value)
82
+ @options[:initial]
83
+ .yield_self { |v| evaluate_default_initial_value(feature, v) }
84
+ .yield_self { |v| feature.instance_variable_set(varible_name, v) }
79
85
  end
80
86
 
81
87
  def evaluate_default_initial_value(feature, value)
@@ -6,43 +6,13 @@ module RgGen
6
6
  module YAMLLoader
7
7
  private
8
8
 
9
- if RUBY_VERSION >= '2.6.0'
10
- def yaml_safe_load(yaml, file)
11
- YAML.safe_load(
12
- yaml,
13
- permitted_classes: [Symbol], aliases: true, filename: file,
14
- symbolize_names: true
15
- )
16
- end
17
- elsif RUBY_VERSION >= '2.5.0'
18
- def yaml_safe_load(yaml, file)
19
- YAML.safe_load(yaml, [Symbol], [], true, file, symbolize_names: true)
20
- end
21
- else
22
- def yaml_safe_load(yaml, file)
23
- reuslt = YAML.safe_load(yaml, [Symbol], [], true, file)
24
- symbolize_keys(reuslt)
25
- end
26
-
27
- def symbolize_keys(result)
28
- case result
29
- when Hash then symbolize_hash(result)
30
- when Array then symbolize_array(result)
31
- else result
32
- end
33
- end
34
-
35
- def symbolize_hash(result)
36
- result.map { |key, value| [key.to_sym, symbolize_keys(value)] }.to_h
37
- end
38
-
39
- def symbolize_array(result)
40
- result.map(&method(:symbolize_keys))
41
- end
42
- end
43
-
44
9
  def load_yaml(file)
45
- yaml_safe_load(File.binread(file), file)
10
+ yaml = File.binread(file)
11
+ YAML.safe_load(
12
+ yaml,
13
+ permitted_classes: [Symbol], aliases: true,
14
+ filename: file, symbolize_names: true
15
+ )
46
16
  end
47
17
  end
48
18
  end
@@ -109,9 +109,9 @@ module RgGen
109
109
  end
110
110
 
111
111
  Options.add_option(:plugins) do |option|
112
- option.long_option '--plugin PLUGIN'
112
+ option.long_option '--plugin PLUGIN[:VERSION]'
113
113
  option.default { [] }
114
- option.action { |value, options| options[:plugins] << value }
114
+ option.action { |value, options| options[:plugins] << value.split(':', 2) }
115
115
  option.description 'Load a RgGen plugin ' \
116
116
  "(name of plugin/path to 'setup.rb' file)"
117
117
  end
@@ -4,14 +4,13 @@ module RgGen
4
4
  module Core
5
5
  module OutputBase
6
6
  class CodeGenerator
7
- def register(kind, block)
8
- return unless block
9
- code_blocks[kind] << block
7
+ def register(kind, &block)
8
+ block_given? && (code_blocks[kind] << block)
10
9
  end
11
10
 
12
11
  def generate(context, code, kind)
13
12
  code_blocks[kind].each do |block|
14
- execute_code_block(context, code, block)
13
+ execute_code_block(context, code, &block)
15
14
  end
16
15
  end
17
16
 
@@ -27,7 +26,7 @@ module RgGen
27
26
  @code_blocks ||= Hash.new { |blocks, kind| blocks[kind] = [] }
28
27
  end
29
28
 
30
- def execute_code_block(context, code, block)
29
+ def execute_code_block(context, code, &block)
31
30
  if block.arity.zero?
32
31
  code << context.instance_exec(&block)
33
32
  else
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module OutputBase
6
+ class DocumentComponentFactory < ComponentFactory
7
+ end
8
+ end
9
+ end
10
+ end
@@ -40,26 +40,30 @@ module RgGen
40
40
 
41
41
  [:pre_code, :main_code, :post_code].each do |phase|
42
42
  define_method(phase) do |kind, **options, &body|
43
- block =
44
- if options[:from_template]
45
- caller_location = caller_locations(1, 1).first
46
- template_path = extract_template_path(options)
47
- -> { process_template(template_path, caller_location) }
48
- else
49
- body
50
- end
51
- code_generators[__method__] ||= CodeGenerator.new
52
- code_generators[__method__].register(kind, block)
43
+ register_code_generator(__method__, kind, **options, &body)
53
44
  end
54
45
  end
55
46
 
47
+ def register_code_generator(phase, kind, **options, &body)
48
+ block =
49
+ if options[:from_template]
50
+ path = extract_template_path(options)
51
+ location = caller_locations(2, 1).first
52
+ -> { process_template(path, location) }
53
+ else
54
+ body
55
+ end
56
+ (code_generators[phase] ||= CodeGenerator.new)
57
+ .register(kind, &block)
58
+ end
59
+
56
60
  def extract_template_path(options)
57
61
  path = options[:from_template]
58
62
  path.equal?(true) ? nil : path
59
63
  end
60
64
 
61
65
  def write_file(file_name_pattern, &body)
62
- @file_writer = FileWriter.new(file_name_pattern, body)
66
+ @file_writer = FileWriter.new(file_name_pattern, &body)
63
67
  end
64
68
 
65
69
  def export(*methods)
@@ -4,7 +4,7 @@ module RgGen
4
4
  module Core
5
5
  module OutputBase
6
6
  class FileWriter
7
- def initialize(pattern, body)
7
+ def initialize(pattern, &body)
8
8
  @pattern = Erubi::Engine.new(pattern)
9
9
  @body = body
10
10
  end
@@ -32,7 +32,7 @@ module RgGen
32
32
 
33
33
  def create_directory(path)
34
34
  directory = path.dirname
35
- directory.directory? || directory.mkpath
35
+ directory.directory? || FileUtils.mkpath(directory)
36
36
  end
37
37
  end
38
38
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module OutputBase
6
+ class SourceFileComponentFactory < ComponentFactory
7
+ private
8
+
9
+ def create_component?(_, register_map)
10
+ !register_map.document_only?
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -11,15 +11,14 @@ module RgGen
11
11
  caller_location ||= caller_locations(1, 1).first
12
12
  path = File.ext(caller_location.path, file_extension.to_s)
13
13
  end
14
- render(context, templates[path])
14
+ render(context, template(path))
15
15
  end
16
16
 
17
17
  private
18
18
 
19
- def templates
20
- @templates ||= Hash.new do |templates, path|
21
- templates[path] = parse_template(path)
22
- end
19
+ def template(path)
20
+ @templates ||= {}
21
+ (@templates[path] ||= parse_template(path))
23
22
  end
24
23
  end
25
24
  end
@@ -29,14 +29,13 @@ module RgGen
29
29
  end
30
30
 
31
31
  def format_array_layer_data(read_data, layer, file)
32
- read_data.each_with_object({}) do |data, layer_data|
33
- layer_data.merge!(fomrat_hash_layer_data(data, layer, file))
34
- end
32
+ read_data
33
+ .map { |data| fomrat_hash_layer_data(data, layer, file) }
34
+ .inject(&:merge)
35
35
  end
36
36
 
37
37
  def fomrat_hash_layer_data(read_data, layer, file)
38
- convert_to_hash(read_data, file)
39
- .reject { |key, _| SUB_LAYER_KEYS[layer]&.include?(key) }
38
+ convert_to_hash(read_data, file).except(*SUB_LAYER_KEYS[layer])
40
39
  end
41
40
 
42
41
  def format_sub_layer_data(read_data, layer, file)
@@ -48,25 +47,24 @@ module RgGen
48
47
  end
49
48
 
50
49
  def format_array_sub_layer_data(read_data, layer, file)
51
- read_data.each_with_object({}) do |data, sub_layer_data|
50
+ read_data.each_with_object([]) do |data, sub_layer_data|
52
51
  format_hash_sub_layer_data(data, layer, file, sub_layer_data)
53
52
  end
54
53
  end
55
54
 
56
- def format_hash_sub_layer_data(read_data, layer, file, sub_layer_data = {})
55
+ def format_hash_sub_layer_data(read_data, layer, file, sub_layer_data = [])
57
56
  convert_to_hash(read_data, file)
58
- .select { |key, _| SUB_LAYER_KEYS[layer]&.include?(key) }
59
- .each do |key, value|
60
- merge_sub_layer_data(sub_layer_data, layer, key, value)
61
- end
57
+ .slice(*SUB_LAYER_KEYS[layer])
58
+ .each { |k, v| merge_sub_layer_data(sub_layer_data, layer, k, v) }
62
59
  sub_layer_data
63
60
  end
64
61
 
65
62
  def merge_sub_layer_data(sub_layer_data, layer, key, value)
66
63
  if SUB_LAYER_KEY_MAP[layer].key?(key)
67
- (sub_layer_data[SUB_LAYER_KEY_MAP[layer][key]] ||= []).concat(value)
64
+ sub_layer_data
65
+ .concat([SUB_LAYER_KEY_MAP[layer][key]].product(value))
68
66
  else
69
- (sub_layer_data[key] ||= []) << value
67
+ sub_layer_data << [key, value]
70
68
  end
71
69
  end
72
70
 
@@ -15,11 +15,13 @@ module RgGen
15
15
  attr_reader :indent
16
16
 
17
17
  def <<(rhs)
18
- return push_string(rhs) if rhs.is_a?(String)
19
- return push_code_block(rhs) if rhs.is_a?(CodeBlock)
20
- return rhs.inject(self, :<<) if rhs.is_a?(Array)
21
- return self << rhs.to_code if rhs.respond_to?(:to_code)
22
- push_word(rhs)
18
+ case rhs
19
+ when String then push_string(rhs)
20
+ when CodeBlock then push_code_block(rhs)
21
+ when Array then rhs.inject(self, :<<)
22
+ when code? then self << rhs.to_code
23
+ else push_word(rhs)
24
+ end
23
25
  end
24
26
 
25
27
  def indent=(indent)
@@ -74,6 +76,10 @@ module RgGen
74
76
  self
75
77
  end
76
78
 
79
+ def code?
80
+ ->(rhs) { rhs.respond_to?(:to_code) }
81
+ end
82
+
77
83
  def newline
78
84
  "\n"
79
85
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module RgGen
4
4
  module Core
5
- VERSION = '0.24.0'
5
+ VERSION = '0.26.0'
6
6
  MAJOR, MINOR, PATCH = VERSION.split('.').map(&:to_i)
7
7
  end
8
8
  end
data/lib/rggen/core.rb CHANGED
@@ -27,7 +27,6 @@ require_relative 'core/utility/regexp_patterns'
27
27
 
28
28
  require_relative 'core/exceptions'
29
29
 
30
- require_relative 'core/base/proxy_call'
31
30
  require_relative 'core/base/internal_struct'
32
31
  require_relative 'core/base/shared_context'
33
32
  require_relative 'core/base/component'
@@ -87,6 +86,8 @@ require_relative 'core/output_base/file_writer'
87
86
  require_relative 'core/output_base/raise_error'
88
87
  require_relative 'core/output_base/component'
89
88
  require_relative 'core/output_base/component_factory'
89
+ require_relative 'core/output_base/source_file_component_factory'
90
+ require_relative 'core/output_base/document_component_factory'
90
91
  require_relative 'core/output_base/feature'
91
92
  require_relative 'core/output_base/feature_factory'
92
93
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rggen-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.24.0
4
+ version: 0.26.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Taichi Ishitani
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-01-20 00:00:00.000000000 Z
11
+ date: 2022-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: docile
@@ -106,7 +106,6 @@ files:
106
106
  - lib/rggen/core/base/feature_factory.rb
107
107
  - lib/rggen/core/base/feature_layer_extension.rb
108
108
  - lib/rggen/core/base/internal_struct.rb
109
- - lib/rggen/core/base/proxy_call.rb
110
109
  - lib/rggen/core/base/shared_context.rb
111
110
  - lib/rggen/core/builder.rb
112
111
  - lib/rggen/core/builder/builder.rb
@@ -158,11 +157,13 @@ files:
158
157
  - lib/rggen/core/output_base/code_generator.rb
159
158
  - lib/rggen/core/output_base/component.rb
160
159
  - lib/rggen/core/output_base/component_factory.rb
160
+ - lib/rggen/core/output_base/document_component_factory.rb
161
161
  - lib/rggen/core/output_base/erb_engine.rb
162
162
  - lib/rggen/core/output_base/feature.rb
163
163
  - lib/rggen/core/output_base/feature_factory.rb
164
164
  - lib/rggen/core/output_base/file_writer.rb
165
165
  - lib/rggen/core/output_base/raise_error.rb
166
+ - lib/rggen/core/output_base/source_file_component_factory.rb
166
167
  - lib/rggen/core/output_base/template_engine.rb
167
168
  - lib/rggen/core/plugin.rb
168
169
  - lib/rggen/core/printers.rb
@@ -194,6 +195,7 @@ licenses:
194
195
  metadata:
195
196
  bug_tracker_uri: https://github.com/rggen/rggen-core/issues
196
197
  mailing_list_uri: https://groups.google.com/d/forum/rggen
198
+ rubygems_mfa_required: 'true'
197
199
  source_code_uri: https://github.com/rggen/rggen-core
198
200
  wiki_uri: https://github.com/rggen/rggen/wiki
199
201
  post_install_message:
@@ -204,15 +206,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
204
206
  requirements:
205
207
  - - ">="
206
208
  - !ruby/object:Gem::Version
207
- version: '2.4'
209
+ version: '2.6'
208
210
  required_rubygems_version: !ruby/object:Gem::Requirement
209
211
  requirements:
210
212
  - - ">="
211
213
  - !ruby/object:Gem::Version
212
214
  version: '0'
213
215
  requirements: []
214
- rubygems_version: 3.2.3
216
+ rubygems_version: 3.3.3
215
217
  signing_key:
216
218
  specification_version: 4
217
- summary: rggen-core-0.24.0
219
+ summary: rggen-core-0.26.0
218
220
  test_files: []
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RgGen
4
- module Core
5
- module Base
6
- class ProxyCall
7
- def initialize(receiver, method)
8
- @receiver = receiver
9
- @method = method
10
- end
11
-
12
- def call(*args, &block)
13
- @receiver.__send__(@method, *args, &block)
14
- end
15
- end
16
- end
17
- end
18
- end