shellopts 2.0.0.pre.14 → 2.0.0
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 +2 -1
- data/.ruby-version +1 -1
- data/README.md +201 -267
- data/TODO +37 -5
- data/doc/format.rb +95 -0
- data/doc/grammar.txt +27 -0
- data/doc/syntax.rb +110 -0
- data/doc/syntax.txt +10 -0
- data/lib/ext/array.rb +62 -0
- data/lib/ext/forward_to.rb +15 -0
- data/lib/ext/lcs.rb +34 -0
- data/lib/shellopts/analyzer.rb +130 -0
- data/lib/shellopts/ansi.rb +8 -0
- data/lib/shellopts/args.rb +25 -15
- data/lib/shellopts/argument_type.rb +139 -0
- data/lib/shellopts/dump.rb +158 -0
- data/lib/shellopts/formatter.rb +292 -92
- data/lib/shellopts/grammar.rb +375 -0
- data/lib/shellopts/interpreter.rb +103 -0
- data/lib/shellopts/lexer.rb +175 -0
- data/lib/shellopts/parser.rb +293 -0
- data/lib/shellopts/program.rb +279 -0
- data/lib/shellopts/renderer.rb +227 -0
- data/lib/shellopts/stack.rb +7 -0
- data/lib/shellopts/token.rb +44 -0
- data/lib/shellopts/version.rb +1 -1
- data/lib/shellopts.rb +359 -3
- data/main +1180 -0
- data/shellopts.gemspec +8 -14
- metadata +86 -41
- data/lib/ext/algorithm.rb +0 -14
- data/lib/ext/ruby_env.rb +0 -8
- data/lib/shellopts/ast/command.rb +0 -112
- data/lib/shellopts/ast/dump.rb +0 -28
- data/lib/shellopts/ast/option.rb +0 -15
- data/lib/shellopts/ast/parser.rb +0 -106
- data/lib/shellopts/constants.rb +0 -88
- data/lib/shellopts/exceptions.rb +0 -21
- data/lib/shellopts/grammar/analyzer.rb +0 -76
- data/lib/shellopts/grammar/command.rb +0 -87
- data/lib/shellopts/grammar/dump.rb +0 -56
- data/lib/shellopts/grammar/lexer.rb +0 -56
- data/lib/shellopts/grammar/option.rb +0 -55
- data/lib/shellopts/grammar/parser.rb +0 -78
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f6c85f64a45ee82fb4abdafd5d36358f8f7a202d9179a670cc86d307813b4a9
|
4
|
+
data.tar.gz: 0a5e262777d044fe3afea501b3d94a8c44f89d4703924c619bfbbf2326e22a95
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34d0eb7f8d15ba2726b062c9f16e36bf0b2649690e4b6487e8b68ce442436100a67928eb47d3896961281e78f77f9252f66f407ce2dafd652fae65d85c229c3d
|
7
|
+
data.tar.gz: 9fc0e55ccde0175fea950a4cdd4f4dd385123e2e89c6ecfde8b4a1d0c6502054394322b2c673a96adfaabbbeaeee95d642034a8f545620286c8b795dc6da2436
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-2.7.1
|
data/README.md
CHANGED
@@ -1,345 +1,289 @@
|
|
1
1
|
# Shellopts
|
2
2
|
|
3
|
-
`ShellOpts` is a
|
4
|
-
|
5
|
-
|
6
|
-
line
|
3
|
+
`ShellOpts` is a command line processing library. It supports short
|
4
|
+
and long options and subcommands, and has built-in help and error messages
|
5
|
+
|
7
6
|
|
8
7
|
## Usage
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
repeated:
|
9
|
+
ShellOpts use a string to specify legal options and documentation. The
|
10
|
+
following program accepts the options --alpha and --beta with an argument. -a
|
11
|
+
and -b are option aliases:
|
14
12
|
|
15
13
|
```ruby
|
16
|
-
|
17
|
-
# Define options
|
18
|
-
USAGE = "a,all count=#? file= +v,verbose -- FILE..."
|
19
|
-
|
20
|
-
# Define default values
|
21
|
-
all = false
|
22
|
-
count = nil
|
23
|
-
file = nil
|
24
|
-
verbosity_level = 0
|
25
|
-
|
26
|
-
# Process command line and return remaining non-option arguments
|
27
|
-
args = ShellOpts.process(USAGE, ARGV) do |opt, arg|
|
28
|
-
case opt
|
29
|
-
when '-a', '--all'; all = true
|
30
|
-
when '--count'; count = arg || 42
|
31
|
-
when '--file'; file = arg # never nil
|
32
|
-
when '-v, '--verbose'; verbosity_level += 1
|
33
|
-
else
|
34
|
-
fail "Internal Error: Unmatched option: '#{opt}'"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
# Process remaining command line arguments
|
39
|
-
args.each { |arg| ... }
|
40
|
-
```
|
41
|
-
|
42
|
-
Note that the `else` clause catches legal but unhandled options; it is not an
|
43
|
-
user error. It typically happens because of a missing or misspelled option name
|
44
|
-
in the `when` clauses
|
14
|
+
require 'shellopts'
|
45
15
|
|
46
|
-
|
47
|
-
status 1 and print an error message and a short usage description on standard
|
48
|
-
error
|
16
|
+
SPEC = "-a,alpha -b,beta=VAL -- ARG1 ARG2"
|
49
17
|
|
50
|
-
|
18
|
+
opts, args = ShellOpts.process(SPEC, ARGV)
|
51
19
|
|
52
|
-
|
53
|
-
|
54
|
-
name/value pair for each option or command and return a list of the remaining
|
55
|
-
non-option arguments
|
20
|
+
alpha = opts.alpha? # True if -a or --alpha are present
|
21
|
+
beta = opts.beta # The value of the -b or --beta option
|
56
22
|
|
57
|
-
```ruby
|
58
|
-
args = ShellOpts.process(USAGE, ARGV) do |opt, arg|
|
59
|
-
case opt
|
60
|
-
when ...
|
61
|
-
end
|
62
|
-
end
|
63
23
|
```
|
64
24
|
|
65
|
-
This calls the block for each option in the same order as on the command line
|
66
|
-
and return the remaining non-option args. It also sets up the `ShellOpts.error` and
|
67
|
-
`ShellOpts.fail` methods. Please note that you need to call `ShellOpts.reset`
|
68
|
-
if you want to process another command line
|
69
|
-
|
70
|
-
If `ShellOpts.process` is called without a block it returns a
|
71
|
-
`ShellOpts::ShellOpts` object. It can be used to process more than one command
|
72
|
-
line at a time and to inspect the grammar and AST
|
73
|
-
|
74
25
|
```ruby
|
75
|
-
shellopts = ShellOpts.process(USAGE, ARGV) # Returns a ShellOpts::ShellOpts object
|
76
|
-
shellopts.each { |opt, arg| ... } # Access options
|
77
|
-
args = shellopts.args # Access remaining arguments
|
78
|
-
shellopts.error "Something went wrong" # Emit an error message and exit
|
79
26
|
```
|
80
27
|
|
81
|
-
|
28
|
+
ShellOpts also allow multi-line definitions with comments that are used as part
|
29
|
+
of help messages
|
82
30
|
|
83
|
-
|
84
|
-
|
85
|
-
dash (`--`) marks the end of the definition, anything after that is not
|
86
|
-
interpreted but copied verbatim in error messages
|
31
|
+
```ruby
|
32
|
+
require 'shellopts'
|
87
33
|
|
88
|
-
|
34
|
+
SPEC = %(
|
35
|
+
-a,alpha @ Brief comment for -a and --alpha options
|
36
|
+
-b,beta=VAL
|
37
|
+
@ Alternative style of brief comment
|
38
|
+
-- ARG1 ARG2
|
39
|
+
)
|
89
40
|
|
90
|
-
|
91
|
-
|
41
|
+
opts, args = ShellOpts.process(SPEC, ARGV)
|
42
|
+
ShellOpts::ShellOpts.brief
|
92
43
|
```
|
93
44
|
|
94
|
-
|
45
|
+
prints
|
95
46
|
|
96
|
-
|
97
|
-
|
47
|
+
```
|
48
|
+
Usage
|
49
|
+
main --alpha --beta=VAL ARG1 ARG2
|
98
50
|
|
99
|
-
|
100
|
-
|
51
|
+
Options
|
52
|
+
-a, --alpha Brief comment for -a and --alpha options
|
53
|
+
-b, --beta=VAL Alternative style of brief comment
|
101
54
|
```
|
102
55
|
|
103
|
-
|
56
|
+
There is also a `ShellOpts.help` method that prints a more detailed
|
57
|
+
documentation, and a `ShellOpts.usage` method that prints a compact usage
|
58
|
+
string
|
104
59
|
|
105
|
-
|
60
|
+
If there is an error in the command line options, the program will exit with
|
61
|
+
status 1 and print an error message and usage on standard error. If there is
|
62
|
+
an error in the specification, a message to the developer with the origin of
|
63
|
+
the error is printed on standard error
|
106
64
|
|
107
|
-
|
108
|
-
|---|---|
|
109
|
-
|+|Repeated option (prefix)|
|
110
|
-
|=|Argument. Mandatory unless `?` is also used|
|
111
|
-
|#|Integer argument|
|
112
|
-
|$|Floating point argument|
|
113
|
-
|?|Optional argument|
|
65
|
+
## Processing
|
114
66
|
|
115
|
-
|
67
|
+
`ShellOpts.process` creates a `ShellOpts::ShellOpts` object and use it to
|
68
|
+
compile the specification and process the command line. It returns a tuple of a
|
69
|
+
Program object and an array of the remaining arguments
|
116
70
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
let the user repeat a 'verbose' option to increase verbosity: `+v,verbose`
|
121
|
-
allows `-vvv` or `--verbose --verbose --verbose`. `ShellOpts::process` yields
|
122
|
-
an entry for each usage so should handle repeated options like this
|
71
|
+
The Program object has accessor methods for each defined option and sub-command
|
72
|
+
to check presence and return an optional argument. Given the options "--alpha
|
73
|
+
--beta=ARG" then the following accessor methods are available:
|
123
74
|
|
124
75
|
```ruby
|
125
|
-
|
76
|
+
# Returns true if the option is present and false otherwise
|
77
|
+
opts.alpha?()
|
78
|
+
opts.beta?()
|
126
79
|
|
127
|
-
|
128
|
-
|
129
|
-
when '-v', '--verbose'; verbosity_level += 1
|
130
|
-
# other options
|
131
|
-
end
|
132
|
-
end
|
80
|
+
# Returns the argument of the beta option or nil if missing
|
81
|
+
opts.beta()
|
133
82
|
```
|
134
83
|
|
135
|
-
|
84
|
+
Given the commands "cmd1! cmd2!" the following methods are available:
|
136
85
|
|
137
|
-
|
138
|
-
|
139
|
-
|
86
|
+
```ruby
|
87
|
+
# Returns the sub-command object or nil if not present
|
88
|
+
opts.cmd1!
|
89
|
+
opts.cmd2!
|
90
|
+
|
91
|
+
opts.subcommand! # Returns the sub-command object or nil if not present
|
92
|
+
opts.subcommand # Returns the sub-command's identifier (eg. :cmd1!)
|
93
|
+
```
|
140
94
|
|
141
|
-
|
142
|
-
prefixed with a single dash on the command line (eg. '-a'). Names with two or
|
143
|
-
more characters are 'long options' and are used with two dashes (eg. '--all').
|
144
|
-
Note that short and long names handles arguments differently
|
95
|
+
It is used like this
|
145
96
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
97
|
+
```ruby
|
98
|
+
case opts.subcommand
|
99
|
+
when :cmd1
|
100
|
+
# opts.cmd1 is defined here
|
101
|
+
when :cmd2
|
102
|
+
# opts.cmd2 is defined here
|
103
|
+
end
|
104
|
+
end
|
152
105
|
```
|
153
106
|
|
154
|
-
|
107
|
+
Sub-commands have options and even sub-sub-commands of their own. They can be
|
108
|
+
nested to any depth (which is not recommended, btw.)
|
155
109
|
|
156
|
-
|
157
|
-
|
158
|
-
|
110
|
+
The module methods `::usage`, `::brief`, and `::help` prints documentation with
|
111
|
+
increasing detail. `::usage` lists the options and commands without any comments,
|
112
|
+
`::brief` includes source text that starts with a '@', and `::help` the full
|
113
|
+
documentation in a man-page like format. Example
|
159
114
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
115
|
+
```ruby
|
116
|
+
SPEC = "-h --help"
|
117
|
+
opts, args = ShellOpts.process(SPEC, ARGV)
|
118
|
+
|
119
|
+
if opts.h?
|
120
|
+
ShellOpts.brief
|
121
|
+
exit
|
122
|
+
elsif opts.help?
|
123
|
+
ShellOpts.help
|
124
|
+
exit
|
125
|
+
end
|
126
|
+
```
|
164
127
|
|
165
|
-
|
128
|
+
The module methods `::error` and `::failure` are used to report errors in a common
|
129
|
+
format and then terminate the program with status 1. `::error` is used to report
|
130
|
+
errors that the user can correct and prints a usage description as a reminder.
|
131
|
+
`::failure` is used to report errors within the program so the usage descriptionn
|
132
|
+
is not printed:
|
166
133
|
|
167
|
-
|
134
|
+
```ruby
|
135
|
+
SPEC = "--var=VAR"
|
136
|
+
opts, args = ShellOpts.process(SPEC, ARGV)
|
168
137
|
|
169
|
-
|
170
|
-
|
171
|
-
local to that command. It is not possible to 'reset' this behaviour so global
|
172
|
-
options should always come before the first command. Nested commands are
|
173
|
-
specified using a dot-separated "path" to the nested sub-command
|
138
|
+
# --var is a mandatory 'option'
|
139
|
+
opts.var? or error "Missing --var 'option'"
|
174
140
|
|
175
|
-
|
176
|
-
|
177
|
-
g,global clone! t,template=
|
178
|
-
g,global clone! t,template= clone.list! v,verbose
|
141
|
+
# later during processing
|
142
|
+
condition or failure "Memory overflow"
|
179
143
|
```
|
180
144
|
|
181
|
-
The last example could be called like `program -g clone list -v`. You may split
|
182
|
-
the usage string to improve readability:
|
183
145
|
|
184
|
-
|
185
|
-
g,global
|
186
|
-
clone! t,template=
|
187
|
-
clone.list! v,verbose
|
188
|
-
```
|
146
|
+
## Specification
|
189
147
|
|
190
|
-
|
148
|
+
The specification is possibly multi-line string, typically named `SPEC`, that
|
149
|
+
is a mix of option or command definitions and related documentation.
|
150
|
+
Indentation is used to nest the elements and '@' is used to tag an option or
|
151
|
+
command with a brief description
|
191
152
|
|
192
|
-
|
193
|
-
|
153
|
+
The specifiction is parsed line-by-line: Lines matching and initial '-', or
|
154
|
+
'--' are considered option definitions and lines starting with a word
|
155
|
+
immediately followed by an exclamation mark is a command definition (like 'cmd!
|
156
|
+
...'). Text following a '@' (except in paragraphs) is a brief comment, the rest
|
157
|
+
is paragraphs
|
194
158
|
|
195
|
-
```ruby
|
196
|
-
USAGE = "a cmd! b c"
|
197
|
-
|
198
|
-
args = ShellOpts.process(USAGE, ARGV) { |opt, arg|
|
199
|
-
case opt
|
200
|
-
when '-a'; # Handle -a
|
201
|
-
when 'cmd'
|
202
|
-
arg.each { |opt, arg|
|
203
|
-
case opt
|
204
|
-
when '-b'; # Handle -b
|
205
|
-
when '-c'; # Handle -c
|
206
|
-
end
|
207
|
-
}
|
208
|
-
end
|
209
|
-
}
|
210
159
|
```
|
160
|
+
-a,alpha @ Brief comment for -a and --alpha options
|
161
|
+
Longer description of the option that is used by `::help`
|
211
162
|
|
212
|
-
|
163
|
+
cmd!
|
164
|
+
@ Alternative style of brief comment
|
213
165
|
|
214
|
-
|
215
|
-
|
216
|
-
can be grouped so that `-abc` is the same as `-a -b -c`. Long options are
|
217
|
-
prefixed with a `--` and can't be grouped
|
166
|
+
Longer description of the command
|
167
|
+
```
|
218
168
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
mandatory arguments but use `=` to separate the option from optional arguments:
|
223
|
-
`--file=/path/to/file`
|
169
|
+
Text starting with '--' follow by a blank character is a free-text description
|
170
|
+
of the command-line arguments. It is not parsed but used in documentation and
|
171
|
+
error messages:
|
224
172
|
|
225
|
-
|
173
|
+
```ruby
|
174
|
+
SPEC = "-a cmd! -- ARG1 ARG2"
|
226
175
|
```
|
227
|
-
f= # -farg or -f arg
|
228
|
-
f=? # -farg
|
229
176
|
|
230
|
-
|
231
|
-
file=? # --file=arg
|
232
|
-
```
|
177
|
+
## Options
|
233
178
|
|
234
|
-
|
179
|
+
The general syntax for options is
|
235
180
|
|
236
|
-
|
237
|
-
|
181
|
+
```
|
182
|
+
<prefix><optionlist>[=argspec][?]
|
183
|
+
```
|
238
184
|
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
newer version of `ShellOpts` or file a bug-report
|
185
|
+
The option list is a comma-separated list of option names. It is prefixed with
|
186
|
+
a '-' if the option list starts with a short option name and '--' if the option
|
187
|
+
list starts with a long name. '-' and '--' can be replaced with '+' or '++' to
|
188
|
+
indicate that the option can be repeated
|
244
189
|
|
245
|
-
|
190
|
+
```
|
191
|
+
-a,alpha @ -a and --alpha
|
192
|
+
++beta @ --beta, can be repeated
|
193
|
+
--gamma=ARG? @ --gamma, takes an optional argument
|
194
|
+
```
|
246
195
|
|
247
|
-
#### Error handling methods
|
248
196
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
program with status 1.
|
197
|
+
An option argument has a name and a type. The type can be specified as '#'
|
198
|
+
(integer), '$' (float), or as a comma-separated list of allowed values. It can
|
199
|
+
also be defined by a keyword that expects a file or directory argument:
|
253
200
|
|
254
|
-
|
255
|
-
|
201
|
+
| Keyword | Type |
|
202
|
+
| --------- | ---- |
|
203
|
+
| FILE | A file if present or in an existing directory if not |
|
204
|
+
| DIR | A directory if present or in an existing directory if not |
|
205
|
+
| PATH | Either a FILE or DIR |
|
206
|
+
| EFILE | An existing file |
|
207
|
+
| EDIR | An existing directory |
|
208
|
+
| EPATH | Either an EFILE or EDIR |
|
209
|
+
| NFILE | A new file |
|
210
|
+
| NDIR | A new directory |
|
211
|
+
| NPATH | A new file or directory |
|
256
212
|
|
257
|
-
|
258
|
-
<PROGRAM>: <MESSAGE>
|
259
|
-
Usage: <PROGRAM> <USAGE>
|
260
|
-
```
|
261
|
-
The usage string is a prettyfied version of the usage definition given to
|
262
|
-
ShellOpts
|
213
|
+
By default the option name is inferred from the type but it can be specified explicitly by separating it from the type with a ':'. Examples:
|
263
214
|
|
264
|
-
`fail` is used to report that something is wrong with the assumptions about the
|
265
|
-
system (eg. disk full) and omits the usage summary
|
266
215
|
```
|
267
|
-
|
216
|
+
-a=# @ -a takes an integer argument
|
217
|
+
-b=MONEY:$ @ -b takes a float argument. Is shown as '-b=MONEY' in messages
|
218
|
+
-c=red,blue,green @ -c takes one of the listed words
|
219
|
+
-d=FILE @ Fails if file exists and is not a file
|
220
|
+
-d=EDIR @ Fails if directory doesn't exist or is not a directory
|
221
|
+
-d=INPUT:EFILE @ Takes and existing file. Shown as '-d=INPUT' in messages
|
268
222
|
```
|
269
223
|
|
270
|
-
|
271
|
-
class methods on `ShellOpts`. They can also be included in the global scope by
|
272
|
-
`include ShellOpts::Utils`
|
224
|
+
## Commands
|
273
225
|
|
274
|
-
|
226
|
+
Commands are specified as lines starting with the name of the command
|
227
|
+
immediately followed by a '!' like `cmd!`. Commands can have options and even
|
228
|
+
subcommands of their own, in the multi-line format they're indented under the
|
229
|
+
command line like this
|
275
230
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
231
|
+
```
|
232
|
+
-a @ Program level option
|
233
|
+
cmd!
|
234
|
+
-b @ Command level option
|
235
|
+
subcmd!
|
236
|
+
-c @ Sub-command level option
|
237
|
+
```
|
280
238
|
|
281
|
-
|
239
|
+
In single-line format, subcommands are specified by prefixing the supercommand's name:
|
282
240
|
|
283
|
-
USAGE="long-and-complex-usage-string"
|
284
|
-
ShellOpts.usage = <<~EOD
|
285
|
-
usage explanation
|
286
|
-
split over
|
287
|
-
multiple lines
|
288
|
-
EOD
|
289
241
|
```
|
290
|
-
|
291
|
-
|
292
|
-
object-level `ShellOpts::ShellOpts#error` method. This is considered a bug and
|
293
|
-
will fixed at some point
|
242
|
+
-a cmd! -b cmd.subcmd! -c
|
243
|
+
```
|
294
244
|
|
295
245
|
## Example
|
296
246
|
|
297
|
-
The rm(1) command could be
|
247
|
+
The rm(1) command could be specified like this:
|
248
|
+
|
298
249
|
```ruby
|
299
250
|
|
300
251
|
require 'shellopts'
|
301
252
|
|
302
253
|
# Define options
|
303
|
-
|
304
|
-
f,force
|
305
|
-
|
306
|
-
v,verbose help version
|
307
|
-
}
|
308
|
-
|
309
|
-
# Define defaults
|
310
|
-
force = false
|
311
|
-
prompt = false
|
312
|
-
prompt_once = false
|
313
|
-
interactive = false
|
314
|
-
interactive_when = nil
|
315
|
-
recursive = false
|
316
|
-
remove_empty_dirs = false
|
317
|
-
one_file_system = false
|
318
|
-
preserve_root = true
|
319
|
-
verbose = false
|
320
|
-
|
321
|
-
# Process command line
|
322
|
-
args = ShellOpts.process(USAGE, ARGV) { |opt, arg|
|
323
|
-
case opt
|
324
|
-
when '-f', '--force'; force = true
|
325
|
-
when '-i'; prompt = true
|
326
|
-
when '-I'; prompt_once = true
|
327
|
-
when '--interactive'; interactive = true; interactive_when = arg
|
328
|
-
when '-r', '-R', '--recursive'; recursive = true
|
329
|
-
when '-d', '--dir'; remove_empty_dirs = true
|
330
|
-
when '--one-file-system'; one_file_system = true
|
331
|
-
when '--preserve-root'; preserve_root = true
|
332
|
-
when '--no-preserve-root'; preserve_root = false
|
333
|
-
when '--verbose'; verbose = true
|
334
|
-
when '--help'; print_help; exit
|
335
|
-
when '--version'; puts VERSION; exit
|
336
|
-
end
|
337
|
-
end
|
254
|
+
SPEC = %(
|
255
|
+
-f,force @ ignore nonexisten files and arguments, never prompt
|
256
|
+
-i @ prompt before every removal
|
338
257
|
|
339
|
-
|
340
|
-
|
341
|
-
|
258
|
+
-I
|
259
|
+
@ prompt once
|
260
|
+
|
261
|
+
prompt once before removing more than three files, or when removing
|
262
|
+
recursively; less intrusive than -i, while still giving protection
|
263
|
+
against most mistakes
|
264
|
+
|
265
|
+
--interactive=WHEN:never,once,always
|
266
|
+
@ prompt according to WHEN
|
342
267
|
|
268
|
+
prompt according to WHEN: never, once (-I), or always (-i); without WHEN, prompt always
|
269
|
+
|
270
|
+
--one-file-system
|
271
|
+
@ stay on fuile system
|
272
|
+
|
273
|
+
when removing a hierarchy recursively, skip any directory that is on a file system different from
|
274
|
+
that of the corresponding command line argument
|
275
|
+
|
276
|
+
--no-preserve-root @ do not treat '/' specially
|
277
|
+
--preserve-root @ do not remove '/' (default)
|
278
|
+
-r,R,recursive @ remove directories and their contents recursively
|
279
|
+
-d,dir @ remove empty directories
|
280
|
+
-v,verbose @ explain what is being done
|
281
|
+
--help @ display this help and exit
|
282
|
+
--version @ output version information and exit
|
283
|
+
|
284
|
+
-- FILE...
|
285
|
+
)
|
286
|
+
```
|
343
287
|
|
344
288
|
## See also
|
345
289
|
|
@@ -378,16 +322,6 @@ release a new version, update the version number in `version.rb`, and then run
|
|
378
322
|
git commits and tags, and push the `.gem` file to
|
379
323
|
[rubygems.org](https://rubygems.org).
|
380
324
|
|
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
|
-
|
391
325
|
## Contributing
|
392
326
|
|
393
327
|
Bug reports and pull requests are welcome on GitHub at
|
data/TODO
CHANGED
@@ -1,8 +1,16 @@
|
|
1
|
-
|
2
|
-
o '
|
3
|
-
o
|
4
|
-
o
|
5
|
-
|
1
|
+
|
2
|
+
o Ignore all text after ' # ' (doesn't conflict with option flag)
|
3
|
+
o Command aliases
|
4
|
+
o Add user-defined setions
|
5
|
+
o Add a SOURCE section with link to git repo
|
6
|
+
o Bullet-lists
|
7
|
+
o Allow a USAGE section (and NAME)
|
8
|
+
o Find source in code an adjust line number in error messages
|
9
|
+
o Rename line and char to lineno and charno
|
10
|
+
o Client-defined argument types
|
11
|
+
o Rename Expr -> ?
|
12
|
+
o Find clean(er) procedural object model
|
13
|
+
o Allow assignment to options (this makes practical stuff easier)
|
6
14
|
o Special handling of --help arguments so that '--help command' is possible
|
7
15
|
o Support for paging of help:
|
8
16
|
begin
|
@@ -14,3 +22,27 @@ o Support for paging of help:
|
|
14
22
|
file.close
|
15
23
|
end
|
16
24
|
|
25
|
+
+ Bold text output
|
26
|
+
+ Recursive format of commands
|
27
|
+
+ Rename Compiler -> Interpreter
|
28
|
+
|
29
|
+
|
30
|
+
OLD
|
31
|
+
|
32
|
+
o Fix that it is near unsable when the user doesn't do 'include ShellOpts'
|
33
|
+
o Subcommands can be parsed as well:
|
34
|
+
opts, args = Shellopts.process(OPTIONS, ARGV)
|
35
|
+
...
|
36
|
+
opts, command = opts.process
|
37
|
+
case command
|
38
|
+
when ...
|
39
|
+
end
|
40
|
+
o 'help' should list commands in declaration order
|
41
|
+
o 'help' should use all levels by default
|
42
|
+
o 'help' should always include top-level options (try setting levels: 10 and
|
43
|
+
see top-level options are gone
|
44
|
+
o A ShellOpts#shift command that makes it possible for Array#expect to emit
|
45
|
+
relevant error messages
|
46
|
+
|
47
|
+
+ Somehow escape comments where a line starts with an option name
|
48
|
+
+ Parse and check enumeration arguments ('--debug=tokens|ast|idr|...')
|