Module: CLASP

Defined in:
lib/clasp/doc_.rb,
lib/clasp/cli.rb,
lib/clasp/aliases.rb,
lib/clasp/version.rb,
lib/clasp/arguments.rb,
lib/clasp/util/immutable_array.rb

Overview

Main module for CLASP.Ruby library

Examples

Simple command-line, no aliases

argv = %w{ --show-all=true infile -c outfile }

args = CLASP::Arguments.new(argv)

puts args.flags.size         # => 1
puts args.flags[0]           # => "#<CLASP::Arguments::Flag:0x007fd23aa3aa98 @arg="-c", @given_index=1, @given_name="-c", @argument_alias=nil, @given_hyphens=1, @given_label="c", @name="-c", @extras={}>"
puts args.options.size       # => 1
puts args.options[0]         # => "#<CLASP::Arguments::Option:0x007fd23aa3aca0 @arg="--show-all=true", @given_index=0, @given_name="--show-all", @argument_alias=nil, @given_hyphens=2, @given_label="show-all", @value="true", @name="--show-all", @extras={}>"
puts args.options[0].value   # => "true"
puts args.values.size        # => 2
puts args.values[0]          # => "infile"
puts args.values[1]          # => "outfile"

Use of the special double-slash flag to treat all subsequent arguments as values

argv = %w{ --show-all=true -- infile outfile -c }

args = CLASP::Arguments.new(argv)

puts args.flags.size         # => 0
puts args.options.size       # => 1
puts args.options[0]         # => "#<CLASP::Arguments::Option:0x007fd23aa3aca0 @arg="--show-all=true", @given_index=0, @given_name="--show-all", @argument_alias=nil, @given_hyphens=2, @given_label="show-all", @value="true", @name="--show-all", @extras={}>"
puts args.values.size        # => 3
puts args.values[0]          # => "infile"
puts args.values[1]          # => "outfile"
puts args.values[2]          # => "-c"

Use of flag short forms

aliases = [

  CLASP.Flag('--verbose', alias: '-v'),
  CLASP.Flag('--trace-output', aliases: [ '-t', '--trace' ]),
]

argv = %w{ -trace -v }

args = CLASP::Arguments.new(argv, aliases)

puts args.flags.size        # => 2
puts args.flags[0].name     # => "--trace-output"
puts args.flags[1].name     # => "--verbose"
puts args.options.size      # => 0
puts args.values.size       # => 0

Use of flag single short forms combined

aliases = [

  CLASP.Flag('--expand', alias: '-x'),
  CLASP.Flag('--verbose', alias: '-v'),
  CLASP.Flag('--trace-output', aliases: [ '-t', '--trace' ]),
]

argv = %w{ -tvx }

args = CLASP::Arguments.new(argv, aliases)

puts args.flags.size        # => 3
puts args.options.size      # => 0
puts args.values.size       # => 0

Use of option short form

aliases = [

  CLASP.Option('--show-all', alias: '-a'),
]

argv = %w{ -c -a true infile outfile }

args = CLASP::Arguments.new(argv, aliases)

puts args.flags.size         # => 1
puts args.flags[0]           # => "#<CLASP::Arguments::Flag:0x007f8593b0ddd8 @arg="-c", @given_index=0, @given_name="-c", @argument_alias=nil, @given_hyphens=1, @given_label="c", @name="-c", @extras={}>"
puts args.options.size       # => 1
puts args.options[0]         # => "#<CLASP::Arguments::Option:0x007f8593b0db80 @arg="-a", @given_index=1, @given_name="-a", @argument_alias=#<CLASP::Option:0x007f8593b2ea10 @name="--show-all", @aliases=["-a"], @help=nil, @values_range=[], @default_value=nil, @extras={}>, @given_hyphens=1, @given_label="a", @value="true", @name="--show-all", @extras={}>"
puts args.values.size        # => 2
puts args.values[0]          # => "infile"
puts args.values[1]          # => "outfile"

Classes of interest

  • ::CLASP::Arguments

  • ::CLASP::Flag

  • ::CLASP::Option

Functions of interest

  • ::CLASP.show_version()

  • ::CLASP#show_version()

  • ::CLASP::show_version()

Defined Under Namespace

Modules: CLI_helpers_, Util Classes: Alias, Arguments, Flag, Option

Constant Summary collapse

VERSION =

Current version of the CLASP.Ruby library

'0.13.3'
VERSION_MAJOR =

Major version of the CLASP.Ruby library

VERSION_PARTS_[0]
VERSION_MINOR =

Minor version of the CLASP.Ruby library

VERSION_PARTS_[1]
VERSION_REVISION =

Revision version of the CLASP.Ruby library

VERSION_PARTS_[2]

Class Method Summary collapse

Class Method Details

.Alias(name, *args) ⇒ Object



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
# File 'lib/clasp/aliases.rb', line 366

def CLASP.Alias(name, *args)

  options  =  args.pop if args[-1].is_a?(::Hash)
  options  ||=  {}

  if options[:alias]

    aliases = [ options[:alias] ]
  elsif options[:aliases]

    aliases = options[:aliases]
  else

    aliases = args
  end

  CLASP::Alias.new name, aliases
