rdm 0.4.14.2 → 0.4.17

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 (63) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile.lock +26 -19
  3. data/bin/rdm +10 -10
  4. data/example/Rdm.packages +1 -17
  5. data/example/config/app.yml +6 -0
  6. data/example/infrastructure/repository/Package.rb +0 -1
  7. data/example/infrastructure/repository/fixture.txt +1 -0
  8. data/lib/rdm.rb +14 -7
  9. data/lib/rdm/errors.rb +3 -0
  10. data/lib/rdm/gen/init.rb +0 -4
  11. data/lib/rdm/package.rb +18 -9
  12. data/lib/rdm/package_importer.rb +4 -18
  13. data/lib/rdm/package_parser.rb +1 -0
  14. data/lib/rdm/packages/compiler_service.rb +1 -7
  15. data/lib/rdm/settings.rb +10 -21
  16. data/lib/rdm/source.rb +1 -18
  17. data/lib/rdm/source_parser.rb +2 -45
  18. data/lib/rdm/templates/init/Rdm.packages +0 -12
  19. data/lib/rdm/utils/ostruct_utils.rb +12 -0
  20. data/lib/rdm/version.rb +1 -1
  21. data/lib/rdm/yml_config/config_caster.rb +32 -0
  22. data/lib/rdm/yml_config/config_manager.rb +39 -0
  23. data/lib/rdm/yml_config/config_validator.rb +51 -0
  24. data/lib/rdm/yml_config/env_config.rb +46 -0
  25. data/lib/rdm/yml_config/env_config_dsl.rb +92 -0
  26. data/lib/rdm/yml_config/validate_config.rb +13 -0
  27. data/rdm.gemspec +3 -0
  28. data/spec/fixtures/SampleSource.rb +2 -4
  29. data/spec/fixtures/app.yml +17 -0
  30. data/spec/rdm/cli/gen_package_spec.rb +0 -2
  31. data/spec/rdm/gen/init_spec.rb +0 -12
  32. data/spec/rdm/gen/package_spec.rb +1 -0
  33. data/spec/rdm/package_importer_spec.rb +34 -2
  34. data/spec/rdm/rdm_spec.rb +1 -1
  35. data/spec/rdm/source_parser_spec.rb +0 -59
  36. data/spec/rdm/yml_config/config_caster_spec.rb +64 -0
  37. data/spec/rdm/yml_config/config_manager_spec.rb +7 -0
  38. data/spec/rdm/yml_config/config_validator_spec.rb +190 -0
  39. data/spec/rdm/yml_config/env_config_dsl_spec.rb +123 -0
  40. data/spec/spec_helper.rb +1 -0
  41. metadata +69 -34
  42. data/example/.rdm/templates/configs/<%=config_path%> +0 -2
  43. data/example/.rdm/templates/configs/<%=role_config_path%> +0 -2
  44. data/example/configs/app/default.yml +0 -2
  45. data/example/configs/app/production.yml +0 -2
  46. data/example/configs/database/default.yml +0 -3
  47. data/example/env_files/development.env +0 -3
  48. data/example/env_files/production.env +0 -5
  49. data/example/env_files/test.env +0 -3
  50. data/lib/rdm/cli/config.rb +0 -31
  51. data/lib/rdm/config.rb +0 -11
  52. data/lib/rdm/config_locals.rb +0 -11
  53. data/lib/rdm/config_manager.rb +0 -68
  54. data/lib/rdm/config_scope.rb +0 -23
  55. data/lib/rdm/gen/config.rb +0 -59
  56. data/lib/rdm/templates/configs/<%=config_path%> +0 -2
  57. data/lib/rdm/templates/configs/<%=role_config_path%> +0 -2
  58. data/lib/rdm/templates/init/env_files/development.env +0 -3
  59. data/lib/rdm/templates/init/env_files/production.env +0 -3
  60. data/lib/rdm/templates/init/env_files/test.env +0 -3
  61. data/spec/fixtures/config.yml +0 -2
  62. data/spec/rdm/config_manager_spec.rb +0 -136
  63. data/spec/rdm/gen/config_spec.rb +0 -31
