shellopts 2.0.4 → 2.0.7

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: 0170d9ce5144afcf716b90a3904250c0afa5d769b7a64f39db0b8084e77b4fb7
4
- data.tar.gz: 81495a3802c472c65812594d847c43b0f59849ea0ebe093c74c2fb7d3e822658
3
+ metadata.gz: 6e8933ca7084aea3e51858cd679eec2a6b34b2fc7ae9a55ccce131947ccc7375
4
+ data.tar.gz: 125309b75338e9205fb05c5c556fca54cbc1cc77ef890a4ca2d6992c69eff302
5
5
  SHA512:
6
- metadata.gz: 195801ea89b22920fca88216ed4bd7ac426b3370e482b61547dac085d1c7d9f1bd0a2d0edc7c3368bf126cd5f4da815dd882ee3149cd291549ff631d6302e93a
7
- data.tar.gz: 6dcd50871438db9f5b0520e4f670f6df6ad04756685838d309874a9601770ee79a7370ebc11b0469d19a9f2be89868c7cfd12cfe028c0c01719b4d8d0593fc59
6
+ metadata.gz: 123b17ded3c4943267612959f3b8ab56a37249e38ea9c338c577ad254ebc1c7c9c305ca9a7a3ee2661d9474e905ddd193c5da8e7a5adc3e711c236349095a636
7
+ data.tar.gz: a3115c875274fccf6628d4c839e3eac36804157f7c56e90b599e8201c1bf8f1070b5b92b7e22cbe2c6615e20b81f4de8b81233227aaccdb873f1016e129d99ae
data/TODO CHANGED
@@ -1,4 +1,5 @@
1
1
 
