shellopts 0.9.5 → 1.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 12f6d1397c2a4ae0a4e8c168f1d695f25ade753c37f94e8b4373ce57aa222593
4
- data.tar.gz: 9589f39de24f13c5d5bf6ae873b58d425cc393654362e9afa7699c5d7dd81a46
3
+ metadata.gz: 3096c35af16a39ffc98b52f02799aa25efa311b20916309496ee33b2a50dcf47
4
+ data.tar.gz: ebc336b7a5595412d1f705378f24dc6136c17e3257db7ca5ddec021349ec2a88
5
5
  SHA512:
6
- metadata.gz: 577ab3793305b1eeee0b3fca253832603fbeaf4d34a511e11a7625aa356b1031e17116213c055cb5672821e524d8c34409398a1209bc3cdade7a53fded96d87f
7
- data.tar.gz: bcadf1a3c495a6bda0863e42c40ef82744abc2fbe401a57286c335b62cc4e50f51ddf76847d2c360fae08f51120f3fbcd4538076e6527f5d379bd5828978f9b7
6
+ metadata.gz: d44d80cc028fa9c9a7add7206b6a0f096cc3deb1c7e3f756075171c4ebfb20fdb6246215ec02d8920e9b450ebfcd5355a0c3b4179cc03d7fb4f6f89eea6f3a15
7
+ data.tar.gz: 5bb562a9806196a6b6594897d3a09b8a1dc70abebf9f51194a6d31c031e86c54e69d1531acbb5ba6d675afb97c12d86ad2da4216af06bdcac8e056430787a97a
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  /.yardoc
3
3
  /_yardoc/
4
4
  /doc/
5
+ /rdoc/
5
6
  /pkg/
6
7
  /spec/reports/
