Class: DenCli::CMD

Inherits:
Object
  • Object
show all
Defined in:
lib/dencli/cmd.rb

Defined Under Namespace

Classes: Opt

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, name, description, exe, defined_in) ⇒ CMD

Returns a new instance of CMD.



7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/dencli/cmd.rb', line 7

def initialize parent, name, description, exe, defined_in
  raise "Proc expected, instead of: #{exe.inspect}"  unless Proc === exe
  @parent, @name, @description, @exe, @defined_in = parent, name, description, lambda( &exe), defined_in
  @parameters = @exe.parameters
  @arguments_required = @exe.parameters.select {|e| :req == e[0] }.map {|e| e[1] }
  @arguments_additional = @exe.parameters.select {|e| :opt == e[0] }.map {|e| e[1] }
  @arguments = @exe.parameters.select {|e| :req == e[0] or :opt == e[0] }.map {|e| e[1] }
  @options_required = @exe.parameters.select {|e| :keyreq == e[0] }.map {|e| e[1] }
  @options_additional = @exe.parameters.select {|e| :key == e[0] }.map {|e| e[1] }
  @options = {}
  completion {|*a| [] }
end

Instance Attribute Details

#argumentsObject (readonly)

Returns the value of attribute arguments.



23
24
25
# File 'lib/dencli/cmd.rb', line 23

def arguments
  @arguments
end

#arguments_additionalObject (readonly) Also known as: additional

Returns the value of attribute arguments_additional.



23
24
25
# File 'lib/dencli/cmd.rb', line 23

def arguments_additional
  @arguments_additional
end

#arguments_requiredObject (readonly) Also known as: required

Returns the value of attribute arguments_required.



23
24
25
# File 'lib/dencli/cmd.rb', line 23

def arguments_required
  @arguments_required
end

#completion(&exe) ⇒ Object (readonly)

Returns the value of attribute completion.



5
6
7
# File 'lib/dencli/cmd.rb', line 5

def completion
  @completion
end

#defined_inObject (readonly)

Returns the value of attribute defined_in.



5
6
7
# File 'lib/dencli/cmd.rb', line 5

def defined_in
  @defined_in
end

#descriptionObject (readonly)

Returns the value of attribute description.



5
6
7
# File 'lib/dencli/cmd.rb', line 5

def description
  @description
end

#exeObject (readonly)

Returns the value of attribute exe.



5
6
7
# File 'lib/dencli/cmd.rb', line 5

def exe
  @exe
end

#nameObject (readonly)

Returns the value of attribute name.



5
6
7
# File 'lib/dencli/cmd.rb', line 5

def name
  @name
end

#optionsObject (readonly)

Returns the value of attribute options.



5
6
7
# File 'lib/dencli/cmd.rb', line 5

def options
  @options
end

#options_additionalObject (readonly)

Returns the value of attribute options_additional.



23
24
25
# File 'lib/dencli/cmd.rb', line 23

def options_additional
  @options_additional
end

#options_requiredObject (readonly)

Returns the value of attribute options_required.



23
24
25
# File 'lib/dencli/cmd.rb', line 23

def options_required
  @options_required
end

#parametersObject (readonly)

Returns the value of attribute parameters.



23
24
25
# File 'lib/dencli/cmd.rb', line 23

def parameters
  @parameters
end

#parentObject (readonly)

Returns the value of attribute parent.



5
6
7
# File 'lib/dencli/cmd.rb', line 5

def parent
  @parent
end

Instance Method Details

#_full_cmd(post) ⇒ Object



20
# File 'lib/dencli/cmd.rb', line 20

def _full_cmd( post) parent._full_cmd [@name]+post end

#_help(output) ⇒ Object



112
113
114
115
# File 'lib/dencli/cmd.rb', line 112

def _help output
  output << "Usage: #{usage}\n#{description}\n"
  _help_options output
end

#_help_options(output) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/dencli/cmd.rb', line 123

def _help_options output
  sc, lc, dc = 0, 0, 0
  @options.each do |_, o|
    s = o.short&.length || 0
    l = o.long&.length || 0
    v = o.val&.length || 0
    d = o.desc&.to_s&.length || 0
    d += 3 + o.default.to_s.length  if o.default?
    if 0 == l
      x = s + (0==v ? 0 : 1+v)
      sc = x  if sc < x
    else
      sc = s  if sc < s
      x = l + (0==v ? 0 : 1+v)
      lc = x  if lc < x
    end
    dc = d  if dc < d
  end
  format = "  %-#{sc}s%s %-#{lc}s %s\n"
  @options.map do |_, o|
    s, l, v, y = o.short, o.long, o.val, ','
    if l.nil?
      s += "#{v}"  if v
      y = ' '
    elsif s.nil?
      l += "=#{v}"  if v
      y = ' '
    end
    d = o.desc || ''
    d += " (#{o.default})"  if o.default?
    output << format % [ s, y, l, d ]
  end
