Module: Autoargs

Defined in:
lib/autoargs.rb,
lib/autoargs/version.rb

Constant Summary collapse

VERSION =
"0.1.0"

Class Method Summary collapse

Class Method Details

.run(method) ⇒ Object



5
6
7
8
9
10
11
12
13
14
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
53
54
55
56
57
# File 'lib/autoargs.rb', line 5

def self.run(method)
    caller_file = caller[0].split(":")[0]

    if caller_file == $0
        ast = Parser::CurrentRuby
            .parse(File.read(caller_file))
            .children
            .select do |node| node.type == :def end
            .map(&:children)
            .select do |name, _| name == method.name end[0]

        abort("No top level method named " + method.name.to_s + " found.") if ast.nil?

        all_args = ast[1].children

        args = all_args
            .select do |arg| arg.type == :arg end
            .map do |arg| arg.children[0] end

        optargs = all_args
            .select do |arg| arg.type == :optarg end
            .map do |arg| { :name => arg.children[0], :default => arg.children[1].children[0] } end

        kwoptargs = Hash[
            all_args
                .select do |arg| arg.type == :kwoptarg end
                .map do |arg| [arg.children[0], arg.children[1].children[0]] end
        ]

        argv_args = ARGV[0 ... args.length]
        argv_optargs = ARGV[args.length ... args.length + optargs.length]
        argv_kwoptargs = Hash[
            (ARGV[args.length + optargs.length .. -1] || [])
                .each_slice(2)
                .map do |name_with_prefix, value|
                    abort("Expected argument " + name_with_prefix + " to start with --.") unless name_with_prefix.start_with?("--")
                    name = name_with_prefix[2 .. -1]
                    abort(name + " is not an option.") unless kwoptargs.has_key?(name.to_sym)
                    [name.to_sym, value]
                end
        ]

        if argv_args.length < args.length
            abort([[caller_file],
                args.map do |arg| "<" + arg.to_s + ">" end,
                optargs.map do |optarg| "[" + optarg[:name].to_s + "=" + optarg[:default].inspect + "]" end,
                kwoptargs.map do |name, default| "[--" + name.to_s + " " + default.inspect + "]" end
            ].flatten(1).join(" "))
        end

        method.call(*ARGV.slice(0, args.length + optargs.length), **argv_kwoptargs)
    end
end