dencli 0.4.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 127668bd8bd4de7dc572ce5c72be6403ca49e9da7690ceb7746c913a497495c3
4
- data.tar.gz: b28f1e67d5c029df9917f6f9609a8d0c718c8a6cda35a0cf1a283cf37a925adb
3
+ metadata.gz: b59309b03abb2d1a44eda112c289335eed1a252bccd89404a4e5017ff876657f
4
+ data.tar.gz: 0ecfaff2dd2928bfdc134ee3dc92737ae2776737e6ada66fd1432de5b470ab76
5
5
  SHA512:
6
- metadata.gz: e5fce26cb4eae5698536a1c1ffbae0571783432acef83451477daf259ee6aed1699542f4a93909c1bc3ac25095b3153a1381f32efa827f489cb3885cba557e7d
7
- data.tar.gz: 8b22f6c8dfdd91fef4ce45819377ac5773e82a01ca168624dbff789d942cb32dec2677de396574198f7643f20f4401a32955239e67b621ecdebf5eb8847f854f
6
+ metadata.gz: d27d7f9d307e1e86684ebb7e771ff865d0d10e4cde501951947997e98d25aafff123826c1973e7615ab45edd7c2bd3d60eacefa56835eacd976a4e9a9f4ed2d8
7
+ data.tar.gz: 70f63e628dcd9b7c2cc8da2302ef0dc33a170efc6281173c05f31b09657c0f4b616cd71faaa3ea09738e629b021e51e6018fda33535d2d34d8570caa0db32acc
data/bin/example.rb CHANGED
@@ -5,15 +5,23 @@ $:.unshift Pathname.new(__FILE__).dirname.dirname.join('lib').to_s
5
5
  require 'dencli'
6
6
 
7
7
  cli = DenCli.new 'example', "This is an example for generate a DenCli-API"
8
- cli.cmd( :example, "I have an example command") { STDERR.puts "This is an example" }
9
- cli.cmd( :help, "", aliases: [nil, '-h', '--help']) {|*args| STDERR.puts cli.help(*args) }
10
-
11
8
  cli.cmd( :args, "Expects and prints given arguments", &lambda {|a, b, c:, d:, e:|
12
9
  p a: a, b: b, c: c, d: d, e: e
13
10
  }).
14
11
  opt( :c, '-c=ForC', "Option c").
15
12
  opt( :d, '-d=ForD', "Option d", default: "something").
16
- opt( :e, '-e', "Toggle e", default: false)
13
+ opt( :e, '-e', "Toggle e", default: false).
14
+ opt( :f, '--[no-]f', "Toggle f", default: false)
15
+
16
+ cli.cmd( :example, "I have an example command") { STDERR.puts "This is an example" }
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)
17
25
 
18
26
  cli.sub( :more, "Sub-Commands are also possible with a new cli") do |sub|
19
27
  sub.cmd( :help, "", aliases: [nil, '-h', '--help']) {|*args| STDERR.puts sub.help(*args) }
@@ -29,7 +37,7 @@ cli.sub( :more, "Sub-Commands are also possible with a new cli") do |sub|
29
37
  opt( :e, '-e', "Toggle e")
30
38
 
31
39
  sub.sub( :deeper, "You want to have Sub-Sub-Commands?") do |sub2|
32
- sub2.cmd( :help, "", aliases: [nil, '-h', '--help'], &lambda {|*args| STDERR.puts sub2.help(*args) })
40
+ sub2.cmd( :help, "", aliases: [nil, '-h', '--help'], &lambda {|*args| sub2.help( *args, output: STDERR) })
33
41
  sub2.cmd( :last, "The last example", &lambda { STDERR.puts "The last example" })
34
42
 
35
43
  sub2.sub( :'sub-commands', "Endless Sub-Sub- ...") do |sub3|
data/lib/dencli/cmd.rb CHANGED
@@ -23,10 +23,11 @@ class DenCli::CMD
23
23
  def options_required() @exe.parameters.select {|e| :keyreq == e[0] }.map {|e| e[1] } end
24
24
  def options_additional() @exe.parameters.select {|e| :key == e[0] }.map {|e| e[1] } end
25
25
 
26
- def help() "Usage: #{usage}\n#{description}\n#{options_help}" end
27
- def complete( *pre, str) @completion.call *pre, str end
26
+ def complete *pre, str
27
+ @completion.call *pre, str
28
+ end
28
29
 
29
- def call( *as)
30
+ def call *as
30
31
  os = {}
31
32
  unless @options.empty?
32
33
  # options like --abc | -x will be provided in os
@@ -53,25 +54,58 @@ class DenCli::CMD
53
54
  end
54
55
  kr = @options.select {|_, o| o.required? and not os.has_key? o.name }
55
56
  unless kr.empty?
56
- raise DenCli::UsageError, "Missing argument(s): #{kr.map {|o| o.as.first }.join ', '}"
57
+ raise DenCli::UsageError, "Missing argument(s): #{kr.map {|o| o.long || o.short }.join ', '}"
57
58
  end
58
59
  end
59
60
  @exe.call *as, **os
60
61
  end
61
62
 
