Module: CLI::Kit::ParseArgs

Includes:
Kernel
Defined in:
lib/cli/kit/parse_args.rb

Instance Method Summary collapse

Instance Method Details

#parse_args(args, opts_defn) ⇒ Object

: ((Array | String) args, Hash[Symbol, Array[untyped]] opts_defn) -> Hash[Symbol, untyped]



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/cli/kit/parse_args.rb', line 15

def parse_args(args, opts_defn)
  start_opts, parser_config = opts_defn.reduce([{}, []]) do |(ini, pcfg), (n, cfg)|
    (vals, desc, short, klass) = cfg
    (init_val, def_val) = Array(vals)

    [
      init_val.nil? ? ini : ini.merge(n => init_val),
      pcfg + [[n, short, desc, def_val, klass]],
    ]
  end

  require('optparse')

  acc_opts = {}
  prsr = OptionParser.new do |opt_p|
    parser_config.each do |(n, short, desc, def_val, klass)|
      (_, mark) = short.split(' ')
      long = "--#{n.to_s.tr("_", "-")}" + (mark.nil? ? '' : " #{mark}")
      opt_args = klass.nil? ? [short, long, desc] : [short, long, klass, desc]

      unsafe_opt_p = opt_p #: as untyped
      unsafe_opt_p.on(*opt_args) do |v|
        acc_opts[n] = if acc_opts.key?(n)
          Array(acc_opts[n]) + Array(v || def_val)
        else
          v || def_val
        end
      end
    end
  end

  arg_v = (args.is_a?(Array) ? args : args.strip.split(/\s+/)).map(&:strip)
  sub = prsr.parse(arg_v)

  { opts: start_opts.merge(acc_opts) }.tap do |a|
    a[:sub] = sub if sub
  end
end