config_layers 0.1.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 +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
|