rggen-core 0.9.0

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