complex_config 0.0.0
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 +7 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.travis.yml +11 -0
- data/.utilsrc +26 -0
- data/Gemfile +5 -0
- data/README.md +131 -0
- data/Rakefile +26 -0
- data/VERSION +1 -0
- data/complex_config.gemspec +52 -0
- data/lib/complex_config.rb +10 -0
- data/lib/complex_config/errors.rb +19 -0
- data/lib/complex_config/plugins.rb +2 -0
- data/lib/complex_config/plugins/enable.rb +4 -0
- data/lib/complex_config/plugins/money.rb +11 -0
- data/lib/complex_config/plugins/uri.rb +12 -0
- data/lib/complex_config/provider.rb +67 -0
- data/lib/complex_config/rude.rb +2 -0
- data/lib/complex_config/settings.rb +68 -0
- data/lib/complex_config/shortcuts.rb +10 -0
- data/lib/complex_config/version.rb +8 -0
- data/spec/complex_config/plugins_spec.rb +42 -0
- data/spec/complex_config/provider_spec.rb +141 -0
- data/spec/complex_config/settings_spec.rb +58 -0
- data/spec/complex_config/shortcuts_spec.rb +44 -0
- data/spec/config/broken_config.yml +1 -0
- data/spec/config/config.yml +13 -0
- data/spec/spec_helper.rb +28 -0
- metadata +189 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 02095dc1d57e5c7310afb22efd984d69b3054473
|
4
|
+
data.tar.gz: ac7bfb58dae97e30b401447649accdeb3ebd3afc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a136b2e271793501909062fb7ec333041de9a53c19490d19655d05946abb3ca7e0bfecff51f944eafd3c7d6d206f7eb491f0a65ae7b98456b50dd7d23976b965
|
7
|
+
data.tar.gz: 56fe16ae1198d30650e57ab501725a15ef78de7afe2930962f62a9b838d1265ee0f39afc8b8e1ff9952686bfbf29469ef1e13538ef4efcdc6748132e4a170e4a
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/.utilsrc
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# vim: set ft=ruby:
|
2
|
+
|
3
|
+
search do
|
4
|
+
prune_dirs /\A(\.svn|\.git|CVS|tmp|tags|coverage|pkg)\z/
|
5
|
+
skip_files /(\A\.|\.sw[pon]\z|\.(log|fnm|jpg|jpeg|png|pdf|svg)\z|tags|~\z)/i
|
6
|
+
end
|
7
|
+
|
8
|
+
discover do
|
9
|
+
prune_dirs /\A(\.svn|\.git|CVS|tmp|tags|coverage|pkg)\z/
|
10
|
+
skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
|
11
|
+
binary false
|
12
|
+
end
|
13
|
+
|
14
|
+
strip_spaces do
|
15
|
+
prune_dirs /\A(\..*|CVS|pkg)\z/
|
16
|
+
skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
|
17
|
+
end
|
18
|
+
|
19
|
+
probe do
|
20
|
+
test_framework :rspec
|
21
|
+
#include_dirs 'features'
|
22
|
+
end
|
23
|
+
|
24
|
+
ssh_tunnel do
|
25
|
+
terminal_multiplexer :tmux
|
26
|
+
end
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
# ComplexConfig
|
2
|
+
|
3
|
+
## Description
|
4
|
+
|
5
|
+
This library makes your YAML configuration files available via a nice API. It
|
6
|
+
also supports different configurations for each `RAILS_ENV` environment and
|
7
|
+
using plugins to return more complex settings values.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
You can use rubygems to fetch the gem and install it for you:
|
12
|
+
|
13
|
+
# gem install complex_config
|
14
|
+
|
15
|
+
You can also put this line into your Gemfile
|
16
|
+
|
17
|
+
gem 'complex_config', require: 'complex_config/rude'
|
18
|
+
|
19
|
+
and bundle. This command will enable all the default plugins and make the `cc`
|
20
|
+
and `complex_config` shortcuts available.
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Given a config file like this and named `config/products.yml`
|
25
|
+
|
26
|
+
evelopment:
|
27
|
+
flux_capacitor:
|
28
|
+
version_20:
|
29
|
+
name: Flux Capacitor Version 2.0
|
30
|
+
price_in_cents: 12_000_00
|
31
|
+
manual_pdf_url: "http://brown-inc.com/manuals/fc_20.pdf"
|
32
|
+
pro_version:
|
33
|
+
name: Flux Capacitor Professional
|
34
|
+
price_in_cents: 23_000_00
|
35
|
+
manual_pdf_url: "http://brown-inc.com/manuals/fc_pro.pdf"
|
36
|
+
enterprise_version:
|
37
|
+
name: Flux Capacitor Enterpise
|
38
|
+
price_in_cents: 1_600_000_00
|
39
|
+
manual_pdf_url: "http://brown-inc.com/manuals/fc_enterprise.pdf"
|
40
|
+
|
41
|
+
test:
|
42
|
+
flux_capacitor:
|
43
|
+
test_version:
|
44
|
+
name: Yadayada
|
45
|
+
price_in_cents: 6_66
|
46
|
+
manual_pdf_url: "http://staging.brown-inc.com/manuals/fc_10.pdf"
|
47
|
+
|
48
|
+
and using `require "complex_config/rude"` in the `"development"` environment you
|
49
|
+
can now access the configuration.
|
50
|
+
|
51
|
+
### Accessing configuration settings
|
52
|
+
|
53
|
+
Fetching the name of a product:
|
54
|
+
|
55
|
+
> cc(:products).flux_capacitor.enterprise_version.name => "Flux Capacitor Enterpise"
|
56
|
+
|
57
|
+
Fetching the price of a product in cents:
|
58
|
+
|
59
|
+
> cc(:products).flux_capacitor.enterprise_version.price_in_cents => 160000000
|
60
|
+
|
61
|
+
Fetching the price of a product and using the ComplexConfig::Plugins::MONEY
|
62
|
+
plugin to format it:
|
63
|
+
|
64
|
+
> cc(:products).flux_capacitor.enterprise_version.price.format => "€1,600,000.00"
|
65
|
+
|
66
|
+
Fetching the URL of a product manual as a string:
|
67
|
+
|
68
|
+
> cc(:products).flux_capacitor.enterprise_version.manual_pdf_url => "http://brown-inc.com/manuals/fc_enterprise.pdf"
|
69
|
+
|
70
|
+
Fetching the URL of a product manual and using the ComplexConfig::Plugins::URI
|
71
|
+
plugin return an URI instance:
|
72
|
+
|
73
|
+
> cc(:products).flux_capacitor.enterprise_version.manual_pdf_uri => #<URI::HTTP:0x007ff626d2a2e8 URL:http://brown-inc.com/manuals/fc_enterprise.pdf>
|
74
|
+
|
75
|
+
You can also fetch config settings from a different environment:
|
76
|
+
|
77
|
+
> cc(:products, :test).flux_capacitor => ---
|
78
|
+
:test_version:
|
79
|
+
:name: Yadayada
|
80
|
+
:price_in_cents: 666
|
81
|
+
:manual_pdf_url: http://staging.brown-inc.com/manuals/fc_10.pdf
|
82
|
+
|
83
|
+
Calling `complex_config(:products)` instead of `cc(…)` would skip the implicite
|
84
|
+
namespacing via the `RAILS_ENV` environment, so
|
85
|
+
`complex_config(:products).test.flux_capacitor` returns the same settings
|
86
|
+
object.
|
87
|
+
|
88
|
+
### Adding plugins
|
89
|
+
|
90
|
+
You can add your own plugins by calling
|
91
|
+
|
92
|
+
ComplexConfig::Provider.add_plugin SomeNamespace::PLUGIN
|
93
|
+
|
94
|
+
### Implementing your own plugins
|
95
|
+
|
96
|
+
A plugin is just a lambda expression with a single argument `id` which
|
97
|
+
identifies the attribute that is being accessed. If it calls `skip` it won't
|
98
|
+
apply and the following plugins are tried until one doesn't call `skip` and
|
99
|
+
returns a value instead.
|
100
|
+
|
101
|
+
Here is the `ComplexConfig::Plugins::MONEY` plugin for example:
|
102
|
+
|
103
|
+
require 'monetize'
|
104
|
+
|
105
|
+
module ComplexConfig::Plugins
|
106
|
+
MONEY = -> id do
|
107
|
+
if cents = ask_and_send("#{id}_in_cents")
|
108
|
+
Money.new(cents)
|
109
|
+
else
|
110
|
+
skip
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
## Changes
|
116
|
+
|
117
|
+
* 2014-12-12 Release 0.0.0
|
118
|
+
|
119
|
+
## Download
|
120
|
+
|
121
|
+
The homepage of this library is located at
|
122
|
+
|
123
|
+
* https://github.com/flori/complex_config
|
124
|
+
|
125
|
+
## Author
|
126
|
+
|
127
|
+
[Florian Frank](mailto:flori@ping.de)
|
128
|
+
|
129
|
+
## License
|
130
|
+
|
131
|
+
This software is licensed under the Apache 2.0 license.
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# vim: set filetype=ruby et sw=2 ts=2:
|
2
|
+
|
3
|
+
require 'gem_hadar'
|
4
|
+
|
5
|
+
GemHadar do
|
6
|
+
name 'complex_config'
|
7
|
+
author 'Florian Frank'
|
8
|
+
email 'flori@ping.de'
|
9
|
+
homepage "https://github.com/flori/#{name}"
|
10
|
+
summary 'configuration library'
|
11
|
+
description 'This library allows you to access configuration files via a simple interface'
|
12
|
+
test_dir 'spec'
|
13
|
+
ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', 'coverage', '.rvmrc', '.AppleDouble', '.DS_Store'
|
14
|
+
readme 'README.md'
|
15
|
+
title "#{name.camelize} -- configuration library"
|
16
|
+
licenses << 'Apache-2.0'
|
17
|
+
|
18
|
+
dependency 'json'
|
19
|
+
dependency 'monetize'
|
20
|
+
development_dependency 'rake'
|
21
|
+
development_dependency 'simplecov'
|
22
|
+
development_dependency 'rspec'
|
23
|
+
development_dependency 'byebug'
|
24
|
+
end
|
25
|
+
|
26
|
+
task :default => :spec
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# stub: complex_config 0.0.0 ruby lib
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "complex_config"
|
6
|
+
s.version = "0.0.0"
|
7
|
+
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
9
|
+
s.require_paths = ["lib"]
|
10
|
+
s.authors = ["Florian Frank"]
|
11
|
+
s.date = "2014-12-12"
|
12
|
+
s.description = "This library allows you to access configuration files via a simple interface"
|
13
|
+
s.email = "flori@ping.de"
|
14
|
+
s.extra_rdoc_files = ["README.md", "lib/complex_config.rb", "lib/complex_config/errors.rb", "lib/complex_config/plugins.rb", "lib/complex_config/plugins/enable.rb", "lib/complex_config/plugins/money.rb", "lib/complex_config/plugins/uri.rb", "lib/complex_config/provider.rb", "lib/complex_config/rude.rb", "lib/complex_config/settings.rb", "lib/complex_config/shortcuts.rb", "lib/complex_config/version.rb"]
|
15
|
+
s.files = [".gitignore", ".rspec", ".travis.yml", ".utilsrc", "Gemfile", "README.md", "Rakefile", "VERSION", "complex_config.gemspec", "lib/complex_config.rb", "lib/complex_config/errors.rb", "lib/complex_config/plugins.rb", "lib/complex_config/plugins/enable.rb", "lib/complex_config/plugins/money.rb", "lib/complex_config/plugins/uri.rb", "lib/complex_config/provider.rb", "lib/complex_config/rude.rb", "lib/complex_config/settings.rb", "lib/complex_config/shortcuts.rb", "lib/complex_config/version.rb", "spec/complex_config/plugins_spec.rb", "spec/complex_config/provider_spec.rb", "spec/complex_config/settings_spec.rb", "spec/complex_config/shortcuts_spec.rb", "spec/config/broken_config.yml", "spec/config/config.yml", "spec/spec_helper.rb"]
|
16
|
+
s.homepage = "https://github.com/flori/complex_config"
|
17
|
+
s.licenses = ["Apache-2.0"]
|
18
|
+
s.rdoc_options = ["--title", "ComplexConfig -- configuration library", "--main", "README.md"]
|
19
|
+
s.rubygems_version = "2.4.4"
|
20
|
+
s.summary = "configuration library"
|
21
|
+
s.test_files = ["spec/complex_config/plugins_spec.rb", "spec/complex_config/provider_spec.rb", "spec/complex_config/settings_spec.rb", "spec/complex_config/shortcuts_spec.rb", "spec/spec_helper.rb"]
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
s.specification_version = 4
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_development_dependency(%q<gem_hadar>, ["~> 1.0.0"])
|
28
|
+
s.add_development_dependency(%q<rake>, [">= 0"])
|
29
|
+
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
30
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
31
|
+
s.add_development_dependency(%q<byebug>, [">= 0"])
|
32
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
33
|
+
s.add_runtime_dependency(%q<monetize>, [">= 0"])
|
34
|
+
else
|
35
|
+
s.add_dependency(%q<gem_hadar>, ["~> 1.0.0"])
|
36
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
37
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
38
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
39
|
+
s.add_dependency(%q<byebug>, [">= 0"])
|
40
|
+
s.add_dependency(%q<json>, [">= 0"])
|
41
|
+
s.add_dependency(%q<monetize>, [">= 0"])
|
42
|
+
end
|
43
|
+
else
|
44
|
+
s.add_dependency(%q<gem_hadar>, ["~> 1.0.0"])
|
45
|
+
s.add_dependency(%q<rake>, [">= 0"])
|
46
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
47
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
48
|
+
s.add_dependency(%q<byebug>, [">= 0"])
|
49
|
+
s.add_dependency(%q<json>, [">= 0"])
|
50
|
+
s.add_dependency(%q<monetize>, [">= 0"])
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ComplexConfig
|
2
|
+
class ComplexConfigError < StandardError
|
3
|
+
def self.wrap(klass, e)
|
4
|
+
Class === klass or klass = ComplexConfig.const_get(klass)
|
5
|
+
error = klass.new(e.message)
|
6
|
+
error.set_backtrace(e.backtrace)
|
7
|
+
error
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class AttributeMissing < ComplexConfigError
|
12
|
+
end
|
13
|
+
|
14
|
+
class ConfigurationFileMissing < ComplexConfigError
|
15
|
+
end
|
16
|
+
|
17
|
+
class ConfigurationSyntaxError < ComplexConfigError
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'set'
|
2
|
+
require 'erb'
|
3
|
+
require 'pathname'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
class ComplexConfig::Provider
|
7
|
+
include Tins::SexySingleton
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@plugins = Set.new
|
11
|
+
end
|
12
|
+
|
13
|
+
attr_reader :plugins
|
14
|
+
|
15
|
+
def add_plugin(plugin)
|
16
|
+
@plugins.add plugin
|
17
|
+
self
|
18
|
+
end
|
19
|
+
|
20
|
+
def apply_plugins(setting, id)
|
21
|
+
@plugins.find do |plugin|
|
22
|
+
catch :skip do
|
23
|
+
value = setting.instance_exec(id, &plugin) and return value
|
24
|
+
end
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def pathname(name)
|
30
|
+
root + "config/#{name}.yml" % name
|
31
|
+
end
|
32
|
+
|
33
|
+
def config(pathname)
|
34
|
+
result = evaluate(pathname)
|
35
|
+
ComplexConfig::Settings[::YAML.load(result, pathname)]
|
36
|
+
rescue ::Errno::ENOENT => e
|
37
|
+
raise ComplexConfig::ComplexConfigError.wrap(:ConfigurationFileMissing, e)
|
38
|
+
rescue ::Psych::SyntaxError => e
|
39
|
+
raise ComplexConfig::ComplexConfigError.wrap(:ConfigurationSyntaxError, e)
|
40
|
+
end
|
41
|
+
|
42
|
+
def [](name)
|
43
|
+
config pathname(name)
|
44
|
+
end
|
45
|
+
memoize_method :[]
|
46
|
+
|
47
|
+
alias flush_cache memoize_cache_clear
|
48
|
+
|
49
|
+
def evaluate(pathname)
|
50
|
+
data = File.read pathname
|
51
|
+
erb = ::ERB.new(data)
|
52
|
+
erb.filename = pathname.to_s
|
53
|
+
erb.result
|
54
|
+
end
|
55
|
+
|
56
|
+
attr_writer :root
|
57
|
+
|
58
|
+
def root
|
59
|
+
@root || defined?(Rails) && Rails.root || Pathname.pwd
|
60
|
+
end
|
61
|
+
|
62
|
+
attr_writer :env
|
63
|
+
|
64
|
+
def env
|
65
|
+
@env || defined?(Rails) && Rails.env || ENV['RAILS_ENV'] || 'development'
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'tins/xt/ask_and_send'
|
3
|
+
|
4
|
+
class ComplexConfig::Settings < JSON::GenericObject
|
5
|
+
def self.[](*a)
|
6
|
+
from_hash *a
|
7
|
+
end
|
8
|
+
|
9
|
+
def each(&block)
|
10
|
+
table.each(&block)
|
11
|
+
end
|
12
|
+
include Enumerable
|
13
|
+
|
14
|
+
def attribute_set?(name)
|
15
|
+
table.key?(name.to_sym)
|
16
|
+
end
|
17
|
+
|
18
|
+
def attribute_names
|
19
|
+
table.keys
|
20
|
+
end
|
21
|
+
|
22
|
+
def attribute_values
|
23
|
+
table.values
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_h
|
27
|
+
each_with_object({}) do |(k, v), h|
|
28
|
+
h[k] = v.ask_and_send(:to_h) || v
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
to_h.to_yaml
|
34
|
+
end
|
35
|
+
|
36
|
+
alias inspect to_s
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def respond_to_missing?(id, include_private = false)
|
41
|
+
id =~ /\?\z/ || super
|
42
|
+
end
|
43
|
+
|
44
|
+
def skip
|
45
|
+
throw :skip
|
46
|
+
end
|
47
|
+
|
48
|
+
def method_missing(id, *a, &b)
|
49
|
+
case
|
50
|
+
when id =~ /\?\z/
|
51
|
+
begin
|
52
|
+
public_send $`.to_sym, *a, &b
|
53
|
+
rescue ComplexConfig::AttributeMissing
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
when id =~ /=\z/
|
57
|
+
super
|
58
|
+
when value = ComplexConfig::Provider.apply_plugins(self, id)
|
59
|
+
value
|
60
|
+
else
|
61
|
+
if attribute_set?(id)
|
62
|
+
super
|
63
|
+
else
|
64
|
+
raise ComplexConfig::AttributeMissing, "no attribute named #{id.inspect}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module ComplexConfig
|
2
|
+
# ComplexConfig version
|
3
|
+
VERSION = '0.0.0'
|
4
|
+
VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
|
5
|
+
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
|
6
|
+
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
|
7
|
+
VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
|
8
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'complex_config/plugins/enable'
|
3
|
+
|
4
|
+
RSpec.describe ComplexConfig::Settings do
|
5
|
+
let :provider do
|
6
|
+
ComplexConfig::Provider
|
7
|
+
end
|
8
|
+
|
9
|
+
let :settings do
|
10
|
+
ComplexConfig::Settings[
|
11
|
+
foo: {
|
12
|
+
test_url: 'http://www.ping.de',
|
13
|
+
cash_in_cents: 100.to_money.cents
|
14
|
+
}
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
context ComplexConfig::Plugins::URI do
|
19
|
+
it 'can return an URL string' do
|
20
|
+
expect(settings.foo.test_url).to eq 'http://www.ping.de'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'can return an URI' do
|
24
|
+
expect(settings.foo.test_uri).to eq URI.parse('http://www.ping.de')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'can skips if blub' do
|
28
|
+
expect { settings.foo.nix_uri }.to raise_error(ComplexConfig::AttributeMissing)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context ComplexConfig::Plugins::MONEY do
|
33
|
+
it 'can return a Fixnum' do
|
34
|
+
expect(settings.foo.cash_in_cents).to eq 100_00
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'can return a Money instance' do
|
38
|
+
expect(settings.foo.cash).to eq 100.to_money
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ComplexConfig::Provider do
|
4
|
+
let :provider do
|
5
|
+
ComplexConfig::Provider
|
6
|
+
end
|
7
|
+
|
8
|
+
context 'plugin' do
|
9
|
+
let :plugin do
|
10
|
+
-> id { __send__ id }
|
11
|
+
end
|
12
|
+
|
13
|
+
let :setting do
|
14
|
+
double('Setting')
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
provider.plugins.clear
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'can add one' do
|
22
|
+
expect { provider.add_plugin plugin }.to change { provider.plugins.size }.by(1)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'can apply plugins' do
|
26
|
+
provider.add_plugin plugin
|
27
|
+
expect(setting).to receive(:foo).and_return :bar
|
28
|
+
expect(provider.apply_plugins(setting, :foo)).to eq :bar
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'pathnames' do
|
33
|
+
module ::Rails
|
34
|
+
def self.root
|
35
|
+
end unless respond_to?(:root)
|
36
|
+
end
|
37
|
+
|
38
|
+
after do
|
39
|
+
provider.root = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'can compute default pathname' do
|
43
|
+
provider.root = Pathname.new('bar')
|
44
|
+
expect(provider.pathname('foo')).to eq Pathname.new('bar/config/foo.yml')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'can derive rails root from Rails.root if present' do
|
48
|
+
dir = Pathname.new('bar')
|
49
|
+
expect(Rails).to receive(:root).and_return(dir)
|
50
|
+
expect(provider.root).to eq dir
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'falls back to current working directory by default' do
|
54
|
+
expect(provider.root).to eq Pathname.pwd
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'reading configurations' do
|
59
|
+
it 'can read a configuration file' do
|
60
|
+
expect(
|
61
|
+
provider.config(asset('config.yml'))
|
62
|
+
).to be_a ComplexConfig::Settings
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'handles missing configuration files' do
|
66
|
+
expect { provider.config(asset('nix_config.yml')) }.to\
|
67
|
+
raise_error(ComplexConfig::ConfigurationFileMissing)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'handles syntax errors in configuration files' do
|
71
|
+
expect { provider.config(asset('broken_config.yml')) }.to\
|
72
|
+
raise_error(ComplexConfig::ConfigurationSyntaxError)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'handling configuration files with []' do
|
77
|
+
before do
|
78
|
+
provider.root = Pathname.new(__FILE__).dirname.dirname
|
79
|
+
end
|
80
|
+
|
81
|
+
after do
|
82
|
+
provider.flush_cache
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'returns the correct configuration' do
|
86
|
+
expect(provider['config']).to be_a ComplexConfig::Settings
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'caches the configuration after first use' do
|
90
|
+
expect {
|
91
|
+
expect(provider['config']).to be_a ComplexConfig::Settings
|
92
|
+
}.to change {
|
93
|
+
provider.instance.__send__(:__memoize_cache__).size
|
94
|
+
}.by(1)
|
95
|
+
expect(provider['config']).to be_a ComplexConfig::Settings
|
96
|
+
expect(provider).not_to receive(:config)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'can flush loaded configurations' do
|
100
|
+
expect(provider['config']).to be_a ComplexConfig::Settings
|
101
|
+
expect {
|
102
|
+
provider.flush_cache
|
103
|
+
}.to change {
|
104
|
+
provider.instance.__send__(:__memoize_cache__).size
|
105
|
+
}.by(-1)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'evaluating configuration files with ERB' do
|
110
|
+
it 'evaluates a config file correctly' do
|
111
|
+
expect(
|
112
|
+
provider.config(asset('config.yml')).development.config.pi
|
113
|
+
).to be_within(1e-6).of Math::PI
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context 'environment' do
|
118
|
+
module ::Rails
|
119
|
+
def self.env
|
120
|
+
end unless respond_to?(:env)
|
121
|
+
end
|
122
|
+
|
123
|
+
after do
|
124
|
+
provider.env = nil
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'can be set manually' do
|
128
|
+
provider.env = 'foobar'
|
129
|
+
expect(provider.env).to eq 'foobar'
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'can derive environments from Rails.env if present' do
|
133
|
+
expect(Rails).to receive(:env).and_return('foobar')
|
134
|
+
expect(provider.env).to eq 'foobar'
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'falls back to "development" as a default' do
|
138
|
+
expect(provider.env).to eq 'development'
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ComplexConfig::Settings do
|
4
|
+
let :provider do
|
5
|
+
ComplexConfig::Provider
|
6
|
+
end
|
7
|
+
|
8
|
+
let :settings do
|
9
|
+
ComplexConfig::Settings[
|
10
|
+
foo: {
|
11
|
+
bar: {
|
12
|
+
baz: true
|
13
|
+
},
|
14
|
+
qux: 'quux'
|
15
|
+
}
|
16
|
+
]
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'can display its attribute_names' do
|
20
|
+
expect(settings.foo.attribute_names).to eq %i[ bar qux ]
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'can display its attribute_values' do
|
24
|
+
values = settings.foo.attribute_values
|
25
|
+
expect(values.first.to_h).to eq(baz: true)
|
26
|
+
expect(values.last).to eq 'quux'
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'can return the value of an attribute' do
|
30
|
+
expect(settings.foo.bar.baz).to eq true
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'can be converted into a hash' do
|
34
|
+
expect(settings.foo.to_h).to eq(bar: { baz: true }, qux: 'quux')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'can be represented as a string' do
|
38
|
+
expect(settings.to_s).to eq <<EOT
|
39
|
+
---
|
40
|
+
:foo:
|
41
|
+
:bar:
|
42
|
+
:baz: true
|
43
|
+
:qux: quux
|
44
|
+
EOT
|
45
|
+
end
|
46
|
+
it 'raises exception if expected attribute is missing' do
|
47
|
+
skip "doesn't work in spec?!?" # XXX
|
48
|
+
expect { settings.foo.baz }.to raise_error(ComplexConfig::AttributeMissing)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'can be checked for set attributes' do
|
52
|
+
expect(settings.foo.attribute_set?(:bar)).to eq true
|
53
|
+
expect(settings.foo.bar?).to be_truthy
|
54
|
+
expect(settings.foo.attribute_set?(:baz)).to eq false
|
55
|
+
# XXX doesn't work in spec?!? expect(settings.foo.baz?).to be_falsy
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'complex_config/shortcuts'
|
3
|
+
|
4
|
+
RSpec.describe 'shortcuts' do
|
5
|
+
let :provider do
|
6
|
+
ComplexConfig::Provider
|
7
|
+
end
|
8
|
+
|
9
|
+
before do
|
10
|
+
provider.root = Pathname.new(__FILE__).dirname.dirname
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'has the complex_config_with_env "shortcut"' do
|
14
|
+
settings = complex_config_with_env('config', 'development')
|
15
|
+
expect(settings).to be_a ComplexConfig::Settings
|
16
|
+
expect(settings.config.baz).to eq 'something'
|
17
|
+
settings = complex_config_with_env('config', 'test')
|
18
|
+
expect(settings).to be_a ComplexConfig::Settings
|
19
|
+
expect(settings.config.baz).to eq 'something else'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'has the alias cc for complex_config_with_env' do
|
23
|
+
settings = cc(:config, :development)
|
24
|
+
expect(settings).to be_a ComplexConfig::Settings
|
25
|
+
expect(settings.config.baz).to eq 'something'
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'considers the environment for complex_config_with_env' do
|
29
|
+
settings = complex_config_with_env('config')
|
30
|
+
expect(settings).to be_a ComplexConfig::Settings
|
31
|
+
expect(settings.config.baz).to eq 'something'
|
32
|
+
allow(provider).to receive(:env).and_return('test')
|
33
|
+
settings = complex_config_with_env('config')
|
34
|
+
expect(settings).to be_a ComplexConfig::Settings
|
35
|
+
expect(settings.config.baz).to eq 'something else'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'has the complex_config shortcut' do
|
39
|
+
settings = complex_config(:config)
|
40
|
+
expect(settings).to be_a ComplexConfig::Settings
|
41
|
+
expect(settings.development.config.baz).to eq 'something'
|
42
|
+
expect(settings.test.config.baz).to eq 'something else'
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
,kaput
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
if ENV['START_SIMPLECOV'].to_i == 1
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter "#{File.basename(File.dirname(__FILE__))}/"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
if ENV.key?('CODECLIMATE_REPO_TOKEN')
|
9
|
+
begin
|
10
|
+
require "codeclimate-test-reporter"
|
11
|
+
rescue LoadError => e
|
12
|
+
warn "Caught #{e.class}: #{e.message} loading codeclimate-test-reporter"
|
13
|
+
else
|
14
|
+
CodeClimate::TestReporter.start
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'rspec'
|
19
|
+
require 'byebug'
|
20
|
+
require 'complex_config'
|
21
|
+
|
22
|
+
def config_dir
|
23
|
+
Pathname.new(__FILE__).dirname + "config"
|
24
|
+
end
|
25
|
+
|
26
|
+
def asset(name)
|
27
|
+
config_dir + name
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: complex_config
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Florian Frank
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-12-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: gem_hadar
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.0.0
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: simplecov
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: byebug
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: json
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: monetize
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: This library allows you to access configuration files via a simple interface
|
112
|
+
email: flori@ping.de
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files:
|
116
|
+
- README.md
|
117
|
+
- lib/complex_config.rb
|
118
|
+
- lib/complex_config/errors.rb
|
119
|
+
- lib/complex_config/plugins.rb
|
120
|
+
- lib/complex_config/plugins/enable.rb
|
121
|
+
- lib/complex_config/plugins/money.rb
|
122
|
+
- lib/complex_config/plugins/uri.rb
|
123
|
+
- lib/complex_config/provider.rb
|
124
|
+
- lib/complex_config/rude.rb
|
125
|
+
- lib/complex_config/settings.rb
|
126
|
+
- lib/complex_config/shortcuts.rb
|
127
|
+
- lib/complex_config/version.rb
|
128
|
+
files:
|
129
|
+
- ".gitignore"
|
130
|
+
- ".rspec"
|
131
|
+
- ".travis.yml"
|
132
|
+
- ".utilsrc"
|
133
|
+
- Gemfile
|
134
|
+
- README.md
|
135
|
+
- Rakefile
|
136
|
+
- VERSION
|
137
|
+
- complex_config.gemspec
|
138
|
+
- lib/complex_config.rb
|
139
|
+
- lib/complex_config/errors.rb
|
140
|
+
- lib/complex_config/plugins.rb
|
141
|
+
- lib/complex_config/plugins/enable.rb
|
142
|
+
- lib/complex_config/plugins/money.rb
|
143
|
+
- lib/complex_config/plugins/uri.rb
|
144
|
+
- lib/complex_config/provider.rb
|
145
|
+
- lib/complex_config/rude.rb
|
146
|
+
- lib/complex_config/settings.rb
|
147
|
+
- lib/complex_config/shortcuts.rb
|
148
|
+
- lib/complex_config/version.rb
|
149
|
+
- spec/complex_config/plugins_spec.rb
|
150
|
+
- spec/complex_config/provider_spec.rb
|
151
|
+
- spec/complex_config/settings_spec.rb
|
152
|
+
- spec/complex_config/shortcuts_spec.rb
|
153
|
+
- spec/config/broken_config.yml
|
154
|
+
- spec/config/config.yml
|
155
|
+
- spec/spec_helper.rb
|
156
|
+
homepage: https://github.com/flori/complex_config
|
157
|
+
licenses:
|
158
|
+
- Apache-2.0
|
159
|
+
metadata: {}
|
160
|
+
post_install_message:
|
161
|
+
rdoc_options:
|
162
|
+
- "--title"
|
163
|
+
- ComplexConfig -- configuration library
|
164
|
+
- "--main"
|
165
|
+
- README.md
|
166
|
+
require_paths:
|
167
|
+
- lib
|
168
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
requirements: []
|
179
|
+
rubyforge_project:
|
180
|
+
rubygems_version: 2.4.4
|
181
|
+
signing_key:
|
182
|
+
specification_version: 4
|
183
|
+
summary: configuration library
|
184
|
+
test_files:
|
185
|
+
- spec/complex_config/plugins_spec.rb
|
186
|
+
- spec/complex_config/provider_spec.rb
|
187
|
+
- spec/complex_config/settings_spec.rb
|
188
|
+
- spec/complex_config/shortcuts_spec.rb
|
189
|
+
- spec/spec_helper.rb
|