rggen-core 0.22.0 → 0.25.1

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +2 -1
  4. data/exe/rggen +2 -2
  5. data/lib/rggen/core.rb +8 -1
  6. data/lib/rggen/core/base/component.rb +5 -6
  7. data/lib/rggen/core/base/component_factory.rb +8 -5
  8. data/lib/rggen/core/builder/builder.rb +23 -17
  9. data/lib/rggen/core/builder/component_registry.rb +8 -9
  10. data/lib/rggen/core/builder/feature_registry.rb +15 -15
  11. data/lib/rggen/core/builder/layer.rb +44 -29
  12. data/lib/rggen/core/builder/list_feature_entry.rb +5 -9
  13. data/lib/rggen/core/builder/loader_registry.rb +1 -2
  14. data/lib/rggen/core/builder/plugin_manager.rb +38 -43
  15. data/lib/rggen/core/builder/plugin_spec.rb +83 -0
  16. data/lib/rggen/core/builder/simple_feature_entry.rb +4 -4
  17. data/lib/rggen/core/configuration.rb +3 -2
  18. data/lib/rggen/core/configuration/toml_loader.rb +18 -0
  19. data/lib/rggen/core/core_extensions/object.rb +4 -4
  20. data/lib/rggen/core/dsl.rb +1 -1
  21. data/lib/rggen/core/exceptions.rb +6 -4
  22. data/lib/rggen/core/facets.rb +1 -1
  23. data/lib/rggen/core/input_base/component.rb +12 -0
  24. data/lib/rggen/core/input_base/component_factory.rb +1 -0
  25. data/lib/rggen/core/input_base/feature.rb +22 -8
  26. data/lib/rggen/core/input_base/input_data.rb +24 -17
  27. data/lib/rggen/core/input_base/input_matcher.rb +5 -5
  28. data/lib/rggen/core/input_base/loader.rb +15 -15
  29. data/lib/rggen/core/input_base/property.rb +17 -11
  30. data/lib/rggen/core/input_base/toml_loader.rb +16 -0
  31. data/lib/rggen/core/input_base/yaml_loader.rb +1 -18
  32. data/lib/rggen/core/options.rb +6 -0
  33. data/lib/rggen/core/output_base/code_generator.rb +5 -6
  34. data/lib/rggen/core/output_base/document_component_factory.rb +10 -0
  35. data/lib/rggen/core/output_base/feature.rb +15 -11
  36. data/lib/rggen/core/output_base/file_writer.rb +1 -1
  37. data/lib/rggen/core/output_base/source_file_component_factory.rb +15 -0
  38. data/lib/rggen/core/output_base/template_engine.rb +4 -5
  39. data/lib/rggen/core/plugin.rb +16 -0
  40. data/lib/rggen/core/register_map.rb +4 -5
  41. data/lib/rggen/core/register_map/hash_loader.rb +6 -9
  42. data/lib/rggen/core/register_map/toml_loader.rb +18 -0
  43. data/lib/rggen/core/utility/attribute_setter.rb +5 -0
  44. data/lib/rggen/core/utility/code_utility/code_block.rb +11 -5
  45. data/lib/rggen/core/utility/error_utility.rb +33 -6
  46. data/lib/rggen/core/version.rb +2 -4
  47. metadata +32 -6
  48. data/lib/rggen/core/base/proxy_call.rb +0 -18
