rggen-core 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +46 -0
  3. data/LICENSE +21 -0
  4. data/README.md +46 -0
  5. data/exe/rggen +13 -0
  6. data/lib/rggen/core.rb +101 -0
  7. data/lib/rggen/core/base/component.rb +54 -0
  8. data/lib/rggen/core/base/component_factory.rb +84 -0
  9. data/lib/rggen/core/base/feature.rb +46 -0
  10. data/lib/rggen/core/base/feature_factory.rb +37 -0
  11. data/lib/rggen/core/base/hierarchical_accessors.rb +91 -0
  12. data/lib/rggen/core/base/hierarchical_feature_accessors.rb +83 -0
  13. data/lib/rggen/core/base/internal_struct.rb +21 -0
  14. data/lib/rggen/core/base/shared_context.rb +18 -0
  15. data/lib/rggen/core/builder.rb +13 -0
  16. data/lib/rggen/core/builder/builder.rb +150 -0
  17. data/lib/rggen/core/builder/category.rb +116 -0
  18. data/lib/rggen/core/builder/component_entry.rb +29 -0
  19. data/lib/rggen/core/builder/component_registry.rb +47 -0
  20. data/lib/rggen/core/builder/feature_registry.rb +126 -0
  21. data/lib/rggen/core/builder/input_component_registry.rb +35 -0
  22. data/lib/rggen/core/builder/list_feature_entry.rb +98 -0
  23. data/lib/rggen/core/builder/output_component_registry.rb +10 -0
  24. data/lib/rggen/core/builder/simple_feature_entry.rb +39 -0
  25. data/lib/rggen/core/cli.rb +29 -0
  26. data/lib/rggen/core/configuration.rb +19 -0
  27. data/lib/rggen/core/configuration/component.rb +10 -0
  28. data/lib/rggen/core/configuration/component_factory.rb +19 -0
  29. data/lib/rggen/core/configuration/error.rb +16 -0
  30. data/lib/rggen/core/configuration/feature.rb +13 -0
  31. data/lib/rggen/core/configuration/feature_factory.rb +11 -0
  32. data/lib/rggen/core/configuration/hash_loader.rb +15 -0
  33. data/lib/rggen/core/configuration/json_loader.rb +18 -0
  34. data/lib/rggen/core/configuration/loader.rb +11 -0
  35. data/lib/rggen/core/configuration/ruby_loader.rb +15 -0
  36. data/lib/rggen/core/configuration/yaml_loader.rb +18 -0
  37. data/lib/rggen/core/core_extensions/casecmp.rb +12 -0
  38. data/lib/rggen/core/core_extensions/forwardable.rb +12 -0
  39. data/lib/rggen/core/core_extensions/forwardable_workaround.rb +22 -0
  40. data/lib/rggen/core/core_extensions/object.rb +14 -0
  41. data/lib/rggen/core/dsl.rb +30 -0
  42. data/lib/rggen/core/exceptions.rb +29 -0
  43. data/lib/rggen/core/facets.rb +7 -0
  44. data/lib/rggen/core/generator.rb +51 -0
  45. data/lib/rggen/core/input_base/component.rb +30 -0
  46. data/lib/rggen/core/input_base/component_factory.rb +88 -0
  47. data/lib/rggen/core/input_base/feature.rb +130 -0
  48. data/lib/rggen/core/input_base/feature_factory.rb +80 -0
  49. data/lib/rggen/core/input_base/input_data.rb +98 -0
  50. data/lib/rggen/core/input_base/input_matcher.rb +79 -0
  51. data/lib/rggen/core/input_base/input_value.rb +34 -0
  52. data/lib/rggen/core/input_base/json_loader.rb +16 -0
  53. data/lib/rggen/core/input_base/loader.rb +44 -0
  54. data/lib/rggen/core/input_base/property.rb +76 -0
  55. data/lib/rggen/core/input_base/verifier.rb +41 -0
  56. data/lib/rggen/core/input_base/yaml_loader.rb +34 -0
  57. data/lib/rggen/core/options.rb +181 -0
  58. data/lib/rggen/core/output_base/code_generator.rb +59 -0
  59. data/lib/rggen/core/output_base/component.rb +100 -0
  60. data/lib/rggen/core/output_base/component_factory.rb +35 -0
  61. data/lib/rggen/core/output_base/erb_engine.rb +21 -0
  62. data/lib/rggen/core/output_base/feature.rb +147 -0
  63. data/lib/rggen/core/output_base/feature_factory.rb +13 -0
  64. data/lib/rggen/core/output_base/file_writer.rb +40 -0
  65. data/lib/rggen/core/output_base/template_engine.rb +27 -0
  66. data/lib/rggen/core/printers.rb +53 -0
  67. data/lib/rggen/core/register_map.rb +21 -0
  68. data/lib/rggen/core/register_map/component.rb +20 -0
  69. data/lib/rggen/core/register_map/component_factory.rb +19 -0
  70. data/lib/rggen/core/register_map/error.rb +16 -0
  71. data/lib/rggen/core/register_map/feature.rb +22 -0
  72. data/lib/rggen/core/register_map/feature_factory.rb +11 -0
  73. data/lib/rggen/core/register_map/hash_loader.rb +47 -0
  74. data/lib/rggen/core/register_map/input_data.rb +34 -0
  75. data/lib/rggen/core/register_map/json_loader.rb +18 -0
  76. data/lib/rggen/core/register_map/loader.rb +15 -0
  77. data/lib/rggen/core/register_map/ruby_loader.rb +15 -0
  78. data/lib/rggen/core/register_map/yaml_loader.rb +18 -0
  79. data/lib/rggen/core/utility/attribute_setter.rb +53 -0
  80. data/lib/rggen/core/utility/code_utility.rb +64 -0
  81. data/lib/rggen/core/utility/code_utility/code_block.rb +88 -0
  82. data/lib/rggen/core/utility/code_utility/line.rb +51 -0
  83. data/lib/rggen/core/utility/code_utility/source_file.rb +104 -0
  84. data/lib/rggen/core/utility/code_utility/structure_definition.rb +54 -0
  85. data/lib/rggen/core/utility/regexp_patterns.rb +38 -0
  86. data/lib/rggen/core/version.rb +10 -0
  87. metadata +188 -0
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ class ComponentFactory < InputBase::ComponentFactory
7
+ private
8
+
9
+ def create_component(*_, &block)
10
+ @target_component.new(&block)
11
+ end
12
+
13
+ def create_input_data(&block)
14
+ InputBase::InputData.new(valid_value_lists, &block)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ class ConfigurationError < Core::RuntimeError
7
+ end
8
+
9
+ module RaiseError
10
+ def error(message, position = nil)
11
+ raise ConfigurationError.new(message, position || @position)
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ class Feature < InputBase::Feature
7
+ include RaiseError
8
+
9
+ alias_method :configuration, :component
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ class FeatureFactory < InputBase::FeatureFactory
7
+ include RaiseError
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ module HashLoader
7
+ def format(read_data, file)
8
+ input_data.values(Hash(read_data), file)
9
+ rescue TypeError => e
10
+ raise Core::LoadError.new(e.message, file)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ class JSONLoader < Loader
7
+ include HashLoader
8
+ include InputBase::JSONLoader
9
+
10
+ support_types [:json]
11
+
12
+ def read_file(file)
13
+ load_json(file)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ class Loader < InputBase::Loader
7
+ include RaiseError
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ class RubyLoader < Loader
7
+ support_types [:rb]
8
+
9
+ def read_file(file)
10
+ input_data.load_file(file)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module Configuration
6
+ class YAMLLoader < Loader
7
+ include HashLoader
8
+ include InputBase::YAMLLoader
9
+
10
+ support_types [:yaml, :yml]
11
+
12
+ def read_file(file)
13
+ load_yaml(file)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ if RUBY_VERSION < '2.4'
4
+ casecmp = Module.new do
5
+ def casecmp?(other)
6
+ casecmp(other).zero?
7
+ end
8
+ end
9
+
10
+ String.send(:include, casecmp)
11
+ Symbol.send(:include, casecmp)
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Forwardable
4
+ def delegate_to_class(method_or_methods)
5
+ Array(method_or_methods)
6
+ .each { |m| def_instance_delegator(:'self.class', m) }
7
+ end
8
+ end
9
+
10
+ if ['2.3.1', '2.3.2', '2.3.3'].include?(RUBY_VERSION)
11
+ require_relative 'forwardable_workaround'
12
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SingleForwardable
4
+ # https://bugs.ruby-lang.org/issues/12478
5
+ def def_single_delegator(accessor, method, ali = method)
6
+ accessor = accessor.to_s
7
+ if method_defined?(accessor) || private_method_defined?(accessor)
8
+ accessor = "#{accessor}()"
9
+ end if self.class === Module
10
+ line_no = __LINE__; str = %{
11
+ def #{ali}(*args, &block)
12
+ begin
13
+ #{accessor}.__send__(:#{method}, *args, &block)
14
+ rescue ::Exception
15
+ $@.delete_if{|s| ::Forwardable::FILE_REGEXP =~ s} unless ::Forwardable::debug
16
+ ::Kernel::raise
17
+ end
18
+ end
19
+ }
20
+ instance_eval(str, __FILE__, line_no)
21
+ end
22
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Object
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)
9
+ end
10
+
11
+ def singleton_exec(*args, &block)
12
+ singleton_class.class_exec(*args, &block)
13
+ end
14
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module DSL
6
+ extend Forwardable
7
+
8
+ attr_setter :builder
9
+
10
+ [
11
+ :input_component_registry,
12
+ :output_component_registry,
13
+ :register_loader,
14
+ :define_loader,
15
+ :define_simple_feature,
16
+ :define_list_feature,
17
+ :define_list_item_feature,
18
+ :enable,
19
+ :disable_all,
20
+ :disable,
21
+ :delete,
22
+ :setup
23
+ ].each do |method_name|
24
+ def_delegator :'RgGen.builder', method_name
25
+ end
26
+ end
27
+ end
28
+
29
+ extend Core::DSL
30
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ class RgGenError < StandardError
6
+ def initialize(message, additional_info = nil)
7
+ super(message)
8
+ @error_message = message
9
+ @additional_info = additional_info
10
+ end
11
+
12
+ attr_reader :error_message
13
+ attr_reader :additional_info
14
+
15
+ def to_s
16
+ additional_info ? "#{super} -- #{additional_info}" : super
17
+ end
18
+ end
19
+
20
+ class BuilderError < RgGenError
21
+ end
22
+
23
+ class RuntimeError < RgGenError
24
+ end
25
+
26
+ class LoadError < Core::RuntimeError
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'facets/array/merge'
4
+ require 'facets/file/ext'
5
+ require 'facets/hash/at'
6
+ require 'facets/pathname/to_path'
7
+ require 'facets/module/attr_setter'
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ class Generator
6
+ def run(builder, options)
7
+ load_setup_file(builder, options[:setup])
8
+ load_configuration(builder, options[:configuration])
9
+ load_register_map(builder, options.register_map_files)
10
+ write_files(builder, options)
11
+ end
12
+
13
+ private
14
+
15
+ attr_reader :configuration
16
+ attr_reader :register_map
17
+
18
+ def load_setup_file(builder, file)
19
+ builder.load_setup_file(file)
20
+ end
21
+
22
+ def load_configuration(builder, file)
23
+ @configuration =
24
+ builder
25
+ .build_factory(:input, :configuration)
26
+ .create(Array(file))
27
+ end
28
+
29
+ def load_register_map(builder, files)
30
+ files.empty? &&
31
+ (raise Core::LoadError.new('no register map files are given'))
32
+ @register_map =
33
+ builder
34
+ .build_factory(:input, :register_map)
35
+ .create(configuration, files)
36
+ end
37
+
38
+ def write_files(builder, options)
39
+ options[:load_only] ||
40
+ file_writers(builder, options[:enable])
41
+ .each { |writer| writer.write_file(options[:output]) }
42
+ end
43
+
44
+ def file_writers(builder, targets)
45
+ builder
46
+ .build_factories(:output, targets)
47
+ .map { |factory| factory.create(configuration, register_map) }
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module InputBase
6
+ class Component < Base::Component
7
+ def add_feature(feature)
8
+ super
9
+ define_property_methods(feature)
10
+ end
11
+
12
+ def properties
13
+ @features.each_value.flat_map(&:properties)
14
+ end
15
+
16
+ def verify(scope)
17
+ @features.each_value { |feature| feature.verify(scope) }
18
+ @children.each { |child| child.verify(scope) } if scope == :all
19
+ end
20
+
21
+ private
22
+
23
+ def define_property_methods(feature)
24
+ target = "@features[:#{feature.feature_name}]"
25
+ def_delegators(target, *feature.properties)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RgGen
4
+ module Core
5
+ module InputBase
6
+ class ComponentFactory < Base::ComponentFactory
7
+ attr_setter :loaders
8
+
9
+ private
10
+
11
+ def preprocess(args)
12
+ if root_factory?
13
+ [*args[0..-2], load_files(args.last)]
14
+ else
15
+ args
16
+ end
17
+ end
18
+
19
+ def load_files(files)
20
+ create_input_data do |input_data|
21
+ files.each { |file| load_file(file, input_data) }
22
+ end
23
+ end
24
+
25
+ def load_file(file, input_data)
26
+ find_loader(file).load_file(file, input_data, valid_value_lists)
27
+ end
28
+
29
+ def find_loader(file)
30
+ loader = loaders.find { |l| l.support?(file) }
31
+ loader || (raise Core::LoadError.new('unsupported file type', file))
32
+ end
33
+
34
+ def create_input_data(&block)
35
+ end
36
+
37
+ def create_features(component, *sources)
38
+ create_active_features(component, sources.last)
39
+ create_passive_features(component)
40
+ end
41
+
42
+ def create_active_features(component, input_data)
43
+ active_feature_factories.each do |name, factory|
44
+ create_feature(component, factory, input_data[name])
45
+ end
46
+ end
47
+
48
+ def create_passive_features(component)
49
+ passive_feature_factories.each_value do |factory|
50
+ create_feature(component, factory)
51
+ end
52
+ end
53
+
54
+ def create_children(component, *sources)
55
+ sources.last.children.each do |child_data|
56
+ create_child(component, *sources[0..-2], child_data)
57
+ end
58
+ end
59
+
60
+ def post_build(component)
61
+ component.verify(:component)
62
+ end
63
+
64
+ def finalize(component)
65
+ component.verify(:all)
66
+ end
67
+
68
+ def active_feature_factories
69
+ @active_feature_factories ||=
70
+ @feature_factories&.select { |_, f| f.active_feature_factory? }
71
+ end
72
+
73
+ def passive_feature_factories
74
+ @passive_feature_factories ||=
75
+ @feature_factories&.select { |_, f| f.passive_feature_factory? }
76
+ end
77
+
78
+ protected
79
+
80
+ def valid_value_lists
81
+ list = [Array(active_feature_factories&.keys)]
82
+ list.concat(Array(child_factory&.valid_value_lists))
83
+ list
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end