Module: ConfigParser::Utils

Included in:
ConfigParser, Flag
Defined in:
lib/config_parser/utils.rb

Overview

A medly of methods used throughout the ConfigParser classes.

Constant Summary collapse

OPTION_BREAK =

The default option break

"--"
OPTION =

Matches an option (long or short)

/\A-./
LONG_FLAG =

Matches a long flag

/\A--.+\z/
SHORT_FLAG =

Matches a short flag

/\A-.\z/
SWITCH =

Matches a switch option (ex: ‘–[no-]opt’, ‘–nest:opt’). After the match:

$1:: the nesting prefix ('nest')
$2:: the negative long prefix ('no')
$3:: the long flag name ('opt')
/\A--(.*?)\[(.*?)-\](.+)\z/
NEST =

Matches a nest option (ex: ‘–nest:opt’). After the match:

$1:: the nesting prefix ('nest')
$2:: the long option ('long')
/\A--(.*):(.+)\z/
DELIMITER =

The default split character for multiple values

','

Class Method Summary collapse

Class Method Details

.guess_hint(attrs) ⇒ Object



214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/config_parser/utils.rb', line 214

def guess_hint(attrs)
  default = attrs[:default]

  case default
  when true, false, nil
    nil
  when Array
    hint = default.join(attrs[:delimiter] || DELIMITER)
    hint.empty? ? nil : hint
  else
    default.to_s
  end
end

.guess_option_type(attrs) ⇒ Object

Guesses an option type based on the attrs.

if...            then...
prefix      =>   :switch
arg_name    =>   guess_option_type_by_arg_name || guess_option_type_by_value
default     =>   (guess_option_type_by_value)
all else    =>   :flag

A guess is just a guess; for certainty specify the type manually.



178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/config_parser/utils.rb', line 178

def guess_option_type(attrs)
  case
  when attrs.has_key?(:prefix)
    :switch
  when attrs.has_key?(:arg_name)
    guess_option_type_by_arg_name(attrs[:arg_name]) || guess_option_type_by_value(attrs[:default])
  when attrs.has_key?(:default)
    guess_option_type_by_value(attrs[:default])
  else
    :flag
  end
end

.guess_option_type_by_arg_name(arg_name) ⇒ Object

Guesses :list if the arg_name has a comma, or nil.



192
193
194
# File 'lib/config_parser/utils.rb', line 192

def guess_option_type_by_arg_name(arg_name)
  arg_name.to_s.include?(',') ? :list : nil
end

.guess_option_type_by_value(value) ⇒ Object

Guesses an option type based on a value.

if...            then...
true        =>   :switch
false       =>   :flag
Array       =>   :list
all else    =>   :option

A guess is just a guess; for certainty specify the type manually.



205
206
207
208
209
210
211
212
# File 'lib/config_parser/utils.rb', line 205

def guess_option_type_by_value(value)
  case value
  when true  then :switch
  when false then :flag
  when Array then :list
  else :option
  end
end

.longify(str) ⇒ Object

Turns the input into a long flag by prefixing ‘–’ (as needed). Raises an error if the input doesn’t result in a long flag. Nils are returned directly.

longify('--opt')       # => '--opt'
longify(:opt)          # => '--opt'


65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/config_parser/utils.rb', line 65

def longify(str)
  return nil if str.nil?

  str = str.to_s
  str = "--#{str}" unless option?(str)

  unless str =~ LONG_FLAG
    raise ArgumentError, "invalid long flag: #{str}"
  end

  str
end

.next_arg(argv) ⇒ Object

Shifts and returns the first argument off of argv if it is an argument (rather than an option) or returns the default value.



97
98
99
# File 'lib/config_parser/utils.rb', line 97

def next_arg(argv)
  option?(argv.at(0)) ? nil : argv.shift
end

.option?(obj) ⇒ Boolean

Returns true if the object is a string and matches OPTION.

Returns:

  • (Boolean)


91
92
93
# File 'lib/config_parser/utils.rb', line 91

def option?(obj)
  obj.kind_of?(String) && obj =~ OPTION ? true : false
end

.parse_attrs(argv) ⇒ Object

Parses the argv into an attributes hash for initializing an option. Heuristics are used to infer what an argument implies.

Argument            Implies
-s                  :short => '-s'
--long              :long => '--long'
--long ARG          :long => '--long', :arg_name => 'ARG'
--[no-]long         :long => '--long', :prefix => 'no', :option_type => :switch
--nest:long         :long => '--nest:long', :nest_keys => ['nest']
'some string'       :desc => 'some string'

Usually you overlay these patterns, for example:

-s ARG              :short => '-s', :arg_name => 'ARG'
--nest:[no-]long    :long => '--nest:long', :nest_keys => ['nest'], :prefix => 'no', :option_type => :switch

The goal of this method is to get things right most of the time, not to be clean, simple, or robust. Some errors in declarations (like an arg_name with a switch) can be detected… others not so much.



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/config_parser/utils.rb', line 127

def parse_attrs(argv)
  attrs={}

  argv.each do |arg|
    unless option?(arg)
      attrs[:desc] = arg
      next
    end

    flag, arg_name = arg.split(/\s+/, 2)

    if flag =~ NEST
      attrs[:nest_keys] = $1.split(':')
    end

    if arg_name
      attrs[:arg_name] = arg_name
    end

    case flag
    when SWITCH
      attrs[:long] = "--#{$1}#{$3}"
      attrs[:prefix] = $2

      if arg_name
        raise ArgumentError, "arg_name specified for switch: #{arg_name}"
      end

    when LONG_FLAG
      attrs[:long] = flag

    when SHORT_FLAG
      attrs[:short] = flag

    else
      raise ArgumentError.new("invalid flag: #{arg.inspect}")
    end
  end

  attrs
end

.prefix_long(switch, prefix, split_char = ':') ⇒ Object

Adds a prefix onto the last nested segment of a long option.

prefix_long('--opt', 'no-')         # => '--no-opt'
prefix_long('--nested:opt', 'no-')  # => '--nested:no-opt'


83
84
85
86
87
88
# File 'lib/config_parser/utils.rb', line 83

def prefix_long(switch, prefix, split_char=':')
  switch = switch[2, switch.length-2] if switch =~ /^--/
  switch = switch.split(split_char)
  switch[-1] = "#{prefix}#{switch[-1]}"
  "--#{switch.join(':')}"
end

.shortify(str) ⇒ Object

Turns the input into a short flag by prefixing ‘-’ (as needed). Raises an error if the input doesn’t result in a short flag. Nils are returned directly.

shortify('-o')         # => '-o'
shortify(:o)           # => '-o'


45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/config_parser/utils.rb', line 45

def shortify(str)
  return nil if str.nil?

  str = str.to_s
  str = "-#{str}" unless option?(str)

  unless str =~ SHORT_FLAG
    raise ArgumentError, "invalid short flag: #{str}"
  end

  str
end

.wrap(line, cols = 80, tabsize = 2) ⇒ Object

A wrapping algorithm slightly modified from: blog.macromates.com/2006/wrapping-text-with-regular-expressions/



103
104
105
106
# File 'lib/config_parser/utils.rb', line 103

def wrap(line, cols=80, tabsize=2)
  line = line.gsub(/\t/, " " * tabsize) unless tabsize == nil
  line.gsub(/(.{1,#{cols}})( +|$\r?\n?)|(.{1,#{cols}})/, "\\1\\3\n").split(/\s*?\n/)
end