2
+ o Add brackets to optional option arguments: '--all=FILE?' -> '--all[=FILE]'
2
3
  o Ignore all text after ' # ' (doesn't conflict with option flag)
3
4
  o Command aliases
4
5
  o Add user-defined setions
@@ -2,18 +2,23 @@
2
2
  module ShellOpts
3
3
  # Specialization of Array for arguments lists. Args extends Array with a
4
4
  # #extract and an #expect method to extract elements from the array. The
5
- # methods raise a ShellOpts::UserError exception in case of errors
5
+ # methods raise a ShellOpts::Error exception in case of errors
6
6
  #
7
7
  class Args < Array
8
+ # :call-seq:
9
+ # extract(count, message = nil)
10
+ # extract(range, message = nil)
11
+ #
8
12
  # Remove and return elements from beginning of the array
9
13
  #
10
14
  # If +count_or_range+ is a number, that number of elements will be
11
15
  # returned. If the count is one, a simple value is returned instead of an
12
16
  # array. If the count is negative, the elements will be removed from the
13
17
  # end of the array. If +count_or_range+ is a range, the number of elements
14
- # returned will be in that range. The range can't contain negative numbers
18
+ # returned will be in that range. Note that the range can't contain
19
+ # negative numbers
15
20
  #
16
- # #extract raise a ShellOpts::UserError exception if there's is not enough
21
+ # #extract raise a ShellOpts::Error exception if there's is not enough
17
22
  # elements in the array to satisfy the request
18
23
  #
19
24
  def extract(count_or_range, message = nil)
@@ -30,16 +35,16 @@ module ShellOpts
30
35
  count.abs <= self.size or inoa(message)
31
36
  start = count >= 0 ? 0 : size + count
32
37
  r = slice!(start, count.abs)
33
- r.size <= 0 ? nil : (r.size == 1 ? r.first : r)
38
+ r.size == 1 ? r.first : r
34
39
  else
35
40
  raise ArgumentError
36
41
  end
37
42
  end
38
43
 
39
44
  # As #extract except it doesn't allow negative counts and that the array is
40
- # expect to be emptied by the operation
45
+ # expected to be emptied by the operation
41
46
  #
42
- # #expect raise a ShellOpts::UserError exception if the array is not emptied
47
+ # #expect raise a ShellOpts::Error exception if the array is not emptied
43
48
  # by the operation
44
49
  #
45
50
  def expect(count_or_range, message = nil)
@@ -55,7 +60,7 @@ module ShellOpts
55
60
 
56
61
  private
57
62
  def inoa(message = nil)
58
- raise ArgumentError, message || "Illegal number of arguments"
63
+ raise ShellOpts::Error, message || "Illegal number of arguments"
59
64
  end
60
65
  end
61
66
  end
@@ -38,16 +38,17 @@ module ShellOpts
38
38
  using Ext::Array::Wrap
39
39
 
40
40
  def puts_usage(bol: false)
41
+ width = [Formatter.rest, Formatter::USAGE_MAX_WIDTH].min
41
42
  if descrs.size == 0
42
43
  print (lead = Formatter.command_prefix || "")
43
44
  indent(lead.size, ' ', bol: bol && lead == "") {
44
- puts render(:multi, Formatter::USAGE_MAX_WIDTH)
45
+ puts render(:multi, width)
45
46
  }
46
47
  else
47
48
  lead = Formatter.command_prefix || ""
48
49
  descrs.each { |descr|
49
50
  print lead
50
- puts render(:single, Formatter::USAGE_MAX_WIDTH, args: [descr.text])
51
+ puts render(:single, width, args: [descr.text])
51
52
  }
52
53
  end
53
54
  end
@@ -199,8 +200,8 @@ module ShellOpts
199
200
  # Number of characters between columns in brief output
200
201
  BRIEF_COL_SEP = 2
201
202
 
202
- # Maximum width of first column in brief option and command lists
203
- BRIEF_COL1_MIN_WIDTH = 6
203
+ # Minimum width of first column in brief option and command lists
204
+ BRIEF_COL1_MIN_WIDTH = 20
204
205
 
205
206
  # Maximum width of first column in brief option and command lists
206
207
  BRIEF_COL1_MAX_WIDTH = 40
@@ -122,6 +122,22 @@ module ShellOpts
122
122
  def self.parse(token)
123
123
  super(nil, token)
124
124
  end
125
+
126
+ def add_stdopts
127
+ option_token = Token.new(:option, 1, 1, "--version")
128
+ brief_token = Token.new(:brief, 1, 1, "Write version number and exit")
129
+ group = OptionGroup.new(self, option_token)
130
+ option = Option.parse(group, option_token)
131
+ brief = Brief.parse(group, brief_token)
132
+
133
+ option_token = Token.new(:option, 1, 1, "-h,help")
134
+ brief_token = Token.new(:brief, 1, 1, "Write help text and exit")
135
+ paragraph_token = Token.new(:text, 1, 1, "-h prints a brief help text, --help prints a longer man-style description of the command")
136
+ group = OptionGroup.new(self, option_token)
137
+ option = Option.parse(group, option_token)
138
+ brief = Brief.parse(group, brief_token)
139
+ paragraph = Paragraph.parse(group, paragraph_token)
140
+ end
125
141
  end
126
142
 
127
143
  class ArgSpec
@@ -146,6 +162,14 @@ module ShellOpts
146
162
  @nodes = {}
147
163
  end
148
164
 
165
+ # def add_stdopts
166
+ # version_token = Token.new(:option, 1, 1, "--version")
167
+ # version_brief = Token.new(:brief, 1, 1, "Gryf gryf")
168
+ # group = Grammar::OptionGroup.new(@program, version_token)
169
+ # option = Grammar::Option.parse(group, version_token)
170
+ # brief = Grammr::Brief.parse(option, version_brief)
171
+ # end
172
+
149
173
  def parse()
150
174
  @program = Grammar::Program.parse(@tokens.shift)
151
175
  oneline = @tokens.first.lineno == @tokens.last.lineno
@@ -1,3 +1,3 @@
1
1
  module ShellOpts
2
- VERSION = "2.0.4"
2
+ VERSION = "2.0.7"
3
3
  end
data/lib/shellopts.rb CHANGED
@@ -102,6 +102,9 @@ module ShellOpts
102
102
  attr_accessor :stdopts
103
103
  attr_accessor :msgopts
104
104
 
105
+ # Version of client program. This is only used if +stdopts+ is true
106
+ attr_reader :version
107
+
105
108
  # Interpreter flags
106
109
  attr_accessor :float
107
110
 
@@ -116,9 +119,9 @@ module ShellOpts
116
119
  attr_reader :tokens
117
120
  alias_method :ast, :grammar # Oops - defined earlier FIXME
118
121
 
119
- def initialize(name: nil, stdopts: true, msgopts: false, float: true, exception: false)
122
+ def initialize(name: nil, stdopts: true, version: nil, msgopts: false, float: true, exception: false)
120
123
  @name = name || File.basename($PROGRAM_NAME)
121
- @stdopts, @msgopts, @float, @exception = stdopts, msgopts, float, exception
124
+ @stdopts, @version, @msgopts, @float, @exception = stdopts, version, msgopts, float, exception
122
125
  end
123
126
 
124
127
  # Compile source and return grammar object. Also sets #spec and #grammar.
@@ -130,7 +133,7 @@ module ShellOpts
130
133
  @file = find_caller_file
131
134
  @tokens = Lexer.lex(name, @spec, @oneline)
132
135
  ast = Parser.parse(tokens)
133
- # TODO: Add standard and message options and their handlers
136
+ ast.add_stdopts if stdopts
134
137
  @grammar = Analyzer.analyze(ast)
135
138
  }