end

.Flag(name, options = {}) ⇒ Object

Generator method that obtains a CLASP::Flag according to the given parameters

Signature

  • Parameters:

    • name
      ::String

      The flag name, e.g. ‘–verbose’

    • options
      ::Hash

      An options hash, containing any of the following

      options:

  • Options:

    • :alias [::String] An alias, e.g. ‘-v’

    • :aliases [::Array] An array of aliases, e.g. [ ‘-v’, ‘-verb’ ] Ignored if :alias is specified

    • :extras An application-defined object, usually a hash of custom attributes

    • :help [::String] A help string



247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'lib/clasp/aliases.rb', line 247

def CLASP.Flag(name, options = {})

  aliases  =  nil
  help = nil
  extras = nil

  options.each do |k, v|

    case  k
    when  Symbol
      case k
      when :alias

        aliases = [ v ]
      when :aliases

        aliases = v unless aliases
      when :help

        help  =  v
      when :extras

        extras  =  v
      else

        raise ArgumentError, "invalid option for flag: '#{k}' => '#{v}'"
      end
    else

      raise ArgumentError, "invalid option type for flag: '#{k}' (#{k.class}) => '#{v}'"
    end
  end

  CLASP::Flag.new(name, aliases, help, extras)
end

.Option(name, options = {}) ⇒ Object

Generator method that obtains a CLASP::Option according to the given parameters

Signature

  • Parameters:

    • name
      ::String

      The flag name, e.g. ‘–verbose’

    • options
      ::Hash

      An options hash, containing any of the following

      options:

  • Options:

    • :alias [::String] An alias, e.g. ‘-v’

    • :aliases [::Array] An array of aliases, e.g. [ ‘-v’, ‘-verb’ ]. Ignored if :alias is specified

    • :default_value The default value for the option

    • :default [DEPRECATED] Alternative to :default_value

    • :extras An application-defined object, usually a hash of custom attributes

    • :help [::String] A help string

    • required
      boolean

      Whether the option is required. May be

      nil

    • required_message
      ::String

      Message to be used when reporting

      that a required option is missing. May be nil in which case a message of the form “<option-name> not specified; use –help for usage”. If begins with the nul character (“0”), then is used in the place of the <option-name> and placed into the rest of the standard form message

    • extras

      An application-defined additional parameter. If nil, it is assigned an empty Hash.

    • :values_range [::Array] An array defining the accepted values for the option

    • :values [DEPRECATED] Alternative to :values_range



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
# File 'lib/clasp/aliases.rb', line 314

def CLASP.Option(name, options = {})

  aliases      =  nil
  help     = nil
  values_range = nil
  default_value  =  nil
  required   =  false
  require_message  =  nil
  extras     = nil

  options.each do |k, v|

    case  k
    when  Symbol
      case k
      when :alias

        aliases = [ v ]
      when :aliases

        aliases = v unless aliases
      when :help

        help  =  v
      when :values_range, :values

        values_range  =  v
      when :default_value, :default

        default_value = v
      when :required

        required  =  v
      when :required_message

        require_message = v
      when :extras

        extras  =  v
      else

        raise ArgumentError, "invalid option for flag: '#{k}' => '#{v}'"
      end
    else

      raise ArgumentError, "invalid option type for flag: '#{k}' (#{k.class}) => '#{v}'"
    end
  end

  CLASP::Option.new(name, aliases, help, values_range, default_value, required, require_message, extras)
end

.show_usage(aliases, options = {}) ⇒ Object

Displays usage for the program according to the given aliases and options

Signature

  • Parameters:

    • aliases

      (Array) The arguments array. May not be nil. Defaults to ARGV.

    • options

      An options hash, containing any of the following options.

  • Options:

    • :exit

      a program exit code; exit() not called if not specified (or nil).

    • :program_name

      program name; inferred from $0 if not specified.

    • :stream

      output stream; $stdout if not specified.

    • :suppress_blank_lines_between_options

      does exactly what it says on the tin.

    • :values

      appends this string to USAGE line if specified.

    • :flags_and_options

      inserts a custom string instead of the default string '[ ... flags and options ... ]'.

    • :info_lines

      inserts 0+ information lines prior to the usage.

Raises:

  • (ArgumentError)


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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/clasp/cli.rb', line 128