7
8
  /tmp/
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 `-a` and `--all` that are aliases
11
- for the same option, `--count` that may be given an integer argument but
12
- defaults to 42, `--file` that has a mandatory argument, and `-v` and
13
- `--verbose` that can be repeated to increase the verbosity level
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
- require 'shellopts'
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 that to
54
- parse the command line. If given a block, the block is called with a name/value
55
- pair for each option or command and return a list of the remaining non-option
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, val| ... } # Access options
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,val|
198
+ args = ShellOpts.process(USAGE, ARGV) { |opt, arg|
188
199
  case opt
189
200
  when '-a'; # Handle -a
190
201
  when 'cmd'
191
- opt.each { |opt, val|
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, val|
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 = val
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
data/TODO CHANGED
@@ -1,5 +1,15 @@
1
1
 
2
2
  TODO
3
+ o Also allow assignment to usage string for ShellOpts::ShellOpts objects
4
+ o Create a ShellOpts.args method? It would be useful when processing commands:
5
+ case opt
6
+ when "command"
7
+ call_command_method(ShellOpts.args[1], ShellOpts.args[2])
8
+ end
9
+ ShellOpts.args would be a shorthand for ShellOpts.shellopts.args
10
+ Another option would be to create an argument-processing method:
11
+ shellopts.argv(2) -> call error if not exactly two arguments else return elements
12
+
3
13
  o Check on return value from #process block to see if all options was handled:
4
14
  case opt
5
15
  when '-v'; verbose = true # Return value 'true' is ok
@@ -11,7 +21,7 @@ TODO
11
21
  o Make an official dump method for debug
12
22
  o Make a note that all options are processed at once and not as-you-go
13
23
  o Test that arguments with spaces work
14
- o Long version usage strings
24
+ o Long version usage strings (major release)
15
25
  o Doc: Example of processing of sub-commands and sub-sub-commands
16
26
 
17
27
  + More tests
data/bin/mkdoc CHANGED
@@ -1,10 +1,15 @@
1
1
  #!/usr/bin/bash
2
2
 
3
- LINK='<link rel="stylesheet" type="text/css" href="stylesheet.css">'
3
+ set -e
4
4
 
5
- {
6
- echo $LINK
7
- pandoc README.md
8
- } >index.html
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 lib
14
+ # Generate rdoc
15
+ rdoc --output=rdoc --force-output lib
@@ -0,0 +1,409 @@
1
+ /*
2
+ Copyright (c) 2017 Chris Patuzzo
3
+ https://twitter.com/chrispatuzzo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+ */
23
+
24
+ body {
25
+ font-family: Helvetica, arial, sans-serif;
26
+ font-size: 14px;
27
+ line-height: 1.6;
28
+ padding-top: 10px;
29
+ padding-bottom: 10px;
30
+ background-color: white;
31
+ padding: 30px;
32
+ color: #333;
33
+ }
34
+
35
+ body > *:first-child {
36
+ margin-top: 0 !important;
37
+ }
38
+
39
+ body > *:last-child {
40
+ margin-bottom: 0 !important;
41
+ }
42
+
43
+ a {
44
+ color: #4183C4;
45
+ text-decoration: none;
46
+ }
47
+
48
+ a.absent {
49
+ color: #cc0000;
50
+ }
51
+
52
+ a.anchor {
53
+ display: block;
54
+ padding-left: 30px;
55
+ margin-left: -30px;
56
+ cursor: pointer;
57
+ position: absolute;
58
+ top: 0;
59
+ left: 0;
60
+ bottom: 0;
61
+ }
62
+
63
+ h1, h2, h3, h4, h5, h6 {
64
+ margin: 20px 0 10px;
65
+ padding: 0;
66
+ font-weight: bold;
67
+ -webkit-font-smoothing: antialiased;
68
+ cursor: text;
69
+ position: relative;
70
+ }
71
+
72
+ h2:first-child, h1:first-child, h1:first-child + h2, h3:first-child, h4:first-child, h5:first-child, h6:first-child {
73
+ margin-top: 0;
74
+ padding-top: 0;
75
+ }
76
+
77
+ h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
78
+ text-decoration: none;
79
+ }
80
+
81
+ h1 tt, h1 code {
82
+ font-size: inherit;
83
+ }
84
+
85
+ h2 tt, h2 code {
86
+ font-size: inherit;
87
+ }
88
+
89
+ h3 tt, h3 code {
90
+ font-size: inherit;
91
+ }
92
+
93
+ h4 tt, h4 code {
94
+ font-size: inherit;
95
+ }
96
+
97
+ h5 tt, h5 code {
98
+ font-size: inherit;
99
+ }
100
+
101
+ h6 tt, h6 code {
102
+ font-size: inherit;
103
+ }
104
+
105
+ h1 {
106
+ font-size: 28px;
107
+ color: black;
108
+ }
109
+
110
+ h2 {
111
+ font-size: 24px;
112
+ border-bottom: 1px solid #cccccc;
113
+ color: black;
114
+ }
115
+
116
+ h3 {
117
+ font-size: 18px;
118
+ }
119
+
120
+ h4 {
121
+ font-size: 16px;
122
+ }
123
+
124
+ h5 {
125
+ font-size: 14px;
126
+ }
127
+
128
+ h6 {
129
+ color: #777777;
130
+ font-size: 14px;
131
+ }
132
+
133
+ p, blockquote, ul, ol, dl, li, table, pre {
134
+ margin: 15px 0;
135
+ }
136
+
137
+ hr {
138
+ border: 0 none;
139
+ color: #cccccc;
140
+ height: 4px;
141
+ padding: 0;
142
+ }
143
+
144
+ body > h2:first-child {
145
+ margin-top: 0;
146
+ padding-top: 0;
147
+ }
148
+
149
+ body > h1:first-child {
150
+ margin-top: 0;
151
+ padding-top: 0;
152
+ }
153
+
154
+ body > h1:first-child + h2 {
155
+ margin-top: 0;
156
+ padding-top: 0;
157
+ }
158
+
159
+ body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
160
+ margin-top: 0;
161
+ padding-top: 0;
162
+ }
163
+
164
+ a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
165
+ margin-top: 0;
166
+ padding-top: 0;
167
+ }
168
+
169
+ h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
170
+ margin-top: 0;
171
+ }
172
+
173
+ li p.first {
174
+ display: inline-block;
175
+ }
176
+
177
+ ul, ol {
178
+ padding-left: 30px;
179
+ }
180
+
181
+ ul :first-child, ol :first-child {
182
+ margin-top: 0;
183
+ }
184
+
185
+ ul :last-child, ol :last-child {
186
+ margin-bottom: 0;
187
+ }
188
+
189
+ dl {
190
+ padding: 0;
191
+ }
192
+
193
+ dl dt {
194
+ font-size: 14px;
195
+ font-weight: bold;
196
+ font-style: italic;
197
+ padding: 0;
198
+ margin: 15px 0 5px;
199
+ }
200
+
201
+ dl dt:first-child {
202
+ padding: 0;
203
+ }
204
+
205
+ dl dt > :first-child {
206
+ margin-top: 0;
207
+ }
208
+
209
+ dl dt > :last-child {
210
+ margin-bottom: 0;
211
+ }
212
+
213
+ dl dd {
214
+ margin: 0 0 15px;
215
+ padding: 0 15px;
216
+ }
217
+
218
+ dl dd > :first-child {
219
+ margin-top: 0;
220
+ }
221
+
222
+ dl dd > :last-child {
223
+ margin-bottom: 0;
224
+ }
225
+
226
+ blockquote {
227
+ border-left: 4px solid #dddddd;
228
+ padding: 0 15px;
229
+ color: #777777;
230
+ }
231
+
232
+ blockquote > :first-child {
233
+ margin-top: 0;
234
+ }
235
+
236
+ blockquote > :last-child {
237
+ margin-bottom: 0;
238
+ }
239
+
240
+ table {
241
+ padding: 0;
242
+ }
243
+ table tr {
244
+ border-top: 1px solid #cccccc;
245
+ background-color: white;
246
+ margin: 0;
247
+ padding: 0;
248
+ }
249
+
250
+ table tr:nth-child(2n) {
251
+ background-color: #f8f8f8;
252
+ }
253
+
254
+ table tr th {
255
+ font-weight: bold;
256
+ border: 1px solid #cccccc;
257
+ text-align: left;
258
+ margin: 0;
259
+ padding: 6px 13px;
260
+ }
261
+
262
+ table tr td {
263
+ border: 1px solid #cccccc;
264
+ text-align: left;
265
+ margin: 0;
266
+ padding: 6px 13px;
267
+ }
268
+
269
+ table tr th :first-child, table tr td :first-child {
270
+ margin-top: 0;
271
+ }
272
+
273
+ table tr th :last-child, table tr td :last-child {
274
+ margin-bottom: 0;
275
+ }
276
+
277
+ img {
278
+ max-width: 100%;
279
+ }
280
+
281
+ span.frame {
282
+ display: block;
283
+ overflow: hidden;
284
+ }
285
+
286
+ span.frame > span {
287
+ border: 1px solid #dddddd;
288
+ display: block;
289
+ float: left;
290
+ overflow: hidden;
291
+ margin: 13px 0 0;
292
+ padding: 7px;
293
+ width: auto;
294
+ }
295
+
296
+ span.frame span img {
297
+ display: block;
298
+ float: left;
299
+ }
300
+
301
+ span.frame span span {
302
+ clear: both;
303
+ color: #333333;
304
+ display: block;
305
+ padding: 5px 0 0;
306
+ }
307
+
308
+ span.align-center {
309
+ display: block;
310
+ overflow: hidden;
311
+ clear: both;
312
+ }
313
+
314
+ span.align-center > span {
315
+ display: block;
316
+ overflow: hidden;
317
+ margin: 13px auto 0;
318
+ text-align: center;
319
+ }
320
+
321
+ span.align-center span img {
322
+ margin: 0 auto;
323
+ text-align: center;
324
+ }
325
+
326
+ span.align-right {
327
+ display: block;
328
+ overflow: hidden;
329
+ clear: both;
330
+ }
331
+
332
+ span.align-right > span {
333
+ display: block;
334
+ overflow: hidden;
335
+ margin: 13px 0 0;
336
+ text-align: right;
337
+ }
338
+
339
+ span.align-right span img {
340
+ margin: 0;
341
+ text-align: right;
342
+ }
343
+
344
+ span.float-left {
345
+ display: block;
346
+ margin-right: 13px;
347
+ overflow: hidden;
348
+ float: left;
349
+ }
350
+
351
+ span.float-left span {
352
+ margin: 13px 0 0;
353
+ }
354
+
355
+ span.float-right {
356
+ display: block;
357
+ margin-left: 13px;
358
+ overflow: hidden;
359
+ float: right;
360
+ }
361
+
362
+ span.float-right > span {
363
+ display: block;
364
+ overflow: hidden;
365
+ margin: 13px auto 0;
366
+ text-align: right;
367
+ }
368
+
369
+ code, tt {
370
+ margin: 0 2px;
371
+ padding: 0 5px;
372
+ white-space: nowrap;
373
+ border: 1px solid #eaeaea;
374
+ background-color: #f8f8f8;
375
+ border-radius: 3px;
376
+ }
377
+
378
+ pre code {
379
+ margin: 0;
380
+ padding: 0;
381
+ white-space: pre;
382
+ border: none;
383
+ background: transparent;
384
+ }
385
+
386
+ .highlight pre {
387
+ background-color: #f8f8f8;
388
+ border: 1px solid #cccccc;
389
+ font-size: 13px;
390
+ line-height: 19px;
391
+ overflow: auto;
392
+ padding: 6px 10px;
393
+ border-radius: 3px;
394
+ }
395
+
396
+ pre {
397
+ background-color: #f8f8f8;
398
+ border: 1px solid #cccccc;
399
+ font-size: 13px;
400
+ line-height: 19px;
401
+ overflow: auto;
402
+ padding: 6px 10px;
403
+ border-radius: 3px;
404
+ }
405
+
406
+ pre code, pre tt {
407
+ background-color: transparent;
408
+ border: none;
409
+ }
data/lib/shellopts.rb CHANGED
@@ -12,6 +12,18 @@ require 'shellopts/utils.rb'
12
12
  # name of the program
