rggen-core 0.24.0 → 0.26.0

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