shellopts 2.0.10 → 2.0.13
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/lib/ext/array.rb +3 -1
- data/lib/shellopts/formatter.rb +34 -51
- data/lib/shellopts/program.rb +16 -3
- data/lib/shellopts/version.rb +1 -1
- data/lib/shellopts.rb +22 -13
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8dd7a731b489dbf650e15549d9768469ae9d6c47c6dba3ae79f4d956fea069ab
|
4
|
+
data.tar.gz: 4b71aff7ba350d4616a136580857a6acd840141ed0b7463034518dcf4ae4dada
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb5792606dd91f46b95fe786b509fd079697c87fd603c667e49740b365cafafa0cdc7b49a0a86c72cd014f9c2d88cdf74f096422e6099403042d8c34d35044b3
|
7
|
+
data.tar.gz: d7f2637649b474741b70dd9334e25107586fe52eb4e4f9a289453699f334488fed60322a676ad20fcab2f0c993785ccdef89be4397055028e75d79795766b972
|
data/lib/ext/array.rb
CHANGED
@@ -41,7 +41,9 @@ module Ext
|
|
41
41
|
|
42
42
|
module Wrap
|
43
43
|
refine ::Array do
|
44
|
-
# Concatenate
|
44
|
+
# Concatenate array of words into lines that are at most +width+
|
45
|
+
# characters wide. +curr+ is the initial number of characters already
|
46
|
+
# used on the first line
|
45
47
|
def wrap(width, curr = 0)
|
46
48
|
lines = [[]]
|
47
49
|
curr -= 1 # Simplifies conditions below
|
data/lib/shellopts/formatter.rb
CHANGED
@@ -1,12 +1,5 @@
|
|
1
1
|
require 'terminfo'
|
2
2
|
|
3
|
-
# TODO: Move to ext/indented_io.rb
|
4
|
-
module IndentedIO
|
5
|
-
class IndentedIO
|
6
|
-
def margin() combined_indent.size end
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
3
|
module ShellOpts
|
11
4
|
module Grammar
|
12
5
|
class Node
|
@@ -216,7 +209,10 @@ module ShellOpts
|
|
216
209
|
BRIEF_COL1_MAX_WIDTH = 40
|
217
210
|
|
218
211
|
# Minimum width of second column in brief option and command lists
|
219
|
-
|
212
|
+
BRIEF_COL2_MIN_WIDTH = 30
|
213
|
+
|
214
|
+
# Maximum width of second column in brief option and command lists
|
215
|
+
BRIEF_COL2_MAX_WIDTH = 70
|
220
216
|
|
221
217
|
# Indent to use in help output
|
222
218
|
HELP_INDENT = 4
|
@@ -226,29 +222,21 @@ module ShellOpts
|
|
226
222
|
|
227
223
|
# Usage string in error messages
|
228
224
|
def self.usage(subject)
|
229
|
-
|
230
|
-
@command_prefix =
|
225
|
+
command = Grammar::Command.command(subject)
|
226
|
+
@command_prefix = command.ancestors.map { |node| node.name + " " }.join
|
231
227
|
setup_indent(1) {
|
232
228
|
print lead = "#{USAGE_STRING}: "
|
233
|
-
indent(lead.size, ' ', bol: false) {
|
229
|
+
indent(lead.size, ' ', bol: false) { command.puts_usage }
|
234
230
|
}
|
235
231
|
end
|
236
232
|
|
237
|
-
# # TODO
|
238
|
-
# def self.usage=(usage_lambda)
|
239
|
-
# end
|
240
|
-
|
241
233
|
# When the user gives a -h option
|
242
|
-
def self.brief(
|
243
|
-
command = Grammar::Command.command(
|
234
|
+
def self.brief(subject)
|
235
|
+
command = Grammar::Command.command(subject)
|
244
236
|
@command_prefix = command.ancestors.map { |node| node.name + " " }.join
|
245
237
|
setup_indent(BRIEF_INDENT) { command.puts_brief }
|
246
238
|
end
|
247
239
|
|
248
|
-
# # TODO
|
249
|
-
# def self.brief=(brief_lambda)
|
250
|
-
# end
|
251
|
-
|
252
240
|
# When the user gives a --help option
|
253
241
|
def self.help(subject)
|
254
242
|
subject = Grammar::Command.command(subject)
|
@@ -262,18 +250,6 @@ module ShellOpts
|
|
262
250
|
obj.is_a?(Grammar::Command) ? obj : obj.__grammar__
|
263
251
|
end
|
264
252
|
|
265
|
-
# # TODO
|
266
|
-
# def self.help_w_lambda(program)
|
267
|
-
# if @help_lambda
|
268
|
-
# #
|
269
|
-
# else
|
270
|
-
# program = Grammar::Command.command(program)
|
271
|
-
# setup_indent(HELP_INDENT) { program.puts_descr }
|
272
|
-
# end
|
273
|
-
# end
|
274
|
-
#
|
275
|
-
# def self.help=(help_lambda) @help_lambda end
|
276
|
-
|
277
253
|
def self.puts_columns(widths, fields)
|
278
254
|
l = []
|
279
255
|
first_width, second_width = *widths
|
@@ -284,40 +260,47 @@ module ShellOpts
|
|
284
260
|
puts first
|
285
261
|
indent(first_width + BRIEF_COL_SEP, ' ') { puts second.wrap(second_width) } if second
|
286
262
|
elsif second
|
287
|
-
|
288
|
-
|
263
|
+
indent_size = first_width + BRIEF_COL_SEP
|
264
|
+
printf "%-#{indent_size}s", first
|
265
|
+
indent(indent_size, ' ', bol: false) { puts second.wrap(second_width) }
|
289
266
|
else
|
290
267
|
puts first
|
291
268
|
end
|
292
269
|
end
|
293
270
|
end
|
294
271
|
|
272
|
+
# Returns a tuple of [first-column-width, second-column-width]. +width+ is
|
273
|
+
# the maximum width of the colunms and the BRIEF_COL_SEP separator.
|
274
|
+
# +fields+ is an array of [subject-string, descr-text] tuples where the
|
275
|
+
# descr is an array of words
|
295
276
|
def self.compute_columns(width, fields)
|
296
|
-
first_max =
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
first_width = first_max
|
307
|
-
second_width = width - first_width - BRIEF_COL_SEP
|
277
|
+
first_max =
|
278
|
+
fields.map { |first, _| first.size }.select { |size| size <= BRIEF_COL1_MAX_WIDTH }.max ||
|
279
|
+
BRIEF_COL1_MIN_WIDTH
|
280
|
+
second_max = fields.map { |_, second| second ? second&.map(&:size).sum + second.size - 1 : 0 }.max
|
281
|
+
first_width = [[first_max, BRIEF_COL1_MIN_WIDTH].max, BRIEF_COL1_MAX_WIDTH].min
|
282
|
+
rest = width - first_width - BRIEF_COL_SEP
|
283
|
+
second_min = [BRIEF_COL2_MIN_WIDTH, second_max].min
|
284
|
+
if rest < second_min
|
285
|
+
first_width = [first_max, width - second_min - BRIEF_COL_SEP].max
|
286
|
+
second_width = [width - first_width - BRIEF_COL_SEP, BRIEF_COL2_MIN_WIDTH].max
|
308
287
|
else
|
309
|
-
|
310
|
-
second_width = BRIEF_COL2_MAX_WIDTH
|
288
|
+
second_width = [[rest, BRIEF_COL2_MIN_WIDTH].max, BRIEF_COL2_MAX_WIDTH].min
|
311
289
|
end
|
312
|
-
|
313
290
|
[first_width, second_width]
|
314
291
|
end
|
315
292
|
|
316
293
|
def self.width()
|
317
294
|
@width ||= TermInfo.screen_width - MARGIN_RIGHT
|
295
|
+
@width
|
296
|
+
end
|
297
|
+
|
298
|
+
# Used in rspec
|
299
|
+
def self.width=(width)
|
300
|
+
@width = width
|
318
301
|
end
|
319
302
|
|
320
|
-
def self.rest() width - $stdout.
|
303
|
+
def self.rest() width - $stdout.tab end
|
321
304
|
|
322
305
|
private
|
323
306
|
# TODO Get rid of?
|
data/lib/shellopts/program.rb
CHANGED
@@ -45,12 +45,12 @@ module ShellOpts
|
|
45
45
|
|
46
46
|
# These names can't be used as option or command names
|
47
47
|
RESERVED_OPTION_NAMES = %w(
|
48
|
-
is_a instance_eval instance_exec method_missing singleton_method_added
|
48
|
+
is_a to_h instance_eval instance_exec method_missing singleton_method_added
|
49
49
|
singleton_method_removed singleton_method_undefined
|
50
50
|
)
|
51
51
|
|
52
|
-
# These methods can be overridden by an option or a command (
|
53
|
-
#
|
52
|
+
# These methods can be overridden by an option or a command (this constant
|
53
|
+
# is not used - it is just for informational purposes)
|
54
54
|
OVERRIDEABLE_METHOD_NAMES = %w(
|
55
55
|
subcommand subcommand! supercommand!
|
56
56
|
)
|
@@ -96,6 +96,19 @@ module ShellOpts
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
+
# Returns a hash of the given options if defined. Returns all options if no
|
100
|
+
# options are given
|
101
|
+
def to_h(*keys)
|
102
|
+
keys = ::Kernel::Array(keys).flatten
|
103
|
+
if keys.empty?
|
104
|
+
@__option_values__
|
105
|
+
else
|
106
|
+
keys.map { |key|
|
107
|
+
@__option_values__.key?(key) ? [key, @__option_values__[key]] : nil
|
108
|
+
}.compact.to_h
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
99
112
|
# Subcommand identifier or nil if not present. #subcommand is often used in
|
100
113
|
# case statement to branch out to code that handles the given subcommand:
|
101
114
|
#
|
data/lib/shellopts/version.rb
CHANGED
data/lib/shellopts.rb
CHANGED
@@ -192,23 +192,23 @@ module ShellOpts
|
|
192
192
|
#
|
193
193
|
# #error is supposed to be used when the user made an error and the usage
|
194
194
|
# is written to help correcting the error
|
195
|
-
#
|
196
195
|
def error(subject = nil, message)
|
197
|
-
saved = $stdout
|
198
|
-
$stdout = $stderr
|
199
196
|
$stderr.puts "#{name}: #{message}"
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
197
|
+
saved = $stdout
|
198
|
+
begin
|
199
|
+
$stdout = $stderr
|
200
|
+
Formatter.usage(grammar)
|
201
|
+
exit 1
|
202
|
+
ensure
|
203
|
+
$stdout = saved
|
204
|
+
end
|
204
205
|
end
|
205
206
|
|
206
207
|
# Write error message to standard error and terminate program with status 1
|
207
208
|
#
|
208
|
-
# #failure
|
209
|
-
#
|
210
|
-
#
|
211
|
-
#
|
209
|
+
# #failure doesn't print the program usage because is supposed to be used
|
210
|
+
# when the user specified the correct arguments but something else went
|
211
|
+
# wrong during processing
|
212
212
|
def failure(message)
|
213
213
|
$stderr.puts "#{name}: #{message}"
|
214
214
|
exit 1
|
@@ -222,7 +222,6 @@ module ShellOpts
|
|
222
222
|
|
223
223
|
# Print help for the given subject or the full documentation if +subject+
|
224
224
|
# is nil. Clears the screen beforehand if :clear is true
|
225
|
-
#
|
226
225
|
def help(subject = nil, clear: true)
|
227
226
|
node = (subject ? @grammar[subject] : @grammar) or
|
228
227
|
raise ArgumentError, "No such command: '#{subject&.sub(".", " ")}'"
|
@@ -333,7 +332,17 @@ module ShellOpts
|
|
333
332
|
def self.instance=(instance) @instance = instance end
|
334
333
|
def self.shellopts() instance end
|
335
334
|
|
336
|
-
|
335
|
+
def self.error(subject = nil, message)
|
336
|
+
instance.error(subject, message) if instance? # Never returns
|
337
|
+
$stderr.puts "#{File.basename($PROGRAM_NAME)}: #{message}"
|
338
|
+
exit 1
|
339
|
+
end
|
340
|
+
|
341
|
+
def self.failure(message)
|
342
|
+
instance.failure(message) if instance?
|
343
|
+
$stderr.puts "#{File.basename($PROGRAM_NAME)}: #{message}"
|
344
|
+
exit 1
|
345
|
+
end
|
337
346
|
|
338
347
|
# The Include module brings the reporting methods into the namespace when
|
339
348
|
# included
|
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
|
+
version: 2.0.13
|
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
|
11
|
+
date: 2022-04-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: forward_to
|