@@ -2,33 +2,22 @@ class Rdm::Settings
2
2
  attr_reader :settings
3
3
 
4
4
  SETTING_KEYS = [
5
- :role, :package_subdir_name, :configs_dir, :config_path, :role_config_path,
5
+ :role, :package_subdir_name, :config_path,
6
6
  :silence_missing_package_file, :silence_missing_package, :compile_path,
7
- :compile_ignore_files, :compile_add_files, :env_files_dir, :env_file_name
7
+ :compile_ignore_files, :compile_add_files
8
8
  ].freeze
9
9
 
10
- SETTING_VARIABLES = [:role, :configs_dir, :config_path, :role_config_path].freeze
10
+ SETTING_VARIABLES = [:role].freeze
11
11
 
12
12
  # Default settings
13
13
  def initialize
14
- silence_missing_package(false)
15
- silence_missing_package_file(false)
16
- package_subdir_name('package')
17
- configs_dir('configs')
18
- env_files_dir('env_files')
19
- compile_ignore_files([
20
- '.gitignore',
21
- '.byebug_history',
22
- '.irbrc',
23
- '.rspec',
24
- '*_spec.rb',
25
- '*.log'
26
- ])
27
- compile_add_files([
28
- 'Gemfile',
29
- 'Gemfile.lock'
30
- ])
31
- compile_path('/tmp/rdm/:package_name')
14
+ silence_missing_package false
15
+ silence_missing_package_file false
16
+ package_subdir_name 'package'
17
+ compile_ignore_files %w(.gitignore .byebug_history .irbrc .rspec *_spec.rb *.log)
18
+ compile_add_files %w(Gemfile Gemfile.lock)
19
+ compile_path '/tmp/rdm/:package_name'
20
+ config_path 'config/:role.yml'
32
21
  end
33
22
 
34
23
  SETTING_KEYS.each do |key|
@@ -3,7 +3,6 @@ class Rdm::Source
3
3
 
4
4
  def initialize(root_path:)
5
5
  @root_path = root_path
6
- @config_names = []
7
6
  @package_paths = []
8
7
  end
9
8
 
@@ -13,15 +12,6 @@ class Rdm::Source
13
12
  @setup_block = block
14
13
  end
15
14
 
16
- # Add config to list of known configs
17
- # @param config_name [String] Config name
18
- def config(config_name)
19
- config_name = config_name.to_s
20
- raise Rdm::Errors::ConfigExists, config_name if @config_names.include?(config_name)
21
-
22
- @config_names << config_name
23
- end
24
-
25
15
  # Add package to list of known packages
26
16
  # @param package_path [String] Package path
27
17
  def package(package_path)
@@ -32,9 +22,8 @@ class Rdm::Source
32
22
  # @param value [Hash<String: Rdm::Package>] Hash of packages by it's name
33
23
  # @param value [Hash<String: Rdm::Config>] Hash of configs by it's name
34
24
  # @return [Hash<String: Rdm::Package>] Hash of packages by it's name
35
- def init_with(packages:, configs:)
25
+ def init_with(packages:)
36
26
  @packages = packages
37
- @configs = configs
38
27
  end
39
28
 
40
29
  # Read initialized packages
@@ -42,10 +31,4 @@ class Rdm::Source
42
31
  def packages
43
32
  @packages || {}
44
33
  end
45
-
46
- # Read initialized configs
47
- # @return [Hash<String: Rdm::Config>] Hash of configs by it's name
48
- def configs
49
- @configs || {}
50
- end
51
34
  end
@@ -15,7 +15,7 @@ class Rdm::SourceParser
15
15
  @stdout = stdout || STDOUT
16
16
  end
17
17
 
18
- # Read source file, parse and init it's packages and configs
18
+ # Read source file, parse and init it's packages
19
19
  # @param source_path [String] Source file path
20
20
  # @return [Rdm::Source] Source
21
21
  def read_and_init_source
@@ -28,9 +28,7 @@ class Rdm::SourceParser
28
28
  validate_rdm_settings!
29
29
 
30
30
  init_and_set_packages(source)
31
- init_and_set_configs(source)
32
- init_and_set_env_variables(source)
33
- source.init_with(packages: packages, configs: configs)
31
+ source.init_with(packages: packages)
34
32
  source
