shellopts 0.9.1 → 0.9.6

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: f97bd1dadffdc1a8e5eab5635bdb186ddb925bafc2fe60b478c84d3b9590fb63
4
- data.tar.gz: 9909d8069a937593e7a583d6fd8db1989f7eb8e321d9c655e2d0f376caeffd24
3
+ metadata.gz: 943b9d0c44ba0291937be24cbc79d0155dfc22ac788c69a76639850d78af3303
4
+ data.tar.gz: f38e038f613c577b06e9d2facc6096b39eb18f28266ba8c58a8280adcf75fe47
5
5
  SHA512:
6
- metadata.gz: 161c50d8cb2dc9abaa91164c3898f57942a6d51fcaadcb83bfd52cb96115548772be5d244d7e620f71751b523fdd5db0ab8a8a8bc76624be40a94d0341ac53c3
7
- data.tar.gz: abaa5c58dfc5aaa98a553b4cb582c738a4bcd3649e5681c034a32b550bb583d106e4b0240cb0c5225dc0c8f58b3a32af2bd314d5894209b39b72e26446c6f4e3
6
+ metadata.gz: 42cc6102c0c66dcffda0b03f9c584c32abc0e62a65dbe79e1389753b74af11f189e27a456e79fb2cb082595622ddbce0840dd22419204e276a48134ac8afd610
7
+ data.tar.gz: 6a3b2e35718a5ee1f52e5d56a50ea067da90fef35a4ac3322738e24d5ba80f4aba4ac4a692caace4bb094ccfb84432e9211fef2b15dfef2e194a95569ca80686
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,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
- 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
+ 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 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
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`. The class methods stores program name and usage
261
- string in global variables that are reset by `ShellOpts.reset`
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
- 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
@@ -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 instead:
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
- def self.process(usage, argv, program_name: File.basename($0), &block)
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. Can only be
97
- # called after #process. Forwards to {::ShellOpts#error}
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&.error(*msgs) or raise InternalError, "ShellOpts class variable not initialized"
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. Forwards to {::ShellOpts#fail}
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&.fail(*msgs) or raise InternalError, "ShellOpts class variable not initialized"
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
- # Usage string. Shorthand for +grammar.usage+
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
- $stderr.puts "#{program_name}: #{msgs.join}"
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
- $stderr.puts "#{program_name}: #{msgs.join}"
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)
@@ -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.
@@ -19,7 +19,6 @@ module ShellOpts
19
19
  attr_reader :commands
20
20
 
21
21
  # List of options in declaration order
22
- # order
23
22
  attr_reader :option_list
24
23
 
25
24
  # List of commands in declaration order
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Shellopts
2
- VERSION = "0.9.1"
2
+ VERSION = "0.9.6"
3
3
  end
@@ -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", "~> 10.0"
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.1
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: 2019-10-20 00:00:00.000000000 Z
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: '10.0'
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: '10.0'
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
- rubyforge_project:
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