centroid 0.1.1 → 1.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 +4 -4
- data/README.md +91 -91
- data/centroid.gemspec +11 -11
- data/lib/centroid.rb +76 -63
- data/test/centroid_test.rb +87 -71
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f35b492a4ea8767187a77faae2f6b6bd5d5a66b6
|
4
|
+
data.tar.gz: 9fe53378ae98e8b4175dba7fe6af296e7fd9ad0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7585bc76ed87101a41c3b46d7febd24f9fdefb4df32ed7bba4b5af60f15d6339f4a90d015d8a14a5aaa32b1d717a94af5acbc1a6ddd8410634fb6a07eaf87de0
|
7
|
+
data.tar.gz: fc57f08f83b93363132a68c6f866c9f5723834fd400c690d11a68776d826f5250f266eadc9a871e432f1f5fb5a92f3aed8e5ad91143113e054c4c86b7dcfdfda
|
data/README.md
CHANGED
@@ -1,91 +1,91 @@
|
|
1
|
-
# Centroid - Ruby
|
2
|
-
|
3
|
-
## Installation
|
4
|
-
|
5
|
-
The Centroid Ruby package is hosted at [rubygems.org](https://rubygems.org/gems/centroid).
|
6
|
-
|
7
|
-
You can install Centroid using gem with `gem install centroid`, or you can clone the repo, then `gem build centroid.gemspec`, and `gem install -l centroid` from the `ruby/` directory.
|
8
|
-
|
9
|
-
## Usage
|
10
|
-
|
11
|
-
Begin by declaring your application's configuration values in JSON. The following example stores the database's server address.
|
12
|
-
|
13
|
-
```json
|
14
|
-
{
|
15
|
-
"database": {
|
16
|
-
"serverAddress": "my-server.local"
|
17
|
-
}
|
18
|
-
}
|
19
|
-
```
|
20
|
-
|
21
|
-
With Centroid's API, Ruby applications can then use the configuration values in this JSON.
|
22
|
-
|
23
|
-
### Ruby API
|
24
|
-
|
25
|
-
The Ruby API is available through the `Centroid::Config` class, an instance of which is used to consume the JSON.
|
26
|
-
|
27
|
-
The `Config` class exposes the `from_file` class method, an initializer, and the instance method `for_environment`.
|
28
|
-
|
29
|
-
#### from_file(filename)
|
30
|
-
|
31
|
-
You can create an instance of `Config` from a JSON file using the `Centroid::Config.from_file(filename)` class method.
|
32
|
-
|
33
|
-
In the example below, note the `serverAddress` configuration value is retrieved using the snake_case `server_address` method even though the value is specified as camelCase in the JSON.
|
34
|
-
|
35
|
-
```rb
|
36
|
-
# from_file.rb
|
37
|
-
config = Centroid::Config.from_file("config.json")
|
38
|
-
server = config.database.server_address # => "my-server.local"
|
39
|
-
```
|
40
|
-
|
41
|
-
### Config(json)
|
42
|
-
|
43
|
-
Alternatively, you can create an instance of `Config` by passing a JSON string to the `Config` initializer.
|
44
|
-
|
45
|
-
```rb
|
46
|
-
# from_string.rb
|
47
|
-
json = '{ "database": { "serverAddress": "my-server.local" } }'
|
48
|
-
config = Centroid::Config(json)
|
49
|
-
server = config.database.server_address # => "my-server.local"
|
50
|
-
```
|
51
|
-
|
52
|
-
### for_enviroment(environment)
|
53
|
-
|
54
|
-
Typically, real-world applications have different configuration values depending on the environment. For example, you might have *dev* and *prod* environments that use different servers, user accounts, etc. However, applications usually have other configuration values that are the same across all environments. Centroid makes it easy to retrieve all the configuration values you need for a specific environment.
|
55
|
-
|
56
|
-
In environment-based configuration, the top-level objects in the JSON represent the various environments. Place the configuration values that are the same across all environments within the *all* environment.
|
57
|
-
|
58
|
-
```json
|
59
|
-
{
|
60
|
-
"dev": {
|
61
|
-
"someResource": {
|
62
|
-
"server": "resource-dev.local"
|
63
|
-
}
|
64
|
-
},
|
65
|
-
"prod": {
|
66
|
-
"someResource": {
|
67
|
-
"server": "resource-prod.local"
|
68
|
-
}
|
69
|
-
},
|
70
|
-
"all": {
|
71
|
-
"keys": {
|
72
|
-
"ssh": "path/to/id_rsa.pub"
|
73
|
-
}
|
74
|
-
}
|
75
|
-
}
|
76
|
-
```
|
77
|
-
|
78
|
-
Then, in the `Config` instance, use the instance method `for_environment` to retrieve the environment-based configuration. Centroid merges the requested environment's configuration values with the *all* environment configuration values.
|
79
|
-
|
80
|
-
In the following example, the configuration for `prod` is merged with the configuration from `all`; the result is then available from a new instance of `Config`.
|
81
|
-
|
82
|
-
```rb
|
83
|
-
# for_enviroment.rb
|
84
|
-
config = Centroid::Config.from_file("config.json").for_environment("prod")
|
85
|
-
server = config.some_resource.server # => "resource-prod.local"
|
86
|
-
solution_path = config.keys.ssh # => "path/to/id_rsa.pub"
|
87
|
-
```
|
88
|
-
|
89
|
-
## Contributing
|
90
|
-
|
91
|
-
See the [contributing section of the main README](../README.md#contributing)
|
1
|
+
# Centroid - Ruby
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
The Centroid Ruby package is hosted at [rubygems.org](https://rubygems.org/gems/centroid).
|
6
|
+
|
7
|
+
You can install Centroid using gem with `gem install centroid`, or you can clone the repo, then `gem build centroid.gemspec`, and `gem install -l centroid` from the `ruby/` directory.
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
Begin by declaring your application's configuration values in JSON. The following example stores the database's server address.
|
12
|
+
|
13
|
+
```json
|
14
|
+
{
|
15
|
+
"database": {
|
16
|
+
"serverAddress": "my-server.local"
|
17
|
+
}
|
18
|
+
}
|
19
|
+
```
|
20
|
+
|
21
|
+
With Centroid's API, Ruby applications can then use the configuration values in this JSON.
|
22
|
+
|
23
|
+
### Ruby API
|
24
|
+
|
25
|
+
The Ruby API is available through the `Centroid::Config` class, an instance of which is used to consume the JSON.
|
26
|
+
|
27
|
+
The `Config` class exposes the `from_file` class method, an initializer, and the instance method `for_environment`.
|
28
|
+
|
29
|
+
#### from_file(filename)
|
30
|
+
|
31
|
+
You can create an instance of `Config` from a JSON file using the `Centroid::Config.from_file(filename)` class method.
|
32
|
+
|
33
|
+
In the example below, note the `serverAddress` configuration value is retrieved using the snake_case `server_address` method even though the value is specified as camelCase in the JSON.
|
34
|
+
|
35
|
+
```rb
|
36
|
+
# from_file.rb
|
37
|
+
config = Centroid::Config.from_file("config.json")
|
38
|
+
server = config.database.server_address # => "my-server.local"
|
39
|
+
```
|
40
|
+
|
41
|
+
### Config(json)
|
42
|
+
|
43
|
+
Alternatively, you can create an instance of `Config` by passing a JSON string to the `Config` initializer.
|
44
|
+
|
45
|
+
```rb
|
46
|
+
# from_string.rb
|
47
|
+
json = '{ "database": { "serverAddress": "my-server.local" } }'
|
48
|
+
config = Centroid::Config(json)
|
49
|
+
server = config.database.server_address # => "my-server.local"
|
50
|
+
```
|
51
|
+
|
52
|
+
### for_enviroment(environment)
|
53
|
+
|
54
|
+
Typically, real-world applications have different configuration values depending on the environment. For example, you might have *dev* and *prod* environments that use different servers, user accounts, etc. However, applications usually have other configuration values that are the same across all environments. Centroid makes it easy to retrieve all the configuration values you need for a specific environment.
|
55
|
+
|
56
|
+
In environment-based configuration, the top-level objects in the JSON represent the various environments. Place the configuration values that are the same across all environments within the *all* environment.
|
57
|
+
|
58
|
+
```json
|
59
|
+
{
|
60
|
+
"dev": {
|
61
|
+
"someResource": {
|
62
|
+
"server": "resource-dev.local"
|
63
|
+
}
|
64
|
+
},
|
65
|
+
"prod": {
|
66
|
+
"someResource": {
|
67
|
+
"server": "resource-prod.local"
|
68
|
+
}
|
69
|
+
},
|
70
|
+
"all": {
|
71
|
+
"keys": {
|
72
|
+
"ssh": "path/to/id_rsa.pub"
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
```
|
77
|
+
|
78
|
+
Then, in the `Config` instance, use the instance method `for_environment` to retrieve the environment-based configuration. Centroid merges the requested environment's configuration values with the *all* environment configuration values.
|
79
|
+
|
80
|
+
In the following example, the configuration for `prod` is merged with the configuration from `all`; the result is then available from a new instance of `Config`.
|
81
|
+
|
82
|
+
```rb
|
83
|
+
# for_enviroment.rb
|
84
|
+
config = Centroid::Config.from_file("config.json").for_environment("prod")
|
85
|
+
server = config.some_resource.server # => "resource-prod.local"
|
86
|
+
solution_path = config.keys.ssh # => "path/to/id_rsa.pub"
|
87
|
+
```
|
88
|
+
|
89
|
+
## Contributing
|
90
|
+
|
91
|
+
See the [contributing section of the main README](../README.md#contributing)
|
data/centroid.gemspec
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
Gem::Specification.new do |s|
|
2
|
-
s.name = 'centroid'
|
3
|
-
s.version = '0.
|
4
|
-
s.summary = 'A centralizaed paradigm to configuration management.'
|
5
|
-
s.description = 'Centroid is a tool for loading configuration values declared in JSON, and accessing those configuration values using object properties.'
|
6
|
-
s.author = 'Resource Data, Inc'
|
7
|
-
s.email = 'oss@resdat.com'
|
8
|
-
s.files = `git ls-files`.split("\n")
|
9
|
-
s.homepage = 'https://github.com/ResourceDataInc/Centroid'
|
10
|
-
s.license = 'MIT'
|
11
|
-
end
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'centroid'
|
3
|
+
s.version = '1.0.0'
|
4
|
+
s.summary = 'A centralizaed paradigm to configuration management.'
|
5
|
+
s.description = 'Centroid is a tool for loading configuration values declared in JSON, and accessing those configuration values using object properties.'
|
6
|
+
s.author = 'Resource Data, Inc'
|
7
|
+
s.email = 'oss@resdat.com'
|
8
|
+
s.files = `git ls-files`.split("\n")
|
9
|
+
s.homepage = 'https://github.com/ResourceDataInc/Centroid'
|
10
|
+
s.license = 'MIT'
|
11
|
+
end
|
data/lib/centroid.rb
CHANGED
@@ -1,63 +1,76 @@
|
|
1
|
-
require "json"
|
2
|
-
|
3
|
-
module Centroid
|
4
|
-
class Config
|
5
|
-
attr_reader :raw_config
|
6
|
-
|
7
|
-
def initialize(config)
|
8
|
-
if config.is_a?(Hash)
|
9
|
-
@raw_config = config
|
10
|
-
else
|
11
|
-
@raw_config = JSON.parse(config)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
1
|
+
require "json"
|
2
|
+
|
3
|
+
module Centroid
|
4
|
+
class Config
|
5
|
+
attr_reader :raw_config
|
6
|
+
|
7
|
+
def initialize(config)
|
8
|
+
if config.is_a?(Hash)
|
9
|
+
@raw_config = config
|
10
|
+
else
|
11
|
+
@raw_config = JSON.parse(config)
|
12
|
+
validate_unique_keys!
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def method_missing(attrib, *)
|
17
|
+
self[attrib]
|
18
|
+
end
|
19
|
+
|
20
|
+
def [](key)
|
21
|
+
value = find_value(key, raw_config)
|
22
|
+
|
23
|
+
raise KeyError.new("Centroid::Config instance does not contain key: #{key}") if value.nil?
|
24
|
+
|
25
|
+
if value.is_a?(Hash)
|
26
|
+
Config.new(value)
|
27
|
+
else
|
28
|
+
value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_s
|
33
|
+
JSON.dump(raw_config)
|
34
|
+
end
|
35
|
+
|
36
|
+
def for_environment(env)
|
37
|
+
env_json = raw_config[env]
|
38
|
+
all_key = actual_key("all", raw_config)
|
39
|
+
if all_key.nil?
|
40
|
+
Config.new(env_json)
|
41
|
+
else
|
42
|
+
all_json = raw_config[all_key]
|
43
|
+
Config.new(all_json.merge(env_json))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.from_file(filename)
|
48
|
+
str_json = File.read(filename)
|
49
|
+
self.new(str_json)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def normalize_key(unnormalised_key)
|
55
|
+
unnormalised_key.to_s.gsub("_", "").downcase
|
56
|
+
end
|
57
|
+
|
58
|
+
def find_value(key, hashtable)
|
59
|
+
hashtable[actual_key(key, hashtable)]
|
60
|
+
end
|
61
|
+
|
62
|
+
def actual_key(key, hashtable)
|
63
|
+
hashtable.keys.find { |k| normalize_key(key) == normalize_key(k) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def validate_unique_keys!
|
67
|
+
normalized_keys = raw_config.keys.map { |k| { key: k, normalized_key: normalize_key(k) } }
|
68
|
+
dups = normalized_keys.group_by { |nk| nk[:normalized_key] }.select { |_, g| g.size > 1 }
|
69
|
+
|
70
|
+
return if dups.empty?
|
71
|
+
|
72
|
+
keys = dups.values.flat_map { |d| d.map { |e| e[:key] } }
|
73
|
+
raise KeyError, "Centroid::Config instance contains duplicate keys: #{keys.join(', ')}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/test/centroid_test.rb
CHANGED
@@ -1,71 +1,87 @@
|
|
1
|
-
require_relative "../lib/centroid"
|
2
|
-
require "test/unit"
|
3
|
-
require "json"
|
4
|
-
|
5
|
-
class ConfigTests < Test::Unit::TestCase
|
6
|
-
def json_config
|
7
|
-
'{"Environment":{"TheKey":"TheValue"}}'
|
8
|
-
end
|
9
|
-
|
10
|
-
def shared_file_path
|
11
|
-
'config.json'
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_create_from_string
|
15
|
-
config = Centroid::Config.new(json_config)
|
16
|
-
assert_equal(config.environment.the_key, "TheValue")
|
17
|
-
end
|
18
|
-
|
19
|
-
def test_create_from_file
|
20
|
-
config = Centroid::Config.from_file(shared_file_path)
|
21
|
-
assert_equal(config.dev.database.server, "sqldev01.centroid.local")
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_raises_if_key_not_found
|
25
|
-
config = Centroid::Config.new(json_config)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
config
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
config
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
1
|
+
require_relative "../lib/centroid"
|
2
|
+
require "test/unit"
|
3
|
+
require "json"
|
4
|
+
|
5
|
+
class ConfigTests < Test::Unit::TestCase
|
6
|
+
def json_config
|
7
|
+
'{"Environment":{"TheKey":"TheValue"}}'
|
8
|
+
end
|
9
|
+
|
10
|
+
def shared_file_path
|
11
|
+
'config.json'
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_create_from_string
|
15
|
+
config = Centroid::Config.new(json_config)
|
16
|
+
assert_equal(config.environment.the_key, "TheValue")
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_create_from_file
|
20
|
+
config = Centroid::Config.from_file(shared_file_path)
|
21
|
+
assert_equal(config.dev.database.server, "sqldev01.centroid.local")
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_raises_if_key_not_found
|
25
|
+
config = Centroid::Config.new(json_config)
|
26
|
+
|
27
|
+
exception = assert_raise KeyError do
|
28
|
+
config = config.does_not_exist
|
29
|
+
end
|
30
|
+
|
31
|
+
assert exception.message =~ /does not contain/i, "Message should indicate key does not exist"
|
32
|
+
assert exception.message =~ /does_not_exist/, "Message should contain missing key"
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_raises_if_duplicate_normalized_keys_exist
|
36
|
+
json = '{ "someKey": "value", "some_key": "value" }'
|
37
|
+
|
38
|
+
exception = assert_raise KeyError do
|
39
|
+
Centroid::Config.new(json)
|
40
|
+
end
|
41
|
+
|
42
|
+
assert exception.message =~ /duplicate/i, "Message should indicate duplicate key"
|
43
|
+
assert exception.message =~ /someKey/, "Message should contain duplicate key"
|
44
|
+
assert exception.message =~ /some_key/, "Message should contain duplicate key"
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_readable_using_snake_case_property
|
48
|
+
config = Centroid::Config.new(json_config)
|
49
|
+
assert_equal(config.environment.the_key, "TheValue")
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_environment_specific_config_is_included
|
53
|
+
config = Centroid::Config.new(json_config)
|
54
|
+
environment_config = config.for_environment("Environment")
|
55
|
+
assert_equal(environment_config.the_key, "TheValue")
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_shared_config_is_included
|
59
|
+
config = Centroid::Config.from_file(shared_file_path)
|
60
|
+
config = config.for_environment("Dev")
|
61
|
+
assert_equal(config.ci.repo, "https://github.com/ResourceDataInc/Centroid")
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_to_string_returns_json
|
65
|
+
config = Centroid::Config.new(json_config)
|
66
|
+
assert_equal(config.to_s, json_config)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_iterating_raw_config
|
70
|
+
config = Centroid::Config.from_file(shared_file_path)
|
71
|
+
keyCount = 0
|
72
|
+
config.raw_config.each { |k| keyCount += 1 }
|
73
|
+
assert_equal(keyCount, 4)
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_modifying_raw_config
|
77
|
+
config = Centroid::Config.new(json_config)
|
78
|
+
config.raw_config["Environment"]["TheKey"] = "NotTheValue"
|
79
|
+
assert_equal(config.environment.the_key, "NotTheValue")
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_environment_specific_config_overrides_all
|
83
|
+
config = Centroid::Config.new('{"Prod": {"Shared": "production!"}, "All": {"Shared": "none"}}')
|
84
|
+
config = config.for_environment("Prod")
|
85
|
+
assert_equal(config.shared, "production!")
|
86
|
+
end
|
87
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: centroid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Resource Data, Inc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-02-
|
11
|
+
date: 2014-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Centroid is a tool for loading configuration values declared in JSON,
|
14
14
|
and accessing those configuration values using object properties.
|
@@ -31,17 +31,17 @@ require_paths:
|
|
31
31
|
- lib
|
32
32
|
required_ruby_version: !ruby/object:Gem::Requirement
|
33
33
|
requirements:
|
34
|
-
- -
|
34
|
+
- - ">="
|
35
35
|
- !ruby/object:Gem::Version
|
36
36
|
version: '0'
|
37
37
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- -
|
39
|
+
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
42
|
requirements: []
|
43
43
|
rubyforge_project:
|
44
|
-
rubygems_version: 2.2.
|
44
|
+
rubygems_version: 2.2.0
|
45
45
|
signing_key:
|
46
46
|
specification_version: 4
|
47
47
|
summary: A centralizaed paradigm to configuration management.
|