dencli 0.2.1 → 0.5.0
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/bin/example.rb +35 -5
- data/lib/dencli/cmd.rb +192 -8
- data/lib/dencli/interactive.rb +1 -1
- data/lib/dencli/sub.rb +77 -17
- data/lib/dencli/version.rb +1 -1
- data/lib/dencli.rb +24 -8
- 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: b59309b03abb2d1a44eda112c289335eed1a252bccd89404a4e5017ff876657f
|
4
|
+
data.tar.gz: 0ecfaff2dd2928bfdc134ee3dc92737ae2776737e6ada66fd1432de5b470ab76
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d27d7f9d307e1e86684ebb7e771ff865d0d10e4cde501951947997e98d25aafff123826c1973e7615ab45edd7c2bd3d60eacefa56835eacd976a4e9a9f4ed2d8
|
7
|
+
data.tar.gz: 70f63e628dcd9b7c2cc8da2302ef0dc33a170efc6281173c05f31b09657c0f4b616cd71faaa3ea09738e629b021e51e6018fda33535d2d34d8570caa0db32acc
|
data/bin/example.rb
CHANGED
@@ -1,25 +1,55 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
require 'pathname'
|
4
|
+
$:.unshift Pathname.new(__FILE__).dirname.dirname.join('lib').to_s
|
3
5
|
require 'dencli'
|
4
6
|
|
5
7
|
cli = DenCli.new 'example', "This is an example for generate a DenCli-API"
|
8
|
+
cli.cmd( :args, "Expects and prints given arguments", &lambda {|a, b, c:, d:, e:|
|
9
|
+
p a: a, b: b, c: c, d: d, e: e
|
10
|
+
}).
|
11
|
+
opt( :c, '-c=ForC', "Option c").
|
12
|
+
opt( :d, '-d=ForD', "Option d", default: "something").
|
13
|
+
opt( :e, '-e', "Toggle e", default: false).
|
14
|
+
opt( :f, '--[no-]f', "Toggle f", default: false)
|
15
|
+
|
6
16
|
cli.cmd( :example, "I have an example command") { STDERR.puts "This is an example" }
|
7
|
-
cli.cmd( :help, "", aliases: [nil, '-h', '--help']
|
17
|
+
cli.cmd( :help, "", aliases: [nil, '-h', '--help'], &lambda {|*args, full:|
|
18
|
+
if full
|
19
|
+
cli.help_full *args, output: STDERR
|
20
|
+
else
|
21
|
+
cli.help *args, output: STDERR
|
22
|
+
end
|
23
|
+
}).
|
24
|
+
opt( :full, '-f', '--[no-]full', "Print all commands and sub-commands.", default: false)
|
8
25
|
|
9
26
|
cli.sub( :more, "Sub-Commands are also possible with a new cli") do |sub|
|
27
|
+
sub.cmd( :help, "", aliases: [nil, '-h', '--help']) {|*args| STDERR.puts sub.help(*args) }
|
10
28
|
sub.cmd( :help, "") {|*args| STDERR.puts cli.help( 'more', *args) }
|
11
29
|
sub.cmd( :example, "Here is an example, too") { STDERR.puts "This is an other example" }
|
12
30
|
sub.cmd( :foo, "BAR") { STDERR.puts "FOO bar"}
|
13
31
|
|
32
|
+
sub.cmd( :args, "Expects and prints given arguments", &lambda {|a, b=1, c:, d: 5, e:|
|
33
|
+
p a: a, b: b, c: c, d: d, e: e
|
34
|
+
}).
|
35
|
+
opt( :c, '-c=ForC', "Option c").
|
36
|
+
opt( :d, '-d=ForD', "Option d (implicit default)").
|
37
|
+
opt( :e, '-e', "Toggle e")
|
38
|
+
|
14
39
|
sub.sub( :deeper, "You want to have Sub-Sub-Commands?") do |sub2|
|
15
|
-
sub2.cmd( :help, ""
|
16
|
-
sub2.cmd( :last, "The last example"
|
40
|
+
sub2.cmd( :help, "", aliases: [nil, '-h', '--help'], &lambda {|*args| sub2.help( *args, output: STDERR) })
|
41
|
+
sub2.cmd( :last, "The last example", &lambda { STDERR.puts "The last example" })
|
17
42
|
|
18
43
|
sub2.sub( :'sub-commands', "Endless Sub-Sub- ...") do |sub3|
|
19
|
-
|
44
|
+
sub3.cmd( :help, "") {|*args| STDERR.puts sub3.help( sub3, *args) }
|
20
45
|
sub3.cmd( :hehe, "The real last example", min: 2) { STDERR.puts "Trust me!" }
|
21
46
|
end
|
22
47
|
end
|
23
48
|
end
|
24
49
|
|
25
|
-
|
50
|
+
begin
|
51
|
+
cli.call *ARGV
|
52
|
+
rescue DenCli::UsageError
|
53
|
+
STDERR.puts $!
|
54
|
+
exit 1
|
55
|
+
end
|
data/lib/dencli/cmd.rb
CHANGED
@@ -1,30 +1,214 @@
|
|
1
1
|
require_relative '../dencli'
|
2
2
|
|
3
|
+
|
3
4
|
class DenCli::CMD
|
4
|
-
attr_reader :parent, :name, :
|
5
|
+
attr_reader :parent, :name, :description, :exe, :completion, :options
|
5
6
|
|
6
|
-
def initialize parent, name,
|
7
|
+
def initialize parent, name, description, exe
|
7
8
|
raise "Proc expected, instead of: #{exe.inspect}" unless Proc === exe
|
8
|
-
@parent, @name, @
|
9
|
+
@parent, @name, @description, @exe = parent, name, description, lambda( &exe)
|
10
|
+
@options = {}
|
9
11
|
completion {|*a| [] }
|
10
12
|
end
|
11
13
|
|
12
14
|
def _full_cmd( post) parent._full_cmd [@name]+post end
|
13
15
|
def full_cmd() _full_cmd [] end
|
14
|
-
def call( *a) @exe.call *a end
|
15
|
-
def help() "#{parent.full_cmd.join ' '} #{name}\n#{ desc}" end
|
16
16
|
|
17
|
-
def
|
17
|
+
def parameters() @exe.parameters end
|
18
|
+
def arguments_required() @exe.parameters.select {|e| :req == e[0] }.map {|e| e[1] } end
|
19
|
+
alias required arguments_required
|
20
|
+
def arguments_additional() @exe.parameters.select {|e| :opt == e[0] }.map {|e| e[1] } end
|
21
|
+
alias additional arguments_additional
|
22
|
+
def arguments() @exe.parameters.select {|e| :req == e[0] or :opt == e[0] }.map {|e| e[1] } end
|
23
|
+
def options_required() @exe.parameters.select {|e| :keyreq == e[0] }.map {|e| e[1] } end
|
24
|
+
def options_additional() @exe.parameters.select {|e| :key == e[0] }.map {|e| e[1] } end
|
25
|
+
|
26
|
+
def complete *pre, str
|
27
|
+
@completion.call *pre, str
|
28
|
+
end
|
29
|
+
|
30
|
+
def call *as
|
31
|
+
os = {}
|
32
|
+
unless @options.empty?
|
33
|
+
# options like --abc | -x will be provided in os
|
34
|
+
options = OptionParser.new
|
35
|
+
options.banner = "#{full_cmd.join ' '}"
|
36
|
+
# see also @options-array
|
37
|
+
@options.each {|_, opt| opt.on options, os }
|
38
|
+
as = options.parse! as
|
39
|
+
end
|
40
|
+
if @exe.lambda?
|
41
|
+
# The difference between a lambda and a Proc is, that Proc has anytime arity=-1.
|
42
|
+
# There will be no check if all arguments are given or some were missing or more than expected.
|
43
|
+
# lambda checks these arguments and has a arity.
|
44
|
+
# We will check it to provide useful errors.
|
45
|
+
pars = required
|
46
|
+
if as.length < pars.length
|
47
|
+
raise DenCli::UsageError, "Missing parameter(s): #{pars[as.length..-1].join " "}"
|
48
|
+
end
|
49
|
+
if parameters.select {|e| :rest == e[0] }.empty?
|
50
|
+
pars = pars + additional
|
51
|
+
if as.length > pars.length
|
52
|
+
raise DenCli::UsageError, "Unused parameter(s): #{as[-pars.length..-1].shelljoin}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
kr = @options.select {|_, o| o.required? and not os.has_key? o.name }
|
56
|
+
unless kr.empty?
|
57
|
+
raise DenCli::UsageError, "Missing argument(s): #{kr.map {|o| o.long || o.short }.join ', '}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
@exe.call *as, **os
|
61
|
+
end
|
62
|
+
|
63
|
+
def usage output: nil
|
64
|
+
output ||= ''
|
65
|
+
_usage output
|
66
|
+
output
|
67
|
+
end
|
68
|
+
|
69
|
+
def _usage output
|
70
|
+
output << full_cmd.join( ' ')
|
71
|
+
@options.each do |_, o|
|
72
|
+
s = "#{o.short||o.long}#{o.val ? ?= : ''}#{o.val}"
|
73
|
+
output << (o.required? ? " #{s}" : " [#{s}]")
|
74
|
+
end
|
75
|
+
if @exe.lambda?
|
76
|
+
required.each {|s| output << " <#{s}>" }
|
77
|
+
output << " [#{additional.map{|s|"<#{s}>"}.join " "}]" unless additional.empty?
|
78
|
+
else
|
79
|
+
output << ' ...'
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def commands *args, &exe
|
84
|
+
yield self
|
85
|
+
end
|
86
|
+
|
87
|
+
def goto *args
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
def help output: nil
|
92
|
+
output ||= ''
|
93
|
+
_help output
|
94
|
+
output
|
95
|
+
end
|
96
|
+
|
97
|
+
def _help output
|
98
|
+
output << "Usage: #{usage}\n#{description}\n"
|
99
|
+
_help_options output
|
100
|
+
end
|
101
|
+
|
102
|
+
def help_options output: nil
|
103
|
+
output ||= ''
|
104
|
+
_help_options output
|
105
|
+
output
|
106
|
+
end
|
107
|
+
|
108
|
+
def _help_options output
|
109
|
+
sc, lc, dc = 0, 0, 0
|
110
|
+
@options.each do |_, o|
|
111
|
+
s = o.short&.length || 0
|
112
|
+
l = o.long&.length || 0
|
113
|
+
v = o.val&.length || 0
|
114
|
+
d = o.desc&.to_s&.length || 0
|
115
|
+
d += 3 + o.default.to_s.length if o.default?
|
116
|
+
if 0 == l
|
117
|
+
x = s + (0==v ? 0 : 1+v)
|
118
|
+
sc = x if sc < x
|
119
|
+
else
|
120
|
+
sc = s if sc < s
|
121
|
+
x = l + (0==v ? 0 : 1+v)
|
122
|
+
lc = x if lc < x
|
123
|
+
end
|
124
|
+
dc = d if dc < d
|
125
|
+
end
|
126
|
+
format = " %-#{sc}s%s %-#{lc}s %s\n"
|
127
|
+
@options.map do |_, o|
|
128
|
+
s, l, v, y = o.short, o.long, o.val, ','
|
129
|
+
if l.nil?
|
130
|
+
s += "=#{v}" if v
|
131
|
+
y = ' '
|
132
|
+
elsif s.nil?
|
133
|
+
l += "=#{v}" if v
|
134
|
+
y = ' '
|
135
|
+
end
|
136
|
+
d = o.desc || ''
|
137
|
+
d += " (#{o.default})" if o.default?
|
138
|
+
output << format % [ s, y, l, d ]
|
139
|
+
end
|
140
|
+
end
|
18
141
|
|
19
142
|
def completion &exe
|
20
143
|
@completion = exe
|
21
144
|
self
|
22
145
|
end
|
23
146
|
|
147
|
+
class Opt
|
148
|
+
attr_reader :name, :long, :short, :val, :desc, :os, :conv, :req
|
149
|
+
def required?() @req end
|
150
|
+
def default?() NilClass != @default end
|
151
|
+
def default() NilClass == @default ? nil : @default end
|
152
|
+
|
153
|
+
def parse_opt_string opt
|
154
|
+
case opt
|
155
|
+
when /\A(--\[no-\][^=]+)\z/
|
156
|
+
@long, @val = $1, nil
|
157
|
+
when /\A(--[^=]+)=(.+)\z/
|
158
|
+
@long, @val = $1, $2 || @val
|
159
|
+
when /\A(--[^=]+)\z/
|
160
|
+
@long, @val = $1, nil
|
161
|
+
when /\A(-[^=-]+)=(.+)\z/
|
162
|
+
@short, @val = $1, $2 || @val
|
163
|
+
when /\A(-[^=-]+)\z/
|
164
|
+
@short, @val = $1, nil
|
165
|
+
else
|
166
|
+
raise ArgumentError, "Unexpected format for option: #{opt.inspect}"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
private :parse_opt_string
|
170
|
+
|
171
|
+
def initialize cmd, name, opt, *alts, desc, default: NilClass, **os, &conv
|
172
|
+
@name, @desc, @default, @os, @conv, @val =
|
173
|
+
name.to_s.to_sym, desc, default, os, conv || lambda{|v|v}, nil
|
174
|
+
parse_opt_string opt
|
175
|
+
alts.each &method( :parse_opt_string)
|
176
|
+
@req =
|
177
|
+
if NilClass != default
|
178
|
+
false
|
179
|
+
elsif cmd.exe.lambda?
|
180
|
+
! cmd.exe.parameters.select {|e| [:keyreq, @name] == e[0..1] }.empty?
|
181
|
+
else
|
182
|
+
nil
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def on parser, store
|
187
|
+
store[@name] = @default if default?
|
188
|
+
parser.on "#{@short}#{@val ? ?= : ''}#{@val}", "#{@long}#{@val ? ?= : ''}#{@val}", **@os do |val|
|
189
|
+
store[@name] = @conv[val]
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def inspect
|
194
|
+
"#<%s:0x%016x %s %s %s %s (%p) %p os=%p conv=%s>" % [
|
195
|
+
self.class.name, object_id, @req ? "<#{@name}>" : "[#{@name}]",
|
196
|
+
@short, @long, @val, @default, @desc, @os,
|
197
|
+
@exe ? "<#{@exe.lambda? ? :lambda: :proc} ##{@exe.arity}>" : "nil"
|
198
|
+
]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def opt name, opt, *alts, desc, **os, &conv
|
203
|
+
r = Opt.new( self, name, opt, *alts, desc, **os, &conv)
|
204
|
+
@options[r.name] = r
|
205
|
+
self
|
206
|
+
end
|
207
|
+
|
24
208
|
def inspect
|
25
|
-
"#<%s:0x%x %s @name=%p @
|
209
|
+
"#<%s:0x%x %s @name=%p @description=%p @parent=<%s:0x%x %s> @exe=<arity=%d>>" % [
|
26
210
|
self.class.name, self.object_id, self.full_cmd,
|
27
|
-
@name, @
|
211
|
+
@name, @description, @parent.class.name, @parent.class.object_id, @parent.full_cmd,
|
28
212
|
@exe.arity
|
29
213
|
]
|
30
214
|
end
|
data/lib/dencli/interactive.rb
CHANGED
@@ -90,7 +90,7 @@ class DenCli::Interactive
|
|
90
90
|
c.subs.values.each do |n|
|
91
91
|
case n
|
92
92
|
when DenCli::Sub
|
93
|
-
n.cmd :exit, "<- #{n.parent.full_cmd.join ' '} - #{n.parent.
|
93
|
+
n.cmd :exit, "<- #{n.parent.full_cmd.join ' '} - #{n.parent.description[3..-1]}", min: 2 do
|
94
94
|
@cur = n.parent
|
95
95
|
end
|
96
96
|
n.cmd '', "", min: 2, aliases: [nil] do
|
data/lib/dencli/sub.rb
CHANGED
@@ -1,26 +1,86 @@
|
|
1
1
|
require_relative '../dencli'
|
2
2
|
|
3
3
|
class DenCli::Sub
|
4
|
-
attr_reader :parent, :name, :
|
4
|
+
attr_reader :parent, :name, :description, :subs, :aliases
|
5
5
|
|
6
|
-
def initialize parent, name,
|
7
|
-
@parent, @name, @
|
6
|
+
def initialize parent, name, description
|
7
|
+
@parent, @name, @description, @subs, @aliases = parent, name, "-> #{description}", {}, {}
|
8
8
|
end
|
9
9
|
|
10
10
|
def _full_cmd( post) parent._full_cmd [@name]+post end
|
11
11
|
def full_cmd() _full_cmd [] end
|
12
12
|
def []( k) @aliases[k] end
|
13
13
|
|
14
|
-
def
|
14
|
+
def usage
|
15
|
+
"#{full_cmd.join ' '} ..."
|
16
|
+
end
|
17
|
+
|
18
|
+
def help n = nil, *a, output: nil
|
19
|
+
output ||= ''
|
20
|
+
_help output, n, *a
|
21
|
+
output
|
22
|
+
end
|
23
|
+
|
24
|
+
def _help output, n = nil, *a
|
15
25
|
if n.nil?
|
16
|
-
|
17
|
-
|
18
|
-
@subs.each do |k, c|
|
19
|
-
r += " % -#{m}s %s\n" % [k, c.desc] unless k.nil?
|
20
|
-
end
|
21
|
-
r
|
26
|
+
output << "#{full_cmd.join ' '}: #{description}\n\n"
|
27
|
+
self.class._help_commands output, @subs
|
22
28
|
elsif @aliases.has_key? n
|
23
|
-
@aliases[n].
|
29
|
+
@aliases[n]._help output, *a
|
30
|
+
else
|
31
|
+
raise DenCli::UnknownCommand, "unknown command: #{_full_cmd( [n])[1..-1].join ' '}, available for #{full_cmd[1..-1].join' '}: #{@subs.keys.join ' '}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def commands &exe
|
36
|
+
yield self
|
37
|
+
@subs.each {|k, c| c.commands &exe }
|
38
|
+
end
|
39
|
+
|
40
|
+
def help_commands output: nil
|
41
|
+
output ||= ''
|
42
|
+
self.class._help_commands output, subs.map {|_,c| c}
|
43
|
+
output
|
44
|
+
end
|
45
|
+
|
46
|
+
def self._help_commands output, subs
|
47
|
+
m = subs.map {|c| x = c.usage.length; 25 < x ? 0 : x }.max
|
48
|
+
subs.each do |c|
|
49
|
+
if 25 < c.usage.length
|
50
|
+
output << "% -#{m}s\n#{' ' * m} " % [c.usage]
|
51
|
+
else
|
52
|
+
output << "% -#{m}s " % [c.usage]
|
53
|
+
end
|
54
|
+
n = m+2
|
55
|
+
prefix = nil
|
56
|
+
c.description.split /\n/ do |l|
|
57
|
+
c = 0
|
58
|
+
l.split %r< > do |w|
|
59
|
+
if prefix
|
60
|
+
output << prefix
|
61
|
+
prefix = nil
|
62
|
+
end
|
63
|
+
wl = w.length
|
64
|
+
if 75 < c+wl
|
65
|
+
output << "\n#{' ' * n}#{w}"
|
66
|
+
c = n+2+wl
|
67
|
+
else
|
68
|
+
output << " #{w}"
|
69
|
+
c += 1 + wl
|
70
|
+
end
|
71
|
+
end
|
72
|
+
prefix = "\n#{' ' * n}"
|
73
|
+
end
|
74
|
+
output << "\n"
|
75
|
+
end
|
76
|
+
output
|
77
|
+
end
|
78
|
+
|
79
|
+
def goto *a
|
80
|
+
return self if a.empty?
|
81
|
+
n, *a = *a
|
82
|
+
if @aliases.has_key? n
|
83
|
+
@aliases[n].goto *a
|
24
84
|
else
|
25
85
|
raise DenCli::UnknownCommand, "unknown command: #{_full_cmd( [n])[1..-1].join ' '}, available for #{full_cmd[1..-1].join' '}: #{@subs.keys.join ' '}"
|
26
86
|
end
|
@@ -46,13 +106,13 @@ class DenCli::Sub
|
|
46
106
|
end
|
47
107
|
private :_add
|
48
108
|
|
49
|
-
def sub name,
|
50
|
-
r = _add name, min, DenCli::Sub.new( self, name,
|
109
|
+
def sub name, description, min: nil, aliases: nil, &exe
|
110
|
+
r = _add name, min, DenCli::Sub.new( self, name, description), aliases
|
51
111
|
block_given? ? yield( r) : r
|
52
112
|
end
|
53
113
|
|
54
|
-
def cmd name,
|
55
|
-
_add name, min, DenCli::CMD.new( self, name,
|
114
|
+
def cmd name, description, min: nil, aliases: nil, &exe
|
115
|
+
_add name, min, DenCli::CMD.new( self, name, description, exe), aliases
|
56
116
|
end
|
57
117
|
|
58
118
|
def complete *pre, str
|
@@ -66,9 +126,9 @@ class DenCli::Sub
|
|
66
126
|
end
|
67
127
|
|
68
128
|
def inspect
|
69
|
-
"#<%s:0x%x %s @name=%p @
|
129
|
+
"#<%s:0x%x %s @name=%p @description=%p @subs={%s} @aliases={%s} @parent=<%s:0x%x %s>>" % [
|
70
130
|
self.class.name, self.object_id, self.full_cmd,
|
71
|
-
@name, @
|
131
|
+
@name, @description, @subs.keys.join(', '), @aliases.keys.join(', '), @parent.class.name, @parent.class.object_id, @parent.full_cmd
|
72
132
|
]
|
73
133
|
end
|
74
134
|
end
|
data/lib/dencli/version.rb
CHANGED
data/lib/dencli.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
1
3
|
class DenCli
|
2
4
|
class UsageError < ::RuntimeError
|
3
5
|
end
|
@@ -54,8 +56,8 @@ class DenCli
|
|
54
56
|
|
55
57
|
attr_reader :subs
|
56
58
|
|
57
|
-
def initialize progname,
|
58
|
-
@subs = Sub.new self, progname,
|
59
|
+
def initialize progname, description
|
60
|
+
@subs = Sub.new self, progname, description
|
59
61
|
end
|
60
62
|
|
61
63
|
def full_cmd
|
@@ -66,20 +68,34 @@ class DenCli
|
|
66
68
|
post
|
67
69
|
end
|
68
70
|
|
69
|
-
def sub *a, &exe
|
70
|
-
@subs.sub *a, &exe
|
71
|
+
def sub *a, **o, &exe
|
72
|
+
@subs.sub *a, **o, &exe
|
71
73
|
end
|
72
74
|
|
73
|
-
def cmd *a, &exe
|
74
|
-
@subs.cmd *a, &exe
|
75
|
+
def cmd *a, **o, &exe
|
76
|
+
@subs.cmd *a, **o, &exe
|
75
77
|
end
|
76
78
|
|
77
79
|
def call *a
|
78
80
|
@subs.call *a
|
79
81
|
end
|
80
82
|
|
81
|
-
def
|
82
|
-
@subs.
|
83
|
+
def usage *args, **opts
|
84
|
+
@subs.usage *args, **opts
|
85
|
+
end
|
86
|
+
|
87
|
+
def help *args, **opts
|
88
|
+
@subs.help *args, **opts
|
89
|
+
end
|
90
|
+
|
91
|
+
def help_full *args, output: nil
|
92
|
+
output ||= STDOUT
|
93
|
+
x = @subs.goto *args
|
94
|
+
_help_full output, x
|
95
|
+
end
|
96
|
+
|
97
|
+
def _help_full output, subs
|
98
|
+
Sub._help_commands output, subs.to_enum( :commands)
|
83
99
|
end
|
84
100
|
|
85
101
|
def [] k
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dencli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Knauf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|