configurable 0.7.0 → 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.
Files changed (38) hide show
  1. data/Help/Command Line.rdoc +141 -0
  2. data/Help/Config Syntax.rdoc +229 -0
  3. data/Help/Config Types.rdoc +143 -0
  4. data/{History → History.rdoc} +9 -0
  5. data/MIT-LICENSE +1 -1
  6. data/README.rdoc +144 -0
  7. data/lib/configurable.rb +7 -270
  8. data/lib/configurable/class_methods.rb +344 -367
  9. data/lib/configurable/config_classes.rb +3 -0
  10. data/lib/configurable/config_classes/list_config.rb +26 -0
  11. data/lib/configurable/config_classes/nest_config.rb +50 -0
  12. data/lib/configurable/config_classes/scalar_config.rb +91 -0
  13. data/lib/configurable/config_hash.rb +87 -112
  14. data/lib/configurable/config_types.rb +6 -0
  15. data/lib/configurable/config_types/boolean_type.rb +22 -0
  16. data/lib/configurable/config_types/float_type.rb +11 -0
  17. data/lib/configurable/config_types/integer_type.rb +11 -0
  18. data/lib/configurable/config_types/nest_type.rb +39 -0
  19. data/lib/configurable/config_types/object_type.rb +58 -0
  20. data/lib/configurable/config_types/string_type.rb +15 -0
  21. data/lib/configurable/conversions.rb +91 -0
  22. data/lib/configurable/module_methods.rb +0 -1
  23. data/lib/configurable/version.rb +1 -5
  24. metadata +73 -30
  25. data/README +0 -207
  26. data/lib/cdoc.rb +0 -413
  27. data/lib/cdoc/cdoc_html_generator.rb +0 -38
  28. data/lib/cdoc/cdoc_html_template.rb +0 -42
  29. data/lib/config_parser.rb +0 -563
  30. data/lib/config_parser/option.rb +0 -108
  31. data/lib/config_parser/switch.rb +0 -44
  32. data/lib/config_parser/utils.rb +0 -177
  33. data/lib/configurable/config.rb +0 -97
  34. data/lib/configurable/indifferent_access.rb +0 -35
  35. data/lib/configurable/nest_config.rb +0 -78
  36. data/lib/configurable/ordered_hash_patch.rb +0 -85
  37. data/lib/configurable/utils.rb +0 -186
  38. data/lib/configurable/validation.rb +0 -768
