configtoolkit 1.0.7 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/FAQ.txt +55 -0
- data/History.txt +3 -0
- data/Manifest.txt +1 -0
- data/README.txt +185 -14
- data/Rakefile +2 -2
- data/lib/configtoolkit/baseconfig.rb +9 -0
- data/test/readerwritertest.rb +1 -2
- metadata +7 -5
data/FAQ.txt
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
=== Why can't I use a normal Ruby Array rather than a ConstrainedArray in my configuration's specification?
|
2
|
+
You can, but you probably don't want to. Actually, underneath, the
|
3
|
+
ConfigToolkit converts Array parameters into ConstrainedArray parameters with
|
4
|
+
no constraints (<code>ConstrainedArray.new(Object, nil, nil)</code>).
|
5
|
+
If you do this and therefore don't specify an element class constraint
|
6
|
+
for the array, the ConfigToolkit will accept *any* value for an element
|
7
|
+
of the array. If this really is what you want, then go wild!
|
8
|
+
|
9
|
+
=== When are the parameter values of a configuration class validated?
|
10
|
+
Every time a parameter's setter is called, the new value is validated
|
11
|
+
against the parameter's specification in order to ensure that it is
|
12
|
+
of the proper class (or can be converted to the proper class) *before* the
|
13
|
+
parameter is set. In addition, if a custom validation block was specified
|
14
|
+
for the paramater, then this is called with the new value *before*
|
15
|
+
the paramter is set. Since all parameter values loaded from a file (during
|
16
|
+
the load method) are set with parameter setters, all values loaded from
|
17
|
+
a file receive this validation.
|
18
|
+
|
19
|
+
In addition, after a load operation and before a dump operation, the
|
20
|
+
configuration is checked in order to ensure that all required parameters have
|
21
|
+
been set. If an optional parameter is found that has not been set, then
|
22
|
+
it is set with its associated default value. Finally, the validate_all_values
|
23
|
+
method is called if it exists.
|
24
|
+
|
25
|
+
The above ensures that parameters are set with only valid values, and that
|
26
|
+
the configuration as a whole is valid right after load and right before
|
27
|
+
dump operations.
|
28
|
+
|
29
|
+
=== How/why does the ConfigToolkit convert parameter values from Strings to other classes?
|
30
|
+
Relatively complex languages like YAML support typed data. Simple
|
31
|
+
configuration formats like key/value pairs, however, do not support typed data;
|
32
|
+
every parameter value is read as a String. Since the ConfigToolkit *knows* the
|
33
|
+
specified class of a parameter value, however, it can attempt to convert the
|
34
|
+
String to the specified class. Unfortunately, Ruby does not have a standard
|
35
|
+
way to convert Strings to other classes (whereas it does have a standard way to
|
36
|
+
convert classes into Strings, the to_s method). So, the ConfigToolkit does
|
37
|
+
the best that it can and provides this conversion for the most common
|
38
|
+
types:
|
39
|
+
* Integers
|
40
|
+
* Floats
|
41
|
+
* Booleans
|
42
|
+
* Symbols
|
43
|
+
* Pathnames
|
44
|
+
* URIs
|
45
|
+
This support hopefully should cover 99.9% of parameters. If you think that
|
46
|
+
additional types should be supported, either particular standard types or
|
47
|
+
arbitrary types via some kind of extension mechanism, please feel free to
|
48
|
+
request the enhancement.
|
49
|
+
|
50
|
+
=== What kind of nesting is supported by the ConfigToolkit?
|
51
|
+
ConfigToolkit::BaseConfig child classes can be nested as parameters
|
52
|
+
within other ConfigToolkit::BaseConfig child classes arbitrarily deep. In
|
53
|
+
addition, one can have ConfigToolkit::ConstrainedArray parameters with
|
54
|
+
ConfigToolkit::BaseConfig element classes (an array of configuration objects
|
55
|
+
as a parameter).
|
data/History.txt
CHANGED
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -1,27 +1,75 @@
|
|
1
1
|
= configtoolkit
|
2
2
|
|
3
|
-
|
3
|
+
Project Page: http://rubyforge.org/projects/configtoolkit/
|
4
4
|
|
5
5
|
== DESCRIPTION:
|
6
6
|
|
7
7
|
This package makes sourcing information from configuration files robust
|
8
8
|
and easy! It:
|
9
|
-
* Allows programmers to specify the type of data that should be
|
9
|
+
* Allows programmers to specify the type of data that should be loaded
|
10
10
|
from a configuration file. The toolkit automatically will validate
|
11
11
|
the file's data against this specification when loading the file, ensuring
|
12
|
-
that the
|
13
|
-
chore of writing validation code.
|
14
|
-
*
|
15
|
-
configuration
|
12
|
+
that the specification always is obeyed and saving the programmer the
|
13
|
+
tedious chore of writing validation code.
|
14
|
+
* Automagically generates parameter accessor methods, an equality operator,
|
15
|
+
and a to_s method from the configuration's specification.
|
16
|
+
* Allows programmers to create configuration files,
|
17
|
+
easily and programatically.
|
16
18
|
* Provides classes that can load from and dump to different kinds of
|
17
|
-
configuration files
|
18
|
-
|
19
|
-
|
19
|
+
configuration files.
|
20
|
+
* Is very extensible, allowing the engine to be used with custom format
|
21
|
+
configuration files and with custom data validation rules.
|
22
|
+
|
23
|
+
== FEATURES:
|
24
|
+
|
25
|
+
* The ConfigToolkit allows programmers to define a new configuration class by
|
26
|
+
specifying the parameters that are included in the configuration. A
|
27
|
+
parameter specification consists of the class of the parameter's values,
|
28
|
+
whether or not the paramater is required, and a default value if the
|
29
|
+
parameter is not required.
|
30
|
+
* Getter and setter methods automatically are added to a new configuration
|
31
|
+
class for each specified parameter.
|
32
|
+
* An equality operator exists for each configuration class that
|
33
|
+
determines equality based on whether all parameter values are equal.
|
34
|
+
* A to_s method that produces very pretty output exists for each
|
35
|
+
configuration class.
|
36
|
+
* Programmers can specify custom validation blocks for each parameter, in
|
37
|
+
order to enforce specifications not directly supported by the engine.
|
38
|
+
* Programmers can define a method in a configuration class that will be
|
39
|
+
called in order to enforce relationships between the values of different
|
40
|
+
parameters.
|
41
|
+
* Programmers can create custom reader and writer classes in order to
|
42
|
+
load from and dump to (respectively) configuration file formats not
|
43
|
+
directly supported by the ConfigToolkit.
|
44
|
+
* Configuration classes can be nested to any depth within each other.
|
45
|
+
* Configuration classes have first class support for Array configuration
|
46
|
+
parameters. Constraints can be specified for a given Array parameter that
|
47
|
+
will ensure that all elements of a value are of a
|
48
|
+
specified class and that there are a specified number of elements in
|
49
|
+
a value.
|
50
|
+
* The ConfigToolkit supports multiple configurations stored
|
51
|
+
in a single file; it is able to distinguish that different configurations
|
52
|
+
within a file belong to different configuration objects. For example,
|
53
|
+
"production" and "test" configuration information can live within the
|
54
|
+
same configuration file and can be loaded into separate configuration
|
55
|
+
instances.
|
56
|
+
* A reader class to read YAML configuration files is included in the
|
57
|
+
Configtoolkit.
|
58
|
+
* A writer class to dump YAML configuration files is included in the
|
59
|
+
Configtoolkit.
|
60
|
+
* The ConfigToolkit includes a full unit testing suite.
|
61
|
+
* The ConfigToolkit code has detailed comments.
|
62
|
+
|
63
|
+
== PROBLEMS:
|
20
64
|
|
21
65
|
None (known).
|
22
66
|
|
23
67
|
== SYNOPSIS:
|
24
68
|
|
69
|
+
This is a sample configuration class:
|
70
|
+
require 'rubygems'
|
71
|
+
require 'configtoolkit'
|
72
|
+
|
25
73
|
class MachineConfig < ConfigToolkit::BaseConfig
|
26
74
|
add_required_param(:name, String)
|
27
75
|
|
@@ -48,12 +96,121 @@ None (known).
|
|
48
96
|
end
|
49
97
|
end
|
50
98
|
|
51
|
-
|
52
|
-
|
53
|
-
|
99
|
+
This code creates a configuration class for a company's servers. The
|
100
|
+
programmer specifies each of the parameters (the parameter's class, whether
|
101
|
+
the parameter is required, and a default value if the parameter is optional).
|
102
|
+
|
103
|
+
The programmer also specifies a method (<code>validate_all_values</code>)
|
104
|
+
that enforces an invariant between multiple parameters. This will be called
|
105
|
+
by the ConfigToolkit at the end of a load or at the start of a dump operation.
|
106
|
+
|
107
|
+
A custom validation block is specified for the <code>num_cpus</code> parameter;
|
108
|
+
the ConfigToolkit engine does not have direct support for
|
109
|
+
checking specifications like "the value must be greater than zero", but these
|
110
|
+
conditions easily can be added by the programmer. Such blocks are
|
111
|
+
called by the engine before the configuration parameter is set to the new
|
112
|
+
value and are executed in the context of the configuration class instance.
|
113
|
+
If there is a problem with the new value, the block should call
|
114
|
+
<code>ConfigToolkit::BaseConfig#raise_error</code>.
|
115
|
+
|
116
|
+
A ConfigToolkit::Boolean class is specified for the
|
117
|
+
<code>behind_firewall</code> and <code>contains_sensitive_data</code>
|
118
|
+
parameters. Ruby does not have a standard boolean
|
119
|
+
class (although it does have TrueClass and FalseClass, for boolean values), and
|
120
|
+
so the ConfigToolkit provides a marker class for boolean values. The value
|
121
|
+
of a parameter specified with ConfigToolkit::Boolean either is true or false.
|
122
|
+
|
123
|
+
A <code>ConfigToolkit::ConstrainedArray.new(URI, 2, 3)</code> class is
|
124
|
+
specified for the <code>addresses</code> parameter. A
|
125
|
+
ConfigToolkit::ConstrainedArray class simply specifies that the
|
126
|
+
parameter value will be an Array that obeys the
|
127
|
+
constraints contained in the ConfigToolkit::ConstrainedArray. In this
|
128
|
+
case, the constraints ensure that all Array elements are of class URI,
|
129
|
+
that the Array has at least two elements, and that the Array has at most
|
130
|
+
three elements.
|
131
|
+
|
132
|
+
The following machines.yaml file contains two MachineConfig configurations:
|
133
|
+
name: apple
|
134
|
+
architecture: powerpc
|
135
|
+
os: AIX
|
136
|
+
num_cpus: 32
|
137
|
+
behind_firewall: no
|
138
|
+
contains_sensitive_data: no
|
139
|
+
addresses:
|
140
|
+
- http://default.designingpatterns.com
|
141
|
+
- http://apple.designingpatterns.com
|
142
|
+
|
143
|
+
production:
|
144
|
+
tokyo:
|
145
|
+
name: orange
|
146
|
+
architecture: ultrasparc
|
147
|
+
os: Solaris
|
148
|
+
num_cpus: 64
|
149
|
+
contains_sensitive_data: yes
|
150
|
+
addresses:
|
151
|
+
- http://production.designingpatterns.com
|
152
|
+
- http://orange.designingpatterns.com
|
153
|
+
|
154
|
+
The first configuration in the file:
|
155
|
+
name: apple
|
156
|
+
architecture: powerpc
|
157
|
+
os: AIX
|
158
|
+
num_cpus: 32
|
159
|
+
behind_firewall: no
|
160
|
+
contains_sensitive_data: no
|
161
|
+
addresses:
|
162
|
+
- http://default.designingpatterns.com
|
163
|
+
- http://apple.designingpatterns.com
|
164
|
+
can be loaded into a MachineConfig instance like this:
|
165
|
+
require 'rubygems'
|
166
|
+
require 'configtoolkit'
|
167
|
+
require 'configtoolkit/yamlreader'
|
168
|
+
|
169
|
+
config = MachineConfig.load(ConfigToolkit::YAMLReader.new("machines.yaml"))
|
170
|
+
|
171
|
+
The second configuration:
|
172
|
+
production:
|
173
|
+
tokyo:
|
174
|
+
name: orange
|
175
|
+
architecture: ultrasparc
|
176
|
+
os: Solaris
|
177
|
+
num_cpus: 64
|
178
|
+
contains_sensitive_data: yes
|
179
|
+
addresses:
|
180
|
+
- http://production.designingpatterns.com
|
181
|
+
- http://orange.designingpatterns.com
|
182
|
+
can be loaded by specifying a "containing object" in the load call.
|
183
|
+
A containing object simply is an object in a configuration file within
|
184
|
+
which a config object is stored. In this case, the containing
|
185
|
+
object is "production.tokyo". So:
|
186
|
+
require 'rubygems'
|
187
|
+
require 'configtoolkit'
|
188
|
+
require 'configtoolkit/yamlreader'
|
189
|
+
|
190
|
+
config = MachineConfig.load(ConfigToolkit::YAMLReader.new("machines.yaml"), "production.tokyo")
|
191
|
+
will load the second configuration in machines.yaml.
|
192
|
+
|
193
|
+
A MachineConfig instance can be dumped like this:
|
194
|
+
require 'rubygems'
|
195
|
+
require 'configtoolkit'
|
196
|
+
require 'configtoolkit/yamlreader'
|
197
|
+
require 'configtoolkit/yamlwriter'
|
198
|
+
|
199
|
+
config = MachineConfig.load(ConfigToolkit::YAMLReader.new("machines.yaml"))
|
200
|
+
config.dump(ConfigToolkit::YAMLWriter.new("apple.yaml", true))
|
201
|
+
|
202
|
+
This will produce the following apple.yaml:
|
203
|
+
---
|
204
|
+
name: apple
|
205
|
+
contains_sensitive_data: false
|
206
|
+
addresses:
|
207
|
+
- http://default.designingpatterns.com
|
208
|
+
- http://apple.designingpatterns.com
|
209
|
+
os: AIX
|
210
|
+
architecture: powerpc
|
211
|
+
num_cpus: 32
|
212
|
+
behind_firewall: false
|
54
213
|
|
55
|
-
The programmer also specifies a method (validate_all_valus) that enforces
|
56
|
-
an invariant between multiple parameters.
|
57
214
|
== REQUIREMENTS:
|
58
215
|
|
59
216
|
Hoe is required, but only for running the tests.
|
@@ -62,6 +219,20 @@ Hoe is required, but only for running the tests.
|
|
62
219
|
|
63
220
|
sudo gem install configtoolkit
|
64
221
|
|
222
|
+
== AUTHORS:
|
223
|
+
|
224
|
+
Designing Patterns: http://www.designingpatterns.com
|
225
|
+
|
226
|
+
Share and Enjoy!
|
227
|
+
|
228
|
+
== SUPPORT
|
229
|
+
|
230
|
+
Please post questions, concerns, or requests for enhancement to the forums on
|
231
|
+
the project page. Alternatively, direct contact information for
|
232
|
+
Designing Patterns can be found on the project page for this gem.
|
233
|
+
Please discuss any enhancements with the authors (Designing Patterns)
|
234
|
+
before doing any work.
|
235
|
+
|
65
236
|
== LICENSE:
|
66
237
|
|
67
238
|
See LICENSE, at the root of the distribution.
|
data/Rakefile
CHANGED
@@ -7,8 +7,8 @@ require 'hoe'
|
|
7
7
|
|
8
8
|
$stderr = STDERR
|
9
9
|
|
10
|
-
Hoe.new('configtoolkit', "1.0
|
11
|
-
p.remote_rdoc_dir = '
|
10
|
+
Hoe.new('configtoolkit', "1.1.0") do |p|
|
11
|
+
p.remote_rdoc_dir = ''
|
12
12
|
p.developer('DesigningPatterns', 'technical.inquiries@designingpatterns.com')
|
13
13
|
end
|
14
14
|
|
@@ -195,6 +195,15 @@ class BaseConfig
|
|
195
195
|
@param_spec_list.push(param_spec)
|
196
196
|
@param_spec_lookup_table[name] = param_spec
|
197
197
|
|
198
|
+
#
|
199
|
+
# Convert Array value classes into ConstrainedArrays with
|
200
|
+
# no constraints. This makes supporting Arrays much easier, since
|
201
|
+
# they can share a code base with ConstrainedArrays.
|
202
|
+
#
|
203
|
+
if(value_class == Array)
|
204
|
+
value_class = ConstrainedArray.new(Object, nil, nil)
|
205
|
+
end
|
206
|
+
|
198
207
|
#
|
199
208
|
# Define the getter and setter methods with a string passed to
|
200
209
|
# class_eval rather than a block, so as to avoid the need to access
|
data/test/readerwritertest.rb
CHANGED
@@ -8,8 +8,7 @@ require 'uri'
|
|
8
8
|
|
9
9
|
class SampleSecondNestedConfig < ConfigToolkit::BaseConfig
|
10
10
|
add_required_param(:req_second_nested_pathname, Pathname)
|
11
|
-
add_required_param(:req_second_nested_array,
|
12
|
-
ConfigToolkit::ConstrainedArray.new(Integer, 2, 2))
|
11
|
+
add_required_param(:req_second_nested_array, Array)
|
13
12
|
end
|
14
13
|
|
15
14
|
class SampleNestedConfig < ConfigToolkit::BaseConfig
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: configtoolkit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- DesigningPatterns
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-05-
|
12
|
+
date: 2008-05-15 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: 1.5.1
|
23
23
|
version:
|
24
|
-
description: "This package makes sourcing information from configuration files robust and easy! It: * Allows programmers to specify the type of data that should be
|
24
|
+
description: "This package makes sourcing information from configuration files robust and easy! It: * Allows programmers to specify the type of data that should be loaded from a configuration file. The toolkit automatically will validate the file's data against this specification when loading the file, ensuring that the specification always is obeyed and saving the programmer the tedious chore of writing validation code. * Automagically generates parameter accessor methods, an equality operator, and a to_s method from the configuration's specification. * Allows programmers to create configuration files, easily and programatically. * Provides classes that can load from and dump to different kinds of configuration files. * Is very extensible, allowing the engine to be used with custom format configuration files and with custom data validation rules."
|
25
25
|
email:
|
26
26
|
- technical.inquiries@designingpatterns.com
|
27
27
|
executables: []
|
@@ -32,12 +32,14 @@ extra_rdoc_files:
|
|
32
32
|
- Manifest.txt
|
33
33
|
- README.txt
|
34
34
|
- History.txt
|
35
|
+
- FAQ.txt
|
35
36
|
files:
|
36
37
|
- Manifest.txt
|
37
38
|
- LICENSE
|
38
39
|
- README.txt
|
39
40
|
- History.txt
|
40
41
|
- Rakefile
|
42
|
+
- FAQ.txt
|
41
43
|
- lib/configtoolkit.rb
|
42
44
|
- lib/configtoolkit/baseconfig.rb
|
43
45
|
- lib/configtoolkit/toolkit.rb
|
@@ -56,7 +58,7 @@ files:
|
|
56
58
|
- test/sample.standard_yaml_classes.yaml
|
57
59
|
- test/webserver.yaml
|
58
60
|
has_rdoc: true
|
59
|
-
homepage: http://
|
61
|
+
homepage: "Project Page: http://rubyforge.org/projects/configtoolkit/"
|
60
62
|
post_install_message:
|
61
63
|
rdoc_options:
|
62
64
|
- --main
|
@@ -81,7 +83,7 @@ rubyforge_project: configtoolkit
|
|
81
83
|
rubygems_version: 1.0.1
|
82
84
|
signing_key:
|
83
85
|
specification_version: 2
|
84
|
-
summary: "This package makes sourcing information from configuration files robust and easy! It: * Allows programmers to specify the type of data that should be
|
86
|
+
summary: "This package makes sourcing information from configuration files robust and easy! It: * Allows programmers to specify the type of data that should be loaded from a configuration file"
|
85
87
|
test_files:
|
86
88
|
- test/test_baseconfig.rb
|
87
89
|
- test/test_yaml.rb
|