13
13
  #
14
14
  module ShellOpts
15
+ # Return the hidden +ShellOpts::ShellOpts+ object (see .process)
16
+ def self.shellopts()
17
+ @shellopts
18
+ end
19
+
20
+ # Prettified usage string used by #error and #fail. Default is +usage+ of
21
+ # the current +ShellOpts::ShellOpts+ object
22
+ def self.usage() @usage || @shellopts&.usage end
23
+
24
+ # Set the usage string
25
+ def self.usage=(usage) @usage = usage end
26
+
15
27
  # Process command line options and arguments. #process takes a usage string
16
28
  # defining the options and the array of command line arguments to be parsed
17
29
  # as arguments
@@ -72,14 +84,16 @@ module ShellOpts
72
84
  # #process saves a hidden {ShellOpts::ShellOpts} class variable used by the
73
85
  # class methods #error and #fail. Call #reset to clear the global object if
74
86
  # 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:
87
+ # create +ShellOpts::ShellOpts+ objects yourself and also use the object methods
88
+ # #error and #fail:
77
89
  #
78
90
  # shellopts = ShellOpts::ShellOpts.new(USAGE, ARGS)
79
91
  # shellopts.each { |name, value| ... }
80
92
  # shellopts.args.each { |arg| ... }
81
93
  # shellopts.error("Something went wrong")
82
94
  #
95
+ # Use #shellopts to get the hidden +ShellOpts::ShellOpts+ object
96
+ #
83
97
  def self.process(usage, argv, program_name: PROGRAM, &block)
84
98
  if !block_given?
85
99
  ShellOpts.new(usage, argv, program_name: program_name)
@@ -95,15 +109,20 @@ module ShellOpts
95
109
  # another command line
96
110
  def self.reset()
97
111
  @shellopts = nil
112
+ @usage = nil
98
113
  end
99
114
 
100
115
  # Print error message and usage string and exit with status 1. It use the
101
116
  # current ShellOpts object if defined. This method should be called in
102
117
  # response to user-errors (eg. specifying an illegal option)
118
+ #
119
+ # If there is no current ShellOpts object +error+ will look for USAGE to make
120
+ # it possible to use +error+ before the command line is processed and also as
121
+ # a stand-alone error reporting method
103
122
  def self.error(*msgs)
104
123
  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)
124
+ usage_string = usage || (defined?(USAGE) && USAGE ? Grammar.compile(PROGRAM, USAGE).usage : nil)
125
+ emit_and_exit(program, @usage.nil?, usage_string, *msgs)
107
126
  end
108
127
 
109
128
  # Print error message and exit with status 1. It use the current ShellOpts
