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
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
|
# File 'lib/autoargs.rb', line 19
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
]
usage = [[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(" ")
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|
begin
raise "Expected argument " + name_with_prefix + " to start with --." unless name_with_prefix.start_with?("--")
raise "Expected value for argument " + name_with_prefix if value.nil?
name = name_with_prefix[2 .. -1]
raise name + " is not an option." unless kwoptargs.has_key?(name.to_sym)
[name.to_sym, value]
rescue Exception => e
puts(e.message)
puts
puts(usage)
abort
end
end
]
abort(usage) if argv_args.length < args.length
positionals = ARGV.slice(0, args.length + optargs.length)
if argv_kwoptargs.keys.length != 0
method.call(*positionals, **argv_kwoptargs)
else
method.call(*positionals)
end
end
end
|