config_parser 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,12 @@
1
+ == 0.5.5 / 2011-07-18
2
+
3
+ * [issue #3] added options to to_s to allow changes to the option/desc columns
4
+ widths
5
+ * [issue #4] made parser check for option_break such that breaks on non-option
6
+ args is possible
7
+ * [issue #5] single-character keys now default to a short rather than long
8
+ option
9
+
1
10
  == 0.5.4 / 2011-07-11
2
11
 
3
12
  Misc cleanup to the README and project structure. Also:
@@ -20,10 +20,10 @@ Define options and their default values using +add+:
20
20
  parser.add :switch, true # true makes a --[no-]switch
21
21
  parser.add :flag, false # false as a default makes a --flag
22
22
  parser.add :list, [] # an array makes a list-style option
23
-
23
+
24
24
  parser.parse 'a b --flag --list x --list y,z c'
25
25
  # => ['a', 'b', 'c']
26
-
26
+
27
27
  parser.config
28
28
  # => {
29
29
  # :option => 'default',
@@ -64,19 +64,19 @@ to the option (although by default it does). As you may expect a block can be
64
64
  given to process values before they are set as configs.
65
65
 
66
66
  parser = ConfigParser.new
67
-
67
+
68
68
  # use args to define the option
69
69
  parser.add(:x, nil, '-o', '--one')
70
-
70
+
71
71
  # use an options hash to define the option
72
72
  parser.add(:y, nil, :short => 't', :long => 'two')
73
-
73
+
74
74
  # use a block to process the values
75
75
  parser.add(:z, nil, :long => 'three') {|value| value.upcase }
76
-
76
+
77
77
  parser.parse('a b --one uno --two dos --three tres c')
78
78
  # => ['a', 'b', 'c']
79
-
79
+
80
80
  parser.config
81
81
  # => {:x => 'uno', :y => 'dos', :z => 'TRES'}
82
82
 
@@ -86,6 +86,16 @@ ConfigParser is available as a gem[http://rubygems.org/gems/config_parser].
86
86
 
87
87
  % gem install config_parser
88
88
 
89
+ == Development
90
+
91
+ To get started, checkout the code from GitHub[http://github.com/thinkerbot/config_parser] and run the tests:
92
+
93
+ git clone git://github.com/thinkerbot/config_parser.git
94
+ cd config_parser
95
+ rake test
96
+
97
+ Please report any issues {here}[http://github.com/thinkerbot/config_parser/issues].
98
+
89
99
  == Info
90
100
 
91
101
  Developer:: {Simon Chiang}[http://github.com/thinkerbot]
@@ -8,27 +8,27 @@ autoload(:Shellwords, 'shellwords')
8
8
  # additionally supports option declaration using an attributes hash.
9
9
  class ConfigParser
10
10
  include Utils
11
-
11
+
12
12
  # Returns an array of the options registered with self, in the order in
13
13
  # which they were added. Separators are also stored in the registry.
14
14
  attr_reader :registry
15
-
15
+
16
16
  # A hash of (flag, Option) pairs mapping command line flags like '-s' or
17
17
  # '--long' to the Option that handles them.
18
18
  attr_reader :options
19
-
19
+
20
20
  # The hash receiving parsed configs.
21
21
  attr_accessor :config
22
-
22
+
23
23
  # The argument to stop processing options.
24
24
  attr_accessor :option_break
25
-
25
+
26
26
  # Set to true to preserve the option break.
27
27
  attr_accessor :preserve_option_break
28
-
28
+
29
29
  # Set to true to assign config defaults on parse.
30
30
  attr_accessor :assign_defaults
31
-
31
+
32
32
  # Initializes a new ConfigParser and passes it to the block, if given.
33
33
  def initialize(config={}, opts={})
34
34
  opts = {
@@ -36,27 +36,27 @@ class ConfigParser
36
36
  :preserve_option_break => false,
37
37
  :assign_defaults => true
38
38
  }.merge(opts)
39
-
39
+
40
40
  @registry = []
41
41
  @options = {}
42
42
  @config = config
43
43
  @option_break = opts[:option_break]
44
44
  @preserve_option_break = opts[:preserve_option_break]
45
45
  @assign_defaults = opts[:assign_defaults]
46
-
46
+
47
47
  yield(self) if block_given?
48
48
  end
49
-
49
+
50
50
  # Returns the config value for key.
51
51
  def [](key)
52
52
  config[key]
53
53
  end
54
-
54
+
55
55
  # Sets the config value for key.
56
56
  def []=(key, value)
57
57
  config[key] = value
58
58
  end
59
-
59
+
60
60
  # Adds a separator string to self, used in to_s.
61
61
  def separator(str)
62
62
  @registry << str
@@ -70,29 +70,29 @@ class ConfigParser
70
70
  # no error is raised. Note that this may remove multiple options.
71
71
  def register(option, override=false)
72
72
  return nil if option.nil?
73
-
73
+
74
74
  if override
75
75
  existing = option.flags.collect {|flag| @options.delete(flag) }
76
76
  @registry -= existing
77
77
  end
78
-
78
+
79
79
  unless @registry.include?(option)
80
80
  @registry << option
81
81
  end
82
-
82
+
83
83
  option.flags.each do |flag|
84
84
  current = @options[flag]
85
-
85
+
86
86
  if current && current != option
87
87
  raise ArgumentError, "already mapped to a different option: #{flag}"
88
88
  end
89
-
89
+
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
97
  # Returns option.
98
98
  def unregister(option)
@@ -100,16 +100,16 @@ class ConfigParser
100
100
  @options.delete_if {|key, value| option == value }
101
101
  option
102
102
  end
103
-
103
+
104
104
  # Sorts options in the registry as specified by the block. Groups of
105
105
  # options as delimited by separators are sorted independently. If no block
106
106
  # is given, options are sorted by their long and short keys.
107
107
  def sort_opts!(&block)
108
108
  block ||= lambda {|option| (option.long || option.short).to_s.sub(/^-+/, '') }
109
-
109
+
110
110
  splits = []
111
111
  current = []
112
-
112
+
113
113
  options = self.options.values.uniq
114
114
  registry.each do |option|
115
115
  if options.include?(option)
@@ -120,14 +120,14 @@ class ConfigParser
120
120
  current = []
121
121
  end
122
122
  end
123
-
123
+
124
124
  splits << current
125
125
  @registry = splits.collect {|split| split.kind_of?(Array) ? split.sort_by(&block) : split }
126
126
  @registry.flatten!
127
-
127
+
128
128
  self
129
129
  end
130
-
130
+
131
131
  # Constructs an Option using args and registers it with self. The args may
132
132
  # contain (in any order) a short switch, a long switch, and a description
133
133
  # string. A callback may be provided as a block to process values for the
@@ -183,12 +183,12 @@ class ConfigParser
183
183
  def on(*args, &block)
184
184
  register new_option(args, &block)
185
185
  end
186
-
186
+
187
187
  # Same as on, but overrides options with overlapping flags.
188
188
  def on!(*args, &block)
189
189
  register new_option(args, &block), true
190
190
  end
191
-
191
+
192
192
  # An alternate syntax for on, where the key and default attributes are set
193
193
  # by the first two args. Like on, add can define option attributes using a
194
194
  # series of args or with a trailing hash.
@@ -204,7 +204,7 @@ class ConfigParser
204
204
  args << attrs
205
205
  on(*args, &block)
206
206
  end
207
-
207
+
208
208
  # Removes options by key. Any options with the specified key are removed.
209
209
  # Returns the removed options.
210
210
  def rm(key)
@@ -216,7 +216,7 @@ class ConfigParser
216
216
  end
217
217
  end.compact
218
218
  end
219
-
219
+
220
220
  # Parses options from argv in a non-destructive manner. Parsing stops if an
221
221
  # argument matching option_break is reached. If preserve_option_break is
222
222
  # specified then the option break is preserved in the remaining arguments.
@@ -228,90 +228,91 @@ class ConfigParser
228
228
  argv = argv.dup unless argv.kind_of?(String)
229
229
  parse!(argv, &block)
230
230
  end
231
-
231
+
232
232
  # Same as parse, but removes parsed args from argv.
233
233
  def parse!(argv=ARGV)
234
234
  argv = Shellwords.shellwords(argv) if argv.kind_of?(String)
235
-
235
+
236
236
  registry.each do |option|
237
237
  if assign_defaults && option.respond_to?(:assign_default)
238
238
  option.assign_default(config)
239
239
  end
240
240
  end
241
-
241
+
242
242
  args = []
243
243
  while !argv.empty?
244
244
  arg = argv.shift
245
-
246
- # determine if the arg is an option
247
- unless option?(arg)
248
- args << arg
249
- next
250
- end
251
-
245
+
252
246
  # add the remaining args and break
253
247
  # for the option break
254
248
  if option_break === arg
255
249
  argv.unshift(arg) if preserve_option_break
256
250
  break
257
251
  end
258
-
252
+
253
+ # determine if the arg is an option
254
+ unless option?(arg)
255
+ args << arg
256
+ next
257
+ end
258
+
259
259
  flag, value = arg, nil
260
-
260
+
261
261
  # try the flag directly
262
262
  unless option = @options[flag]
263
-
263
+
264
264
  # then try --opt=value syntax
265
265
  flag, value = flag.split('=', 2)
266
-
266
+
267
267
  # then try -ovalue syntax
268
268
  if value.nil? && flag[1] != ?-
269
269
  flag, value = flag[0, 2], flag[2, flag.length - 2]
270
270
  end
271
-
271
+
272
272
  unless option = @options[flag]
273
273
  raise "unknown option: #{flag}"
274
274
  end
275
275
  end
276
-
276
+
277
277
  option.parse(flag, value, argv, config)
278
278
  end
279
-
279
+
280
280
  args.concat(argv)
281
281
  argv.replace(args)
282
-
282
+
283
283
  block_given? ? yield(argv, config) : argv
284
284
  end
285
-
285
+
286
286
  # Resets each option and clears the config (if specified). Returns self.
287
287
  def reset(options={})
288
288
  options = {
289
289
  :clear => true
290
290
  }.merge(options)
291
-
291
+
292
292
  registry.each do |option|
293
293
  if option.respond_to?(:reset)
294
294
  option.reset
295
295
  end
296
296
  end
297
-
297
+
298
298
  config.clear if options[:clear]
299
299
  self
300
300
  end
301
-
301
+
302
302
  # Converts the options and separators in self into a help string suitable
303
303
  # for display on the command line.
304
- def to_s
304
+ def to_s(opts={})
305
305
  @registry.collect do |option|
306
- option.to_s.rstrip
306
+ str = option.kind_of?(Flag) ? option.to_s(opts) : option.to_s
307
+ str.rstrip
307
308
  end.join("\n") + "\n"
308
309
  end
309
-
310
+
310
311
  protected
311
-
312
+
312
313
  def option_class(attrs) # :nodoc:
313
314
  type = attrs[:option_type] || guess_option_type(attrs)
314
-
315
+
315
316
  case type
316
317
  when :option then Option
317
318
  when :flag then Flag
@@ -321,16 +322,16 @@ class ConfigParser
321
322
  else raise "unknown option type: #{type}"
322
323
  end
323
324
  end
324
-
325
+
325
326
  # helper to parse an option from an argv. new_option is used
326
327
  # by on and on! to generate options
327
328
  def new_option(argv, &block) # :nodoc:
328
329
  attrs = argv.last.kind_of?(Hash) ? argv.pop : {}
329
330
  attrs = parse_attrs(argv).merge(attrs)
330
-
331
+
331
332
  attrs[:hint] ||= guess_hint(attrs)
332
333
  attrs[:callback] = block if block
333
-
334
+
334
335
  option_class(attrs).new(attrs)
335
336
  end
336
337
  end
@@ -1,59 +1,59 @@
1
1
  require 'config_parser/utils'
2
2
 
3
3
  class ConfigParser
4
-
4
+
5
5
  # Represents a boolean flag-style option. Flag handles the parsing of
6
6
  # specific flags, and provides hooks for processing the various types of
7
7
  # options (Switch, Option, List).
8
8
  class Flag
9
9
  include Utils
10
-
10
+
11
11
  # The config key.
12
12
  attr_reader :key
13
-
13
+
14
14
  # The config nesting keys.
15
15
  attr_reader :nest_keys
16
-
16
+
17
17
  # The default value.
18
18
  attr_reader :default
19
-
19
+
20
20
  # The short flag mapping to self.
21
21
  attr_reader :short
22
-
22
+
23
23
  # The long flag mapping to self.
24
24
  attr_reader :long
25
-
25
+
26
26
  # The description printed by to_s.
27
27
  attr_reader :desc
28
-
28
+
29
29
  # A hint printed by to_s, after desc.
30
30
  attr_reader :hint
31
-
31
+
32
32
  # A callback for processing values (must respond to call, or be nil).
33
33
  attr_reader :callback
34
-
34
+
35
35
  # A tracking flag set to true when assign is called. Useful when assign
36
36
  # works differently for the first assignment than later assignments. See
37
37
  # reset.
38
38
  attr_reader :assigned
39
-
39
+
40
40
  def initialize(attrs={})
41
41
  @key = attrs[:key]
42
42
  @nest_keys = attrs[:nest_keys]
43
43
  @default = attrs[:default]
44
- @short = shortify(attrs[:short])
44
+ @short = shortify(attrs.has_key?(:short) ? attrs[:short] : default_short)
45
45
  @long = longify(attrs.has_key?(:long) ? attrs[:long] : default_long)
46
46
  @desc = attrs[:desc]
47
47
  @hint = attrs[:hint]
48
48
  @callback = attrs[:callback]
49
49
  reset
50
50
  end
51
-
51
+
52
52
  # Returns an array of flags mapping to self (ie [long, short]).
53
53
  def flags
54
54
  [long, short].compact
55
55
  end
56
-
56
+
57
57
  # Parse handles the parsing of flags, which happens in three steps:
58
58
  #
59
59
  # * determine the value (occurs in parse)
@@ -95,17 +95,17 @@ class ConfigParser
95
95
  raise "value specified for #{flag}: #{value.inspect}"
96
96
  end
97
97
  end
98
-
98
+
99
99
  value = (default.nil? ? true : !default)
100
100
  assign(config, process(value))
101
101
  end
102
-
102
+
103
103
  # Process the value by calling the callback, if specified, with the value
104
104
  # and returns the result. Returns value if no callback is specified.
105
105
  def process(value)
106
106
  callback ? callback.call(value) : value
107
107
  end
108
-
108
+
109
109
  # Assigns the default value into config and resets the assigned flag to
110
110
  # false, such that the next assign behaves as if self has not put a value
111
111
  # into config. Returns config.
@@ -114,7 +114,7 @@ class ConfigParser
114
114
  reset
115
115
  config
116
116
  end
117
-
117
+
118
118
  # Assign the value to the config hash, if key is set, and flips assigned
119
119
  # to true. Returns config.
120
120
  def assign(config, value)
@@ -122,51 +122,58 @@ class ConfigParser
122
122
  nest_config = nest(config)
123
123
  nest_config[key] = value
124
124
  end
125
-
125
+
126
126
  @assigned = true
127
127
  config
128
128
  end
129
-
129
+
130
130
  # Returns the nested config hash for config, as specified by nest_keys.
131
131
  def nest(config)
132
132
  nest_keys.each do |key|
133
133
  config = (config[key] ||= {})
134
134
  end if nest_keys
135
-
135
+
136
136
  config
137
137
  end
138
-
138
+
139
139
  # Resets assigned to false.
140
140
  def reset
141
141
  @assigned = false
142
142
  end
143
-
144
- # Formats self as a help string for use on the command line.
145
- def to_s
146
- lines = wrap(desc_str, 43)
147
-
143
+
144
+ # Formats self as a help string for use on the command line (deprecated
145
+ # for that use, see format instead).
146
+ def to_s(opts={})
147
+ width = opts[:width] || 80
148
+ head_size = opts[:head_size] || (width * 0.45).to_i
149
+ desc_size = width - head_size - 1
150
+
151
+ format = "%-#{head_size}s %-#{desc_size}s"
152
+
153
+ lines = wrap(desc_str, desc_size)
154
+
148
155
  header = header_str
149
- header = header.length > 36 ? header.ljust(80) : (LINE_FORMAT % [header, lines.shift])
150
-
156
+ header = header.length > head_size ? header.ljust(width) : (format % [header, lines.shift])
157
+
151
158
  if lines.empty?
152
159
  header
153
160
  else
154
- lines.collect! {|line| LINE_FORMAT % [nil, line] }
161
+ lines.collect! {|line| format % [nil, line] }
155
162
  "#{header}\n#{lines.join("\n")}"
156
163
  end
157
164
  end
158
-
165
+
159
166
  # Returns an inspect string.
160
167
  def inspect
161
168
  "#<#{self.class}:#{object_id} key=#{key.inspect} default=#{default.inspect} long=#{long.inspect} short=#{short.inspect}>"
162
169
  end
163
-
170
+
164
171
  private
165
-
172
+
166
173
  def header_str # :nodoc:
167
174
  " #{short_str}#{long_str}"
168
175
  end
169
-
176
+
170
177
  def short_str # :nodoc:
171
178
  case
172
179
  when short && long then "#{short}, "
@@ -174,11 +181,11 @@ class ConfigParser
174
181
  else ' '
175
182
  end
176
183
  end
177
-
184
+
178
185
  def long_str # :nodoc:
179
186
  long
180
187
  end
181
-
188
+
182
189
  def desc_str # :nodoc:
183
190
  case
184
191
  when hint.nil? && desc.nil?
@@ -189,9 +196,14 @@ class ConfigParser
189
196
  "#{desc} (#{hint})".strip
190
197
  end
191
198
  end
192
-
199
+
193
200
  def default_long # :nodoc:
201
+ return nil if default_short
194
202
  nest_keys ? (nest_keys + [key]).join(':') : key
195
203
  end
204
+
205
+ def default_short # :nodoc:
206
+ key.to_s.length == 1 && nest_keys.nil? ? key : nil
207
+ end
196
208
  end
197
209
  end
@@ -1,46 +1,46 @@
1
1
  require 'config_parser/option'
2
2
 
3
3
  class ConfigParser
4
-
4
+
5
5
  # List represents a special type of Option where multiple values may be
6
6
  # assigned to the same key.
7
7
  class List < Option
8
-
8
+
9
9
  # The delimiter on which to split single values into multiple values; use
10
10
  # nil to prevent splitting.
11
11
  attr_reader :delimiter
12
-
12
+
13
13
  def initialize(attrs={})
14
14
  super
15
-
15
+
16
16
  @delimiter = attrs.has_key?(:delimiter) ? attrs[:delimiter] : DELIMITER
17
17
  @default = split(@default)
18
18
  end
19
-
19
+
20
20
  # Splits the value into multiple values, and then process as usual.
21
21
  def process(value)
22
22
  split(value).collect {|val| super(val) }
23
23
  end
24
-
24
+
25
25
  # Assigns the values to config. Multiple calls to assign will concatenate
26
26
  # (ie when assigned is true) new values onto the existing values. As
27
27
  # usual, no values are assigned if key is not set. Returns config.
28
28
  def assign(config, values)
29
29
  if key
30
30
  nest_config = nest(config)
31
-
31
+
32
32
  unless assigned
33
33
  nest_config[key] = []
34
34
  end
35
-
35
+
36
36
  array = (nest_config[key] ||= [])
37
37
  array.concat(values)
38
38
  end
39
-
39
+
40
40
  @assigned = true
41
41
  config
42
42
  end
43
-
43
+
44
44
  # Splits string values along the delimiter, if specified. Returns array
45
45
  # values directly, and an empty array for nil. All other values are
46
46
  # arrayified like [obj].
@@ -52,9 +52,9 @@ class ConfigParser
52
52
  else [obj]
53
53
  end
54
54
  end
55
-
55
+
56
56
  private
57
-
57
+
58
58
  def header_str # :nodoc:
59
59
  " #{short_str}#{long_str} #{arg_name}..."
60
60
  end
@@ -1,28 +1,28 @@
1
1
  require 'config_parser/switch'
2
2
 
3
3
  class ConfigParser
4
-
4
+
5
5
  # An Option represents a Flag that takes a value.
6
6
  class Option < Flag
7
-
7
+
8
8
  # The default argument name
9
9
  DEFAULT_ARGNAME = 'VALUE'
10
-
10
+
11
11
  # Matches optional argnames
12
12
  OPTIONAL = /\A\[.*\]\z/
13
-
13
+
14
14
  # The argument name printed by to_s.
15
15
  attr_reader :arg_name
16
-
16
+
17
17
  # Set to true to make the argument optional.
18
18
  attr_reader :optional
19
-
19
+
20
20
  def initialize(attrs={})
21
21
  super
22
22
  @arg_name = attrs[:arg_name] || (key ? key.to_s.upcase : DEFAULT_ARGNAME)
23
23
  @optional = (attrs.has_key?(:optional) ? attrs[:optional] : (arg_name =~ OPTIONAL ? true : false))
24
24
  end
25
-
25
+
26
26
  # Parse the flag and value. If no value is provided and a value is
27
27
  # required, then a value is shifted off of argv. The value is then
28
28
  # processed and assigned into config.
@@ -36,12 +36,12 @@ class ConfigParser
36
36
  end
37
37
  end
38
38
  end
39
-
39
+
40
40
  assign(config, process(value))
41
41
  end
42
-
42
+
43
43
  private
44
-
44
+
45
45
  def header_str # :nodoc:
46
46
  " #{short_str}#{long_str} #{arg_name}"
47
47
  end
@@ -1,43 +1,43 @@
1
1
  require 'config_parser/flag'
2
2
 
3
3
  class ConfigParser
4
-
4
+
5
5
  # Switch represents a special type of Option where both positive (--flag)
6
6
  # and negative (--no-flag) flags map to self.
7
7
  class Switch < Flag
8
-
8
+
9
9
  # The negative mapping prefix, defaults to 'no'
10
10
  attr_reader :prefix
11
-
11
+
12
12
  # The negative long flag, determined from long and prefix.
13
13
  attr_reader :negative_long
14
-
14
+
15
15
  def initialize(attrs={})
16
16
  attrs[:default] = true unless attrs.has_key?(:default)
17
17
  super
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
24
  # Returns an array of flags mapping to self (ie [long, negative_long, short]).
25
25
  def flags
26
26
  [long, negative_long, short].compact
27
27
  end
28
-
28
+
29
29
  # Assigns default into config for positive flags and !default for negative
30
30
  # flags. The boolean value is then processed and assigned into config.
31
31
  # Raises an error if a value is provided (switches take none).
32
32
  def parse(flag, value=nil, argv=[], config={})
33
33
  raise "value specified for #{flag}: #{value.inspect}" if value
34
-
34
+
35
35
  value = (flag == negative_long ? !default : default)
36
36
  assign(config, process(value))
37
37
  end
38
38
 
39
39
  private
40
-
40
+
41
41
  def long_str # :nodoc:
42
42
  prefix_long(long, "[#{prefix}-]")
43
43
  end
@@ -1,24 +1,21 @@
1
1
  class ConfigParser
2
-
2
+
3
3
  # A medly of methods used throughout the ConfigParser classes.
4
4
  module Utils
5
5
  module_function
6
-
7
- # A format string used by to_s
8
- LINE_FORMAT = "%-36s %-43s"
9
-
6
+
10
7
  # The default option break
11
8
  OPTION_BREAK = "--"
12
-
9
+
13
10
  # Matches an option (long or short)
14
11
  OPTION = /\A-./
15
-
12
+
16
13
  # Matches a long flag
17
14
  LONG_FLAG = /\A--.+\z/
18
15
 
19
16
  # Matches a short flag
20
17
  SHORT_FLAG = /\A-.\z/
21
-
18
+
22
19
  # Matches a switch option (ex: '--[no-]opt', '--nest:[no-]opt'). After the
23
20
  # match:
24
21
  #
@@ -27,17 +24,17 @@ class ConfigParser
27
24
  # $3:: the long flag name ('opt')
28
25
  #
29
26
  SWITCH = /\A--(.*?)\[(.*?)-\](.+)\z/
30
-
27
+
31
28
  # Matches a nest option (ex: '--nest:opt'). After the match:
32
29
  #
33
30
  # $1:: the nesting prefix ('nest')
34
31
  # $2:: the long option ('long')
35
32
  #
36
33
  NEST = /\A--(.*):(.+)\z/
37
-
34
+
38
35
  # The default split character for multiple values
39
36
  DELIMITER = ','
40
-
37
+
41
38
  # Turns the input into a short flag by prefixing '-' (as needed). Raises
42
39
  # an error if the input doesn't result in a short flag. Nils are
43
40
  # returned directly.
@@ -47,14 +44,14 @@ class ConfigParser
47
44
  #
48
45
  def shortify(str)
49
46
  return nil if str.nil?
50
-
47
+
51
48
  str = str.to_s
52
49
  str = "-#{str}" unless option?(str)
53
-
50
+
54
51
  unless str =~ SHORT_FLAG
55
52
  raise ArgumentError, "invalid short flag: #{str}"
56
53
  end
57
-
54
+
58
55
  str
59
56
  end
60
57
 
@@ -67,17 +64,17 @@ class ConfigParser
67
64
  #
68
65
  def longify(str)
69
66
  return nil if str.nil?
70
-
67
+
71
68
  str = str.to_s
72
69
  str = "--#{str}" unless option?(str)
73
-
70
+
74
71
  unless str =~ LONG_FLAG
75
72
  raise ArgumentError, "invalid long flag: #{str}"
76
73
  end
77
-
74
+
78
75
  str
79
76
  end
80
-
77
+
81
78
  # Adds a prefix onto the last nested segment of a long option.
82
79
  #
83
80
  # prefix_long('--opt', 'no-') # => '--no-opt'
@@ -89,25 +86,25 @@ class ConfigParser
89
86
  switch[-1] = "#{prefix}#{switch[-1]}"
90
87
  "--#{switch.join(':')}"
91
88
  end
92
-
89
+
93
90
  # Returns true if the object is a string and matches OPTION.
94
91
  def option?(obj)
95
92
  obj.kind_of?(String) && obj =~ OPTION ? true : false
96
93
  end
97
-
94
+
98
95
  # Shifts and returns the first argument off of argv if it is an argument
99
96
  # (rather than an option) or returns the default value.
100
97
  def next_arg(argv)
101
98
  option?(argv.at(0)) ? nil : argv.shift
102
99
  end
103
-
100
+
104
101
  # A wrapping algorithm slightly modified from:
105
102
  # http://blog.macromates.com/2006/wrapping-text-with-regular-expressions/
106
103
  def wrap(line, cols=80, tabsize=2)
107
104
  line = line.gsub(/\t/, " " * tabsize) unless tabsize == nil
108
105
  line.gsub(/(.{1,#{cols}})( +|$\r?\n?)|(.{1,#{cols}})/, "\\1\\3\n").split(/\s*?\n/)
109
106
  end
110
-
107
+
111
108
  # Parses the argv into an attributes hash for initializing an option.
112
109
  # Heuristics are used to infer what an argument implies.
113
110
  #
@@ -129,7 +126,7 @@ class ConfigParser
129
126
  # arg_name with a switch) can be detected... others not so much.
130
127
  def parse_attrs(argv)
131
128
  attrs={}
132
-
129
+
133
130
  argv.each do |arg|
134
131
  unless option?(arg)
135
132
  attrs[:desc] = arg
@@ -137,7 +134,7 @@ class ConfigParser
137
134
  end
138
135
 
139
136
  flag, arg_name = arg.split(/\s+/, 2)
140
-
137
+
141
138
  if flag =~ NEST
142
139
  attrs[:nest_keys] = $1.split(':')
143
140
  end
@@ -150,7 +147,7 @@ class ConfigParser
150
147
  when SWITCH
151
148
  attrs[:long] = "--#{$1}#{$3}"
152
149
  attrs[:prefix] = $2
153
-
150
+
154
151
  if arg_name
155
152
  raise ArgumentError, "arg_name specified for switch: #{arg_name}"
156
153
  end
@@ -165,10 +162,10 @@ class ConfigParser
165
162
  raise ArgumentError.new("invalid flag: #{arg.inspect}")
166
163
  end
167
164
  end
168
-
165
+
169
166
  attrs
170
167
  end
171
-
168
+
172
169
  # Guesses an option type based on the attrs.
173
170
  #
174
171
  # if... then...
@@ -190,12 +187,12 @@ class ConfigParser
190
187
  :flag
191
188
  end
192
189
  end
193
-
190
+
194
191
  # Guesses :list if the arg_name has a comma, or nil.
195
192
  def guess_option_type_by_arg_name(arg_name)
196
193
  arg_name.to_s.include?(',') ? :list : nil
197
194
  end
198
-
195
+
199
196
  # Guesses an option type based on a value.
200
197
  #
201
198
  # if... then...
@@ -213,10 +210,10 @@ class ConfigParser
213
210
  else :option
214
211
  end
215
212
  end
216
-
213
+
217
214
  def guess_hint(attrs)
218
215
  default = attrs[:default]
219
-
216
+
220
217
  case default
221
218
  when true, false, nil
222
219
  nil
@@ -1,7 +1,7 @@
1
1
  class ConfigParser
2
2
  MAJOR = 0
3
3
  MINOR = 5
4
- TINY = 4
4
+ TINY = 5
5
5
 
6
6
  VERSION = "#{MAJOR}.#{MINOR}.#{TINY}"
7
7
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: config_parser
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
- - 4
10
- version: 0.5.4
9
+ - 5
10
+ version: 0.5.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Simon Chiang
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-07-11 00:00:00 -06:00
18
+ date: 2011-07-18 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency