shellopts 0.9.5 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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