@@ -0,0 +1,11 @@
1
+ module Configurable
2
+ module ConfigTypes
3
+ class FloatType < ObjectType
4
+ matches Float
5
+
6
+ def cast(input)
7
+ Float(input)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Configurable
2
+ module ConfigTypes
3
+ class IntegerType < ObjectType
4
+ matches Integer
5
+
6
+ def cast(input)
7
+ Integer(input)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,39 @@
1
+ module Configurable
2
+ module ConfigTypes
3
+ class NestType < ObjectType
4
+ class << self
5
+ def init(&block)
6
+ define_method(:init, &block) if block
7
+ self
8
+ end
9
+ end
10
+ matches Hash
11
+
12
+ attr_reader :configurable
13
+
14
+ def initialize(attrs={})
15
+ @configurable = attrs[:configurable]
16
+
17
+ unless configurable.respond_to?(:config) && configurable.class.respond_to?(:configs)
18
+ raise ArgumentError, "invalid configurable: #{configurable.inspect}"
19
+ end
20
+
21
+ super
22
+ end
23
+
24
+ def init(input)
25
+ obj = configurable.dup
26
+ obj.config.merge!(input)
27
+ obj
28
+ end
29
+
30
+ def cast(input)
31
+ configurable.class.configs.import(input)
32
+ end
33
+
34
+ def uncast(value)
35
+ configurable.class.configs.export(value)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,58 @@
1
+ module Configurable
2
+ module ConfigTypes
3
+ class ObjectType
4
+ class << self
5
+ attr_reader :matchers
6
+
7
+ def inherited(base) # :nodoc:
8
+ unless base.instance_variable_defined?(:@matchers)
9
+ base.instance_variable_set(:@matchers, matchers.dup)
10
+ end
11
+ end
12
+
13
+ def subclass(*matchers, &caster)
14
+ subclass = Class.new(self)
15
+ subclass.matches(*matchers)
16
+ subclass.cast(&caster)
17
+ subclass
18
+ end
19
+
20
+ def cast(&block)
21
+ define_method(:cast, &block) if block
22
+ self
23
+ end
24
+
25
+ def uncast(&block)
26
+ define_method(:uncast, &block) if block
27
+ self
28
+ end
29
+
30
+ def errors(&block)
31
+ define_method(:errors, &block) if block
32
+ self
33
+ end
34
+
35
+ def matches(*matchers)
36
+ @matchers = matchers
37
+ self
38
+ end
39
+
40
+ def matches?(value)
41
+ matchers.any? {|matcher| matcher === value }
42
+ end
43
+ end
44
+ matches()
45
+
46
+ def initialize(attrs={})
47
+ end
48
+
49
+ def cast(input)
50
+ input
51
+ end
52
+
53
+ def uncast(value)
54
+ value
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,15 @@
1
+ module Configurable
2
+ module ConfigTypes
3
+ class StringType < ObjectType
4
+ matches String
5
+
6
+ def cast(input)
7
+ String(input)
8
+ end
9
+
10
+ def uncast(value)
11
+ value.to_s
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,91 @@
1
+ require 'configurable/config_classes'
2
+ require 'config_parser'
3
+
4
+ module Configurable
5
+
6
+ # A set of methods used to convert various inputs based on a hash of (key,
7
+ # Config) pairs. Extend the hash and then use the methods.
8
+ module Conversions
9
+ include ConfigTypes
10
+
11
+ # Initializes and returns a ConfigParser generated using the configs for
12
+ # self. Arguments given to parser are passed to the ConfigParser
13
+ # initializer.
14
+ def to_parser(*args, &block)
15
+ parser = ConfigParser.new(*args, &block)
16
+ traverse do |nesting, config|
17
+ next if config[:hidden] == true || nesting.any? {|nest| nest[:hidden] == true }
18
+
19
+ nest_keys = nesting.collect {|nest| nest.key }
20
+ long, short = nesting.collect {|nest| nest.name }.push(config.name).join(':'), nil
21
+ long, short = short, long if long.length == 1
22
+
23
+ guess_attrs = {
24
+ :long => long,
25
+ :short => short
26
+ }
27
+
28
+ config_attrs = {
29
+ :key => config.key,
30
+ :nest_keys => nest_keys,
31
+ :default => config.default,
32
+ :callback => lambda {|value| config.type.cast(value) }
33
+ }
34
+
35
+ attrs = guess_attrs.merge(config.metadata).merge(config_attrs)
36
+ parser.on(attrs)
37
+ end
38
+
39
+ parser.sort_opts!
40
+ parser
41
+ end
42
+
43
+ # Returns a hash of the default values for each config in self.
44
+ def to_default
45
+ default = {}
46
+ each_pair do |key, config|
47
+ default[key] = config.default
48
+ end
49
+ default
50
+ end
51
+
52
+ def import(source, target={})
53
+ each_value do |config|
54
+ name = config.name
55
+
56
+ if source.has_key?(name)
57
+ target[config.key] = config.cast(source[name])
58
+ end
59
+ end
60
+
61
+ target
62
+ end
63
+
64
+ def export(source, target={})
65
+ each_value do |config|
66
+ key = config.key
67
+
68
+ if source.has_key?(key)
69
+ target[config.name] = config.uncast(source[key])
70
+ end
71
+ end
72
+
73
+ target
74
+ end
75
+
76
+ # Yields each config in configs to the block with nesting, after appened
77
+ # self to nesting.
78
+ def traverse(nesting=[], &block)
79
+ each_value do |config|
80
+ if config.type.kind_of?(NestType)
81
+ nesting.push config
82
+ configs = config.type.configurable.class.configs
83
+ configs.traverse(nesting, &block)
84
+ nesting.pop
85
+ else
86
+ yield(nesting, config)
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -1,4 +1,3 @@
1
- require 'lazydoc'
2
1
  require 'configurable/class_methods'
3
2
 
