shellopts 2.0.0.pre.13 → 2.0.1

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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.ruby-version +1 -1
  4. data/README.md +201 -267
  5. data/TODO +46 -134
  6. data/doc/format.rb +95 -0
  7. data/doc/grammar.txt +27 -0
  8. data/doc/syntax.rb +110 -0
  9. data/doc/syntax.txt +10 -0
  10. data/lib/ext/array.rb +58 -5
  11. data/lib/ext/forward_to.rb +15 -0
  12. data/lib/ext/lcs.rb +34 -0
  13. data/lib/shellopts/analyzer.rb +130 -0
  14. data/lib/shellopts/ansi.rb +8 -0
  15. data/lib/shellopts/args.rb +29 -21
  16. data/lib/shellopts/argument_type.rb +139 -0
  17. data/lib/shellopts/dump.rb +158 -0
  18. data/lib/shellopts/formatter.rb +325 -0
  19. data/lib/shellopts/grammar.rb +375 -0
  20. data/lib/shellopts/interpreter.rb +103 -0
  21. data/lib/shellopts/lexer.rb +175 -0
  22. data/lib/shellopts/parser.rb +269 -82
  23. data/lib/shellopts/program.rb +279 -0
  24. data/lib/shellopts/renderer.rb +227 -0
  25. data/lib/shellopts/stack.rb +7 -0
  26. data/lib/shellopts/token.rb +44 -0
  27. data/lib/shellopts/version.rb +2 -2
  28. data/lib/shellopts.rb +439 -220
  29. data/main +1180 -0
  30. data/shellopts.gemspec +9 -15
  31. metadata +85 -42
  32. data/lib/main.rb +0 -1
  33. data/lib/shellopts/ast/command.rb +0 -41
  34. data/lib/shellopts/ast/node.rb +0 -37
  35. data/lib/shellopts/ast/option.rb +0 -21
  36. data/lib/shellopts/ast/program.rb +0 -14
  37. data/lib/shellopts/compiler.rb +0 -128
  38. data/lib/shellopts/generator.rb +0 -15
  39. data/lib/shellopts/grammar/command.rb +0 -80
  40. data/lib/shellopts/grammar/node.rb +0 -33
  41. data/lib/shellopts/grammar/option.rb +0 -66
  42. data/lib/shellopts/grammar/program.rb +0 -65
  43. data/lib/shellopts/idr.rb +0 -236
  44. data/lib/shellopts/main.rb +0 -10
  45. data/lib/shellopts/option_struct.rb +0 -148
  46. data/lib/shellopts/shellopts.rb +0 -123
