Files
cligen/src/cligen/command/generate_register_command.cr
T

87 lines
3.6 KiB
Crystal

require "../flag"
module CliGen
class Command
macro generate_register_command
{% verbatim do %}
def self.register_command(command_array : Array(CliGen::BaseCommandNode), parent : CliGen::BaseCommandNode? = nil)
cmd_flags = [] of CliGen::BaseFlag
cmd_subcommands = [] of CliGen::BaseCommandNode
cmd_pre_run_cmds = [] of Proc(Nil)
cmd_post_run_cmds = [] of Proc(Nil)
{% for var in @type.instance_vars.select(&.annotation(CliGen::Argument)) %}
{% anno = var.annotation(CliGen::Argument) %}
CliGen::Common.check_flag_vars(
raise_base: {{"CliGen::Command(#{@type.name}).generate_register_command"}},
type: {{var.type}},
long: {{anno[:long]}},
env_var: {{anno[:env_var]}},
short: {{anno[:short]}},
validation: {{anno[:validation]}},
on_match: {{anno[:on_match]}},
options: {{anno[:options]}},
description: {{anno[:description]}},
allow_no_verification: {{anno[:allow_no_verification]}},
format: {{anno[:format]}},
delimiter: {{anno[:delimiter]}}
)
cmd_flags << CliGen::Flag({{var.type}}).new(
var: {{ var.name.stringify }},
short: {% if anno[:short] %} {{anno[:short]}} {% else %} nil {% end %},
long: {{ anno[:long] }},
{% if anno[:env_var] == "" %}
{% if @type.name.stringify =~ /::/ %}
env_var: "{{@type.name.upcase.split("::").last.id}}_{{var.name.upcase}}",
{% else %}
env_var: "{{@type.name.upcase.id}}_{{var.name.upcase}}",
{% end %}
{% else %}
env_var: {{anno[:env_var]}},
{% end %}
description: {{ anno[:description] }},
default: {% unless var.default_value.nil? %} {{var.default_value}} {% else %} nil {% end %},
validate: {% if anno[:validation] %} {{anno[:validation]}} {% else %} nil {% end %},
on_match: {% if anno[:on_match] %} {{anno[:on_match]}} {% else %} nil {% end %},
options: {% if anno[:options] %} {{anno[:options]}} {% else %} nil {% end %},
delimiter: {% if anno[:delimiter] %} {{anno[:delimiter]}} {% else %} "," {% end %},
format: {% if anno[:format] %} {{anno[:format]}} {% else %} nil {% end %}
)
{% end %}
{% begin %}
{% cmd_anno = @type.annotation(CliGen::CommandInfo) %}
command = CliGen::CommandNode({{@type}}).new(
{% if @type.name.stringify =~ /::/ %}
name: {{@type.name.stringify.split("::").last.downcase}},
{% else %}
name: {{@type.name.stringify.downcase}},
{% end %}
flags: cmd_flags,
commands: cmd_subcommands,
pre_run_commands: cmd_pre_run_cmds,
post_run_commands: cmd_post_run_cmds,
parent: parent,
description: {{cmd_anno[:description]}}
)
command_array << command
{% end %}
{% for cmd in CliGen::Command.subclasses %}
{% cmd_anno = cmd.annotation(CliGen::CommandInfo) %}
{% unless cmd.annotation(CliGen::CommandInfo) %}
{% raise "ERROR : CliGen::Command(#{@type}).generate_register_command : #{cmd} must have an CliGen::CommandInfo annotation" %}
{% end %}
{% unless cmd_anno[:parent].nil? %}
{% if cmd_anno[:parent].resolve == @type %}
{{cmd}}.register_command(cmd_subcommands, parent: command)
{% end %}
{% end %}
{% end %}
end
{% end %}
end
end
end