4
3
  module Configurable
@@ -1,7 +1,3 @@
1
1
  module Configurable
2
- MAJOR = 0
3
- MINOR = 7
4
- TINY = 0
5
-
6
- VERSION="#{MAJOR}.#{MINOR}.#{TINY}"
2
+ VERSION = '1.0.0'
7
3
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: configurable
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 23
5
+ prerelease:
5
6
  segments:
7
+ - 1
6
8
  - 0
7
- - 7
8
9
  - 0
9
- version: 0.7.0
10
+ version: 1.0.0
10
11
  platform: ruby
11
12
  authors:
12
13
  - Simon Chiang
@@ -14,63 +15,101 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-05-02 00:00:00 -06:00
18
+ date: 2011-07-12 00:00:00 -06:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: lazydoc
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
- - - ">="
27
+ - - ~>
26
28
  - !ruby/object:Gem::Version
29
+ hash: 15
27
30
  segments:
28
31
  - 1
29
32
  - 0
30
- - 0
31
- version: 1.0.0
33
+ version: "1.0"
32
34
  type: :runtime
33
35
  version_requirements: *id001
34
- description:
35
- email: simon.a.chiang@gmail.com
36
+ - !ruby/object:Gem::Dependency
37
+ name: config_parser
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 3
45
+ segments:
46
+ - 0
47
+ - 5
48
+ - 4
49
+ version: 0.5.4
50
+ type: :runtime
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: bundler
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 15
61
+ segments:
62
+ - 1
63
+ - 0
64
+ version: "1.0"
65
+ type: :development
66
+ version_requirements: *id003
67
+ description: Configurable adds methods to declare class configurations. Configurations are inheritable, delegate to methods, and have hash-like access. Configurable constructs configs such that they easily map to config files, web forms, and the command line.
68
+ email:
69
+ - simon.a.chiang@gmail.com
36
70
  executables: []
37
71
 
38
72
  extensions: []
39
73
 
40
74
  extra_rdoc_files:
41
75
  - MIT-LICENSE
42
- - README
43
- - History
76
+ - README.rdoc
77
+ - History.rdoc
78
+ - Help/Command Line.rdoc
79
+ - Help/Config Syntax.rdoc
80
+ - Help/Config Types.rdoc
44
81
  files:
45
- - lib/cdoc.rb
46
- - lib/cdoc/cdoc_html_generator.rb
47
- - lib/cdoc/cdoc_html_template.rb
48
- - lib/config_parser.rb
49
- - lib/config_parser/option.rb
50
- - lib/config_parser/switch.rb
51
- - lib/config_parser/utils.rb
52
82
  - lib/configurable.rb
53
83
  - lib/configurable/class_methods.rb
54
- - lib/configurable/config.rb
84
+ - lib/configurable/config_classes.rb
85
+ - lib/configurable/config_classes/list_config.rb
86
+ - lib/configurable/config_classes/nest_config.rb
87
+ - lib/configurable/config_classes/scalar_config.rb
55
88
  - lib/configurable/config_hash.rb
56
- - lib/configurable/indifferent_access.rb
89
+ - lib/configurable/config_types.rb
90
+ - lib/configurable/config_types/boolean_type.rb
91
+ - lib/configurable/config_types/float_type.rb
92
+ - lib/configurable/config_types/integer_type.rb
93
+ - lib/configurable/config_types/nest_type.rb
94
+ - lib/configurable/config_types/object_type.rb
95
+ - lib/configurable/config_types/string_type.rb
96
+ - lib/configurable/conversions.rb
57
97
  - lib/configurable/module_methods.rb
58
- - lib/configurable/nest_config.rb
59
- - lib/configurable/ordered_hash_patch.rb
60
- - lib/configurable/utils.rb
61
- - lib/configurable/validation.rb
62
98
  - lib/configurable/version.rb
63
99
  - MIT-LICENSE
64
- - README
65
- - History
100
+ - README.rdoc
101
+ - History.rdoc
102
+ - Help/Command Line.rdoc
103
+ - Help/Config Syntax.rdoc
104
+ - Help/Config Types.rdoc
66
105
  has_rdoc: true
