71 lines
3.0 KiB
Crystal
71 lines
3.0 KiB
Crystal
module CliGen::Parser
|
|
|
|
macro extended
|
|
{% verbatim do %}
|
|
macro define_parser
|
|
def self.make_parser(parent_parser : OptionParser) : Nil
|
|
{% puts "#{@type.name} OptionParser is being generated" %}
|
|
{% name = @type.name.split("::").last %}
|
|
{% var = name.downcase %}
|
|
{% methods = @type.class.methods %}
|
|
{% info = @type.annotation(::CliGen::CommandInfo) %}
|
|
{% raise "ERROR : No CommandInfo annotation provided to {{@type.name}}" unless info %}
|
|
subparser = OptionParser.new do |parser|
|
|
parser.banner = {{@type.name}}::HEADER
|
|
|
|
{% selections = methods.select(&.annotation(::CliGen::CommandSelection)) %}
|
|
{% if selections.size > 0 %}
|
|
CliGen.define_section("Selections", parser)
|
|
{% for selection in selections %}
|
|
{% selection_anno = selection.annotation(::CliGen::CommandSelection) %}
|
|
parser.on({{selection.name.stringify}}, {{selection_anno[:description]}}){
|
|
{{@type.name}}.{{selection_anno[:selector]}}= {{selection.name.stringify}}
|
|
}
|
|
{% end %}
|
|
{% end %}
|
|
|
|
{% subcommands = methods.select(&.annotation(::CliGen::SubCommand)) %}
|
|
{% if subcommands.size > 0 %}
|
|
CliGen.define_section("Subcommands", parser)
|
|
{% for subcommand in subcommands %}
|
|
{% subcommand_anno = subcommand.annotation(::CliGen::SubCommand) %}
|
|
parser.on({{subcommand.name.stringify}}, {{subcommand_anno[:description]}}){
|
|
{{@type.name}}.action= {{subcommand.name.stringify}}
|
|
}
|
|
{% end %}
|
|
{% end %}
|
|
|
|
{% arguments = methods.select(&.annotation(::CliGen::CommandArgument)) %}
|
|
{% if arguments.size > 0 %}
|
|
CliGen.define_section("Provide Arguments", parser)
|
|
{% for argument in arguments %}
|
|
{% argument_anno = argument.annotation(::CliGen::CommandArgument) %}
|
|
{% if argument_anno[:short] == "" && argument_anno[:long] != "" %}
|
|
parser.on({{argument_anno[:long]}}, {{argument_anno[:description]}}){|val|
|
|
{% elsif argument_anno[:short] != "" && argument_anno[:long] == "" %}
|
|
parser.on({{argument_anno[:short]}}, {{argument_anno[:description]}}){|val|
|
|
{% else %}
|
|
parser.on({{argument_anno[:short]}}, {{argument_anno[:long]}}, {{argument_anno[:description]}}){|val|
|
|
{% end %}
|
|
{{@type.name}}.{{argument.name}}(val)
|
|
}
|
|
{% end %}
|
|
{% end %}
|
|
CliGen.define_default_flags(parser)
|
|
end
|
|
parent_parser.on({{var}}, {{info[:description]}}){
|
|
raise "ERROR : {{var.id}} not found in ARGV" unless i = ARGV.index({{var}})
|
|
## Removing all preceeding arguments so that only the actual required
|
|
## args for the next command are present
|
|
ARGV.shift(i+1)
|
|
abort subparser if ARGV.empty?
|
|
subparser.parse
|
|
{{@type.name}}.run
|
|
}
|
|
end
|
|
end
|
|
{% end %}
|
|
end
|
|
|
|
end
|