dencli 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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