35
33
  end
36
34
 
@@ -57,37 +55,6 @@ class Rdm::SourceParser
57
55
  end
58
56
  end
59
57
 
60
- def init_and_set_configs(source)
61
- source.config_names.each do |config_name|
62
- default_path = settings.read_setting(:config_path, vars: { config_name: config_name })
63
- role_path = settings.read_setting(:role_config_path, vars: { config_name: config_name })
64
- config = Rdm::Config.new
65
- config.default_path = default_path
66
- config.role_path = role_path
67
- config.name = config_name
68
- configs[config_name] = config
69
- end
70
- end
71
-
72
- def init_and_set_env_variables(source)
73
- return unless settings.read_setting(:env_file_name)
74
-
75
- unless File.exists?(env_file_path)
76
- @stdout.puts "WARNING! Environment file '#{settings.read_setting(:env_file_name)}' was not found. Please, add #{env_file_path} file..."
77
- return
78
- end
79
-
80
- File.foreach(env_file_path) do |line|
81
- key, value = line.split('=').map(&:strip)
82
-
83
- if ENV.has_key?(key) && ENV[key] != value
84
- @stdout.puts "WARNING! Environment file '#{settings.read_setting(:env_file_name)}' overwrites ENV['#{key}'] variable from '#{ENV.fetch(key, nil)}' to '#{value}' ..."
85
- end
86
-
87
- ENV[key] = value
88
- end
89
- end
90
-
91
58
  # Make sure that all required settings are in place
92
59
  def validate_rdm_settings!
93
60
  if settings.read_setting(:role).nil?
@@ -102,12 +69,6 @@ class Rdm::SourceParser
102
69
  File.dirname(source_path)
103
70
  end
104
71
 
105
- def env_file_path
106
- file_path = File.join(root_path, settings.read_setting(:env_files_dir), "#{settings.read_setting(:env_file_name)}")
107
-
108
- file_path.gsub(/\.env$/, '').concat('.env')
109
- end
110
-
111
72
  # [String] Source file content
112
73
  def source_content
113
74
  @source_content ||= File.read(source_path)
@@ -117,10 +78,6 @@ class Rdm::SourceParser
117
78
  @packages ||= {}
118
79
  end
119
80
 
120
- def configs
121
- @configs ||= {}
122
- end
123
-
124
81
  def settings
125
82
  Rdm.settings
126
83
  end
@@ -3,22 +3,10 @@ setup do
3
3
  ENV['RUBY_ENV'] || raise('please set RUBY_ENV environment variable')
4
4
  end
5
5
 
6
- env_file_name do
7
- ENV['ENV_FILE']
8
- end
9
-
10
- configs_dir 'configs'
11
- config_path ':configs_dir/:config_name/default.yml'
12
- role_config_path ':configs_dir/:config_name/:role.yml'
13
-
14
- env_files_dir 'env_files'
15
6
  package_subdir_name 'package'
16
7
  silence_missing_package true
17
8
  end
18
9
 
19
- config :database
20
- config :logging
21
-
22
10
 
23
11
  # package 'core/application/commands'
24
12
  # package 'core/utils'
@@ -0,0 +1,12 @@
1
+ require 'ostruct'
2
+
3
+ class Rdm::Utils::Ostruct
4
+ class << self
5
+ def to_recursive_ostruct(hash)
6
+ OpenStruct.new(hash.each_with_object({}) do |(key, val), memo|
7
+ memo[key] = val.is_a?(Hash) ? to_recursive_ostruct(val) : val
8
+ end)
9
+ end
10
+ end
11
+ end
12
+
@@ -1,3 +1,3 @@
1
1
  module Rdm
2
- VERSION = '0.4.14.2'.freeze
2
+ VERSION = '0.4.17'.freeze
3
3
  end
