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.
- checksums.yaml +5 -5
- data/Gemfile.lock +26 -19
- data/bin/rdm +10 -10
- data/example/Rdm.packages +1 -17
- data/example/config/app.yml +6 -0
- data/example/infrastructure/repository/Package.rb +0 -1
- data/example/infrastructure/repository/fixture.txt +1 -0
- data/lib/rdm.rb +14 -7
- data/lib/rdm/errors.rb +3 -0
- data/lib/rdm/gen/init.rb +0 -4
- data/lib/rdm/package.rb +18 -9
- data/lib/rdm/package_importer.rb +4 -18
- data/lib/rdm/package_parser.rb +1 -0
- data/lib/rdm/packages/compiler_service.rb +1 -7
- data/lib/rdm/settings.rb +10 -21
- data/lib/rdm/source.rb +1 -18
- data/lib/rdm/source_parser.rb +2 -45
- data/lib/rdm/templates/init/Rdm.packages +0 -12
- data/lib/rdm/utils/ostruct_utils.rb +12 -0
- data/lib/rdm/version.rb +1 -1
- data/lib/rdm/yml_config/config_caster.rb +32 -0
- data/lib/rdm/yml_config/config_manager.rb +39 -0
- data/lib/rdm/yml_config/config_validator.rb +51 -0
- data/lib/rdm/yml_config/env_config.rb +46 -0
- data/lib/rdm/yml_config/env_config_dsl.rb +92 -0
- data/lib/rdm/yml_config/validate_config.rb +13 -0
- data/rdm.gemspec +3 -0
- data/spec/fixtures/SampleSource.rb +2 -4
- data/spec/fixtures/app.yml +17 -0
- data/spec/rdm/cli/gen_package_spec.rb +0 -2
- data/spec/rdm/gen/init_spec.rb +0 -12
- data/spec/rdm/gen/package_spec.rb +1 -0
- data/spec/rdm/package_importer_spec.rb +34 -2
- data/spec/rdm/rdm_spec.rb +1 -1
- data/spec/rdm/source_parser_spec.rb +0 -59
- data/spec/rdm/yml_config/config_caster_spec.rb +64 -0
- data/spec/rdm/yml_config/config_manager_spec.rb +7 -0
- data/spec/rdm/yml_config/config_validator_spec.rb +190 -0
- data/spec/rdm/yml_config/env_config_dsl_spec.rb +123 -0
- data/spec/spec_helper.rb +1 -0
- metadata +69 -34
- data/example/.rdm/templates/configs/<%=config_path%> +0 -2
- data/example/.rdm/templates/configs/<%=role_config_path%> +0 -2
- data/example/configs/app/default.yml +0 -2
- data/example/configs/app/production.yml +0 -2
- data/example/configs/database/default.yml +0 -3
- data/example/env_files/development.env +0 -3
- data/example/env_files/production.env +0 -5
- data/example/env_files/test.env +0 -3
- data/lib/rdm/cli/config.rb +0 -31
- data/lib/rdm/config.rb +0 -11
- data/lib/rdm/config_locals.rb +0 -11
- data/lib/rdm/config_manager.rb +0 -68
- data/lib/rdm/config_scope.rb +0 -23
- data/lib/rdm/gen/config.rb +0 -59
- data/lib/rdm/templates/configs/<%=config_path%> +0 -2
- data/lib/rdm/templates/configs/<%=role_config_path%> +0 -2
- data/lib/rdm/templates/init/env_files/development.env +0 -3
- data/lib/rdm/templates/init/env_files/production.env +0 -3
- data/lib/rdm/templates/init/env_files/test.env +0 -3
- data/spec/fixtures/config.yml +0 -2
- data/spec/rdm/config_manager_spec.rb +0 -136
- data/spec/rdm/gen/config_spec.rb +0 -31
data/lib/rdm/settings.rb
CHANGED
@@ -2,33 +2,22 @@ class Rdm::Settings
|
|
2
2
|
attr_reader :settings
|
3
3
|
|
4
4
|
SETTING_KEYS = [
|
5
|
-
:role, :package_subdir_name, :
|
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
|
7
|
+
:compile_ignore_files, :compile_add_files
|
8
8
|
].freeze
|
9
9
|
|
10
|
-
SETTING_VARIABLES = [:role
|
10
|
+
SETTING_VARIABLES = [:role].freeze
|
11
11
|
|
12
12
|
# Default settings
|
13
13
|
def initialize
|
14
|
-
silence_missing_package
|
15
|
-
silence_missing_package_file
|
16
|
-
package_subdir_name
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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|
|
data/lib/rdm/source.rb
CHANGED
@@ -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
|
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
|
data/lib/rdm/source_parser.rb
CHANGED
@@ -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
|
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
|
-
|
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'
|
data/lib/rdm/version.rb
CHANGED
@@ -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
|