end

#_usage(output) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/dencli/cmd.rb', line 76

def _usage output
  output << full_cmd.join( ' ')
  @options.each do |_, o|
    s = "#{o.short||o.long}#{(!o.short && o.val) ? ?= : ''}#{o.val}"
    output << (o.required? ? " #{s}" : " [#{s}]")
  end
  if @exe.lambda?
    parameters.each do |(type, name)|
      case type
      when :req
        output << " <#{name}>"
      when :opt
        output << " [<#{name}>]"
      when :rest
        output << " [<#{name}> ...]"
      end
    end
  else
    output << ' [...]'
  end
end

#call(*as) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/dencli/cmd.rb', line 33

def call *as
  os = {}
  unless @options.empty?
    # options like --abc | -x will be provided in os
    options = OptionParser.new
    options.banner = "#{full_cmd.join ' '}"
    # see also @options-array
    @options.each {|_, opt| opt.on options, os }
    as = options.parse! as
  end
  if @exe.lambda?
    # The difference between a lambda and a Proc is, that Proc has anytime arity=-1.
    # There will be no check if all arguments are given or some were missing or more than expected.
    # lambda checks these arguments and has a arity.
    # We will check it to provide useful errors.
    pars = required
    if as.length < pars.length
      raise DenCli::UsageError, "Missing parameter(s): #{pars[as.length..-1].join " "}"
    end
    if parameters.select {|e| :rest == e[0] }.empty?
      pars = pars + additional
      if as.length > pars.length
        raise DenCli::UsageError, "Unused parameter(s): #{as[-pars.length..-1].shelljoin}"
      end
    end
    kr = @options.select {|_, o| o.required? and not os.has_key? o.name }
    unless kr.empty?
      raise DenCli::UsageError, "Missing argument(s): #{kr.map {|_, o| o.long || o.short }.join ', '}"
    end
  end
  if os.empty?
    @exe.call *as
  else
    @exe.call *as, **os
  end
end

#commands(*args) {|name, _self| ... } ⇒ Object

Yields:

Yield Parameters:

  • _self (DenCli::CMD)

    the object that the method was called on



98
99
100
# File 'lib/dencli/cmd.rb', line 98

def commands *args
  yield name, self
end

#complete(*pre, str) ⇒ Object



29
30
31
# File 'lib/dencli/cmd.rb', line 29

def complete *pre, str
  @completion.call *pre, str
end

#full_cmdObject



21
# File 'lib/dencli/cmd.rb', line 21

def full_cmd() _full_cmd [] end

#goto(*args) ⇒ Object



102
103
104
# File 'lib/dencli/cmd.rb', line 102

def goto *args
  self
end

#help(output: nil) ⇒ Object



106
107
108
109
110
# File 'lib/dencli/cmd.rb', line 106

def help output: nil
  output ||= ''
  _help output
  output
end

#help_options(output: nil) ⇒ Object



117
118
119
120
121
# File 'lib/dencli/cmd.rb', line 117

def help_options output: nil
  output ||= ''
  _help_options output
  output
end

#inspectObject



226
227
228
229
230
231
232
# File 'lib/dencli/cmd.rb', line 226

def inspect
  "#<%s:0x%x %s @name=%p @description=%p @options=%p @parent=<%s:0x%x %s> @exe=<arity=%d>>" % [
    self.class.name, self.object_id, self.full_cmd,
    @name, @description, @options.values, @parent.class.name, @parent.class.object_id, @parent.full_cmd,
    @exe.arity
  ]
end

#opt(name, opt, *args, desc, default: NilClass, &conv) ⇒ Object



220
221
222
223
224
# File 'lib/dencli/cmd.rb', line 220

def opt name, opt, *args, desc, default: NilClass, &conv
  r = Opt.new( self, name, opt, *args, desc, default: default, &conv)
  @options[r.name] = r
  self
end

#usage(output: nil) ⇒ Object



70
71
72
73
74
# File 'lib/dencli/cmd.rb', line 70

def usage output: nil
  output ||= ''
  _usage output
  output
end