@@ -111,7 +130,7 @@ module ShellOpts
111
130
  # user-errors but system errors (like disk full)
112
131
  def self.fail(*msgs)
113
132
  program = @shellopts&.program_name || PROGRAM
114
- emit_and_exit(program, nil, *msgs)
133
+ emit_and_exit(program, false, nil, *msgs)
115
134
  end
116
135
 
117
136
  # The compilation object
@@ -119,7 +138,7 @@ module ShellOpts
119
138
  # Name of program
120
139
  attr_reader :program_name
121
140
 
122
- # Usage string. Shorthand for +grammar.usage+
141
+ # Prettified usage string used by #error and #fail. Shorthand for +grammar.usage+
123
142
  def usage() @grammar.usage end
124
143
 
125
144
  # The grammar compiled from the usage string. If #ast is defined, it's
@@ -172,13 +191,13 @@ module ShellOpts
172
191
  # should be called in response to user-errors (eg. specifying an illegal
173
192
  # option)
174
193
  def error(*msgs)
175
- ::ShellOpts.emit_and_exit(program_name, usage, msgs)
194
+ ::ShellOpts.emit_and_exit(program_name, true, usage, msgs)
176
195
  end
177
196
 
178
197
  # Print error message and exit with status 1. This method should not be
179
198
  # called in response to user-errors but system errors (like disk full)
180
199
  def fail(*msgs)
181
- ::ShellOpts.emit_and_exit(program_name, nil, msgs)
200
+ ::ShellOpts.emit_and_exit(program_name, false, nil, msgs)
182
201
  end
183
202
  end
184
203
 
@@ -199,9 +218,13 @@ module ShellOpts
199
218
  private
200
219
  @shellopts = nil
201
220
 
202
- def self.emit_and_exit(program, usage, *msgs)
221
+ def self.emit_and_exit(program, use_usage, usage, *msgs)
203
222
  $stderr.puts "#{program}: #{msgs.join}"
204
- $stderr.puts "Usage: #{program} #{usage}" if usage
223
+ if use_usage
224
+ $stderr.puts "Usage: #{program} #{usage}" if usage
225
+ else
226
+ $stderr.puts usage if usage
227
+ end
205
228
  exit 1
206
229
  end
207
230
  end
@@ -1,3 +1,3 @@
1
1
  module Shellopts
2
- VERSION = "0.9.5"
2
+ VERSION = "1.0.1"
3
3
  end
data/shellopts.gemspec CHANGED
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
33
  spec.require_paths = ["lib"]
34
34
 
35
- spec.add_development_dependency "bundler", "~> 1.16"
35
+ spec.add_development_dependency "bundler", "~> 2.2.10"
36
36
  spec.add_development_dependency "rake", ">= 12.3.3"
37
37
  spec.add_development_dependency "rspec", "~> 3.0"
38
38
  spec.add_development_dependency "indented_io"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shellopts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.5
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-04-03 00:00:00.000000000 Z
11
+ date: 2021-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.16'
19
+ version: 2.2.10
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.16'
26
+ version: 2.2.10
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -103,6 +103,7 @@ files:
103
103
  - bin/console
104
104
  - bin/mkdoc
105
105
  - bin/setup
106
+ - doc/stylesheet.css
106
107
  - lib/ext/array.rb
107
108
  - lib/shellopts.rb
108
109
  - lib/shellopts/ast/command.rb
@@ -137,8 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
138
  - !ruby/object:Gem::Version
138
139
  version: '0'
139
140
  requirements: []
140
- rubyforge_project:
141
- rubygems_version: 2.7.6
141
+ rubygems_version: 3.0.8
142
142
  signing_key:
143
143
  specification_version: 4
144
144
  summary: Parse command line options and arguments