54 lines
3.5 KiB
Crystal
54 lines
3.5 KiB
Crystal
module CliGen
|
|
class Command
|
|
macro argument(variable, description, long = nil, short = nil, validation = nil, on_match = nil, def_setter = false, options = nil)
|
|
{% raise "ERROR : CliGen::Command.argument : def_setter must be a Bool" unless def_setter.is_a? BoolLiteral %}
|
|
{% raise "ERROR : CliGen::Command.argument : First argument (#{variable}) must be a TypeDeclaration (ex: '<var> : <type> [= val]')" unless variable.is_a? TypeDeclaration %}
|
|
{% name = variable.var %}
|
|
{% type = variable.type %}
|
|
{% if short %}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided short must be a string" unless short.is_a? StringLiteral %}
|
|
{% end %}
|
|
{% if long %}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided long must be a string" unless long.is_a? StringLiteral %}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided long must match --[a-zA-Z0-9-_]+" unless long =~ /^--[a-zA-Z0-9-_]+/ %}
|
|
{% else %}
|
|
{% long = "--#{name.downcase}" %}
|
|
{% end %}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : You must provide a description" unless description %}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided description must be a String" unless description.is_a? StringLiteral %}
|
|
{% unless on_match.nil? %}
|
|
{% puts "DEBUG : #{@type.name}.argument(#{name}) : OnMatch:\n\tid: #{on_match}\n\treturn_type: #{on_match.return_type}\n\tinput_vars: #{on_match.args}" if env("DEBUG")%}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided on_match must be a Proc" unless on_match.is_a? ProcLiteral %}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided on_match return type must be Nil" unless on_match.return_type.resolve == Nil %}
|
|
{% end %}
|
|
{% unless validation.nil? %}
|
|
{% puts "DEBUG : #{@type.name}.argument(#{name}) : Validation:\n\tid: #{validation}\n\treturn_type: #{validation.return_type}\n\tinput_vars: #{validation.args}" if env("DEBUG")%}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided validation must be a Proc" unless validation.is_a? ProcLiteral %}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided validation return type must be a Bool" unless validation.return_type.resolve == Bool %}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided validation provided validation must have an input variable" if validation.args.empty? %}
|
|
{% arg = validation.args.first %}
|
|
{% unless arg.restriction == type %}
|
|
{% example = "->(#{arg.name} : #{type}) : Bool { #{validation.body} }" %}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided validation input value must be #{type}. EX: #{example}" %}
|
|
{% end %}
|
|
{% end %}
|
|
{% if options %}
|
|
{% options = options.resolve if options.is_a? Path %}
|
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided options must be an ArrayLiteral" unless options.is_a? ArrayLiteral %}
|
|
{% end %}
|
|
|
|
@[CliGen::Argument(short: {{short}}, long: {{long}}, description: {{description}}, validation: {{validation}}, on_match: {{on_match}}, options: {{options}})]
|
|
@{{variable}}
|
|
|
|
{% if def_setter %}
|
|
def {{variable.var}}= (value : {{type}})
|
|
{% unless validation.nil? %}
|
|
raise "ERROR : #{@type.name}##{@def.name} : Provided value #{value} is not passing validation" unless {{validation}}.call(value)
|
|
{% end %}
|
|
@{{name}} = value
|
|
end
|
|
{% end %}
|
|
end
|
|
end
|
|
end
|