67
- homepage: http://tap.rubyforge.org/configurable
106
+ homepage: http://github.com/thinkerbot/configurable
68
107
  licenses: []
69
108
 
70
109
  post_install_message:
71
110
  rdoc_options:
72
111
  - --main
73
- - README
112
+ - README.rdoc
74
113
  - -S
75
114
  - -N
76
115
  - --title
@@ -78,23 +117,27 @@ rdoc_options:
78
117
  require_paths:
79
118
  - lib
80
119
  required_ruby_version: !ruby/object:Gem::Requirement
120
+ none: false
81
121
  requirements:
82
122
  - - ">="
83
123
  - !ruby/object:Gem::Version
124
+ hash: 3
84
125
  segments:
85
126
  - 0
86
127
  version: "0"
87
128
  required_rubygems_version: !ruby/object:Gem::Requirement
129
+ none: false
88
130
  requirements:
89
131
  - - ">="
90
132
  - !ruby/object:Gem::Version
133
+ hash: 3
91
134
  segments:
92
135
  - 0
93
136
  version: "0"
94
137
  requirements: []
95
138
 
96
- rubyforge_project: tap
97
- rubygems_version: 1.3.6
139
+ rubyforge_project:
140
+ rubygems_version: 1.6.2
98
141
  signing_key:
99
142
  specification_version: 3
100
143
  summary: configurable