def self.show_usage aliases, options={}

  options  ||=  {}

  raise ArgumentError, "aliases may not be nil" if aliases.nil?
  raise TypeError, "aliases must be an array or must respond to each, reject and select" unless ::Array === aliases || (aliases.respond_to?(:each) && aliases.respond_to?(:reject) && aliases.respond_to?(:select))

  constants    = CLI_helpers_::Constants
  aliases.each { |a| raise ::TypeError, "each element in aliases array must be one of the types #{constants::VALID_ALIAS_TYPES_STRING}" unless constants::VALID_ALIAS_TYPES.any? { |c| c === a } }

  alias_dups = {}
  aliases.each { |a| a.aliases.each { |aa| warn "WARNING: alias '#{aa}' is already used for alias '#{a}'" if alias_dups.has_key? aa; alias_dups[aa] = a; } }

  suppress_blanks  =  options[:suppress_blank_lines_between_options] || ENV['SUPPRESS_BLANK_LINES_BETWEEN_OPTIONS']

  stream     = options[:stream] || $stdout
  program_name = options[:program_name] || File.basename($0)

  info_lines   =  options[:info_lines]
  case info_lines
  when ::Array
    ;
  when ::NilClass
    info_lines  =  []
  else
    info_lines = [ info_lines ] unless [ :each, :empty? ].all? { |m| info_lines.respond_to? m }
  end
  info_lines.map! do |line|

    case line
    when :version

      CLI_helpers_.generate_version_string_ options
    else

      line
    end
  end

  values     = options[:values] || ''
  values     = " #{values}" if !values.empty? && ' ' != values[0]

  flags_and_options  =  options[:flags_and_options] || ' [ ... flags and options ... ]'
  flags_and_options  =  " #{flags_and_options}" if !flags_and_options.empty? && ' ' != flags_and_options[0]

  # sift the aliases to sort out which are value-option aliases (VOAs)

  voas     = {}

  aliases.select { |a| a.name =~ /^-+[a-zA-Z0-3_-]+[=:].+/ }.each do |a|

    a.name =~ /^(-+[a-zA-Z0-3_-]+)[=:](.+)$/

    voas[$1]  =  [] unless voas.has_key? $1
    voas[$1]  << [ a, $2 ]
  end

  fas        = {}

  aliases.select { |a| Alias === a }.each do |a|

    fas[a.name] = [] unless fas.has_key? $1
    fas[a.name] <<  a
  end

  aliases      =  aliases.reject { |a| a.name =~ /^-+[a-zA-Z0-3_-]+[=:].+/ }

  info_lines.each { |info_line| stream.puts info_line } unless info_lines.empty?

  stream.puts "USAGE: #{program_name}#{flags_and_options}#{values}"
  stream.puts

  unless aliases.empty?

    stream.puts "flags/options:"
    stream.puts
    aliases.each do |a|

      case a
      when Alias

        next
      when Flag

        if fas.has_key? a.name

          fas[a.name].each do |fa|

            fa.aliases.each { |al| stream.puts "\t#{al}" }
          end
        end
        a.aliases.each { |al| stream.puts "\t#{al}" }
        stream.puts "\t#{a.name}"
        stream.puts "\t\t#{a.help}"
      when Option

        if voas.has_key? a.name

          voas[a.name].each do |ar|

            ar[0].aliases.each { |al| stream.puts "\t#{al} #{ar[0].name}" }
          end
        end
        a.aliases.each { |al| stream.puts "\t#{al} <value>" }
        stream.puts "\t#{a.name}=<value>"
        stream.puts "\t\t#{a.help}"
        unless a.values_range.empty?

          stream.puts "\t\twhere <value> one of:"
          a.values_range.each { |v| stream.puts "\t\t\t#{v}" }
        end
      end
      stream.puts unless suppress_blanks
    end
  end

  exit options[:exit] if options[:exit]
end

.show_version(aliases, options = {}) ⇒ Object

Displays version for the program according to the given aliases and options

Signature

  • Parameters:

    • aliases

      (Array) The arguments array. May not be nil. Defaults to ARGV.

    • options

      An options hash, containing any of the following options.

  • Options:

    • :exit

      a program exit code; exit() not called if not specified (or nil).

    • :program_name

      program name; inferred from $0 if not specified.

    • :stream

      output stream; $stdout if not specified.

    • :version

      an array (of N elements, each of which will be separated by a period ‘.’), or a string. Must be specified if not :version_major.

    • :version_major

      a number or string. Only considered and must be specified if :version is not.

    • :version_minor

      a number or string. Only considered if :version is not.

    • :version_revision

      a number or string. Only considered if :version is not.

    • :version_build

      a number or string. Only considered if :version is not.

    • :version_prefix

      optional string to prefix the version number(s).

Raises:

  • (ArgumentError)


265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/clasp/cli.rb', line 265

def self.show_version aliases, options = {}

  options  ||=  {}

  raise ArgumentError, "aliases may not be nil" if aliases.nil?
  raise TypeError, "aliases must be an array or must respond to each, reject and select" unless ::Array === aliases || (aliases.respond_to?(:each) && aliases.respond_to?(:reject) && aliases.respond_to?(:select))

  constants    = CLI_helpers_::Constants
  aliases.each { |a| raise ::TypeError, "each element in aliases array must be one of the types #{constants::VALID_ALIAS_TYPES_STRING}" unless constants::VALID_ALIAS_TYPES.any? { |c| c === a } }

  stream     = options[:stream] || $stdout

  version_string = CLI_helpers_.generate_version_string_ options

  stream.puts version_string

  exit options[:exit] if options[:exit]
end