Class: Moister::SubcommandOptionParser

Inherits:
OptionParserExtra show all
Defined in:
lib/moister.rb

Instance Method Summary collapse

Methods inherited from OptionParserExtra

#on

Constructor Details

#initializeSubcommandOptionParser

Returns a new instance of SubcommandOptionParser.



28
29
30
31
32
33
34
# File 'lib/moister.rb', line 28

def initialize
  # options applicable to all subcommands
  @for_all = []
  @subcommands = {}
  @aliases = {}
  super
end

Instance Method Details

#for_all(&block) ⇒ Object

add a block to configure every subcommand



46
47
48
# File 'lib/moister.rb', line 46

def for_all &block
  @for_all.push block
end

#parse(args = ARGV) ⇒ Object



131
132
133
# File 'lib/moister.rb', line 131

def parse(args = ARGV)
  parse! args.clone
end

#parse!(args = ARGV) ⇒ Object



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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/moister.rb', line 70

def parse!(args = ARGV)
  apply_for_all self
  order! args
  if args.empty?
    ParseResults.new(nil, [], @config)
  else
    cmd = args.first
    _alias = @aliases[cmd]
    cmd = _alias if _alias
    subcmd_meta = @subcommands[cmd]
    raise "invalid subcommand: #{cmd}" unless @subcommands.has_key? cmd
    args.shift

    subcmd_config = @config[cmd] = {}
    positionals = OptionParserExtra.new(@config[cmd]) do |subop|
      apply_for_all subop
      subop.banner = subcmd_meta[:banner]
      parse_cmdline = subcmd_meta[:parse_cmdline]
      parse_cmdline.call(subop) if parse_cmdline
    end.order! args

    positionals_meta = subcmd_meta[:positionals]
    if positionals_meta
      positionals_meta.each do |positional_meta|
        array_match = false
        optional = if positional_meta =~ /^\[.+\]$/
          optional = true
          positional_meta = positional_meta[1..-2]
        end

        positional_name = if positional_meta =~ /^\*[a-z\-]+$/
          array_match = true
          positional_meta[1..-1]
        else
          positional_meta
        end

        if array_match
          if positionals.empty?
            if optional
              subcmd_config[positional_name] = []
              next
            end
            raise "`#{cmd}' subcommand requires at least one `#{positional_name}' parameter"
          end
          subcmd_config[positional_name] = positionals
          positionals = []
        else
          if positionals.empty?
            next if optional
            raise "`#{cmd}' subcommand requires `#{positional_name}' parameter"
          end
          subcmd_config[positional_name] = positionals.shift
        end
      end
    end

    ParseResults.new(cmd, positionals, @config)
  end
end

#subcommand(name, banner, &block) ⇒ Object



36
37
38
39
40
41
42
43
# File 'lib/moister.rb', line 36

def subcommand name, banner, &block
  name, *positionals = name.split ' '
  name, *aliases = name.split(',')
  subcmd = { name: name, banner: banner, parse_cmdline: block }
  subcmd[:positionals] = positionals unless positionals.empty?
  @subcommands[name] = subcmd
  aliases.each { |_alias| @aliases[_alias] = name }
end

#to_sObject Also known as: help



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/moister.rb', line 50

def to_s
  ret = super
  prefixes = @subcommands.values.map do |subcmd|
    prefix = subcmd[:name]
    prefix +=  ' ' + subcmd[:positionals].join(' ') if subcmd.has_key? :positionals
    prefix
  end
  max_len = prefixes.map(&:length).max

  ret += "\ncommands:\n"
  @subcommands.values.each_with_index do |subcmd, idx|
    prefix = prefixes[idx]
    prefix += ' ' * (max_len - prefix.length + 2)
    ret += "    #{prefix}  #{subcmd[:banner]}\n"
  end
  ret
end