@@ -0,0 +1,32 @@
1
+ require 'morf'
2
+
3
+ class Rdm::ConfigCaster
4
+ def initialize(envs)
5
+ @envs = envs
6
+ end
7
+
8
+ def cast(hash)
9
+ hash[@envs.name] ||= {}
10
+ caster.cast(hash, input_keys: :string, skip_unexpected_attributes: true)
11
+ end
12
+
13
+
14
+ def to_hcast_string(env)
15
+ eval_string = "#{env.type} :#{env.name}, optional: #{env.optional}"
16
+ eval_string += env.is_array? ? ", each: :#{env.children.first.type}" : ""
17
+ eval_string += env.is_hash? ? %Q( do \n #{env.children.map { |e| to_hcast_string(e) }.join("\n")} \nend) : ""
18
+
19
+ eval_string
20
+ end
21
+
22
+ private
23
+
24
+ def caster
25
+ @caster ||= Class.new
26
+ @caster.include(Morf::Caster)
27
+
28
+ @caster.class_eval "attributes do\n #{to_hcast_string(@envs)}\n end"
29
+
30
+ @caster
31
+ end
32
+ end
@@ -0,0 +1,39 @@
1
+ require 'yaml'
2
+
3
+ class Rdm::ConfigManager
4
+ class << self
5
+ def load_config(envs:, path_to_config:)
6
+ new_config = Rdm::ConfigCaster.new(envs).cast(YAML.load(File.read(path_to_config)))
7
+ validate_params!(new_config, envs)
8
+
9
+ instance.config.merge! new_config
10
+ end
11
+
12
+ def reset!
13
+ instance.config.clear
14
+ end
15
+
16
+ def method_missing(meth, *args, &block)
17
+ instance.send(meth)
18
+ end
19
+
20
+ def instance
21
+ @instance ||= new
22
+ end
23
+
24
+ private
25
+
26
+ def validate_params!(config, envs)
27
+ Rdm::ConfigValidator.new(envs).validate!(config)
28
+ end
29
+ end
30
+
31
+ def method_missing(meth)
32
+ config.keys.include?(meth) ? Rdm::Utils::Ostruct.to_recursive_ostruct(config).send(meth) :
33
+ (raise ArgumentError, ":#{meth} configuration was not defined for current package. Add `import '#{meth}'` to your Package.rb file")
34
+ end
35
+
36
+ def config
37
+ @config ||= {}
38
+ end
39
+ end
@@ -0,0 +1,51 @@
1
+ require 'attr_validator'
2
+
3
+ class Rdm::ConfigValidator
4
+ def initialize(env_config)
5
+ @env_config = env_config
6
+ end
7
+
8
+ def validate!(hash_config)
9
+ dto = OpenStruct.new(hash_config)
10
+
11
+ if @env_config.is_hash?
12
+ @env_config.children.each do |subconfig|
13
+ self.class.new(subconfig).validate!(dto.send(@env_config.name).to_h)
14
+ end
15
+ elsif @env_config.is_array?
16
+ dto.send(@env_config.name).each do |el|
17
+ array_dto = OpenStruct.new(@env_config.name => el)
18
+ validator(@env_config.name, @env_config.children.first.validates.to_hash).validate!(array_dto)
19
+ end
20
+ else
21
+ validator(@env_config.name, @env_config.validates.to_hash).validate!(dto)
22
+ end
23
+
24
+ dto
25
+ rescue AttrValidator::Errors::ValidationError => e
26
+ raise Rdm::Errors::InvalidConfig, e.message
27
+ end
28
+
29
+ private
30
+
31
+ def validator(name, env_config)
32
+ return @validator if @validator
33
+
34
+ validator_class = Class.new
35
+ validator_class.include(AttrValidator::Validator)
36
+
37
+ validator_class.class_eval( to_attr_validator_string(name, env_config) )
38
+
39
+ @validator = validator_class.new
40
+ end
41
+
42
+ def to_attr_validator_string(name, validates)
43
+ validates_string = []
44
+
45
+ validates.each do |key, value|
46
+ validates_string.push "validates :#{name}, #{key}: #{value}"
47
+ end
48
+
49
+ validates_string.join("\n")
50
+ end
51
+ end
@@ -0,0 +1,46 @@
1
+ class Rdm::EnvConfig
2
+ module Types
3
+ STRING = :string
4
+ ARRAY = :array
5
+ HASH = :hash
6
+ SYMBOL = :symbol
7
+ INTEGER = :integer
8
+
9
+ ALL = [STRING, ARRAY, HASH, SYMBOL, INTEGER]
10
+ end
11
+
12
+ attr_reader :name, :type, :optional, :default, :validates
13
+ attr_accessor :children
14
+
15
+ def initialize(name:, type:, optional: false, default: nil, validates: nil, children: nil)
16
+ @name = name
17
+ @type = Types::ALL.include?(type) ? type: (raise ArgumentError, "Invalid env type")
18
+ @optional = !!optional
19
+ @validates = validates || Rdm::ValidateConfig.new
20
+ @children = (children || []).select {|e| e.is_a?(Rdm::EnvConfig)}
21
+ @default = default
22
+ end
23
+
24
+ def to_hash
25
+ hash = {
26
+ name: @name,
27
+ type: @type,
28
+ optional: @optional,
29
+ default: @default,
30
+ }.delete_if { |_, v| v.nil? }
31
+
32
+ hash[:children] = @children.map(&:to_hash) if @children.any?
33
+ hash[:validates] = @validates.to_hash if @validates.to_hash.any?
34
+
35
+ hash
36
+ end
37
+
38
+ def is_array?
39
+ @type == Types::ARRAY
40
+ end
41
+
42
+ def is_hash?
43
+ @type == Types::HASH
44
+ end
45
+ end
46
+
@@ -0,0 +1,92 @@
1
+ class Rdm::EnvConfigDSL
2
+ attr_reader :data
3
+
4
+ module Types
5
+ STRING = :string
6
+ ARRAY = :array
7
+ HASH = :hash
8
+ SYMBOL = :symbol
9
+ INTEGER = :integer
10
+
11
+ ALL = [STRING, ARRAY, HASH, SYMBOL, INTEGER]
12
+ end
13
+
14
+ def initialize
15
+ @data = []
16
+ end
17
+
18
+ def string(name, opts = {}, &block)
19
+ validations = Rdm::ValidateConfig.new
20
+ validations.instance_exec(&block) if block_given?
21
+
22
+ @data.push(
23
+ Rdm::EnvConfig.new(
24
+ name: name,
25
+ type: Types::STRING,
26
+ optional: opts[:optional],
27
+ default: opts[:default],
28
+ validates: validations
29
+ )
30
+ )
31
+ end
32
+
33
+ def symbol(name, opts = {}, &block)
34
+ validations = Rdm::ValidateConfig.new
35
+ validations.instance_exec(&block) if block_given?
36
+
37
+ @data.push(
38
+ Rdm::EnvConfig.new(
39
+ name: name,
40
+ type: Types::SYMBOL,
41
+ optional: opts[:optional],
42
+ default: opts[:default],
43
+ validates: validations
44
+ )
45
+ )
46
+ end
47
+
48
+ def integer(name, opts = {}, &block)
49
+ validations = Rdm::ValidateConfig.new
50
+ validations.instance_exec(&block) if block_given?
51
+
52
+ @data.push(
53
+ Rdm::EnvConfig.new(
54
+ name: name,
55
+ type: Types::INTEGER,
56
+ optional: opts[:optional],
57
+ default: opts[:default],
58
+ validates: validations
59
+ )
60
+ )
61
+ end
62
+
63
+ def array(name, opts = {}, &block)
64
+ array_values = self.class.new
65
+ array_values.send(opts.fetch(:each), nil, {}, &block)
66
+
67
+ @data.push(
68
+ Rdm::EnvConfig.new(
69
+ name: name,
70
+ type: Types::ARRAY,
71
+ optional: opts[:optional],
72
+ default: opts[:default],
73
+ children: array_values.data
74
+ )
75
+ )
76
+ end
77
+
78
+ def hash(name, opts = {}, &block)
79
+ hash_values = self.class.new
80
+ hash_values.instance_exec(&block)
81
+
82
+ @data.push(
83
+ Rdm::EnvConfig.new(
84
+ name: name,
85
+ type: Types::HASH,
86
+ optional: opts[:optional],
87
+ default: opts[:default],
88
+ children: hash_values.data
89
+ )
90
+ )
91
+ end
92
+ end