shellopts 0.9.1 → 0.9.6
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 +43 -14
- data/TODO +7 -0
- data/bin/mkdoc +11 -6
- data/lib/shellopts.rb +47 -14
- data/lib/shellopts/compiler.rb +1 -1
- data/lib/shellopts/grammar/command.rb +0 -1
- data/lib/shellopts/utils.rb +16 -0
- data/lib/shellopts/version.rb +1 -1
- data/shellopts.gemspec +1 -1
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 943b9d0c44ba0291937be24cbc79d0155dfc22ac788c69a76639850d78af3303
|
4
|
+
data.tar.gz: f38e038f613c577b06e9d2facc6096b39eb18f28266ba8c58a8280adcf75fe47
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42cc6102c0c66dcffda0b03f9c584c32abc0e62a65dbe79e1389753b74af11f189e27a456e79fb2cb082595622ddbce0840dd22419204e276a48134ac8afd610
|
7
|
+
data.tar.gz: 6a3b2e35718a5ee1f52e5d56a50ea067da90fef35a4ac3322738e24d5ba80f4aba4ac4a692caace4bb094ccfb84432e9211fef2b15dfef2e194a95569ca80686
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,20 +1,20 @@
|
|
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
|
-
|
11
|
-
|
12
|
-
|
13
|
-
`--verbose`
|
10
|
+
Program that accepts the options -a or --all, --count, --file, and -v or
|
11
|
+
--verbose. The usage definition expects `--count` to have an optional integer
|
12
|
+
argument, `--file` to have a mandatory argument, and allows `-v` and
|
13
|
+
`--verbose` to be repeated:
|
14
14
|
|
15
|
-
```ruby
|
16
|
-
require 'shellopts'
|
17
15
|
|
16
|
+
```ruby
|
17
|
+
|
18
18
|
# Define options
|
19
19
|
USAGE = "a,all count=#? file= +v,verbose -- FILE..."
|
20
20
|
|
@@ -36,7 +36,7 @@ args = ShellOpts.process(USAGE, ARGV) do |opt, arg|
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
# Process remaining arguments
|
39
|
+
# Process remaining command line arguments
|
40
40
|
args.each { |arg| ... }
|
41
41
|
```
|
42
42
|
|
@@ -50,10 +50,10 @@ error
|
|
50
50
|
|
51
51
|
## Processing
|
52
52
|
|
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
|
53
|
+
`ShellOpts.process` compiles a usage definition string into a grammar and use
|
54
|
+
that to parse the command line. If given a block, the block is called with a
|
55
|
+
name/value pair for each option or command and return a list of the remaining
|
56
|
+
non-option arguments
|
57
57
|
|
58
58
|
```ruby
|
59
59
|
args = ShellOpts.process(USAGE, ARGV) do |opt, arg|
|
@@ -101,6 +101,18 @@ An option is defined by a list of comma-separated names optionally prefixed by a
|
|
101
101
|
[ "+" ] name-list [ "=" [ "#" | "$" ] [ label ] [ "?" ] ]
|
102
102
|
```
|
103
103
|
|
104
|
+
#### Flags
|
105
|
+
|
106
|
+
There are the following flags:
|
107
|
+
|
108
|
+
|Flag|Effect|
|
109
|
+
|---|---|
|
110
|
+
|+|Repeated option (prefix)|
|
111
|
+
|=|Argument. Mandatory unless `?` is also used|
|
112
|
+
|#|Integer argument|
|
113
|
+
|$|Floating point argument|
|
114
|
+
|?|Optional argument|
|
115
|
+
|
104
116
|
#### Repeated options
|
105
117
|
|
106
118
|
Options are unique by default and the user will get an error if an option is
|
@@ -257,8 +269,25 @@ system (eg. disk full) and omits the usage summary
|
|
257
269
|
```
|
258
270
|
|
259
271
|
The methods are defined as instance methods on `ShellOpts::ShellOpts` and as
|
260
|
-
class methods on `ShellOpts`.
|
261
|
-
|
272
|
+
class methods on `ShellOpts`. They can also be included in the global scope by
|
273
|
+
`include ShellOpts::Utils`
|
274
|
+
|
275
|
+
#### Usage string
|
276
|
+
|
277
|
+
The error handling methods prints a prettified version of the usage string
|
278
|
+
given to `ShellOpts.parse`. It can be overridden by assigning to
|
279
|
+
`ShellOpts.usage`. You'll often assign to the usage string when it needs to be
|
280
|
+
split over several lines:
|
281
|
+
|
282
|
+
```ruby
|
283
|
+
|
284
|
+
USAGE="long-and-complex-usage-string"
|
285
|
+
ShellOpts.usage = %(
|
286
|
+
usage explanation
|
287
|
+
split over
|
288
|
+
multiple lines
|
289
|
+
)
|
290
|
+
```
|
262
291
|
|
263
292
|
## Example
|
264
293
|
|
data/TODO
CHANGED
@@ -1,5 +1,11 @@
|
|
1
1
|
|
2
2
|
TODO
|
3
|
+
o Check on return value from #process block to see if all options was handled:
|
4
|
+
case opt
|
5
|
+
when '-v'; verbose = true # Return value 'true' is ok
|
6
|
+
# Unhandled option means return value is nil
|
7
|
+
end
|
8
|
+
o Consolidate some of the 3 variations of #error and #fail
|
3
9
|
o Add a option flag for solitary options (--help)
|
4
10
|
o Make a #to_yaml
|
5
11
|
o Make an official dump method for debug
|
@@ -54,6 +60,7 @@ LATER
|
|
54
60
|
o Escape of separator in lists
|
55
61
|
o Handle output of subcommand usage like "cmd1 cmd1.cmd2 cmd2"
|
56
62
|
o Command-specific arguments: clone! o,opt ++ ARG1 ARG2...
|
63
|
+
o Hostname and email as basic types
|
57
64
|
|
58
65
|
ON TO_H BRANCH
|
59
66
|
ShellOpts.process(usage, argv) { |opt,val| ... } => args
|
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,12 +2,28 @@ require "shellopts/version"
|
|
2
2
|
|
3
3
|
require 'shellopts/compiler.rb'
|
4
4
|
require 'shellopts/parser.rb'
|
5
|
+
require 'shellopts/utils.rb'
|
5
6
|
|
6
7
|
# ShellOpts is a library for parsing command line options and sub-commands. The
|
7
8
|
# library API consists of the methods {ShellOpts.process}, {ShellOpts.error},
|
8
9
|
# and {ShellOpts.fail} and the result class {ShellOpts::ShellOpts}
|
9
10
|
#
|
11
|
+
# ShellOpts inject the constant PROGRAM into the global scope. It contains the
|
12
|
+
# name of the program
|
13
|
+
#
|
10
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
|
+
|
11
27
|
# Process command line options and arguments. #process takes a usage string
|
12
28
|
# defining the options and the array of command line arguments to be parsed
|
13
29
|
# as arguments
|
@@ -68,15 +84,17 @@ module ShellOpts
|
|
68
84
|
# #process saves a hidden {ShellOpts::ShellOpts} class variable used by the
|
69
85
|
# class methods #error and #fail. Call #reset to clear the global object if
|
70
86
|
# you really need to parse more than one command line. Alternatively you can
|
71
|
-
# create +ShellOpts::ShellOpts+ objects yourself and use the object methods
|
72
|
-
# #error and #fail
|
87
|
+
# create +ShellOpts::ShellOpts+ objects yourself and also use the object methods
|
88
|
+
# #error and #fail:
|
73
89
|
#
|
74
90
|
# shellopts = ShellOpts::ShellOpts.new(USAGE, ARGS)
|
75
91
|
# shellopts.each { |name, value| ... }
|
76
92
|
# shellopts.args.each { |arg| ... }
|
77
93
|
# shellopts.error("Something went wrong")
|
78
94
|
#
|
79
|
-
|
95
|
+
# Use #shellopts to get the hidden +ShellOpts::ShellOpts+ object
|
96
|
+
#
|
97
|
+
def self.process(usage, argv, program_name: PROGRAM, &block)
|
80
98
|
if !block_given?
|
81
99
|
ShellOpts.new(usage, argv, program_name: program_name)
|
82
100
|
else
|
@@ -91,17 +109,28 @@ module ShellOpts
|
|
91
109
|
# another command line
|
92
110
|
def self.reset()
|
93
111
|
@shellopts = nil
|
112
|
+
@usage = nil
|
94
113
|
end
|
95
114
|
|
96
|
-
# Print error message and usage string and exit with status 1.
|
97
|
-
#
|
115
|
+
# Print error message and usage string and exit with status 1. It use the
|
116
|
+
# current ShellOpts object if defined. This method should be called in
|
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
|
98
122
|
def self.error(*msgs)
|
99
|
-
@shellopts&.
|
123
|
+
program = @shellopts&.program_name || PROGRAM
|
124
|
+
usage_string = usage || (defined?(USAGE) && USAGE ? Grammar.compile(PROGRAM, USAGE).usage : nil)
|
125
|
+
emit_and_exit(program, usage_string, *msgs)
|
100
126
|
end
|
101
127
|
|
102
|
-
# Print error message and exit with status 1.
|
128
|
+
# Print error message and exit with status 1. It use the current ShellOpts
|
129
|
+
# object if defined. This method should not be called in response to
|
130
|
+
# user-errors but system errors (like disk full)
|
103
131
|
def self.fail(*msgs)
|
104
|
-
@shellopts&.
|
132
|
+
program = @shellopts&.program_name || PROGRAM
|
133
|
+
emit_and_exit(program, nil, *msgs)
|
105
134
|
end
|
106
135
|
|
107
136
|
# The compilation object
|
@@ -109,7 +138,7 @@ module ShellOpts
|
|
109
138
|
# Name of program
|
110
139
|
attr_reader :program_name
|
111
140
|
|
112
|
-
#
|
141
|
+
# Prettified usage string used by #error and #fail. Shorthand for +grammar.usage+
|
113
142
|
def usage() @grammar.usage end
|
114
143
|
|
115
144
|
# The grammar compiled from the usage string. If #ast is defined, it's
|
@@ -162,16 +191,13 @@ module ShellOpts
|
|
162
191
|
# should be called in response to user-errors (eg. specifying an illegal
|
163
192
|
# option)
|
164
193
|
def error(*msgs)
|
165
|
-
|
166
|
-
$stderr.puts "Usage: #{program_name} #{usage}"
|
167
|
-
exit 1
|
194
|
+
::ShellOpts.emit_and_exit(program_name, usage, msgs)
|
168
195
|
end
|
169
196
|
|
170
197
|
# Print error message and exit with status 1. This method should not be
|
171
198
|
# called in response to user-errors but system errors (like disk full)
|
172
199
|
def fail(*msgs)
|
173
|
-
|
174
|
-
exit 1
|
200
|
+
::ShellOpts.emit_and_exit(program_name, nil, msgs)
|
175
201
|
end
|
176
202
|
end
|
177
203
|
|
@@ -191,5 +217,12 @@ module ShellOpts
|
|
191
217
|
|
192
218
|
private
|
193
219
|
@shellopts = nil
|
220
|
+
|
221
|
+
def self.emit_and_exit(program, usage, *msgs)
|
222
|
+
$stderr.puts "#{program}: #{msgs.join}"
|
223
|
+
$stderr.puts "Usage: #{program} #{usage}" if usage
|
224
|
+
exit 1
|
225
|
+
end
|
194
226
|
end
|
195
227
|
|
228
|
+
PROGRAM = File.basename($PROGRAM_NAME)
|
data/lib/shellopts/compiler.rb
CHANGED
@@ -27,7 +27,7 @@ module ShellOpts
|
|
27
27
|
|
28
28
|
# Initialize a Compiler object. source is the option definition string
|
29
29
|
def initialize(program_name, source)
|
30
|
-
@program_name, @tokens = program_name, source.split(/\s+/)
|
30
|
+
@program_name, @tokens = program_name, source.split(/\s+/).reject(&:empty?)
|
31
31
|
|
32
32
|
# @commands_by_path is an hash from command-path to Command or Program
|
33
33
|
# object. The top level Program object has nil as its path.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
module ShellOpts
|
3
|
+
# Use `include ShellOpts::Utils` to include ShellOpts utility methods in the
|
4
|
+
# global namespace
|
5
|
+
module Utils
|
6
|
+
# Forwards to `ShellOpts.error`
|
7
|
+
def error(*msgs)
|
8
|
+
::ShellOpts.error(*msgs)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Forwards to `ShellOpts.fail`
|
12
|
+
def fail(*msgs)
|
13
|
+
::ShellOpts.fail(*msgs)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/shellopts/version.rb
CHANGED
data/shellopts.gemspec
CHANGED
@@ -33,7 +33,7 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.require_paths = ["lib"]
|
34
34
|
|
35
35
|
spec.add_development_dependency "bundler", "~> 1.16"
|
36
|
-
spec.add_development_dependency "rake", "
|
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"
|
39
39
|
spec.add_development_dependency "simplecov"
|
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.
|
4
|
+
version: 0.9.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Claus Rasmussen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 12.3.3
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 12.3.3
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
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
|
@@ -115,6 +116,7 @@ files:
|
|
115
116
|
- lib/shellopts/grammar/option.rb
|
116
117
|
- lib/shellopts/grammar/program.rb
|
117
118
|
- lib/shellopts/parser.rb
|
119
|
+
- lib/shellopts/utils.rb
|
118
120
|
- lib/shellopts/version.rb
|
119
121
|
- shellopts.gemspec
|
120
122
|
homepage: http://github.com/clrgit/shellopts
|
@@ -136,8 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
138
|
- !ruby/object:Gem::Version
|
137
139
|
version: '0'
|
138
140
|
requirements: []
|
139
|
-
|
140
|
-
rubygems_version: 2.7.6
|
141
|
+
rubygems_version: 3.0.8
|
141
142
|
signing_key:
|
142
143
|
specification_version: 4
|
143
144
|
summary: Parse command line options and arguments
|