Module: ClassX::Commandable

Defined in:
lib/classx/commandable.rb

Overview

add cli interface to your classx based class.

require 'classx'

$ClassXCommandableMappingOf[Symbol] = String

class YourApp 
  include ClassX
  extend ClassX::Commandable

  has :arg1, 
    :kind_of => Symbol, 
    :desc => 'please specify arg1',
    :coerce => { String => proc {|val| val.to_sym } }

  has :arg2,
    :kind_of => Integer,
    :desc => "this is arg2",
    :optional => true

  def run
    # do something!!
    p attribute_of
  end
end

if $0 == __FILE__
  YourApp.from_argv.run
end

and run, $ruby example/commandable.rb

example/commandable.rb [options]
    -a, --arg1 String                please specify arg1
        --arg2 [Integer]             this is arg2
    -h, --help                       show this document

please see and run example/commandable.rb

Defined Under Namespace

Classes: MissingCoerceMapping

Instance Method Summary collapse

Instance Method Details

#from_argv(argv = ARGV.dup) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/classx/commandable.rb', line 48

def from_argv argv=ARGV.dup
  OptionParser.new do |opt|
    begin
      opt.banner = "#{$0} [options]"
      value_of = {}
      short_option_of = {}
      attribute_of.keys.sort.each do |key|
        val = attribute_of[key]
        next if val.config[:no_cmd_option]
        
        val_format = val.value_class ? "#{val.value_class}" : "VAL"
        if val.optional?
          val_format = "[#{val_format}]"
        end

        short_option = key.split(//).first
        unless short_option_of[short_option]
          short_option_of[short_option] = key
        end

        if val.value_class
          begin
            if short_option_of[short_option] == key
              opt.on(
                "-#{short_option}", 
                "--#{key} #{val_format}", 
                val.value_class, val.desc
              ) {|v| value_of[key] = v }
            else
              opt.on("--#{key} #{val_format}", val.value_class, val.desc) {|v| value_of[key] = v }
            end
          rescue Exception => e
            if $ClassXCommandableMappingOf[val.value_class]
              if short_option_of[short_option] == key
                opt.on(
                  "-#{short_option}", 
                  "--#{key} #{$ClassXCommandableMappingOf[val.value_class]}", 
                  $ClassXCommandableMappingOf[val.value_class], val.desc
                ) {|v| value_of[key] = v }
              else
                opt.on(
                  "--#{key} #{$ClassXCommandableMappingOf[val.value_class]}", 
                  $ClassXCommandableMappingOf[val.value_class], val.desc
                ) {|v| value_of[key] = v }
              end
            else
              raise MissingCoerceMapping, "missing coerce rule. please specify $ClassXCommandableMappingOf"
            end
          end
        else
          if short_option_of[short_option] == key
            opt.on("-#{short_option}", "--#{key} #{val_format}", val.desc ) {|v| value_of[key] = v }
          else
            opt.on("--#{key} #{val_format}", val.desc ) {|v| value_of[key] = v }
          end
        end
      end

      opt.on('-h', '--help', 'show this document') {|v| raise OptionParser::ParseError }
      opt.parse!(argv)

      return new(value_of)
    rescue ClassX::InstanceException, OptionParser::ParseError => e
      warn opt
      exit
    end
  end
end