config_layers 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.gitreview +4 -0
- data/.rspec +2 -0
- data/.rubocop.yml +33 -0
- data/Gemfile +4 -0
- data/README.md +161 -0
- data/Rakefile +27 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/config_layers.gemspec +28 -0
- data/lib/config_layers/version.rb +4 -0
- data/lib/config_layers.rb +38 -0
- data/lib/prc_base_config.rb +309 -0
- data/lib/prc_core_config.rb +1218 -0
- data/lib/prc_section_config.rb +90 -0
- metadata +143 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: c3f2439ed377f78c7280ee7eb27b2d6b077688a5
|
4
|
+
data.tar.gz: e4ddb0c54bdbfd14a249e209dabfba7aaa87cdab
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 82c7d7d882993984abe7d452df09753e87d9f63b6d68a1f12351658ea25f774e32b44fe15edf9503710d907a2d39da6d79df1da62425ee6bdac6722e8640af34
|
7
|
+
data.tar.gz: 88de4f1b5081874d8da6dbb19627f5343952b059fc5c732d3283bac3eed3a8fee1e03bfc228de641a2212cd37ce66b6ab1264d6309eaf30778b1aea2756eef4d
|
data/.gitignore
ADDED
data/.gitreview
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# Copyright 2013 Hewlett-Packard Development Company, L.P.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
# use: rubocop --show-cops
|
16
|
+
# to validate configuration.
|
17
|
+
# rubocop config
|
18
|
+
AllCops:
|
19
|
+
Include:
|
20
|
+
- '**/Rakefile'
|
21
|
+
Style/HashSyntax:
|
22
|
+
EnforcedStyle: hash_rockets
|
23
|
+
|
24
|
+
# lets start with 40, but 10 is way to small..
|
25
|
+
Metrics/MethodLength:
|
26
|
+
Max: 40
|
27
|
+
# If Method length is increased, class length need to be extended as well.
|
28
|
+
Metrics/ClassLength:
|
29
|
+
Max: 150
|
30
|
+
|
31
|
+
# allow arguments to be longer than 15
|
32
|
+
Metrics/AbcSize:
|
33
|
+
Max: 40
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
# ConfigLayers
|
2
|
+
|
3
|
+
ConfigLayers is a library which help to manage a complex configuration hierarchy, (Hash of Hashes/Array/...)
|
4
|
+
per layers.
|
5
|
+
|
6
|
+
* What kind of complexity are we trying to resolve?
|
7
|
+
|
8
|
+
If you are using yaml or json, you can write anything in that format in some configuration file.
|
9
|
+
Ex:
|
10
|
+
|
11
|
+
:global:
|
12
|
+
:url: http://url.example.org
|
13
|
+
:options:
|
14
|
+
:timeout: 60
|
15
|
+
:port: 4708
|
16
|
+
:application
|
17
|
+
:publish: [ help, about, main, go ]
|
18
|
+
|
19
|
+
When you load this yaml, you are going to get a Hash containing hash/array/string/... etc...
|
20
|
+
then, when you want to access :timeout, you access it like that:
|
21
|
+
|
22
|
+
timeout = data[:global][:options][:timeout]
|
23
|
+
|
24
|
+
If your data has this Hash of Hash of Hash, loaded in memory, then you get the data.
|
25
|
+
But you need to manage the exception or do some test for each Hash, otherwise you get a
|
26
|
+
nil exception.
|
27
|
+
|
28
|
+
ConfigLayers simplify this:
|
29
|
+
|
30
|
+
- access ':timeout' :
|
31
|
+
|
32
|
+
config = PRC::BaseConfig.new(data)
|
33
|
+
|
34
|
+
timeout = config[:global, :options, :timeout]
|
35
|
+
|
36
|
+
No need to add any test.
|
37
|
+
|
38
|
+
- set ':timeout' :
|
39
|
+
|
40
|
+
config[:global, :options, :timeout] = 60
|
41
|
+
|
42
|
+
No need to create the Hash structure to set the ':timeout'
|
43
|
+
|
44
|
+
ConfigLayer embed YAML, so you can load and save this data from/to a yaml file...
|
45
|
+
|
46
|
+
config.save(filename)
|
47
|
+
config.load(filename)
|
48
|
+
|
49
|
+
You can check the key existence as well!
|
50
|
+
|
51
|
+
if config.exist?(:global, :options, :timeout)
|
52
|
+
<do things>
|
53
|
+
end
|
54
|
+
|
55
|
+
* What is that layer notion in ConfigLayers?
|
56
|
+
|
57
|
+
If you have an application which has some predefine default, a system config, a user config
|
58
|
+
and an account config, you may want to get a consolidated environment that you want to use.
|
59
|
+
|
60
|
+
if we are back in the previous ':timeout' example, let's say that :
|
61
|
+
- application default for timeout is. 60
|
62
|
+
- the system config has no timeout data.
|
63
|
+
- the user config has 120
|
64
|
+
- and the user load an account file that also has a timeout to 90
|
65
|
+
|
66
|
+
If the application run, with the account data loaded, when the application wants to get the timeout data
|
67
|
+
|
68
|
+
you expect to just read it! But you need to check if found in account, use it, otherwise check in user
|
69
|
+
config, etc... until the application defaults if none of those previous configuration file has the :timeout
|
70
|
+
setting...
|
71
|
+
|
72
|
+
Here with ConfigLayers, you create a class based on CoreConfig and you define those layers.
|
73
|
+
then you just access you data!
|
74
|
+
|
75
|
+
Ex: This is a real simple example.
|
76
|
+
|
77
|
+
# We define layers
|
78
|
+
class MyConfigApp < PRC::CoreConfig
|
79
|
+
def initialize(files)
|
80
|
+
config_layers = []
|
81
|
+
|
82
|
+
# Application default layer
|
83
|
+
config_layers << define_default_layer
|
84
|
+
|
85
|
+
# runtime Config layer
|
86
|
+
config_layers << define_layer('system', files[0])
|
87
|
+
|
88
|
+
# User Config layer
|
89
|
+
config_layers << define_layer('user', files[1])
|
90
|
+
|
91
|
+
# Account config layer
|
92
|
+
config_layers << define_layer('account', files[2]))
|
93
|
+
|
94
|
+
initialize_layers(config_layers)
|
95
|
+
end
|
96
|
+
|
97
|
+
def define_layer(name, filename)
|
98
|
+
config = PRC::BaseConfig.new()
|
99
|
+
config.load(filename)
|
100
|
+
PRC::CoreConfig.define_layer(:name => name,
|
101
|
+
:config => config,
|
102
|
+
:file_set => true,
|
103
|
+
:load => true, :save => true)
|
104
|
+
end
|
105
|
+
|
106
|
+
def define_default_layer
|
107
|
+
config = PRC.BaseConfig()
|
108
|
+
config[:global, :options, :timeout] = 60
|
109
|
+
PRC::CoreConfig.define_layer(:name => 'default',
|
110
|
+
:config => config)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Using my ConfigLayers
|
115
|
+
files = ['/etc/myapp.yaml', '~/.myapp.yaml', '~/.conf/account/myaccount.yaml']
|
116
|
+
config = MyConfigApp.new(files)
|
117
|
+
|
118
|
+
[...]
|
119
|
+
|
120
|
+
puts config[:global, :options, :timeout]
|
121
|
+
|
122
|
+
|
123
|
+
As you saw, we define the layer, load or set it, assign a name and declare in a new class
|
124
|
+
and just use that class...
|
125
|
+
|
126
|
+
You can do strongly more.
|
127
|
+
|
128
|
+
You can define you own layer, you can redefine how your access data.
|
129
|
+
For example, you can ignore some layers...
|
130
|
+
|
131
|
+
You can get a full consolidated data, with merge!
|
132
|
+
|
133
|
+
## Installation
|
134
|
+
|
135
|
+
Add this line to your application's Gemfile:
|
136
|
+
|
137
|
+
```ruby
|
138
|
+
gem 'config_layers'
|
139
|
+
```
|
140
|
+
|
141
|
+
And then execute:
|
142
|
+
|
143
|
+
$ bundle
|
144
|
+
|
145
|
+
Or install it yourself as:
|
146
|
+
|
147
|
+
$ gem install config_layers
|
148
|
+
|
149
|
+
## Development
|
150
|
+
|
151
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
152
|
+
|
153
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
154
|
+
|
155
|
+
## Contributing
|
156
|
+
|
157
|
+
1. Fork it ( https://github.com/[my-github-username]/config_layers/fork )
|
158
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
159
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
160
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
161
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'rubocop/rake_task'
|
4
|
+
require 'rdoc/task'
|
5
|
+
|
6
|
+
task :default => [:lint, :spec]
|
7
|
+
|
8
|
+
desc 'Run the specs.'
|
9
|
+
RSpec::Core::RakeTask.new do |t|
|
10
|
+
t.pattern = 'spec/*_spec.rb'
|
11
|
+
t.rspec_opts = '-f doc'
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Generate lorj documentation'
|
15
|
+
RDoc::Task.new do |rdoc|
|
16
|
+
rdoc.main = 'README.md'
|
17
|
+
rdoc.rdoc_files.include('README.md', 'lib', 'example', 'bin')
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Run RuboCop on the project'
|
21
|
+
RuboCop::RakeTask.new(:lint) do |task|
|
22
|
+
task.formatters = ['progress']
|
23
|
+
task.verbose = true
|
24
|
+
task.fail_on_error = true
|
25
|
+
end
|
26
|
+
|
27
|
+
task :build => [:lint, :spec]
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'config_layers'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
require 'pry'
|
11
|
+
Pry.start
|
12
|
+
|
13
|
+
# require "irb"
|
14
|
+
# IRB.start
|
data/bin/setup
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'config_layers/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "config_layers"
|
8
|
+
spec.version = ConfigLayers::VERSION
|
9
|
+
spec.authors = ["Christophe Larsonneur"]
|
10
|
+
spec.email = ["clarsonneur@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{ConfigLayers, a simple multiple configuration management.}
|
13
|
+
spec.description = %q{Manage your application configuration files easily.}
|
14
|
+
spec.homepage = "http://github.com/forj-oss/config_layers"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "subhash", '~> 0.1.0'
|
22
|
+
spec.add_runtime_dependency "pry"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.1.0"
|
27
|
+
spec.add_development_dependency "rubocop", "~> 0.30.0"
|
28
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
|
4
|
+
#--
|
5
|
+
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'config_layers/version'
|
21
|
+
|
22
|
+
# This is the config_layers library.
|
23
|
+
#
|
24
|
+
# To use it, add require 'config_layers'
|
25
|
+
|
26
|
+
require 'subhash' # recursive Hash
|
27
|
+
|
28
|
+
require 'prc_base_config' # PRC::BaseConfig class
|
29
|
+
require 'prc_section_config' # PRC::SectionConfig class
|
30
|
+
require 'prc_core_config' # PRC::CoreConfig class
|
31
|
+
|
32
|
+
# Redefine Object to add a boolean? function.
|
33
|
+
class Object
|
34
|
+
# Simplify boolean test on objects
|
35
|
+
def boolean?
|
36
|
+
self.is_a?(TrueClass) || self.is_a?(FalseClass)
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,309 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require 'yaml'
|
18
|
+
|
19
|
+
module PRC
|
20
|
+
# This class is Base config system of lorj.
|
21
|
+
#
|
22
|
+
# It implements basic config features:
|
23
|
+
# * #erase - To cleanup all data in self config
|
24
|
+
# * #[] - To get a value for a key or tree of keys
|
25
|
+
# * #[]= - To set a value for a key in the tree.
|
26
|
+
# * #exist? - To check the existence of a value from a key
|
27
|
+
# * #del - To delete a key tree.
|
28
|
+
# * #save - To save all data in a yaml file
|
29
|
+
# * #load - To load data from a yaml file
|
30
|
+
# * #data_options - To influence on how exist?, [], []=, load and save will
|
31
|
+
# behave
|
32
|
+
#
|
33
|
+
# Config Data are managed as Hash of Hashes.
|
34
|
+
# It uses actively Hash.rh_* functions. See rh.rb.
|
35
|
+
class BaseConfig
|
36
|
+
# internal Hash data of this config.
|
37
|
+
# Do not use it except if you know what you are doing.
|
38
|
+
attr_reader :data
|
39
|
+
|
40
|
+
# * *set*: set the config file name. It accepts relative or absolute path to
|
41
|
+
# the file.
|
42
|
+
# * *get*: get the config file name used by #load and #save.
|
43
|
+
attr_accessor :filename
|
44
|
+
|
45
|
+
# config layer version
|
46
|
+
attr_accessor :version
|
47
|
+
|
48
|
+
# config layer latest version
|
49
|
+
attr_reader :latest_version
|
50
|
+
|
51
|
+
# initialize BaseConfig
|
52
|
+
#
|
53
|
+
# * *Args*
|
54
|
+
# - +keys+ : Array of key path to found
|
55
|
+
#
|
56
|
+
# * *Returns*
|
57
|
+
# - boolean : true if the key path was found
|
58
|
+
#
|
59
|
+
# ex:
|
60
|
+
# value = CoreConfig.New({ :test => {:titi => 'found'}})
|
61
|
+
# # => creates a CoreConfig with this Hash of Hash
|
62
|
+
def initialize(value = nil, latest_version = nil)
|
63
|
+
@data = {}
|
64
|
+
@data = value if value.is_a?(Hash)
|
65
|
+
@data_options = {} # Options for exist?/set/get/load/save
|
66
|
+
@latest_version = latest_version
|
67
|
+
@version = latest_version
|
68
|
+
end
|
69
|
+
|
70
|
+
# data_options set data options used by exist?, get, set, load and save
|
71
|
+
# functions.
|
72
|
+
#
|
73
|
+
# CoreConfig class type, call data_options to set options, before calling
|
74
|
+
# functions: exist?, get, set, load and save.
|
75
|
+
#
|
76
|
+
# Currently, data_options implements:
|
77
|
+
# - :data_readonly : The data cannot be updated. set will not update
|
78
|
+
# the value.
|
79
|
+
# - :file_readonly : The file used to load data cannot be updated.
|
80
|
+
# save will not update the file.
|
81
|
+
#
|
82
|
+
# The child class can superseed or replace data options with their own
|
83
|
+
# options.
|
84
|
+
# Ex: If your child class want to introduce notion of sections,
|
85
|
+
# you can define the following with get:
|
86
|
+
#
|
87
|
+
# class MySection < PRC::BaseConfig
|
88
|
+
# # by default, section name to use by get/set is :default
|
89
|
+
# def data_options(options = {:section => :default})
|
90
|
+
# p_data_options(options)
|
91
|
+
# end
|
92
|
+
#
|
93
|
+
# def [](*keys)
|
94
|
+
# p_get(@data_options[:section], *keys)
|
95
|
+
# end
|
96
|
+
#
|
97
|
+
# def []=(*keys, value)
|
98
|
+
# p_set(@data_options[:section], *keys, value)
|
99
|
+
# end
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# * *Args*
|
103
|
+
# - +keys+ : Array of key path to found
|
104
|
+
#
|
105
|
+
# * *Returns*
|
106
|
+
# - boolean : true if the key path was found
|
107
|
+
def data_options(options = nil)
|
108
|
+
p_data_options options
|
109
|
+
end
|
110
|
+
|
111
|
+
# exist?
|
112
|
+
#
|
113
|
+
# * *Args*
|
114
|
+
# - +keys+ : Array of key path to found
|
115
|
+
#
|
116
|
+
# * *Returns*
|
117
|
+
# - boolean : true if the key path was found
|
118
|
+
#
|
119
|
+
# ex:
|
120
|
+
# { :test => {:titi => 'found'}}
|
121
|
+
def exist?(*keys)
|
122
|
+
p_exist?(*keys)
|
123
|
+
end
|
124
|
+
|
125
|
+
# Erase the data in the object. internal version is cleared as well.
|
126
|
+
#
|
127
|
+
# * *Returns*
|
128
|
+
# - Hash : {}.
|
129
|
+
#
|
130
|
+
def erase
|
131
|
+
@version = @latest_version
|
132
|
+
@data = {}
|
133
|
+
end
|
134
|
+
|
135
|
+
# Get function
|
136
|
+
#
|
137
|
+
# * *Args*
|
138
|
+
# - +keys+ : Array of key path to found
|
139
|
+
#
|
140
|
+
# * *Returns*
|
141
|
+
# -
|
142
|
+
#
|
143
|
+
def [](*keys)
|
144
|
+
p_get(*keys)
|
145
|
+
end
|
146
|
+
|
147
|
+
# Set function
|
148
|
+
#
|
149
|
+
# * *Args*
|
150
|
+
# - +keys+ : set a value in the Array of key path.
|
151
|
+
#
|
152
|
+
# * *Returns*
|
153
|
+
# - The value set or nil
|
154
|
+
#
|
155
|
+
# ex:
|
156
|
+
# value = CoreConfig.New
|
157
|
+
#
|
158
|
+
# value[:level1, :level2] = 'value'
|
159
|
+
# # => {:level1 => {:level2 => 'value'}}
|
160
|
+
|
161
|
+
def del(*keys)
|
162
|
+
p_del(*keys)
|
163
|
+
end
|
164
|
+
|
165
|
+
# Set function
|
166
|
+
#
|
167
|
+
# * *Args*
|
168
|
+
# - +keys+ : set a value in the Array of key path.
|
169
|
+
#
|
170
|
+
# * *Returns*
|
171
|
+
# - The value set or nil
|
172
|
+
#
|
173
|
+
# ex:
|
174
|
+
# value = CoreConfig.New
|
175
|
+
#
|
176
|
+
# value[:level1, :level2] = 'value'
|
177
|
+
# # => {:level1 => {:level2 => 'value'}}
|
178
|
+
def []=(*keys, value)
|
179
|
+
p_set(*keys, value)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Load from a file
|
183
|
+
#
|
184
|
+
# * *Args* :
|
185
|
+
# - +filename+ : file name to load. This file name will become the default
|
186
|
+
# file name to use next time.
|
187
|
+
# * *Returns* :
|
188
|
+
# - true if loaded.
|
189
|
+
# * *Raises* :
|
190
|
+
# - ++ ->
|
191
|
+
def load(filename = nil)
|
192
|
+
p_load(filename)
|
193
|
+
end
|
194
|
+
|
195
|
+
# Save to a file
|
196
|
+
#
|
197
|
+
# * *Args* :
|
198
|
+
# - +filename+ : file name to save. This file name will become the default
|
199
|
+
# file name to use next time.
|
200
|
+
# * *Returns* :
|
201
|
+
# - boolean if saved or not. true = saved.
|
202
|
+
def save(filename = nil)
|
203
|
+
p_save(filename)
|
204
|
+
end
|
205
|
+
|
206
|
+
# transform keys from string to symbol until deep level. Default is 1.
|
207
|
+
#
|
208
|
+
# * *Args* :
|
209
|
+
# - +level+ : Default 1. level to transform
|
210
|
+
#
|
211
|
+
# * *Returns* :
|
212
|
+
# - it self, with config updated.
|
213
|
+
def rh_key_to_symbol(level = 1)
|
214
|
+
data.rh_key_to_symbol level
|
215
|
+
end
|
216
|
+
|
217
|
+
# Check the need to transform keys from string to symbol until deep level.
|
218
|
+
# Default is 1.
|
219
|
+
#
|
220
|
+
# * *Args* :
|
221
|
+
# - +level+ : Default 1: levels to verify
|
222
|
+
#
|
223
|
+
# * *Returns* :
|
224
|
+
# - true if need to be updated.
|
225
|
+
#
|
226
|
+
def rh_key_to_symbol?(level = 1)
|
227
|
+
data.rh_key_to_symbol? level
|
228
|
+
end
|
229
|
+
|
230
|
+
# Redefine the file name attribute set.
|
231
|
+
#
|
232
|
+
# * *Args* :
|
233
|
+
# - +filename+ : default file name to use.
|
234
|
+
# * *Returns* :
|
235
|
+
# - filename
|
236
|
+
def filename=(filename) #:nodoc:
|
237
|
+
@filename = File.expand_path(filename) unless filename.nil?
|
238
|
+
end
|
239
|
+
|
240
|
+
# Print a representation of the Layer data
|
241
|
+
def to_s
|
242
|
+
msg = format("File : %s\n", @filename)
|
243
|
+
msg += data.to_yaml
|
244
|
+
msg
|
245
|
+
end
|
246
|
+
|
247
|
+
def latest_version?
|
248
|
+
(@version == @latest_version)
|
249
|
+
end
|
250
|
+
|
251
|
+
private
|
252
|
+
|
253
|
+
def p_data_options(options = nil)
|
254
|
+
@data_options = options unless options.nil?
|
255
|
+
@data_options
|
256
|
+
end
|
257
|
+
|
258
|
+
def p_exist?(*keys)
|
259
|
+
return nil if keys.length == 0
|
260
|
+
|
261
|
+
(@data.rh_exist?(*keys))
|
262
|
+
end
|
263
|
+
|
264
|
+
def p_get(*keys)
|
265
|
+
return nil if keys.length == 0
|
266
|
+
|
267
|
+
@data.rh_get(*keys)
|
268
|
+
end
|
269
|
+
|
270
|
+
def p_del(*keys)
|
271
|
+
return nil if keys.length == 0
|
272
|
+
|
273
|
+
@data.rh_del(*keys)
|
274
|
+
end
|
275
|
+
|
276
|
+
def p_set(*keys, value)
|
277
|
+
return nil if keys.length == 0
|
278
|
+
return p_get(*keys) if @data_options[:data_readonly]
|
279
|
+
|
280
|
+
@data.rh_set(value, keys)
|
281
|
+
end
|
282
|
+
|
283
|
+
def p_load(file = nil)
|
284
|
+
self.filename = file unless file.nil?
|
285
|
+
|
286
|
+
fail 'Config filename not set.' if @filename.nil?
|
287
|
+
|
288
|
+
@data = YAML.load_file(File.expand_path(@filename))
|
289
|
+
|
290
|
+
if @data.key?(:file_version)
|
291
|
+
@version = @data[:file_version]
|
292
|
+
@data.delete(:file_version)
|
293
|
+
end
|
294
|
+
true
|
295
|
+
end
|
296
|
+
|
297
|
+
def p_save(file = nil)
|
298
|
+
return false if @data_options[:file_readonly]
|
299
|
+
self.filename = file unless file.nil?
|
300
|
+
|
301
|
+
fail 'Config filename not set.' if @filename.nil?
|
302
|
+
@data_dup = @data.dup
|
303
|
+
@data_dup[:file_version] = @version unless @version.nil?
|
304
|
+
|
305
|
+
File.open(@filename, 'w+') { |out| YAML.dump(@data_dup, out) }
|
306
|
+
true
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|