config_parser 0.2.0 → 0.3.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.
- data/History +6 -0
- data/lib/config_parser.rb +40 -17
- data/lib/config_parser/flag.rb +5 -0
- data/lib/config_parser/list.rb +0 -8
- data/lib/config_parser/switch.rb +5 -5
- data/lib/config_parser/utils.rb +10 -10
- data/lib/config_parser/version.rb +3 -3
- metadata +11 -4
data/History
CHANGED
data/lib/config_parser.rb
CHANGED
@@ -64,12 +64,12 @@ class ConfigParser
|
|
64
64
|
|
65
65
|
# Registers the option with self by adding it to the registry and mapping
|
66
66
|
# the option flags into options. Raises an error for conflicting flags.
|
67
|
-
# Returns
|
67
|
+
# Returns option.
|
68
68
|
#
|
69
69
|
# If override is specified, options with conflicting flags are removed and
|
70
70
|
# no error is raised. Note that this may remove multiple options.
|
71
71
|
def register(option, override=false)
|
72
|
-
return if option.nil?
|
72
|
+
return nil if option.nil?
|
73
73
|
|
74
74
|
if override
|
75
75
|
existing = option.flags.collect {|flag| @options.delete(flag) }
|
@@ -90,14 +90,41 @@ class ConfigParser
|
|
90
90
|
@options[flag] = option
|
91
91
|
end
|
92
92
|
|
93
|
-
|
93
|
+
option
|
94
94
|
end
|
95
95
|
|
96
96
|
# Unregisters the option by removing it from the registry and options.
|
97
|
-
# Returns
|
97
|
+
# Returns option.
|
98
98
|
def unregister(option)
|
99
99
|
@registry.delete(option)
|
100
100
|
@options.delete_if {|key, value| option == value }
|
101
|
+
option
|
102
|
+
end
|
103
|
+
|
104
|
+
# Sorts options in the registry as specified by the block. Groups of
|
105
|
+
# options as delimited by separators are sorted independently. If no
|
106
|
+
# block is given, options are sorted by their long and short keys.
|
107
|
+
def sort_opts!(&block)
|
108
|
+
block ||= lambda {|option| option.long || option.short }
|
109
|
+
|
110
|
+
splits = []
|
111
|
+
current = []
|
112
|
+
|
113
|
+
options = self.options.values.uniq
|
114
|
+
registry.each do |option|
|
115
|
+
if options.include?(option)
|
116
|
+
current << option
|
117
|
+
else
|
118
|
+
splits << current
|
119
|
+
splits << option
|
120
|
+
current = []
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
splits << current
|
125
|
+
@registry = splits.collect {|split| split.kind_of?(Array) ? split.sort_by(&block) : split }
|
126
|
+
@registry.flatten!
|
127
|
+
|
101
128
|
self
|
102
129
|
end
|
103
130
|
|
@@ -142,23 +169,19 @@ class ConfigParser
|
|
142
169
|
# If this is too ambiguous (and at times it is), provide a trailing hash
|
143
170
|
# defining all or part of the option:
|
144
171
|
#
|
145
|
-
# psr.on('-k', 'description', :long => '--key', :
|
172
|
+
# psr.on('-k', 'description', :long => '--key', :option_type => :list) do |args|
|
146
173
|
# # ...
|
147
174
|
# end
|
148
175
|
#
|
149
176
|
# The trailing hash wins if there is any overlap in the parsed attributes
|
150
177
|
# and those provided by the hash.
|
151
178
|
def on(*args, &block)
|
152
|
-
|
153
|
-
register option
|
154
|
-
option
|
179
|
+
register new_option(args, &block)
|
155
180
|
end
|
156
181
|
|
157
182
|
# Same as on, but overrides options with overlapping flags.
|
158
183
|
def on!(*args, &block)
|
159
|
-
|
160
|
-
register option, true
|
161
|
-
option
|
184
|
+
register new_option(args, &block), true
|
162
185
|
end
|
163
186
|
|
164
187
|
# An alternate syntax for on, where the key and default attributes are set
|
@@ -179,15 +202,15 @@ class ConfigParser
|
|
179
202
|
end
|
180
203
|
|
181
204
|
# Removes options by key. Any options with the specified key are removed.
|
182
|
-
# Returns
|
205
|
+
# Returns the removed options.
|
183
206
|
def rm(key)
|
184
|
-
options.values.
|
207
|
+
options.values.collect do |option|
|
185
208
|
if option.key == key
|
186
209
|
unregister(option)
|
210
|
+
else
|
211
|
+
nil
|
187
212
|
end
|
188
|
-
end
|
189
|
-
|
190
|
-
self
|
213
|
+
end.compact
|
191
214
|
end
|
192
215
|
|
193
216
|
# Parses options from argv in a non-destructive manner. Parsing stops if an
|
@@ -268,7 +291,7 @@ class ConfigParser
|
|
268
291
|
protected
|
269
292
|
|
270
293
|
def option_class(attrs) # :nodoc:
|
271
|
-
type = attrs[:
|
294
|
+
type = attrs[:option_type] || guess_option_type(attrs)
|
272
295
|
|
273
296
|
case type
|
274
297
|
when :option then Option
|
data/lib/config_parser/flag.rb
CHANGED
@@ -130,6 +130,11 @@ class ConfigParser
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
+
# Returns an inspect string.
|
134
|
+
def inspect
|
135
|
+
"#<#{self.class}:#{object_id} key=#{key.inspect} default=#{default.inspect} long=#{long.inspect} short=#{short.inspect}>"
|
136
|
+
end
|
137
|
+
|
133
138
|
private
|
134
139
|
|
135
140
|
def header_str # :nodoc:
|
data/lib/config_parser/list.rb
CHANGED
@@ -9,9 +9,6 @@ class ConfigParser
|
|
9
9
|
# The default split character for multiple values
|
10
10
|
DELIMITER = ','
|
11
11
|
|
12
|
-
# The maximum number of values that may be specified; nil for unlimited.
|
13
|
-
attr_reader :limit
|
14
|
-
|
15
12
|
# The delimiter on which to split single values into multiple values; use
|
16
13
|
# nil to prevent splitting.
|
17
14
|
attr_reader :delimiter
|
@@ -20,7 +17,6 @@ class ConfigParser
|
|
20
17
|
super
|
21
18
|
|
22
19
|
@delimiter = attrs.has_key?(:delimiter) ? attrs[:delimiter] : DELIMITER
|
23
|
-
@limit = attrs[:limit]
|
24
20
|
@default = split(@default)
|
25
21
|
end
|
26
22
|
|
@@ -37,10 +33,6 @@ class ConfigParser
|
|
37
33
|
nest_config = nest(config)
|
38
34
|
array = (nest_config[key] ||= [])
|
39
35
|
array.concat(values)
|
40
|
-
|
41
|
-
if limit && array.length > limit
|
42
|
-
raise "too many assignments for #{key.inspect}"
|
43
|
-
end
|
44
36
|
end
|
45
37
|
|
46
38
|
config
|
data/lib/config_parser/switch.rb
CHANGED
@@ -10,7 +10,7 @@ class ConfigParser
|
|
10
10
|
attr_reader :prefix
|
11
11
|
|
12
12
|
# The negative long flag, determined from long and prefix.
|
13
|
-
attr_reader :
|
13
|
+
attr_reader :negative_long
|
14
14
|
|
15
15
|
def initialize(attrs={})
|
16
16
|
attrs[:default] = true unless attrs.has_key?(:default)
|
@@ -18,12 +18,12 @@ class ConfigParser
|
|
18
18
|
|
19
19
|
raise ArgumentError, "no long specified" unless long
|
20
20
|
@prefix = attrs[:prefix] || 'no'
|
21
|
-
@
|
21
|
+
@negative_long = prefix_long(long, "#{prefix}-")
|
22
22
|
end
|
23
23
|
|
24
|
-
# Returns an array of flags mapping to self (ie [long,
|
24
|
+
# Returns an array of flags mapping to self (ie [long, negative_long, short]).
|
25
25
|
def flags
|
26
|
-
[long,
|
26
|
+
[long, negative_long, short].compact
|
27
27
|
end
|
28
28
|
|
29
29
|
# Assigns default into config for positive flags and !default for negative
|
@@ -32,7 +32,7 @@ class ConfigParser
|
|
32
32
|
def parse(flag, value=nil, argv=[], config={})
|
33
33
|
raise "value specified for #{flag}: #{value.inspect}" if value
|
34
34
|
|
35
|
-
value = (flag ==
|
35
|
+
value = (flag == negative_long ? !default : default)
|
36
36
|
assign(config, process(value))
|
37
37
|
end
|
38
38
|
|
data/lib/config_parser/utils.rb
CHANGED
@@ -23,7 +23,7 @@ class ConfigParser
|
|
23
23
|
# match:
|
24
24
|
#
|
25
25
|
# $1:: the nesting prefix ('nest')
|
26
|
-
# $2:: the
|
26
|
+
# $2:: the negative long prefix ('no')
|
27
27
|
# $3:: the long flag name ('opt')
|
28
28
|
#
|
29
29
|
SWITCH = /\A--(.*?)\[(.*?)-\](.+)\z/
|
@@ -112,14 +112,14 @@ class ConfigParser
|
|
112
112
|
# -s :short => '-s'
|
113
113
|
# --long :long => '--long'
|
114
114
|
# --long ARG :long => '--long', :arg_name => 'ARG'
|
115
|
-
# --[no-]long :long => '--long', :prefix => 'no', :
|
115
|
+
# --[no-]long :long => '--long', :prefix => 'no', :option_type => :switch
|
116
116
|
# --nest:long :long => '--nest:long', :nest_keys => ['nest']
|
117
117
|
# 'some string' :desc => 'some string'
|
118
118
|
#
|
119
119
|
# Usually you overlay these patterns, for example:
|
120
120
|
#
|
121
121
|
# -s ARG :short => '-s', :arg_name => 'ARG'
|
122
|
-
# --nest:[no-]long :long => '--nest:long', :nest_keys => ['nest'], :prefix => 'no', :
|
122
|
+
# --nest:[no-]long :long => '--nest:long', :nest_keys => ['nest'], :prefix => 'no', :option_type => :switch
|
123
123
|
#
|
124
124
|
# The goal of this method is to get things right most of the time, not to
|
125
125
|
# be clean, simple, or robust. Some errors in declarations (like an
|
@@ -170,26 +170,26 @@ class ConfigParser
|
|
170
170
|
#
|
171
171
|
# if... then...
|
172
172
|
# prefix => :switch
|
173
|
-
# arg_name =>
|
174
|
-
# default => (
|
173
|
+
# arg_name => guess_option_type_by_arg_name || guess_option_type_by_value
|
174
|
+
# default => (guess_option_type_by_value)
|
175
175
|
# all else => :flag
|
176
176
|
#
|
177
177
|
# A guess is just a guess; for certainty specify the type manually.
|
178
|
-
def
|
178
|
+
def guess_option_type(attrs)
|
179
179
|
case
|
180
180
|
when attrs.has_key?(:prefix)
|
181
181
|
:switch
|
182
182
|
when attrs.has_key?(:arg_name)
|
183
|
-
|
183
|
+
guess_option_type_by_arg_name(attrs[:arg_name]) || guess_option_type_by_value(attrs[:default])
|
184
184
|
when attrs.has_key?(:default)
|
185
|
-
|
185
|
+
guess_option_type_by_value(attrs[:default])
|
186
186
|
else
|
187
187
|
:flag
|
188
188
|
end
|
189
189
|
end
|
190
190
|
|
191
191
|
# Guesses :list if the arg_name has a comma, or nil.
|
192
|
-
def
|
192
|
+
def guess_option_type_by_arg_name(arg_name)
|
193
193
|
arg_name.to_s.include?(',') ? :list : nil
|
194
194
|
end
|
195
195
|
|
@@ -202,7 +202,7 @@ class ConfigParser
|
|
202
202
|
# all else => :option
|
203
203
|
#
|
204
204
|
# A guess is just a guess; for certainty specify the type manually.
|
205
|
-
def
|
205
|
+
def guess_option_type_by_value(value)
|
206
206
|
case value
|
207
207
|
when true then :switch
|
208
208
|
when false then :flag
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: config_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 19
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
-
|
8
|
+
- 3
|
8
9
|
- 0
|
9
|
-
version: 0.
|
10
|
+
version: 0.3.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Simon Chiang
|
@@ -14,16 +15,18 @@ autorequire:
|
|
14
15
|
bindir: bin
|
15
16
|
cert_chain: []
|
16
17
|
|
17
|
-
date: 2010-
|
18
|
+
date: 2010-10-02 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
|
@@ -66,23 +69,27 @@ rdoc_options:
|
|
66
69
|
require_paths:
|
67
70
|
- lib
|
68
71
|
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
69
73
|
requirements:
|
70
74
|
- - ">="
|
71
75
|
- !ruby/object:Gem::Version
|
76
|
+
hash: 3
|
72
77
|
segments:
|
73
78
|
- 0
|
74
79
|
version: "0"
|
75
80
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
76
82
|
requirements:
|
77
83
|
- - ">="
|
78
84
|
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
79
86
|
segments:
|
80
87
|
- 0
|
81
88
|
version: "0"
|
82
89
|
requirements: []
|
83
90
|
|
84
91
|
rubyforge_project: ""
|
85
|
-
rubygems_version: 1.3.
|
92
|
+
rubygems_version: 1.3.7
|
86
93
|
signing_key:
|
87
94
|
specification_version: 3
|
88
95
|
summary: Parse command-line options into a configuration hash
|