136
139
  self
@@ -143,6 +146,20 @@ module ShellOpts
143
146
  handle_exceptions {
144
147
  @argv = argv.dup
145
148
  @program, @args = Interpreter.interpret(grammar, argv, float: float, exception: exception)
149
+ if stdopts
150
+ if @program.version?
151
+ version or raise ArgumentError, "Version not specified"
152
+ puts version
153
+ exit
154
+ elsif @program.help?
155
+ if @program[:help].name == "-h"
156
+ ShellOpts.brief
157
+ else
158
+ ShellOpts.help
159
+ end
160
+ exit
161
+ end
162
+ end
146
163
  }
147
164
  self
148
165
  end
@@ -177,7 +194,7 @@ module ShellOpts
177
194
  saved = $stdout
178
195
  $stdout = $stderr
179
196
  $stderr.puts "#{name}: #{message}"
180
- Formatter.usage(program)
197
+ Formatter.usage(grammar)
181
198
  exit 1
182
199
  ensure
183
200
  $stdout = saved
@@ -203,9 +220,10 @@ module ShellOpts
203
220
  # Print help for the given subject or the full documentation if +subject+
204
221
  # is nil. Clears the screen beforehand if :clear is true
205
222
  #
206
- def help(subject = nil, clear: false)
223
+ def help(subject = nil, clear: true)
207
224
  node = (subject ? @grammar[subject] : @grammar) or
208
225
  raise ArgumentError, "No such command: '#{subject&.sub(".", " ")}'"
226
+ print '' if clear
209
227
  Formatter.help(node)
210
228
  end
211
229
 
@@ -310,6 +328,7 @@ module ShellOpts
310
328
  def self.instance?() !@instance.nil? end
311
329
  def self.instance() @instance or raise Error, "ShellOpts is not initialized" end
312
330
  def self.instance=(instance) @instance = instance end
331
+ def self.shellopts() instance end
313
332
 
314
333
  forward_self_to :instance, :error, :failure
315
334
 
data/main CHANGED
@@ -7,18 +7,33 @@ require 'shellopts'
7
7
 
8
8
  include ShellOpts
9
9
 
10
+ VERSION = "1.2.3"
10
11
 
11
12
  SPEC = %(
12
- -a,alpha @ Brief comment for -a and --alpha options
13
- Longer and more elaborate description of the --alpha option
13
+ -a @ An option
14
+ )
15
+ opts, args = ShellOpts::process(SPEC, ARGV, version: VERSION)
16
+ #ShellOpts::ShellOpts.help
14
17
 
15
- -b,beta=ARG
16
- @ Alternative style of brief comment
17
18
 
18
- Longer and more elaborate description of the --beta option
19
- )
20
19
 
21
- opts, args = ShellOpts.process(SPEC, ARGV)
20
+
21
+
22
+
23
+ __END__
24
+
25
+
26
+ #SPEC = %(
27
+ # -a,alpha @ Brief comment for -a and --alpha options
28
+ # Longer and more elaborate description of the --alpha option
29
+ #
30
+ # -b,beta=ARG
31
+ # @ Alternative style of brief comment
32
+ #
33
+ # Longer and more elaborate description of the --beta option
34
+ #)
35
+ #
36
+ #opts, args = ShellOpts.process(SPEC, ARGV)
22
37
  #puts "opts.alpha?: #{opts.alpha?.inspect}"
23
38
  #puts "opts.alpha: #{opts.alpha.inspect}"
24
39
  #puts "opts.beta?: #{opts.beta?.inspect}"
@@ -266,8 +281,9 @@ SPEC4 = %(
266
281
 
267
282
  SPEC5 = "cmd! cmd!"
268
283
 
269
- shellopts = ShellOpts::ShellOpts.new(exception: false)
284
+ shellopts = ShellOpts::ShellOpts.new(exception: true)
270
285
  #shellopts.compile("cmd! cmd!")
286
+
271
287
  shellopts.compile(SPEC)
272
288
  #shellopts.compile(SPEC2)
273
289
  #shellopts.compile(SPEC3)
@@ -277,9 +293,9 @@ shellopts.compile(SPEC)
277
293
  #shellopts.tokens.each(&:dump)
278
294
  #exit
279
295
 
280
- shellopts.usage
296
+ #shellopts.usage
281
297
  #shellopts.brief
282
- #shellopts.help
298
+ shellopts.help
283
299
  #shellopts.help("cmd")
284
300
  #shellopts.help(ARGV.first)
285
301
 
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: 2.0.4
4
+ version: 2.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Claus Rasmussen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-01 00:00:00.000000000 Z
11
+ date: 2022-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: forward_to