@@ -1,66 +0,0 @@
1
- module ShellOpts
2
- module Grammar
3
- # Models an Option
4
- #
5
- # Sets Node#key to the first long option name if present or else the first short option
6
- class Option < Node
7
- # List of short names (incl. '-')
8
- attr_reader :short_names
9
-
10
- # List of long names (incl. '--')
11
- attr_reader :long_names
12
-
13
- # Name of the key attribute (eg. if key is :all then key_name is '--all'
14
- attr_reader :key_name
15
-
16
- # List of flags (Symbol)
17
- def flags() @flags.keys end
18
-
19
- # Informal name of argument (eg. 'FILE'). nil if not present
20
- attr_reader :label
21
-
22
- # Initialize an option. Short and long names are arrays of the short/long
23
- # option names (incl. the '-'/'--' prefix). It is assumed that at least
24
- # one name is given. Flags is a list of symbolic flags. Allowed flags are
25
- # :repeated, :argument, :optional, :integer, and :float. Note that
26
- # there's no :string flag, it's status is inferred. label is the optional
27
- # informal name of the option argument (eg. 'FILE') or nil if not present
28
- def initialize(short_names, long_names, flags, label = nil)
29
- @key_name = long_names.first || short_names.first
30
- name = @key_name.sub(/^-+/, "")
31
- super(name.to_sym, name)
32
- @short_names, @long_names = short_names, long_names
33
- @flags = flags.map { |flag| [flag, true] }.to_h
34
- @label = label
35
- end
36
-
37
- # Array of option names with short names first and then the long names
38
- def names() @short_names + @long_names end
39
-
40
- # Array of names and the key
41
- def identifiers() names + [key] end
42
-
43
- # Return true if +ident+ is equal to any name or to key
44
- def match?(ident) names.include?(ident) || ident == key end
45
-
46
- # Flag query methods. Returns true if the flag is present and otherwise nil
47
- def repeated?() @flags[:repeated] || false end
48
- def argument?() @flags[:argument] || false end
49
- def optional?() argument? && @flags[:optional] || false end
50
- def string?() argument? && !integer? && !float? end
51
- def integer?() argument? && @flags[:integer] || false end
52
- def float?() argument? && @flags[:float] || false end
53
-
54
- # :nocov:
55
- def dump
56
- super {
57
- puts "short_names: #{short_names.inspect}"
58
- puts "long_names: #{long_names.inspect}"
59
- puts "flags: #{flags.inspect}"
60
- puts "label: #{label.inspect}"
61
- }
62
- end
63
- # :nocov:
64
- end
65
- end
66
- end
@@ -1,65 +0,0 @@
1
- module ShellOpts
2
- module Grammar
3
- # Program is the root object of the grammar
4
- class Program < Command
5
- # Array of non-option litteral arguments (ie. what comes after the double dash ('+--+') in
6
- # the usage definition). Initially empty but filled out during compilation
7
- attr_reader :args
8
-
9
- # Initialize a top-level Program object
10
- def initialize(name, option_list)
11
- super(nil, name, option_list)
12
- @args = []
13
- end
14
-
15
- # Usage string to be used in error messages. The string is kept short by
16
- # only listing the shortest option (if there is more than one)
17
- def usage
18
- (
19
- render_options(option_list) +
20
- subcommand_list.map { |cmd| render_subcommand(cmd) } +
21
- args
22
- ).flatten.join(" ")
23
- end
24
-
25
- # :nocov:
26
- def dump(&block)
27
- super {
28
- puts "args: #{args.inspect}"
29
- puts "usage: #{usage.inspect}"
30
- }
31
- end
32
- # :nocov:
33
-
34
- private
35
- def render_subcommand(subcommand)
36
- [subcommand.name] + render_options(subcommand.option_list) +
37
- subcommand.subcommand_list.map { |cmd| render_subcommand(cmd) }.flatten
38
- end
39
-
40
- def render_options(options)
41
- options.map { |opt|
42
- s = opt.names.first
43
- if opt.argument?
44
- arg_string =
45
- if opt.label
46
- opt.label
47
- elsif opt.integer?
48
- "INT"
49
- elsif opt.float?
50
- "FLOAT"
51
- else
52
- "ARG"
53
- end
54
- if opt.optional?
55
- s += "[=#{arg_string}]"
56
- else
57
- s += "=#{arg_string}"
58
- end
59
- end
60
- s
61
- }
62
- end
63
- end
64
- end
65
- end
data/lib/shellopts/idr.rb DELETED
@@ -1,236 +0,0 @@
1
-
2
- module ShellOpts
3
- # Idr models the Internal Data Representation of a program. It is the native
4
- # representation of a command
5
- #
6
- # The IDR should ideally be completely detached from the compile-time grammar
7
- # and AST but they are only hidden from view in this implementation. Create
8
- # a Shellopts object instead to access the compiler data
9
- #
10
- module Idr
11
- # Base class for the Idr class hierarchy. It is constructed from an Ast
12
- # object by #generate. Node is modelled as an element of a hash with a key
13
- # and a value. Options have their (optional) argument as value while
14
- # commands use +self+ as value
15
- class Node
16
- # Parent node. nil for the top-level Program object
17
- attr_reader :parent
18
-
19
- # Unique key (within context) for the option or command. nil for the
20
- # top-level Program object
21
- attr_reader :key
22
-
23
- # Name of command or option as used on the command line
24
- attr_reader :name
25
-
26
- # Value of node. This can be a simple value (String, Integer, or Float),
27
- # an Array of values, or a Idr::Command object. Note that the value of a
28
- # Command object is the object itself
29
- #
30
- # Repeated options are implemented as an Array with one element for each
31
- # use of the option. The element is nil if the option doesn't take
32
- # arguments or if an optional argument is missing.
33
- attr_reader :value
34
-
35
- # The top-level Program object
36
- def program() @program ||= (parent&.program || self) end
37
-
38
- protected
39
- # Copy arguments into instance variables
40
- def initialize(parent, ast, key, name, value)
41
- @parent, @ast, @key, @name, @value = parent, ast, key, name, value
42
- end
43
-
44
- # The AST node for this Idr object
45
- attr_reader :ast
46
-
47
- # Shorthand to the grammar node for this Idr object
48
- def grammar() @ast.grammar end
49
- end
50
-
51
- # Base class for Options
52
- class Option < Node
53
- end
54
-
55
- class SimpleOption < Option
56
- protected
57
- # Initialize with defauls from the Ast. +value+ is set to true if option
58
- # doesn't take an argument
59
- def initialize(parent, ast)
60
- value = ast.grammar.argument? ? ast.value : true
61
- super(parent, ast, ast.key, ast.name, value)
62
- end
63
- end
64
-
65
- # An OptionGroup models repeated options collapsed into a single key. The
66
- # name of the group should be set to the name of the key (eg. '--all' if
67
- # the key is :all)
68
- class OptionGroup < Option
69
- # Array of names of the options
70
- attr_reader :names
71
-
72
- # Array of values of the options
73
- alias :values :value
74
-
75
- # Name is set to the key name and value to an array of option values
76
- def initialize(parent, key, name, options)
77
- @names = options.map(&:name)
78
- super(parent, nil, key, name, options.map(&:value))
79
- end
80
- end
81
-
82
- class Command < Node
83
- # Hash from key to options with repeated option_list collapsed into a
84
- # option group. It also include an entry for the subcommand. Options are
85
- # ordered by first use on the command line. The command entry will always
86
- # be last
87
- attr_reader :options
88
-
89
- # List of command line options in the same order as on the command line
90
- attr_reader :option_list
91
-
92
- # Subcommand object. Possibly nil
93
- attr_reader :subcommand
94
-
95
- # True if ident is declared
96
- def declared?(ident) option?(ident) || subcommand?(ident) end
97
-
98
- # True if ident is declared as an option
99
- def option?(ident) grammar.options.key?(ident) end
100
-
101
- # True if ident is declared as a command
102
- def subcommand?(ident) grammar.subcommands.key?(ident) end
103
-
104
- # True if ident is present
105
- def key?(ident)
106
- declared?(ident) or raise InternalError, "Undefined identifier: #{ident.inspect}"
107
- key = grammar.identifier2key(ident)
108
- @options.key?(key)
109
- end
110
-
111
- # Value of ident. Repeated options are collapsed into an OptionGroup object
112
- def [](ident)
113
- declared?(ident) or raise InternalError, "Undefined identifier: #{ident.inspect}"
114
- key = grammar.identifier2key(ident)
115
- if @options.key?(key)
116
- @options[key].value
117
- elsif option?(key)
118
- false
119
- else
120
- nil
121
- end
122
- end
123
-
124
- # Apply defaults recursively. Values can be lambdas that will be evaluated to
125
- # get the default value. TODO
126
- def apply(defaults = {}) raise InternalError, "Not implemented" end
127
-
128
- # Return options and command as an array
129
- def to_a() @ast.values end
130
-
131
- # Return options and command as a hash. The hash also define the
132
- # singleton method #subcommand that returns the key of the subcommand
133
- #
134
- # +key_type+ controls the type of keys used: +:key+ (the default) use the
135
- # symbolic key, +:name+ use #name. Note that using +:name+ can cause
136
- # name collisions between option and command names
137
- #
138
- # +aliases+ maps from key to replacement key (which could be any object).
139
- # +aliases+ can be used to avoid name collisions between options and
140
- # commands when using key_format: :name
141
- #
142
- # IDEA: Add a singleton methods to the hash with #name, #usage, etc.
143
- #
144
- def to_h(key_type: ::ShellOpts.default_key_type, aliases: {})
145
- keys = map_keys(key_type, aliases)
146
- value = {}
147
- value.define_singleton_method(:subcommand) { nil }
148
- options.values.each { |opt| # includes subcommand
149
- key = keys[opt.key]
150
- case opt
151
- when Option
152
- value[key] = opt.value
153
- when Command
154
- value[key] = opt.value.to_h(key_type: key_type, aliases: aliases[opt.key] || {})
155
- value.define_singleton_method(:subcommand) { key } # Redefine
156
- else
157
- # :nocov:
158
- raise InternalError, "Oops"
159
- # :nocov:
160
- end
161
- }
162
- value
163
- end
164
-
165
- # Return options and command as a struct
166
- def to_struct(key_type: ::ShellOpts.default_key_type, aliases: {})
167
- OptionStruct.new(self, key_type, aliases)
168
- end
169
-
170
- protected
171
- # Initialize an Idr::Command object and all dependent objects
172
- def initialize(parent, ast)
173
- super(parent, ast, ast.key, ast.name, self)
174
- @option_list = ast.options.map { |node| SimpleOption.new(self, node) }
175
- @subcommand = Command.new(self, ast.subcommand) if ast.subcommand
176
- @options = @option_list.group_by { |option| option.key }.map { |key, option_list|
177
- option =
178
- if ast.grammar.options[key].repeated?
179
- OptionGroup.new(self, key, ast.grammar.options[key].key_name, option_list)
180
- else
181
- option_list.first
182
- end
183
- [key, option]
184
- }.to_h
185
- @options[subcommand.key] = @subcommand if @subcommand
186
- end
187
-
188
- # Internal-key to used-key map. Checks for reserved words and
189
- # name-collisions
190
- def map_keys(key_type, aliases, reserved_words = [])
191
- keys = {}
192
- used_keys = {}
193
- (grammar.option_list + grammar.subcommand_list).each { |node|
194
- internal_key = node.key
195
- key = aliases[internal_key] || (key_type == :name ? node.name.to_sym : internal_key)
196
- !reserved_words.include?(key) or
197
- raise ::ShellOpts::ConversionError, "'#{key}' is a reserved word"
198
- !used_keys.key?(key) or
199
- raise ::ShellOpts::ConversionError, "Name collision between '--#{key}' and '#{key}!'"
200
- keys[internal_key] = key
201
- used_keys[key] = true
202
- }
203
- keys
204
- end
205
- end
206
-
207
- class Program < Command
208
- # Name of program
209
- def name() @shellopts.name end
210
- def name=(name) @shellopts.name = name end
211
-
212
- # Usage string
213
- def usage() @shellopts.usage end
214
- def usage=(usage) @shellopts.usage = usage end
215
-
216
- # #key is nil for the top-level Program object
217
- def key() nil end
218
-
219
- # Remaining command line arguments
220
- def args() @shellopts.args end
221
-
222
- # Initialize the top-level Idr::Program object
223
- def initialize(shellopts)
224
- @shellopts = shellopts
225
- super(nil, shellopts.ast)
226
- end
227
-
228
- # Emit error message and a usage description before exiting with status 1
229
- def error(*args) @shellopts.error(*error_messages) end
230
-
231
- # Emit error message before exiting with status 1
232
- def fail(*args) @shellopts.fail(*error_messages) end
233
- end
234
- end
235
- end
236
-
@@ -1,10 +0,0 @@
1
-
2
- module ShellOpts
3
- # Gives access to the ruby main object
4
- module Main
5
- CALLER_RE = /^.*:in `<main>'$/
6
- def self.main() TOPLEVEL_BINDING.eval("self") end
7
- end
8
- end
9
-
10
-
@@ -1,148 +0,0 @@
1
-
2
- require 'shellopts/shellopts.rb'
3
- require 'shellopts/idr'
4
-
5
- module ShellOpts
6
- # FIXME: Outdated
7
- #
8
- # Struct representation of options. Usually created by ShellOpts::to_struct
9
- #
10
- # OptionStruct objects give easy access to configuration option values but
11
- # meta data are more circuitously accessed through class methods with an
12
- # explicit instance argument
13
- #
14
- # Option values are accessed through a member methods named after the key of
15
- # the option. Repeated options have an Array value with one element (possibly
16
- # nil) for each use of the option. A query method with a '?' suffixed to the
17
- # name returns true or false depending on whether the option was used or not
18
- #
19
- # option - Value of option. Either an object or an Array if the option can
20
- # be repeated
21
- # option? - True iff option was given
22
- #
23
- # Command methods return a nested OptionStruct object while the special
24
- # #command method returns the key of actual command (if any). Use
25
- # +strukt.send(strukt.command)+ to get the subcommand of a OptionStruct. It
26
- # is possible to rename #command method to avoid name collisions
27
- #
28
- # name! - Command. An OptionStruct or nil if not given on the command line
29
- # subcommand - Key of command. Can be renamed
30
- #
31
- # ---------------------------------
32
- # name! - Command. An OptionStruct or nil if not given on the command line
33
- #
34
- # key! - Key of command
35
- # value! - Value of command (a subcommand). Can be renamed
36
- #
37
- # Note: There is no command query method because option and command names
38
- # live in seperate namespaces and could cause colllisions. Check +name!+ for
39
- # nil to detect if a command was given
40
- #
41
- # Meta data are extracted through class methods to avoid polluting the object
42
- # namespace. OptionStruct use an OptionsHash object internally and
43
- # implements a subset of its meta methods by forwarding to it. The
44
- # OptionsHash object can be accessed through the #options_hash method
45
- #
46
- # Note that #command is defined as both an instance method and a class
47
- # method. Use the class method to make the code work with all OptionStruct
48
- # objects even if #command has been renamed
49
- #
50
- # +ShellOpts+ is derived from +BascicObject+ that reserves some words for
51
- # internal use (+__id__+, +__send__+, +instance_eval+, +instance_exec+,
52
- # +method_missing+, +singleton_method_added+, +singleton_method_removed+,
53
- # +singleton_method_undefined+). ShellOpts also define two reserved words of
54
- # its own (+__options_hash__+ and +__command__+). ShellOpts raise an
55
- # ShellOpts::ConversionError if an option collides with one of the
56
- # reserved words or with the special #command method
57
- #
58
- class OptionStruct < BasicObject
59
- # Create a OptionStruct object recursively from an Idr::Command object
60
- def self.new(idr, key_type, aliases = {})
61
- # Shorthands
62
- ast = idr.instance_variable_get("@ast")
63
- grammar = ast.grammar
64
-
65
- # Get key map
66
- keys = idr.send(:map_keys, key_type, aliases, RESERVED_WORDS)
67
-
68
- # Allocate OptionStruct instance
69
- instance = allocate
70
-
71
- # Set reference to Idr object. Is currently unused
72
- set_variable(instance, "@__idr__", idr)
73
-
74
- # Generate general option accessor methods
75
- grammar.option_list.each { |option|
76
- key = keys[option.key]
77
- instance.instance_eval("def #{key}() @#{key} end")
78
- instance.instance_eval("def #{key}?() false end")
79
- }
80
-
81
- # Generate accessor method for present options
82
- idr.option_list.each { |option|
83
- key = keys[option.key]
84
- set_variable(instance, "@#{key}", idr[option.key])
85
- instance.instance_eval("def #{key}?() true end")
86
- }
87
-
88
- # Generate general #subcommand methods
89
- if !idr.subcommand
90
- instance.instance_eval("def subcommand() nil end")
91
- instance.instance_eval("def subcommand?() false end")
92
- instance.instance_eval %(
93
- def subcommand!(*msgs)
94
- $stderr.puts "in subcommand!"
95
- ::Kernel.raise ::ShellOpts::UserError, (msgs.empty? ? 'No command' : msgs.join)
96
- end
97
- )
98
- end
99
-
100
- # Generate individual subcommand methods
101
- grammar.subcommand_list.each { |subcommand|
102
- key = keys[subcommand.key]
103
- if subcommand.key == idr.subcommand&.key
104
- struct = OptionStruct.new(idr.subcommand, key_type, aliases[idr.subcommand.key] || {})
105
- set_variable(instance, "@subcommand", struct)
106
- instance.instance_eval("def #{key}() @subcommand end")
107
- instance.instance_eval("def subcommand() :#{key} end")
108
- instance.instance_eval("def subcommand?() true end")
109
- instance.instance_eval("def subcommand!(*msgs) :#{key} end")
110
- else
111
- instance.instance_eval("def #{key}() nil end")
112
- end
113
- }
114
-
115
- instance
116
- end
117
-
118
- private
119
- # Return class of object. #class is not defined for BasicObjects so this
120
- # method provides an alternative way of getting the class
121
- def self.class_of(object)
122
- # https://stackoverflow.com/a/18621313/2130986
123
- ::Kernel.instance_method(:class).bind(object).call
124
- end
125
-
126
- # Class method implementation of ObjectStruct#instance_variable_set that is
127
- # not defined in a BasicObject
128
- def self.set_variable(this, var, value)
129
- # https://stackoverflow.com/a/18621313/2130986
130
- ::Kernel.instance_method(:instance_variable_set).bind(this).call(var, value)
131
- end
132
-
133
- # Class method implementation of ObjectStruct#instance_variable_get that is
134
- # not defined in a BasicObject
135
- def self.get_variable(this, var)
136
- # https://stackoverflow.com/a/18621313/2130986
137
- ::Kernel.instance_method(:instance_variable_get).bind(this).call(var)
138
- end
139
-
140
- BASIC_OBJECT_RESERVED_WORDS = %w(
141
- __id__ __send__ instance_eval instance_exec method_missing
142
- singleton_method_added singleton_method_removed
143
- singleton_method_undefined).map(&:to_sym)
144
- OPTIONS_STRUCT_RESERVED_WORDS = %w(__idr__ subcommand).map(&:to_sym)
145
- RESERVED_WORDS = BASIC_OBJECT_RESERVED_WORDS + OPTIONS_STRUCT_RESERVED_WORDS
146
- end
147
- end
148
-
@@ -1,123 +0,0 @@
1
-
2
- require "shellopts"
3
-
4
- require "shellopts/args.rb"
5
-
6
- # TODO
7
- #
8
- # PROCESSING
9
- # 1. Compile spec string and yield a grammar
10
- # 2. Parse the options using the grammar and yield an AST
11
- # 3. Construct the Program model from the AST
12
- # 4. Apply defaults to the model
13
- # 6. Run validations on the model
14
- # 5. Create representation from the model
15
- #
16
-
17
- module ShellOpts
18
- # The command line processing object
19
- class ShellOpts
20
- # Name of program
21
- attr_accessor :name
22
-
23
- # Usage string. If #usage is nil, the auto-generated default is used
24
- def usage() @usage || @grammar.usage end
25
- def usage=(usage) @usage = usage end
26
-
27
- # Specification of the command
28
- attr_reader :spec
29
-
30
- # Original argv argument
31
- attr_reader :argv
32
-
33
- # The grammar compiled from the spec string
34
- attr_reader :grammar
35
-
36
- # The AST parsed from the command line arguments
37
- attr_reader :ast
38
-
39
- # The IDR generated from the Ast
40
- attr_reader :idr
41
-
42
- # Compile a spec string into a grammar
43
- #
44
- # +spec+ is the spec string, and +argv+ the command line (typically the
45
- # global ARGV array). +name+ is the name of the program and defaults to the
46
- # basename of the program
47
- #
48
- # Syntax errors in the spec string are caused by the developer and cause
49
- # #initialize to raise a +ShellOpts::CompilerError+ exception. Errors in
50
- # the +argv+ arguments are caused by the user and cause #process to raise
51
- # ShellOpts::UserError exception
52
- #
53
- # TODO: Change to (name, spec, argv, usage: nil) because
54
- # ShellOpts::ShellOpts isn't a magician like the ShellOpts module
55
- def initialize(spec, argv, name: ::ShellOpts.default_name, usage: ::ShellOpts.default_usage)
56
- @name = name
57
- @spec = spec
58
- @usage = usage
59
- @argv = argv
60
- begin
61
- @grammar = Grammar.compile(@name, @spec)
62
- rescue Grammar::Compiler::Error => ex
63
- raise CompilerError.new(5, ex.message)
64
- end
65
- end
66
-
67
- # Process command line arguments and return self. Raises a
68
- # ShellOpts::UserError in case of an error
69
- def process
70
- begin
71
- @ast = Ast.parse(@grammar, @argv)
72
- @idr = Idr.generate(self)
73
- rescue Ast::Parser::Error => ex
74
- raise UserError.new(ex.message)
75
- end
76
- self
77
- end
78
-
79
- # Return an array representation of options and commands in the same order
80
- # as on the command line. Each option or command is represented by a [name,
81
- # value] pair. The value of an option is be nil if the option didn't have
82
- # an argument and else either a String, Integer, or Float. The value of a
83
- # command is an array of its options and commands
84
- def to_a() idr.to_a end
85
-
86
- # Return a hash representation of the options. See {ShellOpts::OptionsHash}
87
- def to_h(key_type: ::ShellOpts.default_key_type, aliases: {})
88
- @idr.to_h(key_type: :key_type, aliases: aliases)
89
- end
90
-
91
- # TODO
92
- # Return OptionHash object
93
- # def to_hash(...)
94
-
95
- # Return a struct representation of the options. See {ShellOpts::OptionStruct}
96
- def to_struct(key_type: ::ShellOpts.default_key_type, aliases: {})
97
- @idr.to_struct(key_type: key_type, aliases: aliases)
98
- end
99
-
100
- # List of remaining non-option command line arguments. Returns a Argv object
101
- def args() Args.new(self, ast&.arguments) end
102
-
103
- # Iterate options and commands as name/value pairs. Same as +to_a.each+
104
- def each(&block) to_a.each(&block) end
105
-
106
- # Print error messages and spec string and exit with status 1. This method
107
- # should be called in response to user-errors (eg. specifying an illegal
108
- # option)
109
- def error(*msgs, exit: true)
110
- msg = "#{name}: #{msgs.join}\n" + (@usage ? usage : "Usage: #{name} #{usage}")
111
- $stderr.puts msg.rstrip
112
- exit(1) if exit
113
- end
114
-
115
- # Print error message and exit with status 1. This method should called in
116
- # response to system errors (like disk full)
117
- def fail(*msgs, exit: true)
118
- $stderr.puts "#{name}: #{msgs.join}"
119
- exit(1) if exit
120
- end
121
- end
122
- end
123
-