Skip to content

Commit 884cb77

Browse files
Alan YeoPair
authored andcommitted
Add support for Cloud Foundry
Signed-off-by: Gamaliel Amaudruz <[email protected]>
1 parent 95870b1 commit 884cb77

26 files changed

+489
-33
lines changed

.ruby-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.3.1
1+
2.3.3

.travis.yml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ sudo: false
44
rvm:
55
- 2.0.0
66
- 2.1.10
7-
- 2.2.5
8-
- 2.3.1
7+
- 2.2.6
8+
- 2.3.3
9+
- 2.4.0-rc1
910
gemfile:
1011
- gemfiles/rails_3.gemfile
1112
- gemfiles/rails_4.gemfile
@@ -18,10 +19,18 @@ matrix:
1819
gemfile: gemfiles/rails_5.gemfile
1920
- rvm: 2.1.10
2021
gemfile: gemfiles/rails_5.gemfile
21-
- rvm: 2.2.5
22+
- rvm: 2.2.6
2223
gemfile: gemfiles/rails_3.gemfile
23-
- rvm: 2.3.1
24+
- rvm: 2.3.3
2425
gemfile: gemfiles/rails_3.gemfile
26+
- rvm: 2.4.0-rc1
27+
gemfile: gemfiles/rails_3.gemfile
28+
- rvm: 2.4.0-rc1
29+
gemfile: gemfiles/rails_4.gemfile
30+
- rvm: 2.4.0-rc1
31+
gemfile: gemfiles/rails_4.1.gemfile
32+
- rvm: 2.4.0-rc1
33+
gemfile: gemfiles/rails_4.2.gemfile
2534
before_install:
2635
- gem install bundler
2736
script:

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Changelog
22

