dencli 0.5.0 → 0.5.4
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 +11 -8
- data/lib/dencli/cmd.rb +26 -15
- data/lib/dencli/sub.rb +50 -30
- data/lib/dencli/version.rb +1 -1
- data/lib/dencli.rb +7 -0
- 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: 71cb3a66fe8101078796ec7dfb0c793d315416020c76e11f2b312c32f6d3c1b2
|
4
|
+
data.tar.gz: 1675ca2b4f22fc083948bec274aa75c067e41622dc3d65059a9b200a86d21e0e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 938480ac26fa9cbac07118edfa407b1a59d2e9534b43fdd308bf4e81a96e78a20fc2b3d3143029d6a8b1f516ebbd14af7507ae703e395d46ad4abfdbd3b42844
|
7
|
+
data.tar.gz: af52e24ace634da494e17b5efa06bdc475fa64d9250218d38b1c60ee7d4b9897cfdce6cf6cf54f141acca8ec836140a2ad368ac27ceb0bbd2b1cdf1c3b43598a
|
data/bin/example.rb
CHANGED
@@ -4,21 +4,24 @@ require 'pathname'
|
|
4
4
|
$:.unshift Pathname.new(__FILE__).dirname.dirname.join('lib').to_s
|
5
5
|
require 'dencli'
|
6
6
|
|
7
|
-
cli = DenCli.new
|
8
|
-
cli.cmd( :args, "Expects and prints given arguments",
|
7
|
+
cli = DenCli.new :example, "This is an example for generate a DenCli-API"
|
8
|
+
cli.cmd( :args, "Expects and prints given arguments",
|
9
|
+
&lambda {|a, b, c:, d:, e:, f:, g:|
|
9
10
|
p a: a, b: b, c: c, d: d, e: e
|
10
11
|
}).
|
11
12
|
opt( :c, '-c=ForC', "Option c").
|
12
|
-
opt( :d, '-
|
13
|
+
opt( :d, '-dForD', "Option d", default: "something").
|
13
14
|
opt( :e, '-e', "Toggle e", default: false).
|
14
|
-
opt( :f, '--[no-]f', "Toggle f", default: false)
|
15
|
+
opt( :f, '--[no-]f', "Toggle f", default: false).
|
16
|
+
opt( :g, '--long-option=sth', "Long option, no short option", default: "nothing").
|
17
|
+
opt( :h, '-hsth', "No long option, only short option", default: "nothing")
|
15
18
|
|
16
19
|
cli.cmd( :example, "I have an example command") { STDERR.puts "This is an example" }
|
17
|
-
cli.cmd( :help, "", aliases: [nil, '-h', '--help'], &lambda {|*
|
20
|
+
cli.cmd( :help, "An example for help", aliases: [nil, '-h', '--help'], &lambda {|*commands, full:|
|
18
21
|
if full
|
19
|
-
cli.help_full *
|
22
|
+
cli.help_full *commands, output: STDERR
|
20
23
|
else
|
21
|
-
cli.help *
|
24
|
+
cli.help *commands, output: STDERR
|
22
25
|
end
|
23
26
|
}).
|
24
27
|
opt( :full, '-f', '--[no-]full', "Print all commands and sub-commands.", default: false)
|
@@ -37,7 +40,7 @@ cli.sub( :more, "Sub-Commands are also possible with a new cli") do |sub|
|
|
37
40
|
opt( :e, '-e', "Toggle e")
|
38
41
|
|
39
42
|
sub.sub( :deeper, "You want to have Sub-Sub-Commands?") do |sub2|
|
40
|
-
sub2.cmd( :help, "", aliases: [nil, '-h', '--help'], &lambda {|*
|
43
|
+
sub2.cmd( :help, "", aliases: [nil, '-h', '--help'], &lambda {|*commands| sub2.help( *commands, output: STDERR) })
|
41
44
|
sub2.cmd( :last, "The last example", &lambda { STDERR.puts "The last example" })
|
42
45
|
|
43
46
|
sub2.sub( :'sub-commands', "Endless Sub-Sub- ...") do |sub3|
|
data/lib/dencli/cmd.rb
CHANGED
@@ -7,6 +7,12 @@ class DenCli::CMD
|
|
7
7
|
def initialize parent, name, description, exe
|
8
8
|
raise "Proc expected, instead of: #{exe.inspect}" unless Proc === exe
|
9
9
|
@parent, @name, @description, @exe = parent, name, description, lambda( &exe)
|
10
|
+
@parameters = @exe.parameters
|
11
|
+
@arguments_required = @exe.parameters.select {|e| :req == e[0] }.map {|e| e[1] }
|
12
|
+
@arguments_additional = @exe.parameters.select {|e| :opt == e[0] }.map {|e| e[1] }
|
13
|
+
@arguments = @exe.parameters.select {|e| :req == e[0] or :opt == e[0] }.map {|e| e[1] }
|
14
|
+
@options_required = @exe.parameters.select {|e| :keyreq == e[0] }.map {|e| e[1] }
|
15
|
+
@options_additional = @exe.parameters.select {|e| :key == e[0] }.map {|e| e[1] }
|
10
16
|
@options = {}
|
11
17
|
completion {|*a| [] }
|
12
18
|
end
|
@@ -14,14 +20,11 @@ class DenCli::CMD
|
|
14
20
|
def _full_cmd( post) parent._full_cmd [@name]+post end
|
15
21
|
def full_cmd() _full_cmd [] end
|
16
22
|
|
17
|
-
|
18
|
-
|
23
|
+
attr_reader :parameters,
|
24
|
+
:arguments_required, :arguments_additional, :arguments,
|
25
|
+
:options_required, :options_additional
|
19
26
|
alias required arguments_required
|
20
|
-
def arguments_additional() @exe.parameters.select {|e| :opt == e[0] }.map {|e| e[1] } end
|
21
27
|
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
28
|
|
26
29
|
def complete *pre, str
|
27
30
|
@completion.call *pre, str
|
@@ -54,7 +57,7 @@ class DenCli::CMD
|
|
54
57
|
end
|
55
58
|
kr = @options.select {|_, o| o.required? and not os.has_key? o.name }
|
56
59
|
unless kr.empty?
|
57
|
-
raise DenCli::UsageError, "Missing argument(s): #{kr.map {|o| o.long || o.short }.join ', '}"
|
60
|
+
raise DenCli::UsageError, "Missing argument(s): #{kr.map {|_, o| o.long || o.short }.join ', '}"
|
58
61
|
end
|
59
62
|
end
|
60
63
|
@exe.call *as, **os
|
@@ -69,19 +72,27 @@ class DenCli::CMD
|
|
69
72
|
def _usage output
|
70
73
|
output << full_cmd.join( ' ')
|
71
74
|
@options.each do |_, o|
|
72
|
-
s = "#{o.short||o.long}#{o.val ? ?= : ''}#{o.val}"
|
75
|
+
s = "#{o.short||o.long}#{(!o.short && o.val) ? ?= : ''}#{o.val}"
|
73
76
|
output << (o.required? ? " #{s}" : " [#{s}]")
|
74
77
|
end
|
75
78
|
if @exe.lambda?
|
76
|
-
|
77
|
-
|
79
|
+
parameters.each do |(type, name)|
|
80
|
+
case type
|
81
|
+
when :req
|
82
|
+
output << " <#{name}>"
|
83
|
+
when :opt
|
84
|
+
output << " [<#{name}>]"
|
85
|
+
when :rest
|
86
|
+
output << " [<#{name}> ...]"
|
87
|
+
end
|
88
|
+
end
|
78
89
|
else
|
79
90
|
output << ' ...'
|
80
91
|
end
|
81
92
|
end
|
82
93
|
|
83
|
-
def commands *args
|
84
|
-
yield self
|
94
|
+
def commands *args
|
95
|
+
yield name, self
|
85
96
|
end
|
86
97
|
|
87
98
|
def goto *args
|
@@ -127,7 +138,7 @@ class DenCli::CMD
|
|
127
138
|
@options.map do |_, o|
|
128
139
|
s, l, v, y = o.short, o.long, o.val, ','
|
129
140
|
if l.nil?
|
130
|
-
s += "
|
141
|
+
s += "#{v}" if v
|
131
142
|
y = ' '
|
132
143
|
elsif s.nil?
|
133
144
|
l += "=#{v}" if v
|
@@ -158,9 +169,9 @@ class DenCli::CMD
|
|
158
169
|
@long, @val = $1, $2 || @val
|
159
170
|
when /\A(--[^=]+)\z/
|
160
171
|
@long, @val = $1, nil
|
161
|
-
when /\A(-[^=-]
|
172
|
+
when /\A(-[^=-])=?(.+)\z/
|
162
173
|
@short, @val = $1, $2 || @val
|
163
|
-
when /\A(-[^=-]
|
174
|
+
when /\A(-[^=-])\z/
|
164
175
|
@short, @val = $1, nil
|
165
176
|
else
|
166
177
|
raise ArgumentError, "Unexpected format for option: #{opt.inspect}"
|
data/lib/dencli/sub.rb
CHANGED
@@ -4,6 +4,9 @@ class DenCli::Sub
|
|
4
4
|
attr_reader :parent, :name, :description, :subs, :aliases
|
5
5
|
|
6
6
|
def initialize parent, name, description
|
7
|
+
#DenCli::assert_type self, __method__, :name, name, Symbol
|
8
|
+
#DenCli::assert_type self, __method__, :parent, parent, DenCli, DenCli::Sub
|
9
|
+
#DenCli::assert_type self, __method__, :description, description, String
|
7
10
|
@parent, @name, @description, @subs, @aliases = parent, name, "-> #{description}", {}, {}
|
8
11
|
end
|
9
12
|
|
@@ -11,8 +14,19 @@ class DenCli::Sub
|
|
11
14
|
def full_cmd() _full_cmd [] end
|
12
15
|
def []( k) @aliases[k] end
|
13
16
|
|
14
|
-
def usage
|
15
|
-
|
17
|
+
def usage output: nil
|
18
|
+
output ||= ''
|
19
|
+
_usage output
|
20
|
+
output
|
21
|
+
end
|
22
|
+
|
23
|
+
def _usage output
|
24
|
+
output << full_cmd.join( ' ')
|
25
|
+
if @aliases.has_key? nil
|
26
|
+
output << " [<command> ...]"
|
27
|
+
else
|
28
|
+
output << " <command> [...]"
|
29
|
+
end
|
16
30
|
end
|
17
31
|
|
18
32
|
def help n = nil, *a, output: nil
|
@@ -33,7 +47,7 @@ class DenCli::Sub
|
|
33
47
|
end
|
34
48
|
|
35
49
|
def commands &exe
|
36
|
-
yield self
|
50
|
+
yield name, self
|
37
51
|
@subs.each {|k, c| c.commands &exe }
|
38
52
|
end
|
39
53
|
|
@@ -43,37 +57,39 @@ class DenCli::Sub
|
|
43
57
|
output
|
44
58
|
end
|
45
59
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
c
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
60
|
+
class <<self
|
61
|
+
def _help_commands output, subs
|
62
|
+
m = subs.map {|_name,c| x = c.usage.length; 25 < x ? 0 : x }.max
|
63
|
+
subs.each do |_name, c|
|
64
|
+
if 25 < c.usage.length
|
65
|
+
output << "% -#{m}s\n#{' ' * m} " % [c.usage]
|
66
|
+
else
|
67
|
+
output << "% -#{m}s " % [c.usage]
|
68
|
+
end
|
69
|
+
n = m+2
|
70
|
+
prefix = nil
|
71
|
+
c.description.split( /\n/).each do |l|
|
72
|
+
c = 0
|
73
|
+
l.split( %r< >).each do |w|
|
74
|
+
if prefix
|
75
|
+
output << prefix
|
76
|
+
prefix = nil
|
77
|
+
end
|
78
|
+
wl = w.length
|
79
|
+
if 75 < c+wl
|
80
|
+
output << "\n#{' ' * n}#{w}"
|
81
|
+
c = n+2+wl
|
82
|
+
else
|
83
|
+
output << " #{w}"
|
84
|
+
c += 1 + wl
|
85
|
+
end
|
70
86
|
end
|
87
|
+
prefix = "\n#{' ' * n}"
|
71
88
|
end
|
72
|
-
|
89
|
+
output << "\n"
|
73
90
|
end
|
74
|
-
output
|
91
|
+
output
|
75
92
|
end
|
76
|
-
output
|
77
93
|
end
|
78
94
|
|
79
95
|
def goto *a
|
@@ -96,6 +112,10 @@ class DenCli::Sub
|
|
96
112
|
end
|
97
113
|
|
98
114
|
def _add name, min, obj, aliases
|
115
|
+
#DenCli::assert_type self, __method__, :name, name, Symbol, NilClass
|
116
|
+
#DenCli::assert_type self, __method__, :min, min, Integer, NilClass
|
117
|
+
#DenCli::assert_type self, __method__, :obj, obj, DenCli::Sub, DenCli::CMD
|
118
|
+
#DenCli::assert_type self, __method__, :aliases, aliases, Array, NilClass
|
99
119
|
name = name.to_s unless name.nil?
|
100
120
|
@subs[name] = obj
|
101
121
|
DenCli.gen_aliases( name, min) {|a| @aliases[a] = obj }
|
data/lib/dencli/version.rb
CHANGED
data/lib/dencli.rb
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
require 'optparse'
|
2
2
|
|
3
|
+
|
3
4
|
class DenCli
|
5
|
+
def self.assert_type klass, method, argument_name, object, *types
|
6
|
+
unless types.any? {|type| object.is_a? type }
|
7
|
+
raise ArgumentError, "#{klass.name}.#{method} expects #{types.map( &:to_s).join '|' } for #{argument_name}, not: #{object.inspect}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
4
11
|
class UsageError < ::RuntimeError
|
5
12
|
end
|
6
13
|
class UnknownCommand < UsageError
|
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.5.
|
4
|
+
version: 0.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Knauf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|