@@ -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,16 @@ 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(
55
- instance_eval("-> { #{File.binread(file)} }", file, 1)
56
- )
48
+ build_by_block(&instance_eval(<<~BODY, file, 1))
49
+ -> { #{File.binread(file)} } # -> { File.binread(file) }
50
+ BODY
57
51
  end
58
52
 
59
53
  private
@@ -62,6 +56,16 @@ module RgGen
62
56
  @valid_value_lists[layer].include?(value_name)
63
57
  end
64
58
 
59
+ def assign_value(value_name, value, position)
60
+ @values[value_name] =
61
+ case value
62
+ when InputValue
63
+ value
64
+ else
65
+ InputValue.new(value, position)
66
+ end
67
+ end
68
+
65
69
  def define_setter_methods
66
70
  @valid_value_lists[layer].each(&method(:define_setter_method))
67
71
  end
@@ -73,13 +77,16 @@ module RgGen
73
77
  end
74
78
 
75
79
  def value_setter(value_name, value, position)
76
- position ||= position_from_caller
77
- value(value_name, value, position)
80
+ value(value_name, value, position || position_from_caller)
78
81
  end
79
82
 
80
83
  def position_from_caller
81
84
  locations = caller_locations(3, 2)
82
- locations[0].path.include?('docile') ? locations[1] : locations[0]
85
+ include_docile_path?(locations[0]) && locations[1] || locations[0]
86
+ end
87
+
88
+ def include_docile_path?(caller_location)
89
+ caller_location.path.include?('docile')
83
90
  end
84
91
 
85
92
  def create_child_data(layer, &block)
@@ -92,8 +99,8 @@ module RgGen
92
99
 
93
100
  protected
94
101
 
95
- def build_by_block(block)
96
- block && Docile.dsl_eval(self, &block)
102
+ def build_by_block(&block)
103
+ block_given? && Docile.dsl_eval(self, &block)
97
104
  end
98
105
  end
99
106
  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
 
@@ -53,33 +53,33 @@ module RgGen
53
53
  end
54
54
 
55
55
  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
56
+ layer_data =
57
+ valid_values(layer)
58
+ .map { |value_name| extract_value(read_data, layer, value_name) }
59
+ .compact.to_h
64
60
  layer_data.empty? ? nil : layer_data
65
61
  end
66
62
 
67
- def extract_value(read_data, extractor, layer_data, value)
68
- data = extractor.extract(read_data)
69
- data && (layer_data[value] = data)
63
+ def extract_value(read_data, layer, value_name)
64
+ value =
65
+ @extractors
66
+ .select { |extractor| extractor.target_value?(layer, value_name) }
67
+ .map { |extractor| extractor.extract(read_data) }
68
+ .compact.last
69
+ value && [value_name, value]
70
70
  end
71
71
 
72
72
  def filter_layer_data(layer_data, layer)
73
- layer_data
74
- .select { |key, _| valid_values(layer).include?(key) }
73
+ layer_data.slice(*valid_values(layer))
75
74
  end
76
75
 
77
76
  def format_sub_layer_data(_read_data, _layer, _file)
78
77
  end
79
78
 
80
79
  def valid_values(layer)
81
- @valid_value_lists[layer]
82
- .reject { |value| @ignore_values[layer]&.include?(value) }
80
+ list = @valid_value_lists[layer]
81
+ ignore_values = @ignore_values[layer]
82
+ ignore_values && (list - ignore_values) || list
83
83
  end
84
84
  end
85
85
  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)
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module InputBase
6
+ module TOMLLoader
7
+ private
8
+
9
+ def load_toml(file)
10
+ toml = File.binread(file)
11
+ Tomlrb.parse(toml, symbolize_keys: true)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -14,26 +14,9 @@ module RgGen
14
14
  symbolize_names: true
15
15
  )
16
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
17
  else
22
18
  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
- if result.is_a? Hash
29
- result.each_with_object({}) do |(key, value), hash|
30
- hash[key.to_sym] = symbolize_keys(value)
31
- end
32
- elsif result.is_a? Array
33
- result.map(&method(:symbolize_keys))
34
- else
35
- result
36
- end
19
+ YAML.safe_load(yaml, [Symbol], [], true, file, symbolize_names: true)
37
20
  end
38
21
  end
39
22
 
@@ -150,6 +150,12 @@ module RgGen
150
150
  end
151
151
  end
152
152
 
153
+ Options.add_option(:print_verbose_info) do |option|
154
+ option.long_option '--print-verbose-info'
155
+ option.default false
156
+ option.description 'Print verbose information when an error occurs'
157
+ end
158
+
153
159
  Options.add_option(:print_backtrace) do |option|
154
160
  option.long_option '--print-backtrace'
155
161
  option.default false
@@ -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,11 +26,11 @@ 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
34
- context .instance_exec(code, &block)
33
+ context.instance_exec(code, &block)
35
34
  end
36
35
  end
37
36
 
@@ -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
@@ -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
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Plugin
6
+ attr_reader :plugin_spec
7
+
8
+ private
9
+
10
+ def setup_plugin(name)
11
+ @plugin_spec = Builder::PluginSpec.new(name, self)
12
+ block_given? && yield(@plugin_spec)
13
+ end
14
+ end
15
+ end
16
+ end