3+
## 1.4.0
4+
5+
* Added support for passing a raw ruby hash into to both `Settings.add_source!` and `Settings.prepend_source!` ([#108](https://github.com/railsconfig/config/pull/159) thanks to [@halloffame](https://github.com/halloffame))
6+
* Added new reserved name `test` ([#158](https://github.com/railsconfig/config/pull/158) thanks to [@milushov](https://github.com/milushov))
7+
* `to_hash` should not replace nested config objects with Hash ([#160](https://github.com/railsconfig/config/issues/160) thanks to [@seikichi](https://github.com/seikichi))
8+
39
## 1.3.0
410

511
* **WARNING:** Overwrite arrays found in previously loaded settings file ([#137](https://github.com/railsconfig/config/pull/137) thanks to [@Fryguy](https://github.com/Fryguy) and [@dtaniwaki](https://github.com/dtaniwaki)) - this is a change breaking previous behaviour. If you want to keep Config to work as before, which is merging arrays found in following loaded settings file, please add `config.overwrite_arrays = false` to your Config initializer

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,15 @@ Settings.reload!
193193
> Note: this is an example usage, it is easier to just use the default local files `settings.local.yml,
194194
settings/#{Rails.env}.local.yml and environments/#{Rails.env}.local.yml` for your developer specific settings.
195195

196+
You also have the option to add a raw hash as a source. One use case might be storing settings in the database or in environment variables that overwrite what is in the YML files.
197+
198+
```ruby
199+
Settings.add_source!({some_secret: ENV['some_secret']})
200+
Settings.reload!
201+
```
202+
203+
You may pass a hash to `prepend_source!` as well.
204+
196205
## Embedded Ruby (ERB)
197206

198207
Embedded Ruby is allowed in the configuration files. Consider the two following config files.
@@ -300,6 +309,16 @@ filesystem gets recreated from the git sources on each instance refresh. To use
300309

301310
To upload your local values to Heroku you could ran `bundle exec rake config:heroku`.
302311

312+
### Working with Cloud Foundry
313+
314+
Cloud Foundry integration will generate a manifest adding to your CF manifest.yml the defined ENV variables under the `env` section of specified app in the yaml file.
315+
You must specify the app name and optionally the name of your CF manifest file:
316+
317+
bundle exec rake config:cf[app_name, cf_manifest.yml]
318+
319+
The result of this command will have the manifest file name suffixed with the environment you ran the task in. You can then push your app with the generated manifest.
320+
321+
303322
### Fine-tuning
304323

305324
You can customize how environment variables are processed:

lib/config.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
require 'config/version'
66
require 'config/integrations/rails/engine' if defined?(::Rails)
77
require 'config/sources/yaml_source'
8+
require 'config/sources/hash_source'
89
require 'deep_merge'
910

1011
module Config
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
require 'bundler'
2+
require 'yaml'
3+
require_relative '../../../lib/config/integrations/helpers/cf_manifest_merger'
4+
5+
module Config
6+
module Integrations
7+
class CloudFoundry < Struct.new(:app_name, :file_path)
8+
9+
def invoke
10+
manifest_path = file_path || 'manifest.yml'
11+
file_name, _ext = manifest_path.split('.yml')
12+
13+
manifest_hash = YAML.load(IO.read(File.join(::Rails.root, manifest_path)))
14+
15+
puts "Generating manifest... (base cf manifest: #{manifest_path})"
16+
17+
merged_hash = Config::CFManifestMerger.new(app_name, manifest_hash).add_to_env
18+
19+
target_manifest_path = File.join(::Rails.root, "#{file_name}-#{::Rails.env}.yml")
20+
IO.write(target_manifest_path, merged_hash.to_yaml)
21+
22+
puts "File #{target_manifest_path} generated."
23+
end
24+
25+
end
26+
end
27+
end
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
require_relative 'helpers'
2+
3+
module Config
4+
class CFManifestMerger
5+
include Integrations::Helpers
6+
7+
def initialize(app_name, manifest_hash)
8+
@app_name = app_name
9+
@manifest_hash = manifest_hash
10+
raise ArgumentError.new("Manifest path & app name must be specified") unless @app_name && @manifest_hash
11+
end
12+
13+
def add_to_env
14+
15+
settings_hash = Config.const_get(Config.const_name).to_hash.stringify_keys
16+
17+
prefix_keys_with_const_name_hash = to_dotted_hash(settings_hash, namespace: Config.const_name)
18+
19+
app_hash = @manifest_hash['applications'].detect { |hash| hash['name'] == @app_name }
20+
21+
raise ArgumentError, "Application '#{@app_name}' is not specified in your manifest" if app_hash.nil?
22+
23+
check_conflicting_keys(app_hash['env'], settings_hash)
24+
25+
app_hash['env'].merge!(prefix_keys_with_const_name_hash)
26+
27+
@manifest_hash
28+
end
29+
30+
private
31+
32+
def check_conflicting_keys(env_hash, settings_hash)
33+
conflicting_keys = env_hash.keys & settings_hash.keys
34+
raise ArgumentError.new("Conflicting keys: #{conflicting_keys.join(', ')}") if conflicting_keys.any?
35+
end
36+
37+
end
38+
end
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module Config::Integrations::Helpers
2+
3+
def to_dotted_hash(source, target: {}, namespace: nil)
4+
raise ArgumentError, "target must be a hash (given: #{target.class.name})" unless target.kind_of? Hash
5+
prefix = "#{namespace}." if namespace
6+
case source
7+
when Hash
8+
source.each do |key, value|
9+
to_dotted_hash(value, target: target, namespace: "#{prefix}#{key}")
10+
end
11+
when Array
12+
source.each_with_index do |value, index|
13+
to_dotted_hash(value, target: target, namespace: "#{prefix}#{index}")
14+
end
15+
else
16+
target[namespace] = source
17+
end
18+
target
19+
end
20+
21+
end

lib/config/integrations/heroku.rb

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
require 'bundler'
2+
require_relative 'helpers/helpers'
23

34
module Config
45
module Integrations
56
class Heroku < Struct.new(:app)
7+
include Integrations::Helpers
8+
69
def invoke
710
puts 'Setting vars...'
811
heroku_command = "config:set #{vars}"
@@ -14,13 +17,13 @@ def invoke
1417
def vars
1518
# Load only local options to Heroku
1619
Config.load_and_set_settings(
17-
Rails.root.join("config", "settings.local.yml").to_s,
18-
Rails.root.join("config", "settings", "#{environment}.local.yml").to_s,
19-
Rails.root.join("config", "environments", "#{environment}.local.yml").to_s
20+
::Rails.root.join("config", "settings.local.yml").to_s,
21+
::Rails.root.join("config", "settings", "#{environment}.local.yml").to_s,
22+
::Rails.root.join("config", "environments", "#{environment}.local.yml").to_s
2023
)
2124

2225
out = ''
23-
dotted_hash = to_dotted_hash Kernel.const_get(Config.const_name).to_hash, {}, Config.const_name
26+
dotted_hash = to_dotted_hash Kernel.const_get(Config.const_name).to_hash, namespace: Config.const_name
2427
dotted_hash.each {|key, value| out += " #{key}=#{value} "}
2528
out
2629
end
@@ -38,22 +41,6 @@ def `(command)
3841
Bundler.with_clean_env { super }
3942
end
4043

41-
def to_dotted_hash(source, target = {}, namespace = nil)
42-
prefix = "#{namespace}." if namespace
43-
case source
44-
when Hash
45-
source.each do |key, value|
46-
to_dotted_hash(value, target, "#{prefix}#{key}")
47-
end
48-
when Array
49-
source.each_with_index do |value, index|
50-
to_dotted_hash(value, target, "#{prefix}#{index}")
51-
end
52-
else
53-
target[namespace] = source
54-
end
55-
target
56-
end
5744
end
5845
end
5946
end

lib/config/integrations/rails/railtie.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ def preload
1515

1616
# Load rake tasks (eg. Heroku)
1717
rake_tasks do
18-
Dir[File.join(File.dirname(__FILE__), '../tasks/*.rake')].each { |f| load f }
18+
Dir[File.join(File.dirname(__FILE__), '../../tasks/*.rake')].each { |f| load f }
1919
end
2020

2121
config.before_configuration { preload }

0 commit comments

Comments
 (0)