shellopts 0.9.5 → 2.0.0.pre.2
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +59 -17
- data/TODO +30 -1
- data/bin/mkdoc +11 -6
- data/lib/shellopts.rb +120 -180
- data/lib/shellopts/args.rb +36 -0
- data/lib/shellopts/ast/node.rb +1 -1
- data/lib/shellopts/compiler.rb +7 -7
- data/lib/shellopts/generator.rb +15 -0
- data/lib/shellopts/grammar/command.rb +27 -9
- data/lib/shellopts/grammar/option.rb +11 -1
- data/lib/shellopts/grammar/program.rb +2 -2
- data/lib/shellopts/idr.rb +209 -0
- data/lib/shellopts/messenger.rb +71 -0
- data/lib/shellopts/option_struct.rb +245 -0
- data/lib/shellopts/shellopts.rb +100 -0
- data/lib/shellopts/version.rb +1 -1
- data/rs +40 -0
- metadata +13 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79a36712cf9c41a500726cd042d9932f1c6ed7f7e7a334d5d245e0ad31185c75
|
4
|
+
data.tar.gz: ddeec0f65a4d8e4250cbc9d1332626395c135d0c4e34d879fafcfb89b492699a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2890ba5f277385eb8cc30a9e168d618f3633278cc41066c302ed82d7be46eeefb5a30f41a2471947bc78a0e55e8219cc472887a91b9d753a6687dfda605231e6
|
7
|
+
data.tar.gz: a02ecb6e6613163f2915125ea0cd71cab30c7fd3c11f840a99bad0cb27b6a14dad0b3c806d55f8ab752e4f7921731cab0753c562499b7c88eeb8e5e8400efaab
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,20 +1,19 @@
|
|
1
1
|
# Shellopts
|
2
2
|
|
3
|
-
`ShellOpts` is a simple command line parsing libray that covers most modern use
|
3
|
+
`ShellOpts` is a simple Linux command line parsing libray that covers most modern use
|
4
4
|
cases incl. sub-commands. Options and commands are specified using a
|
5
5
|
getopt(1)-like string that is interpreted by the library to process the command
|
6
6
|
line
|
7
7
|
|
8
8
|
## Usage
|
9
9
|
|
10
|
-
The following program accepts
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
The following program accepts the options -a or --all, --count, --file, and -v
|
11
|
+
or --verbose. It expects `--count` to have an optional integer argument,
|
12
|
+
`--file` to have a mandatory argument, and allows `-v` and `--verbose` to be
|
13
|
+
repeated:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
|
17
|
-
|
16
|
+
|
18
17
|
# Define options
|
19
18
|
USAGE = "a,all count=#? file= +v,verbose -- FILE..."
|
20
19
|
|
@@ -36,7 +35,7 @@ args = ShellOpts.process(USAGE, ARGV) do |opt, arg|
|
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
|
-
# Process remaining arguments
|
38
|
+
# Process remaining command line arguments
|
40
39
|
args.each { |arg| ... }
|
41
40
|
```
|
42
41
|
|
@@ -50,10 +49,10 @@ error
|
|
50
49
|
|
51
50
|
## Processing
|
52
51
|
|
53
|
-
`ShellOpts.process` compiles a usage definition string into a grammar and use
|
54
|
-
parse the command line. If given a block, the block is called with a
|
55
|
-
pair for each option or command and return a list of the remaining
|
56
|
-
arguments
|
52
|
+
`ShellOpts.process` compiles a usage definition string into a grammar and use
|
53
|
+
that to parse the command line. If given a block, the block is called with a
|
54
|
+
name/value pair for each option or command and return a list of the remaining
|
55
|
+
non-option arguments
|
57
56
|
|
58
57
|
```ruby
|
59
58
|
args = ShellOpts.process(USAGE, ARGV) do |opt, arg|
|
@@ -74,7 +73,7 @@ line at a time and to inspect the grammar and AST
|
|
74
73
|
|
75
74
|
```ruby
|
76
75
|
shellopts = ShellOpts.process(USAGE, ARGV) # Returns a ShellOpts::ShellOpts object
|
77
|
-
shellopts.each { |opt,
|
76
|
+
shellopts.each { |opt, arg| ... } # Access options
|
78
77
|
args = shellopts.args # Access remaining arguments
|
79
78
|
shellopts.error "Something went wrong" # Emit an error message and exit
|
80
79
|
```
|
@@ -101,6 +100,18 @@ An option is defined by a list of comma-separated names optionally prefixed by a
|
|
101
100
|
[ "+" ] name-list [ "=" [ "#" | "$" ] [ label ] [ "?" ] ]
|
102
101
|
```
|
103
102
|
|
103
|
+
#### Flags
|
104
|
+
|
105
|
+
There are the following flags:
|
106
|
+
|
107
|
+
|Flag|Effect|
|
108
|
+
|---|---|
|
109
|
+
|+|Repeated option (prefix)|
|
110
|
+
|=|Argument. Mandatory unless `?` is also used|
|
111
|
+
|#|Integer argument|
|
112
|
+
|$|Floating point argument|
|
113
|
+
|?|Optional argument|
|
114
|
+
|
104
115
|
#### Repeated options
|
105
116
|
|
106
117
|
Options are unique by default and the user will get an error if an option is
|
@@ -184,11 +195,11 @@ sub-commands) to the command:
|
|
184
195
|
```ruby
|
185
196
|
USAGE = "a cmd! b c"
|
186
197
|
|
187
|
-
args = ShellOpts.process(USAGE, ARGV) { |opt,
|
198
|
+
args = ShellOpts.process(USAGE, ARGV) { |opt, arg|
|
188
199
|
case opt
|
189
200
|
when '-a'; # Handle -a
|
190
201
|
when 'cmd'
|
191
|
-
|
202
|
+
arg.each { |opt, arg|
|
192
203
|
case opt
|
193
204
|
when '-b'; # Handle -b
|
194
205
|
when '-c'; # Handle -c
|
@@ -260,6 +271,27 @@ The methods are defined as instance methods on `ShellOpts::ShellOpts` and as
|
|
260
271
|
class methods on `ShellOpts`. They can also be included in the global scope by
|
261
272
|
`include ShellOpts::Utils`
|
262
273
|
|
274
|
+
#### Usage string
|
275
|
+
|
276
|
+
The error handling methods prints a prettified version of the usage string
|
277
|
+
given to `ShellOpts.parse`. The usage string can be overridden by assigning to
|
278
|
+
`ShellOpts.usage`. A typical use case is when you want to split the usage
|
279
|
+
description over multiple lines:
|
280
|
+
|
281
|
+
```ruby
|
282
|
+
|
283
|
+
USAGE="long-and-complex-usage-string"
|
284
|
+
ShellOpts.usage = <<~EOD
|
285
|
+
usage explanation
|
286
|
+
split over
|
287
|
+
multiple lines
|
288
|
+
EOD
|
289
|
+
```
|
290
|
+
|
291
|
+
Note that this only affects the module-level `ShellOpts.error` method and not
|
292
|
+
object-level `ShellOpts::ShellOpts#error` method. This is considered a bug and
|
293
|
+
will fixed at some point
|
294
|
+
|
263
295
|
## Example
|
264
296
|
|
265
297
|
The rm(1) command could be implemented like this
|
@@ -287,12 +319,12 @@ preserve_root = true
|
|
287
319
|
verbose = false
|
288
320
|
|
289
321
|
# Process command line
|
290
|
-
args = ShellOpts.process(USAGE, ARGV) { |opt,
|
322
|
+
args = ShellOpts.process(USAGE, ARGV) { |opt, arg|
|
291
323
|
case opt
|
292
324
|
when '-f', '--force'; force = true
|
293
325
|
when '-i'; prompt = true
|
294
326
|
when '-I'; prompt_once = true
|
295
|
-
when '--interactive'; interactive = true; interactive_when =
|
327
|
+
when '--interactive'; interactive = true; interactive_when = arg
|
296
328
|
when '-r', '-R', '--recursive'; recursive = true
|
297
329
|
when '-d', '--dir'; remove_empty_dirs = true
|
298
330
|
when '--one-file-system'; one_file_system = true
|
@@ -346,6 +378,16 @@ release a new version, update the version number in `version.rb`, and then run
|
|
346
378
|
git commits and tags, and push the `.gem` file to
|
347
379
|
[rubygems.org](https://rubygems.org).
|
348
380
|
|
381
|
+
## Implementation
|
382
|
+
|
383
|
+
FIXME
|
384
|
+
# ShellOpts is a library for parsing command line options and commands. It
|
385
|
+
# consists of the interface module {ShellOpts}, the implementation class
|
386
|
+
# {ShellOpts::ShellOpts} and the representation classes
|
387
|
+
# {ShellOpts::OptionsHash} and {ShellOpts::OptionsStruct}.
|
388
|
+
# {ShellOpts::Messenger} is used for error messages
|
389
|
+
|
390
|
+
|
349
391
|
## Contributing
|
350
392
|
|
351
393
|
Bug reports and pull requests are welcome on GitHub at
|
data/TODO
CHANGED
@@ -1,5 +1,34 @@
|
|
1
1
|
|
2
2
|
TODO
|
3
|
+
o Remove ! from OptionStruct#subcommand return value. We know we're
|
4
|
+
processing commands so there is no need to have a distinct name and it
|
5
|
+
feels a lot more intuitive without it
|
6
|
+
o Add validation block to ShellOpts class methods
|
7
|
+
o Get rid of key_name. Define #name on Grammar::Node instead
|
8
|
+
o Define #name to the string name of the option/command without prefixed '--'
|
9
|
+
for options. This can cause collisions but they can be avoided using aliases
|
10
|
+
o Clean-up
|
11
|
+
o Grammar::options -> Grammar::option_multihash
|
12
|
+
o Clean-up identifiers etc.
|
13
|
+
o Un-multi-izing Grammar::option_multihash and turn it into a regular hash from key to option
|
14
|
+
o subcommand vs. command consistency
|
15
|
+
o Implement ObjectStruct#key! and ObjectStruct#value! (?)
|
16
|
+
o Allow command_alias == nil to suppress the method
|
17
|
+
o Raise on non-existing names/keys. Only return nil for declared names/keys that are not present
|
18
|
+
o Use hash_tree
|
19
|
+
o Also allow assignment to usage string for ShellOpts::ShellOpts objects
|
20
|
+
o Create a ShellOpts.args method? It would be useful when processing commands:
|
21
|
+
case opt
|
22
|
+
when "command"
|
23
|
+
call_command_method(ShellOpts.args[1], ShellOpts.args[2])
|
24
|
+
end
|
25
|
+
ShellOpts.args would be a shorthand for ShellOpts.shellopts.args
|
26
|
+
Another option would be to create an argument-processing method:
|
27
|
+
shellopts.argv(2) -> call error if not exactly two arguments else return elements
|
28
|
+
o Add a ShellOpts.option method:
|
29
|
+
file = ShellOpts.option("--file")
|
30
|
+
This will only work for options on the outermost level... maybe:
|
31
|
+
file = ShellOpts.option("load! --file")
|
3
32
|
o Check on return value from #process block to see if all options was handled:
|
4
33
|
case opt
|
5
34
|
when '-v'; verbose = true # Return value 'true' is ok
|
@@ -11,7 +40,7 @@ TODO
|
|
11
40
|
o Make an official dump method for debug
|
12
41
|
o Make a note that all options are processed at once and not as-you-go
|
13
42
|
o Test that arguments with spaces work
|
14
|
-
o Long version usage strings
|
43
|
+
o Long version usage strings (major release)
|
15
44
|
o Doc: Example of processing of sub-commands and sub-sub-commands
|
16
45
|
|
17
46
|
+ More tests
|
data/bin/mkdoc
CHANGED
@@ -1,10 +1,15 @@
|
|
1
1
|
#!/usr/bin/bash
|
2
2
|
|
3
|
-
|
3
|
+
set -e
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
# Generate github-like page
|
6
|
+
(
|
7
|
+
cd doc
|
8
|
+
{
|
9
|
+
echo '<link rel="stylesheet" type="text/css" href="stylesheet.css">'
|
10
|
+
pandoc ../README.md
|
11
|
+
} >index.html
|
12
|
+
)
|
9
13
|
|
10
|
-
rdoc
|
14
|
+
# Generate rdoc
|
15
|
+
rdoc --output=rdoc --force-output lib
|
data/lib/shellopts.rb
CHANGED
@@ -2,208 +2,148 @@ require "shellopts/version"
|
|
2
2
|
|
3
3
|
require 'shellopts/compiler.rb'
|
4
4
|
require 'shellopts/parser.rb'
|
5
|
+
require 'shellopts/generator.rb'
|
6
|
+
require 'shellopts/option_struct.rb'
|
7
|
+
require 'shellopts/messenger.rb'
|
5
8
|
require 'shellopts/utils.rb'
|
6
9
|
|
7
|
-
#
|
8
|
-
|
9
|
-
|
10
|
+
# Name of program. Defined as the basename of the program file
|
11
|
+
PROGRAM = File.basename($PROGRAM_NAME)
|
12
|
+
|
13
|
+
# ShellOpts main Module
|
14
|
+
#
|
15
|
+
# This module contains methods to process command line options and arguments.
|
16
|
+
# ShellOpts keeps a reference in ShellOpts.shellopts to the result of the last
|
17
|
+
# command that was processed through its interface and use it as the implicit
|
18
|
+
# object of many of its methods. This matches the typical use case where only
|
19
|
+
# one command line is ever processed and makes it possible to create class
|
20
|
+
# methods that knows about the command like #error and #fail
|
21
|
+
#
|
22
|
+
# For example; the following process and convert a command line into a struct
|
23
|
+
# representation and also sets ShellOpts.shellopts object so that the #error
|
24
|
+
# method can print a relevant usage string:
|
25
|
+
#
|
26
|
+
# USAGE = "a,all f,file=FILE -- ARG1 ARG2"
|
27
|
+
# opts, args = ShellOpts.as_struct(USAGE, ARGV)
|
28
|
+
# File.exist?(opts.file) or error "Can't find #{opts.file}"
|
29
|
+
#
|
30
|
+
# The command line is processed through one of the methods #process, #as_array,
|
31
|
+
# #as_hash, or #as_struct that returns a [data, args] tuple. The data type
|
32
|
+
# depends on the method: #process yields a Idr object that internally serves as
|
33
|
+
# the base for the #as_array and #as_hash and #as_struct that converts it into
|
34
|
+
# an Array, Hash, or ShellOpts::OptionStruct object. For example:
|
35
|
+
#
|
36
|
+
# USAGE = "..."
|
37
|
+
# ShellOpts.process(USAGE, ARGV)
|
38
|
+
# program, args = ShellOpts.as_program(USAGE, ARGV)
|
39
|
+
# array, args = ShellOpts.as_array(USAGE, ARGV)
|
40
|
+
# hash, args = ShellOpts.as_hash(USAGE, ARGV)
|
41
|
+
# struct, args = ShellOpts.as_struct(USAGE, ARGV)
|
10
42
|
#
|
11
|
-
#
|
43
|
+
# +args+ is a ShellOpts::Argv object containing the the remaning command line
|
44
|
+
# arguments. Argv is derived from Array
|
45
|
+
#
|
46
|
+
# ShellOpts can raise the exception CompilerError is there is an error in the
|
47
|
+
# USAGE string. If there is an error in the user supplied command line, #error
|
48
|
+
# is called instead and the program terminates with exit code 1. ShellOpts
|
49
|
+
# raises ConversionError is there is a name collision when converting to the
|
50
|
+
# hash or struct representations. Note that CompilerError and ConversionError
|
51
|
+
# are caused by misuse of the library and the problem should be corrected by
|
52
|
+
# the developer
|
53
|
+
#
|
54
|
+
# ShellOpts injects the constant PROGRAM into the global scope. It contains the
|
12
55
|
# name of the program
|
13
56
|
#
|
14
57
|
module ShellOpts
|
15
|
-
#
|
16
|
-
|
17
|
-
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
#
|
24
|
-
# The value of an option is its argument, the value of a command is an array
|
25
|
-
# of name/value pairs of options and subcommands. Option values are converted
|
26
|
-
# to the target type (String, Integer, Float) if specified
|
27
|
-
#
|
28
|
-
# Example
|
29
|
-
#
|
30
|
-
# # Define options
|
31
|
-
# USAGE = 'a,all g,global +v,verbose h,help save! snapshot f,file=FILE h,help'
|
32
|
-
#
|
33
|
-
# # Define defaults
|
34
|
-
# all = false
|
35
|
-
# global = false
|
36
|
-
# verbose = 0
|
37
|
-
# save = false
|
38
|
-
# snapshot = false
|
39
|
-
# file = nil
|
40
|
-
#
|
41
|
-
# # Process options
|
42
|
-
# argv = ShellOpts.process(USAGE, ARGV) do |name, value|
|
43
|
-
# case name
|
44
|
-
# when '-a', '--all'; all = true
|
45
|
-
# when '-g', '--global'; global = value
|
46
|
-
# when '-v', '--verbose'; verbose += 1
|
47
|
-
# when '-h', '--help'; print_help(); exit(0)
|
48
|
-
# when 'save'
|
49
|
-
# save = true
|
50
|
-
# value.each do |name, value|
|
51
|
-
# case name
|
52
|
-
# when '--snapshot'; snapshot = true
|
53
|
-
# when '-f', '--file'; file = value
|
54
|
-
# when '-h', '--help'; print_save_help(); exit(0)
|
55
|
-
# end
|
56
|
-
# end
|
57
|
-
# else
|
58
|
-
# raise "Not a user error. The developer forgot or misspelled an option"
|
59
|
-
# end
|
60
|
-
# end
|
61
|
-
#
|
62
|
-
# # Process remaining arguments
|
63
|
-
# argv.each { |arg| ... }
|
64
|
-
#
|
65
|
-
# If an error is encountered while compiling the usage string, a
|
66
|
-
# +ShellOpts::Compiler+ exception is raised. If the error happens while
|
67
|
-
# parsing the command line arguments, the program prints an error message and
|
68
|
-
# exits with status 1. Failed assertions raise a +ShellOpts::InternalError+
|
69
|
-
# exception
|
70
|
-
#
|
71
|
-
# Note that you can't process more than one command line at a time because
|
72
|
-
# #process saves a hidden {ShellOpts::ShellOpts} class variable used by the
|
73
|
-
# class methods #error and #fail. Call #reset to clear the global object if
|
74
|
-
# you really need to parse more than one command line. Alternatively you can
|
75
|
-
# create +ShellOpts::ShellOpts+ objects yourself and use the object methods
|
76
|
-
# #error and #fail instead:
|
77
|
-
#
|
78
|
-
# shellopts = ShellOpts::ShellOpts.new(USAGE, ARGS)
|
79
|
-
# shellopts.each { |name, value| ... }
|
80
|
-
# shellopts.args.each { |arg| ... }
|
81
|
-
# shellopts.error("Something went wrong")
|
82
|
-
#
|
83
|
-
def self.process(usage, argv, program_name: PROGRAM, &block)
|
84
|
-
if !block_given?
|
85
|
-
ShellOpts.new(usage, argv, program_name: program_name)
|
86
|
-
else
|
87
|
-
@shellopts.nil? or raise InternalError, "ShellOpts class variable already initialized"
|
88
|
-
@shellopts = ShellOpts.new(usage, argv, program_name: program_name)
|
89
|
-
@shellopts.each(&block)
|
90
|
-
@shellopts.args
|
58
|
+
# Base class for ShellOpts exceptions
|
59
|
+
class Error < RuntimeError; end
|
60
|
+
|
61
|
+
# Raised when a syntax error is detected in the usage string
|
62
|
+
class CompilerError < Error
|
63
|
+
def initialize(start, message)
|
64
|
+
super(message)
|
65
|
+
set_backtrace(caller(start))
|
91
66
|
end
|
92
67
|
end
|
93
68
|
|
94
|
-
#
|
95
|
-
#
|
96
|
-
|
97
|
-
@shellopts = nil
|
98
|
-
end
|
69
|
+
# Raised when an error is detected during conversion from the Idr to array,
|
70
|
+
# hash, or struct
|
71
|
+
class ConversionError < Error; end
|
99
72
|
|
100
|
-
#
|
101
|
-
|
102
|
-
# response to user-errors (eg. specifying an illegal option)
|
103
|
-
def self.error(*msgs)
|
104
|
-
program = @shellopts&.program_name || PROGRAM
|
105
|
-
usage = @shellopts&.usage || (defined?(USAGE) && USAGE ? Grammar.compile(PROGRAM, USAGE).usage : nil)
|
106
|
-
emit_and_exit(program, usage, *msgs)
|
107
|
-
end
|
73
|
+
# Raised when an internal error is detected
|
74
|
+
class InternalError < Error; end
|
108
75
|
|
109
|
-
#
|
110
|
-
|
111
|
-
# user-errors but system errors (like disk full)
|
112
|
-
def self.fail(*msgs)
|
113
|
-
program = @shellopts&.program_name || PROGRAM
|
114
|
-
emit_and_exit(program, nil, *msgs)
|
115
|
-
end
|
76
|
+
# The current compilation object. It is set by #process
|
77
|
+
def self.shellopts() @shellopts end
|
116
78
|
|
117
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
def usage() @grammar.usage end
|
124
|
-
|
125
|
-
# The grammar compiled from the usage string. If #ast is defined, it's
|
126
|
-
# equal to ast.grammar
|
127
|
-
attr_reader :grammar
|
128
|
-
|
129
|
-
# The AST resulting from parsing the command line arguments
|
130
|
-
attr_reader :ast
|
131
|
-
|
132
|
-
# List of remaining non-option command line arguments. Shorthand for ast.arguments
|
133
|
-
def args() @ast.arguments end
|
134
|
-
|
135
|
-
# Compile a usage string into a grammar and use that to parse command line
|
136
|
-
# arguments
|
137
|
-
#
|
138
|
-
# +usage+ is the usage string, and +argv+ the command line (typically the
|
139
|
-
# global ARGV array). +program_name+ is the name of the program and is
|
140
|
-
# used in error messages. It defaults to the basename of the program
|
141
|
-
#
|
142
|
-
# Errors in the usage string raise a CompilerError exception. Errors in the
|
143
|
-
# argv arguments terminates the program with an error message
|
144
|
-
def initialize(usage, argv, program_name: File.basename($0))
|
145
|
-
@program_name = program_name
|
146
|
-
begin
|
147
|
-
@grammar = Grammar.compile(program_name, usage)
|
148
|
-
@ast = Ast.parse(@grammar, argv)
|
149
|
-
rescue Grammar::Compiler::Error => ex
|
150
|
-
raise CompilerError.new(5, ex.message)
|
151
|
-
rescue Ast::Parser::Error => ex
|
152
|
-
error(ex.message)
|
153
|
-
end
|
154
|
-
end
|
79
|
+
# Process command line and set and return the shellopts compile object
|
80
|
+
def self.process(usage, argv, name: self.name, message: nil)
|
81
|
+
@shellopts.nil? or reset
|
82
|
+
messenger = message && Messenger.new(name, message, format: :custom)
|
83
|
+
@shellopts = ShellOpts.new(usage, argv, name: name, messenger: messenger)
|
84
|
+
end
|
155
85
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
86
|
+
# Return the internal data representation of the command line (Idr::Program).
|
87
|
+
# Note that #as_program that the remaning arguments are accessible through
|
88
|
+
# the returned object
|
89
|
+
def self.as_program(usage, argv, name: self.name, message: nil)
|
90
|
+
process(usage, argv, name: name, message: message)
|
91
|
+
[shellopts.idr, shellopts.args]
|
92
|
+
end
|
160
93
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
end
|
169
|
-
end
|
94
|
+
# Process command line, set current shellopts object, and return a [array, argv]
|
95
|
+
# tuple. Returns the representation of the current object if not given any
|
96
|
+
# arguments
|
97
|
+
def self.as_array(usage, argv, name: self.name, message: nil)
|
98
|
+
process(usage, argv, name: name, message: message)
|
99
|
+
[shellopts.to_a, shellopts.args]
|
100
|
+
end
|
170
101
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
102
|
+
# Process command line, set current shellopts object, and return a [hash, argv]
|
103
|
+
# tuple. Returns the representation of the current object if not given any
|
104
|
+
# arguments
|
105
|
+
def self.as_hash(usage, argv, name: self.name, message: nil, use: ShellOpts::DEFAULT_USE, aliases: {})
|
106
|
+
process(usage, argv, name: name, message: message)
|
107
|
+
[shellopts.to_hash(use: use, aliases: aliases), shellopts.args]
|
108
|
+
end
|
177
109
|
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
110
|
+
# Process command line, set current shellopts object, and return a [struct, argv]
|
111
|
+
# tuple. Returns the representation of the current object if not given any
|
112
|
+
# arguments
|
113
|
+
def self.as_struct(usage, argv, name: self.name, message: nil, use: ShellOpts::DEFAULT_USE, aliases: {})
|
114
|
+
process(usage, argv, name: name, message: message)
|
115
|
+
[shellopts.to_struct(use: use, aliases: aliases), shellopts.args]
|
183
116
|
end
|
184
117
|
|
185
|
-
#
|
186
|
-
|
118
|
+
# Process command line, set current shellopts object, and then iterate
|
119
|
+
# options and commands as an array. Returns an enumerator to the array
|
120
|
+
# representation of the current shellopts object if not given a block
|
121
|
+
# argument
|
122
|
+
def self.each(usage = nil, argv = nil, name: self.name, message: nil, &block)
|
123
|
+
process(usage, argv, name: name, message: message)
|
124
|
+
shellopts.each(&block)
|
125
|
+
end
|
187
126
|
|
188
|
-
#
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
127
|
+
# Print error message and usage string and exit with status 1. This method
|
128
|
+
# should be called in response to user-errors (eg. specifying an illegal
|
129
|
+
# option)
|
130
|
+
def self.error(*msgs)
|
131
|
+
raise "Oops" if shellopts.nil?
|
132
|
+
shellopts.error(*msgs)
|
194
133
|
end
|
195
134
|
|
196
|
-
#
|
197
|
-
|
135
|
+
# Print error message and exit with status 1. This method should not be
|
136
|
+
# called in response to system errors (eg. disk full)
|
137
|
+
def self.fail(*msgs)
|
138
|
+
raise "Oops" if shellopts.nil?
|
139
|
+
shellopts.fail(*msgs)
|
140
|
+
end
|
198
141
|
|
199
142
|
private
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
$stderr.puts "#{program}: #{msgs.join}"
|
204
|
-
$stderr.puts "Usage: #{program} #{usage}" if usage
|
205
|
-
exit 1
|
143
|
+
# Reset state variables
|
144
|
+
def self.reset()
|
145
|
+
@shellopts = nil
|
206
146
|
end
|
207
|
-
end
|
208
147
|
|
209
|
-
|
148
|
+
@shellopts = nil
|
149
|
+
end
|