rdm 0.4.17 → 0.4.18

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 (64) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -8
  3. data/bin/rdm +10 -10
  4. data/example/.rdm/templates/configs/<%=config_path%> +2 -0
  5. data/example/.rdm/templates/configs/<%=role_config_path%> +2 -0
  6. data/example/Rdm.packages +17 -1
  7. data/example/configs/app/default.yml +2 -0
  8. data/example/configs/app/production.yml +2 -0
  9. data/example/configs/database/default.yml +3 -0
  10. data/example/env_files/development.env +3 -0
  11. data/example/env_files/production.env +5 -0
  12. data/example/env_files/test.env +3 -0
  13. data/example/infrastructure/repository/Package.rb +1 -0
  14. data/lib/rdm.rb +7 -14
  15. data/lib/rdm/cli/config.rb +31 -0
  16. data/lib/rdm/config.rb +11 -0
  17. data/lib/rdm/config_locals.rb +11 -0
  18. data/lib/rdm/config_manager.rb +68 -0
  19. data/lib/rdm/config_scope.rb +23 -0
  20. data/lib/rdm/errors.rb +0 -3
  21. data/lib/rdm/gen/config.rb +59 -0
  22. data/lib/rdm/gen/init.rb +4 -0
  23. data/lib/rdm/package.rb +9 -18
  24. data/lib/rdm/package_importer.rb +17 -3
  25. data/lib/rdm/package_parser.rb +0 -1
  26. data/lib/rdm/packages/compiler_service.rb +7 -1
  27. data/lib/rdm/settings.rb +21 -10
  28. data/lib/rdm/source.rb +18 -1
  29. data/lib/rdm/source_parser.rb +45 -2
  30. data/lib/rdm/spec_runner/runner.rb +2 -2
  31. data/lib/rdm/templates/configs/<%=config_path%> +2 -0
  32. data/lib/rdm/templates/configs/<%=role_config_path%> +2 -0
  33. data/lib/rdm/templates/init/Rdm.packages +12 -0
  34. data/lib/rdm/templates/init/env_files/development.env +3 -0
  35. data/lib/rdm/templates/init/env_files/production.env +3 -0
  36. data/lib/rdm/templates/init/env_files/test.env +3 -0
  37. data/lib/rdm/version.rb +1 -1
  38. data/rdm.gemspec +0 -3
  39. data/spec/fixtures/SampleSource.rb +4 -2
  40. data/spec/fixtures/config.yml +2 -0
  41. data/spec/rdm/cli/gen_package_spec.rb +2 -0
  42. data/spec/rdm/config_manager_spec.rb +136 -0
  43. data/spec/rdm/gen/config_spec.rb +31 -0
  44. data/spec/rdm/gen/init_spec.rb +12 -0
  45. data/spec/rdm/gen/package_spec.rb +0 -1
  46. data/spec/rdm/package_importer_spec.rb +2 -34
  47. data/spec/rdm/rdm_spec.rb +1 -1
  48. data/spec/rdm/source_parser_spec.rb +59 -0
  49. data/spec/spec_helper.rb +0 -1
  50. metadata +27 -63
  51. data/example/config/app.yml +0 -6
  52. data/example/infrastructure/repository/fixture.txt +0 -1
  53. data/lib/rdm/utils/ostruct_utils.rb +0 -12
  54. data/lib/rdm/yml_config/config_caster.rb +0 -32
  55. data/lib/rdm/yml_config/config_manager.rb +0 -39
  56. data/lib/rdm/yml_config/config_validator.rb +0 -51
  57. data/lib/rdm/yml_config/env_config.rb +0 -46
  58. data/lib/rdm/yml_config/env_config_dsl.rb +0 -92
  59. data/lib/rdm/yml_config/validate_config.rb +0 -13
  60. data/spec/fixtures/app.yml +0 -17
  61. data/spec/rdm/yml_config/config_caster_spec.rb +0 -64
  62. data/spec/rdm/yml_config/config_manager_spec.rb +0 -7
  63. data/spec/rdm/yml_config/config_validator_spec.rb +0 -190
  64. data/spec/rdm/yml_config/env_config_dsl_spec.rb +0 -123
