Added format support for filtering arguments
This commit is contained in:
@@ -30,7 +30,8 @@ module CliGen
|
||||
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 %} nil {% end %}
|
||||
delimiter: {% if anno[:delimiter] %} {{anno[:delimiter]}} {% else %} nil {% end %},
|
||||
format: {% if anno[:format] %} {{anno[:format]}} {% else %} nil {% end %}
|
||||
)
|
||||
{% debug if env("DEBUG") %}
|
||||
{% end %}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module CliGen
|
||||
class Command
|
||||
macro argument(variable, description, long = nil, short = nil, validation = nil, on_match = nil, def_setter = false, def_getter = false, options = nil, delimiter = ",")
|
||||
macro argument(variable, description, long = nil, short = nil, validation = nil, on_match = nil, def_setter = false, def_getter = false, options = nil, delimiter = ",", format = 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 %}
|
||||
@@ -37,8 +37,12 @@ module CliGen
|
||||
{% 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 %}
|
||||
{% if format %}
|
||||
{% format = format.resolve if format.is_a? Path %}
|
||||
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided format must be a RegexLiteral" unless format.is_a? RegexLiteral %}
|
||||
{% end %}
|
||||
|
||||
@[CliGen::Argument(short: {{short}}, long: {{long}}, description: {{description}}, validation: {{validation}}, on_match: {{on_match}}, options: {{options}}, delimiter: {{delimiter}})]
|
||||
@[CliGen::Argument(short: {{short}}, long: {{long}}, description: {{description}}, validation: {{validation}}, on_match: {{on_match}}, options: {{options}}, delimiter: {{delimiter}}, format: {{format}})]
|
||||
@{{variable}}
|
||||
|
||||
{% if def_getter %}
|
||||
|
||||
+36
-13
@@ -87,8 +87,6 @@ module CliGen
|
||||
end
|
||||
when CliGen::Regex::FLAG_WITH_ARG
|
||||
CliGen::MatchType::FlagWithArg
|
||||
when CliGen::Regex::SHORT_WITH_INLINE_ARG
|
||||
CliGen::MatchType::ShortWithInlineArg
|
||||
when CliGen::Regex::FLAG_MULTIPLE_SHORT
|
||||
CliGen::MatchType::FlagMultipleShort
|
||||
else
|
||||
@@ -108,7 +106,7 @@ module CliGen
|
||||
subcommands.any?{|f| f.name == arg}
|
||||
end
|
||||
|
||||
def flag?(arg : String) : BaseFlag
|
||||
def flag?(arg : String) : Bool
|
||||
@flags.any?(&.matches?(arg))
|
||||
end
|
||||
|
||||
@@ -221,17 +219,43 @@ module CliGen
|
||||
raise "Oh good, you broke regex. How the hell did it match in find_match but not above? What the hell is going on"
|
||||
end
|
||||
|
||||
when MatchType::ShortWithInlineArg
|
||||
abort "#{CliGen::APPNAME}: invalid flag '#{arg.value}' — inline values are not supported. Did you mean '#{arg.value[0..1]} #{arg.value[2..]}' ?"
|
||||
|
||||
when MatchType::FlagMultipleShort
|
||||
arg.value.gsub(/^-/, "").chars.map { |c| "-#{c}" }.each do |flag|
|
||||
case match = find_match(flag)
|
||||
val = arg.value.gsub(/^-/,"")
|
||||
|
||||
# If the next character in the series is a flag assume the remaining are flags as well.
|
||||
if flag?("-#{val[1]}")
|
||||
chars = val.chars
|
||||
chars.map { |c| "-#{c}" }.each do |flag|
|
||||
case match = find_match(flag)
|
||||
when BaseFlag
|
||||
# If this is the last flag in the series let it process others
|
||||
if flag == "-#{chars.last}"
|
||||
if match.requires_arg?
|
||||
match.process(args.reject(&.processed?))
|
||||
else
|
||||
match.process
|
||||
end
|
||||
else
|
||||
abort "#{CliGen::APPNAME}: cannot bundle flag that requires an argument: #{flag}" if match.requires_arg?
|
||||
match.process
|
||||
end
|
||||
when MatchType::NoMatch
|
||||
abort "ERROR : CommandNode(#{@name}).process : No flag match for '#{flag}'"
|
||||
end
|
||||
end
|
||||
else
|
||||
# In this case we assume the characters following the flag is the argument
|
||||
flg = "-#{val[0]}"
|
||||
argument = Arg.new(value: val[1..], index: 0)
|
||||
case match = find_match(flg)
|
||||
when BaseFlag
|
||||
abort "#{CliGen::APPNAME}: cannot bundle flag that requires an argument: #{flag}" if match.requires_arg?
|
||||
match.process
|
||||
if match.requires_arg?
|
||||
match.process([argument])
|
||||
else
|
||||
abort "ERROR : CommandNode(#{@name}).process : Unknown characters proceeding a boolean flag(#{flg}) : #{val[1..]}"
|
||||
end
|
||||
when MatchType::NoMatch
|
||||
raise "ERROR : CommandNode(#{@name}).process : No flag match for '#{flag}'"
|
||||
abort "ERROR : CommandNode(#{@name}).process : No flag match for '#{arg.value}'"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -246,8 +270,7 @@ module CliGen
|
||||
{% unless T == Nil %}
|
||||
unless passed_execution
|
||||
cls = T.new(handler: self.as(CliGen::BaseCommandNode))
|
||||
{% prerun = T.methods.select(&.annotation(CliGen::PreRunCommand)) %}
|
||||
{% for cmd in prerun %}
|
||||
{% for cmd in T.methods.select(&.annotation(CliGen::PreRunCommand)) %}
|
||||
cls.{{cmd.name}}
|
||||
{% end %}
|
||||
{% subcmds = T.methods.select(&.annotation(CliGen::SubCommand)) %}
|
||||
|
||||
+6
-1
@@ -42,6 +42,7 @@ module CliGen
|
||||
@options : Array(T)?
|
||||
@validate : (T -> Bool)?
|
||||
@on_match : Proc(Nil)?
|
||||
@format : ::Regex?
|
||||
|
||||
def initialize(
|
||||
var : String,
|
||||
@@ -53,7 +54,8 @@ module CliGen
|
||||
@default : T? = nil,
|
||||
@options : Array(T)? = nil,
|
||||
@validate : (T -> Bool)? = nil,
|
||||
@on_match : Proc(Nil)? = nil
|
||||
@on_match : Proc(Nil)? = nil,
|
||||
@format : ::Regex? = nil
|
||||
)
|
||||
super(var, short, long, env_var, description, delimiter)
|
||||
end
|
||||
@@ -76,6 +78,9 @@ module CliGen
|
||||
{% elem = T.type_vars.first %}
|
||||
argv.each do |arg|
|
||||
break if arg.flag?
|
||||
unless @format.nil?
|
||||
break unless arg.value =~ @format
|
||||
end
|
||||
{% if elem == Int32 %}
|
||||
abort "ERROR : Flag({{T}}) : Provided arguemnt(#{arg.value}) was not an integer" unless arg.int?
|
||||
(@value ||= [] of Int32) << arg.value.to_i
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
module CliGen::Regex
|
||||
FLAG_REGEX=/^(-[a-zA-Z]|--[a-zA-Z-_0-9]+)/
|
||||
FLAG_REGEX=/^(-[a-zA-Z]|--[a-zA-Z-_0-9]+)$/
|
||||
FLAG_WITH_ARG=/^(?<flag>(-[a-zA-Z]|--[a-zA-Z-_]+))="?(?<arg>\S+?)"?$/
|
||||
FLAG_MULTIPLE_SHORT=/^-[a-zA-Z]+$/
|
||||
SHORT_WITH_INLINE_ARG=/^-[a-zA-Z][a-zA-Z0-9]+$/
|
||||
FLAG_MULTIPLE_SHORT=/^-[a-zA-Z0-9]+/
|
||||
|
||||
INPUT_DATETIME_REGEX = /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$/
|
||||
INPUT_DATE_REGEX = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/
|
||||
|
||||
Reference in New Issue
Block a user