data/README DELETED
@@ -1,207 +0,0 @@
1
- = Configurable[http://tap.rubyforge.org/configurable]
2
-
3
- Class configurations that map to the command line.
4
-
5
- == Description
6
-
7
- Configurable allows the declaration of class configurations. Configurations
8
- are inheritable, delegate to methods, and have hash-like access. Configurable
9
- maps configurations to the command line through ConfigParser and is used by
10
- the Tap[http://tap.rubyforge.org] framework.
11
-
12
- Check out these links for development and bug tracking.
13
-
14
- * Website[http://tap.rubyforge.org/configurable]
15
- * Github[http://github.com/bahuvrihi/configurable/tree/master]
16
- * {Google Group}[http://groups.google.com/group/ruby-on-tap]
17
-
18
- ==== Minimal Example
19
-
20
- Include Configurable and declare configurations using the config method.
21
- Configs now have accessors and initialize with the default value.
22
-
23
- class ConfigClass
24
- include Configurable
25
- config :key, 'default', :short => 'k' # a sample config
26
- end
27
-
28
- c = ConfigClass.new
29
- c.key # => 'default'
30
- c.key = 'new value'
31
- c.config[:key] # => 'new value'
32
-
33
- Use a ConfigParser to parse configurations from the command line. Non-class
34
- options may be defined with (mostly) the same syntax as {OptionParser}[http://www.ruby-doc.org/core/classes/OptionParser.html]:
35
-
36
- parser = ConfigParser.new
37
-
38
- # add class configurations
39
- parser.add(ConfigClass.configurations)
40
-
41
- # define an option a-la OptionParser
42
- parser.on '-s', '--long ARGUMENT', 'description' do |value|
43
- parser[:long] = value
44
- end
45
-
46
- parser.parse "one two --key value -s VALUE three"
47
- # => ['one', 'two', 'three']
48
-
49
- parser.config
50
- # => {
51
- # :key => 'value',
52
- # :long => 'VALUE'
53
- # }
54
-
55
- "\n" + parser.to_s
56
- # => %Q{
57
- # -k, --key KEY a sample config
58
- # -s, --long ARGUMENT description
59
- # }
60
-
61
- == Usage
62
-
63
- The config method is used to declare class configurations. A block may be
64
- provided to validate/transform inputs; many standard validations are available
65
- through the 'c' method (an alias for the
66
- {Validation}[link:classes/Configurable/Validation.html] module).
67
-
68
- class ConfigClass
69
- include Configurable
70
-
71
- # basic #
72
-
73
- config :key, 'default' # a simple config
74
- config :flag, false, &c.flag # a flag config
75
- config :switch, false, &c.switch # a --[no-]switch config
76
- config :num, 10, &c.integer # integer only
77
-
78
- # fancy #
79
-
80
- config :range, 1..10, &c.range # specifies a range
81
- config :select, 'a', &c.select('a','b') # value must be 'a' or 'b'
82
- config :list, [], &c.list # allows a list of entries
83
-
84
- # custom #
85
-
86
- config :upcase, 'default' do |value| # custom transformation
87
- value.upcase
88
- end
89
-
90
- config :alt, 'default', # alternative flags
91
- :short => 's',
92
- :long => 'long',
93
- :arg_name => 'CUSTOM'
94
-
95
- # Initializes a new instance, setting the overriding configs.
96
- def initialize(config={})
97
- initialize_config(config)
98
- end
99
- end
100
-
101
- ConfigParser uses the config declarations to parse configurations and to make
102
- a documented help string:
103
-
104
- parser = ConfigParser.new
105
- parser.add(ConfigClass.configurations)
106
-
107
- parser.parse "a b --key=value --flag --no-switch --num 8 c"
108
- # => ['a', 'b', 'c']
109
-
110
- parser.config
111
- # => {
112
- # :key => 'value',
113
- # :flag => true,
114
- # :switch => false,
115
- # :num => '8',
116
- # :range => 1..10,
117
- # :select => 'a',
118
- # :list => [],
119
- # :upcase => 'default',
120
- # :alt => 'default'
121
- # }
122
-
123
- "\n" + parser.to_s
124
- # => %Q{
125
- # --key KEY a simple config
126
- # --flag a flag config
127
- # --[no-]switch a --[no-]switch config
128
- # --num NUM integer only
129
- # --range RANGE specifies a range
130
- # --select SELECT value must be 'a' or 'b'
131
- # --list LIST allows a list of entries
132
- # --upcase UPCASE custom transformation
133
- # -s, --long CUSTOM alternative flags
134
- # }
135
-
136
- Configurable classes typically call initialize_config to set configurations
137
- during initialization. The validation/transformation blocks are called as
138
- configurations are set. Notice how the :num and :upcase configs are translated
139
- on the instance:
140
-
141
- c = ConfigClass.new(parser.config)
142
- c.config.to_hash
143
- # => {
144
- # :key => 'value',
145
- # :flag => true,
146
- # :switch => false,
147
- # :num => 8, # no longer a string
148
- # :range => 1..10,
149
- # :select => 'a',
150
- # :list => [],
151
- # :upcase => 'DEFAULT', # no longer downcase
152
- # :alt => 'default'
153
- # }
154
-
155
- Configurations automatically generate accessors (the blocks are basically
156
- writer methods), and may be accessed through the config object. Configurations
157
- are validated every time they are set, regardless of whether they are set
158
- through an accessor or config.
159
-
160
- c.upcase # => 'DEFAULT'
161
-
162
- c.config[:upcase] = 'neW valuE'
163
- c.upcase # => 'NEW VALUE'
164
-
165
- c.upcase = 'fiNal Value'
166
- c.config[:upcase] # => 'FINAL VALUE'
167
-
168
- c.select = 'b' # ok
169
- c.select = 'c' # !> ValidationError
170
- c.config[:select] = 'c' # !> ValidationError
171
-
172
- By default config treats string and symbol keys identically, making YAML an
173
- obvious choice for configuration files.
174
-
175
- yaml_str = %Q{
176
- key: a new value
177
- flag: false
178
- range: 1..100
179
- }
180
-
181
- c.reconfigure(YAML.load(yaml_str))
182
- c.config.to_hash
183
- # => {
184
- # :key => 'a new value',
185
- # :flag => false,
186
- # :switch => false,
187
- # :num => 8,
188
- # :range => 1..100,
189
- # :select => 'b',
190
- # :list => [],
191
- # :upcase => 'FINAL VALUE',
192
- # :alt => 'default'
193
- # }
194
-
195
- See the Configurable module for more details.
196
-
197
- == Installation
198
-
199
- Configurable is available as a gem on Gemcutter[http://gemcutter.org/gems/configurable].
200
-
201
- % gem install configurable
202
-
203
- == Info
204
-
205
- Developer:: {Simon Chiang}[http://bahuvrihi.wordpress.com]
206
- License:: {MIT-Style}[link:files/MIT-LICENSE.html]
207
-