@@ -45,6 +45,10 @@ module Rdm
45
45
  @template_detector.gem_template_folder('package'),
46
46
  File.dirname(@template_detector.project_template_folder('package'))
47
47
  )
48
+ FileUtils.cp_r(
49
+ @template_detector.gem_template_folder('configs'),
50
+ File.dirname(@template_detector.project_template_folder('configs'))
51
+ )
48
52
 
49
53
  generated_files
50
54
  end
@@ -2,11 +2,6 @@ class Rdm::Package
2
2
  DEFAULT_GROUP = '_default_'.freeze
3
3
 
4
4
  attr_accessor :metadata, :local_dependencies, :external_dependencies, :file_dependencies, :config_dependencies, :path
5
- attr_reader :environments
6
-
7
- def inspect
8
- "Rdm::Package(name: #{name}, path: #{path})"
9
- end
10
5
 
11
6
  def local_dependencies(group = nil)
12
7
  fetch_dependencies(@local_dependencies || {}, group)
@@ -20,6 +15,10 @@ class Rdm::Package
20
15
  fetch_dependencies(@file_dependencies || {}, group)
21
16
  end
22
17
 
18
+ def config_dependencies(group = nil)
19
+ fetch_dependencies(@config_dependencies || {}, group)
20
+ end
21
+
23
22
  def local_dependencies_with_groups
24
23
  return {} if @local_dependencies.nil?