62
- def usage
63
- args =
64
- @options.map do |_, o|
65
- s = "#{o.short}#{o.val ? ?= : ''}#{o.val}"; o.required? ? "#{s} " : "[#{s}] "
66
- end
67
- "#{full_cmd.join ' '} #{args.join ''}"+
68
- (@exe.lambda? ? (
69
- required.map{|s|"<#{s}>"}.join( " ")+
70
- (additional.empty? ? "" : " [#{additional.map{|s|"<#{s}>"}.join " "}]")
71
- ) : '...')
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
72
85
  end
73
86
 
74
- def options_help
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
75
109
  sc, lc, dc = 0, 0, 0
76
110
  @options.each do |_, o|
77
111
  s = o.short&.length || 0
@@ -89,8 +123,8 @@ class DenCli::CMD
89
123
  end
90
124
  dc = d if dc < d
91
125
  end
92
- format = " %-#{sc}s%s %-#{lc}s %s"
93
- @options.map {|_, o|
126
+ format = " %-#{sc}s%s %-#{lc}s %s\n"
127
+ @options.map do |_, o|
94
128
  s, l, v, y = o.short, o.long, o.val, ','
95
129
  if l.nil?
96
130
  s += "=#{v}" if v
@@ -101,8 +135,8 @@ class DenCli::CMD
101
135
  end
102
136
  d = o.desc || ''
103
137
  d += " (#{o.default})" if o.default?
104
- format % [ s, y, l, d ]
105
- }.join "\n"
138
+ output << format % [ s, y, l, d ]
139
+ end
106
140
  end
107
141
 
108
142
  def completion &exe
@@ -116,34 +150,29 @@ class DenCli::CMD
116
150
  def default?() NilClass != @default end
117
151
  def default() NilClass == @default ? nil : @default end
118
152
 
119
- def initialize cmd, name, opt, *alts, desc, default: NilClass, **os, &conv
120
- long = short = val = nil
153
+ def parse_opt_string opt
121
154
  case opt
122
- when /\A(--[^=-]+)=(.+)\z/
123
- long, val = $1, $2
124
- when /\A(--[^=-]+)\z/
125
- long, val = $1, nil
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
126
161
  when /\A(-[^=-]+)=(.+)\z/
127
- short, val = $1, $2
162
+ @short, @val = $1, $2 || @val
128
163
  when /\A(-[^=-]+)\z/
129
- short, val = $1, nil
130
- else raise ArgumentError, "Unexpected format for option: #{opt.inspect}"
131
- end
132
- alts.each do |alt|
133
- case alt
134
- when /\A(--[^=-]+)=(.+)\z/
135
- long, val = $1, val || $2
136
- when /\A(--[^=-]+)\z/
137
- long, val = $1, nil
138
- when /\A(-[^=-]+)=(.+)\z/
139
- short, val = $1, val || $2
140
- when /\A(-[^=-]+)\z/
141
- short, val = $1, nil
142
- else raise ArgumentError, "Unexpected format for option: #{alt.inspect}"
143
- end
164
+ @short, @val = $1, nil
165
+ else
166
+ raise ArgumentError, "Unexpected format for option: #{opt.inspect}"
144
167
  end
145
- @name, @short, @long, @val, @desc, @default, @os, @conv =
146
- name.to_s.to_sym, short, long, val, desc, default, os, conv || lambda{|v|v}
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)
147
176
  @req =
148
177
  if NilClass != default
149
178
  false
@@ -155,6 +184,7 @@ class DenCli::CMD
155
184
  end
156
185
 
157
186
  def on parser, store
187
+ store[@name] = @default if default?
158
188
  parser.on "#{@short}#{@val ? ?= : ''}#{@val}", "#{@long}#{@val ? ?= : ''}#{@val}", **@os do |val|
159
189
  store[@name] = @conv[val]
160
190
  end
data/lib/dencli/sub.rb CHANGED
@@ -15,16 +15,72 @@ class DenCli::Sub
15
15
  "#{full_cmd.join ' '} ..."
16
16
  end
17
17
 
18
- def help n = nil, *a
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
19
25
  if n.nil?
20
- r = "#{full_cmd.join ' '}: #{description}\n\n"
21
- m = @subs.map {|k,c| k.nil? ? 0 : c.usage.length }.max
22
- @subs.each do |k, c|
23
- r += " % -#{m}s %s\n" % [c.usage, c.description] unless k.nil?
24
- end
25
- r
26
+ output << "#{full_cmd.join ' '}: #{description}\n\n"
27
+ self.class._help_commands output, @subs
26
28
  elsif @aliases.has_key? n
27
- @aliases[n].help *a
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
28
84
  else
29
85
  raise DenCli::UnknownCommand, "unknown command: #{_full_cmd( [n])[1..-1].join ' '}, available for #{full_cmd[1..-1].join' '}: #{@subs.keys.join ' '}"
30
86
  end
@@ -1,3 +1,3 @@
1
1
  class DenCli
2
- VERSION = '0.4.0'
2
+ VERSION = '0.5.0'
3
3
  end
data/lib/dencli.rb CHANGED
@@ -80,8 +80,22 @@ class DenCli
80
80
  @subs.call *a
81
81
  end
82
82
 
83
- def help *args
84
- @subs.help *args
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)
85
99
  end
86
100
 
87
101
  def [] k
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dencli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Knauf