25
24
  @local_dependencies.each_with_object(
@@ -50,7 +49,11 @@ class Rdm::Package
50
49
  @file_dependencies[current_group] << file
51
50
  end
52
51
 
53
- def import_config(*args)
52
+ # Import config dependency
53
+ def import_config(dependency)
54
+ @config_dependencies ||= {}
55
+ @config_dependencies[current_group] ||= []
56
+ @config_dependencies[current_group] << dependency
54
57
  end
55
58
 
56
59
  def package
@@ -81,18 +84,6 @@ class Rdm::Package
81
84
  other_package.name == name
82
85
  end
83
86
 
84
- def set_environments(&block)
85
- environments.children = Rdm::EnvConfigDSL.new.instance_exec(&block) if block_given?
86
- end
87
-
88
- def environments
89
- @environments ||= Rdm::EnvConfig.new(
90
- name: name,
91
- type: Rdm::EnvConfig::Types::HASH,
92
- optional: false
93
- )
94
- end
95
-
96
87
  private
97
88
 
98
89
  def current_group
@@ -31,7 +31,6 @@ class Rdm::PackageImporter
31
31
  # @return [Rdm::Package] Current package
32
32
  def import_file(package_path, group: nil)
33
33
  package = Rdm::PackageParser.parse_file(package_path)
34
-
35
34
  source = read_and_init_source(package.source)
36
35
 
37
36
  # Init Rdm.root based on Rdm.packages directory
@@ -47,6 +46,10 @@ class Rdm::PackageImporter
47
46
  @imported_packages ||= []
48
47
  end
49
48
 
49
+ def imported_configs
50
+ @imported_configs ||= []
51
+ end
52
+
50
53
  # Import package and initialize module
51
54
  def import_package(package_name, source:, group: nil)
52
55
  return imported_packages if imported_packages.include?(package_name.to_s)
@@ -62,6 +65,11 @@ class Rdm::PackageImporter
62
65
  import_package(dependency, source: source, group: group)
63
66
  end
64
67
 
68
+ # also import config dependencies
69
+ package.config_dependencies(group).each do |dependency|
70
+ import_config(dependency, source: source)
71
+ end
72
+
65
73
  # only after importing dependencies - require package itself
66
74
  begin
67
75
  require package_name
@@ -97,13 +105,19 @@ class Rdm::PackageImporter
97
105
  require File.join(package.path, file_path)
98
106
  end
99
107
 
100
- Rdm::ConfigManager.load_config(envs: package.environments, path_to_config: Rdm.settings.config_path)
101
-
102
108
  unless ActiveSupport::Dependencies.autoload_paths.include?(package_dir_name)
103
109
  ActiveSupport::Dependencies.autoload_paths << package_dir_name
104
110
  end
105
111
  end
106
112
 
113
+ def import_config(config_name, source:)
114
+ return if imported_configs.include?(config_name)
115
+ config = source.configs[config_name.to_s]
116
+ raise "Can't find config with name: #{config_name}" if config.nil?
117
+ Rdm.config.load_config(config, source: source)
118
+ imported_configs << config_name
119
+ end
120
+
107
121
  def read_and_init_source(source_path)
108
122
  source_parser.read_and_init_source(source_path)
109
123
  end
@@ -16,7 +16,6 @@ class Rdm::PackageParser
16
16
 
17
17
  def parse(package_content)
18
18
  spec = Rdm::Package.new
19
-
20
19
  spec.instance_eval(package_content)
21
20
  spec
22
21
  end
@@ -56,7 +56,13 @@ module Rdm
56
56
  end
57
57
  end
58
58
 
59
- # TODO: paste generated env files to compile directory
59
+ FileUtils.cp_r(File.join(@project_path, 'configs'), File.join(@compile_path, 'configs'))
60
+ if Dir.exists?(File.join(@project_path, Rdm.settings.env_files_dir))
61
+ FileUtils.cp_r(
62
+ File.join(@project_path, Rdm.settings.env_files_dir),
63
+ File.join(@compile_path, Rdm.settings.env_files_dir)
64
+ )
65
+ end
60
66
 
61
67
  Rdm.settings.compile_ignore_files.each do |file|
62
68
  Dir["#{@compile_path}/**/#{file}"].each do |file_to_remove|
@@ -2,22 +2,33 @@ class Rdm::Settings
2
2
  attr_reader :settings
3
3
 
4
4
  SETTING_KEYS = [
5
- :role, :package_subdir_name, :config_path,
5
+ :role, :package_subdir_name, :configs_dir, :config_path, :role_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, :env_files_dir, :env_file_name
8
8
  ].freeze
9
9
 
10
- SETTING_VARIABLES = [:role].freeze
10
+ SETTING_VARIABLES = [:role, :configs_dir, :config_path, :role_config_path].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
- 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'
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')
21
32
  end
22
33
 
23
34
  SETTING_KEYS.each do |key|
@@ -3,6 +3,7 @@ class Rdm::Source
3
3
 
4
4
  def initialize(root_path:)
5
5
  @root_path = root_path
6
+ @config_names = []
6
7
  @package_paths = []
7
8
  end
8
9
 
@@ -12,6 +13,15 @@ class Rdm::Source
12
13
  @setup_block = block
13
14
  end
14
15
 
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
+
15
25
  # Add package to list of known packages
16
26
  # @param package_path [String] Package path
17
27
  def package(package_path)
@@ -22,8 +32,9 @@ class Rdm::Source
22
32
  # @param value [Hash<String: Rdm::Package>] Hash of packages by it's name
23
33
  # @param value [Hash<String: Rdm::Config>] Hash of configs by it's name
24
34
  # @return [Hash<String: Rdm::Package>] Hash of packages by it's name
25
- def init_with(packages:)
35
+ def init_with(packages:, configs:)
26
36
  @packages = packages
37
+ @configs = configs
27
38
  end
28
39
 
29
40
  # Read initialized packages
@@ -31,4 +42,10 @@ class Rdm::Source
31
42
  def packages
32
43
  @packages || {}
33
44
  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
34
51
  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
18
+ # Read source file, parse and init it's packages and configs
19
19
  # @param source_path [String] Source file path
20
20
  # @return [Rdm::Source] Source
21
21
  def read_and_init_source
@@ -28,7 +28,9 @@ class Rdm::SourceParser
28
28
  validate_rdm_settings!
29
29
 
30
30
  init_and_set_packages(source)
31
- source.init_with(packages: packages)
31
+ init_and_set_configs(source)
32
+ init_and_set_env_variables(source)
33
+ source.init_with(packages: packages, configs: configs)
32
34
  source
33
35
  end
34
36
 
@@ -55,6 +57,37 @@ class Rdm::SourceParser
55
57
  end
56
58
  end
57
59
 
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
+
58
91
  # Make sure that all required settings are in place
59
92
  def validate_rdm_settings!
60
93
  if settings.read_setting(:role).nil?
@@ -69,6 +102,12 @@ class Rdm::SourceParser
69
102
  File.dirname(source_path)
70
103
  end
71
104
 
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
+
72
111
  # [String] Source file content
73
112
  def source_content
74
113
  @source_content ||= File.read(source_path)
@@ -78,6 +117,10 @@ class Rdm::SourceParser
78
117
  @packages ||= {}
79
118
  end
80
119
 
120
+ def configs
121
+ @configs ||= {}
122
+ end
123
+
81
124
  def settings
82
125
  Rdm.settings
83
126
  end
@@ -170,7 +170,7 @@ class Rdm::SpecRunner::Runner
170
170
  start_from = running_packages.index {|cmd_params| cmd_params.package_name == @from}
171
171
 
172
172
  if start_from.nil?
173
- puts "Pacakge :#{@from} does not exists"
173
+ puts "Package :#{@from} does not exists"
174
174
  exit(1)
175
175
  end
176
176
 
@@ -191,7 +191,7 @@ class Rdm::SpecRunner::Runner
191
191
 
192
192
  running_packages
193
193
  .map(&:command)
194
- .join(' && ')
194
+ .join('; ')
195
195
  end
196
196
 
197
197
  def display_missing_specs
@@ -0,0 +1,2 @@
1
+ <%=config_name%>:
2
+ <%=config_locals%>
@@ -0,0 +1,2 @@
1
+ <%=config_name%>:
2
+ <%=config_locals%>
@@ -3,10 +3,22 @@ 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'
6
15
  package_subdir_name 'package'
7
16
  silence_missing_package true
8
17
  end
9
18
 
19
+ config :database
20
+ config :logging
21
+
10
22
 
11
23
  # package 'core/application/commands'
12
24
  # package 'core/utils'
@@ -0,0 +1,3 @@
1
+ RUBY_ENV=development
2
+
3
+ APP_NAME=Application
@@ -0,0 +1,3 @@
1
+ RUBY_ENV=production
2
+
3
+ APP_NAME=Application
@@ -0,0 +1,3 @@
1
+ RUBY_ENV=test
2
+
3
+ APP_NAME=Application
@@ -1,3 +1,3 @@
1
1
  module Rdm
2
- VERSION = '0.4.17'.freeze
2
+ VERSION = '0.4.18'.freeze
3
3
  end
@@ -23,7 +23,4 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "codecov"
24
24
  spec.add_dependency "activesupport"
25
25
  spec.add_dependency "commander", "~> 4.4"
26
- spec.add_dependency "morf"
27
- spec.add_dependency "hcast"
28
- spec.add_dependency "attr_validator"
29
26
  end
@@ -1,8 +1,10 @@
1
1
  setup do
2
- role 'example'
3
- config_path 'app.yml'
2
+ role "example"
3
+ config_path "config"
4
4
  silence_missing_package true
5
5
  end
6
6
 
7
+ config :database
8
+
7
9
  package "application/web"
8
10
  package "domain/core"
@@ -0,0 +1,2 @@
1
+ development:
2
+ foo: "<%= 'bar' %>"
@@ -98,4 +98,6 @@ describe Rdm::CLI::GenPackage do
98
98
  expect(stdout.output).to include("Package name was not specified!")
99
99
  end
100
100
  end
101
+
102
+
101
103
  end
@@ -0,0 +1,136 @@
1
+ require 'spec_helper'
2
+
3
+ describe Rdm::ConfigManager do
4
+ subject { Rdm::ConfigManager.new }
5
+
6
+ let(:example_path) {
7
+ Pathname.new(
8
+ File.join(File.expand_path('../../../', __FILE__), 'example')
9
+ )
10
+ }
11
+ let(:config_manager) { Rdm::ConfigManager.new }
12
+ let(:source_file) { example_path.join('Rdm.packages').to_s }
13
+ let(:source) { Rdm::SourceParser.read_and_init_source(source_file)}
14
+
15
+ describe "#load_config" do
16
+ context "config.default_path" do
17
+ let(:config){ Rdm::Config.build(name: "name", default_path: "configs/app/default.yml", role_path: nil) }
18
+ it "works" do
19
+ config_manager.load_config(config, source: source)
20
+ end
21
+ end
22
+
23
+ context "config.role_path" do
24
+ let(:config){ Rdm::Config.build(name: "name", default_path: nil, role_path: "configs/app/production.yml") }
25
+ it "works" do
26
+ config_manager.load_config(config, source: source)
27
+ end
28
+ end
29
+ end
30
+
31
+ describe "#update_using_file" do
32
+ context "file missing and raise_if_missing=true" do
33
+ let(:config){ Rdm::Config.build(name: "name", default_path: "configs/app/not-there.yml", role_path: nil) }
34
+ it "raises" do
35
+ expect{
36
+ config_manager.load_config(config, source: source)
37
+ }.to raise_error(RuntimeError, Regexp.new("Config file is not found at path"))
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "#update_using_file" do
43
+ let(:fixtures_path) {
44
+ File.join(File.expand_path("../../", __FILE__), 'fixtures')
45
+ }
46
+
47
+ before :each do
48
+ subject.update_using_file(File.join(fixtures_path, "config.yml"))
49
+ end
50
+
51
+ it "parses yml with erb correctly" do
52
+ expect(subject.development.foo).to eq("bar")
53
+ end
54
+ end
55
+
56
+ describe "#update_using_hash" do
57
+ before :each do
58
+ subject.update_using_hash(
59
+ database: {
60
+ username: "foo",
61
+ password: "bar"
62
+ },
63
+ lib_name: "rdm",
64
+ version: 1,
65
+ published: true,
66
+ draft: false,
67
+ features: ["dependency_manager", "config_manager"]
68
+ )
69
+ end
70
+
71
+ it "returns given value for string" do
72
+ expect(subject.lib_name).to eq("rdm")
73
+ end
74
+
75
+ it "returns given value for int" do
76
+ expect(subject.version).to eq(1)
77
+ end
78
+
79
+ it "returns given value for true bool" do
80
+ expect(subject.published).to eq(true)
81
+ end
82
+
83
+ it "returns given value for false bool" do
84
+ expect(subject.draft).to eq(false)
85
+ end
86
+
87
+ it "returns given value for array" do
88
+ expect(subject.features).to eq(["dependency_manager", "config_manager"])
89
+ end
90
+
91
+ it "creates another child scope for nested hash" do
92
+ expect(subject.database).to be_instance_of(Rdm::ConfigScope)
93
+ expect(subject.database.username).to eq("foo")
94
+ expect(subject.database.password).to eq("bar")
95
+ end
96
+
97
+ context "when already has config" do
98
+ before :each do
99
+ subject.update_using_hash(
100
+ database: {
101
+ username: "new_username",
102
+ password: "new_password"
103
+ }
104
+ )
105
+ end
106
+
107
+ it "keeps old configs" do
108
+ expect(subject.lib_name).to eq('rdm')
109
+ end
110
+
111
+ it "rewrites new configs" do
112
+ expect(subject.database.username).to eq('new_username')
113
+ end
114
+ end
115
+ end
116
+
117
+ describe "to_h" do
118
+ before :each do
119
+ subject.update_using_hash(
120
+ site_name: "Sample app",
121
+ database: {
122
+ username: "username",
123
+ password: "password"
124
+ }
125
+ )
126
+ end
127
+
128
+ it "returns attributes in root scope" do
129
+ expect(subject.to_h["site_name"]).to eq("Sample app")
130
+ end
131
+
132
+ it "returns attributes in child scope" do
133
+ expect(subject.to_h["database"]["username"]).to eq("username")
134
+ end
135
+ end
136
+ end