Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 405303e4f8 | |||
| 29327a3e83 |
@@ -0,0 +1,9 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*.cr]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
trim_trailing_whitespace = true
|
||||||
+11
-14
@@ -1,14 +1,11 @@
|
|||||||
# Crystal build artifacts
|
*
|
||||||
/.build/
|
!CLAUDE.md
|
||||||
/bin/
|
!src/
|
||||||
|
!src/**
|
||||||
# Compiled test binary (crystal build test.cr)
|
!shard.yml
|
||||||
test
|
!README.md
|
||||||
|
!design.adoc
|
||||||
# Shards cache
|
!docs/
|
||||||
/.shards/
|
!docs/**
|
||||||
/lib/
|
!Makefile
|
||||||
|
!LICENSE
|
||||||
# Editor
|
|
||||||
tags
|
|
||||||
.DS_Store
|
|
||||||
|
|||||||
+4
-6
@@ -44,10 +44,8 @@ module MyModule
|
|||||||
"myutil mycommand do_thing --myvar 5"
|
"myutil mycommand do_thing --myvar 5"
|
||||||
]
|
]
|
||||||
|
|
||||||
subcommand do_thing : Int32,
|
subcommand do_thing, description: "Do the THING", examples: MyModule::MyCommand::DO_THING_EXAMPLES do
|
||||||
description: "Do the THING",
|
|
||||||
examples: MyModule::MyCommand::DO_THING_EXAMPLES \
|
|
||||||
do
|
|
||||||
output = 0
|
output = 0
|
||||||
|
|
||||||
@myvar.times do |i|
|
@myvar.times do |i|
|
||||||
@@ -55,11 +53,11 @@ module MyModule
|
|||||||
output += i
|
output += i
|
||||||
end
|
end
|
||||||
|
|
||||||
output
|
puts "Total : %i" % output
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
CliGen::App.process(ARGV)
|
CliGen::App.process
|
||||||
end
|
end
|
||||||
----
|
----
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
require "./cligen/coercable"
|
||||||
require "./cligen/parsable"
|
require "./cligen/parsable"
|
||||||
require "./cligen/annotations"
|
require "./cligen/annotations"
|
||||||
require "./cligen/format"
|
require "./cligen/format"
|
||||||
@@ -10,6 +11,11 @@ require "./cligen/app"
|
|||||||
module CliGen
|
module CliGen
|
||||||
VERSION = "0.1.0"
|
VERSION = "0.1.0"
|
||||||
|
|
||||||
|
macro override_help_template(filepath)
|
||||||
|
{% raise "ERROR : CliGen.override_help_template : File(#{filepath}) doesn't exist" unless file_exists?(filepath) %}
|
||||||
|
CliGen::HELP_OVERRIDE_TEMPLATE = {{`readlink -f #{filepath}`.strip.stringify}}
|
||||||
|
end
|
||||||
|
|
||||||
APPNAME = File.basename(PROGRAM_NAME)
|
APPNAME = File.basename(PROGRAM_NAME)
|
||||||
|
|
||||||
record AdditionalDefaultFlag,
|
record AdditionalDefaultFlag,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ module CliGen
|
|||||||
validate: {% if anno[:validate] %} {{anno[:validate]}} {% else %} nil {% end %},
|
validate: {% if anno[:validate] %} {{anno[:validate]}} {% else %} nil {% end %},
|
||||||
on_match: {% if anno[:on_match] %} {{anno[:on_match]}} {% else %} nil {% end %}
|
on_match: {% if anno[:on_match] %} {{anno[:on_match]}} {% else %} nil {% end %}
|
||||||
)
|
)
|
||||||
{% debug %}
|
{% debug if env("DEBUG") %}
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
# Keep a copy of every flag on the root for global matching
|
# Keep a copy of every flag on the root for global matching
|
||||||
@@ -44,7 +44,7 @@ module CliGen
|
|||||||
post_run_commands: cmd_post_run_cmds,
|
post_run_commands: cmd_post_run_cmds,
|
||||||
description: {{cmd_info[:description]}}
|
description: {{cmd_info[:description]}}
|
||||||
)
|
)
|
||||||
{% debug %}
|
{% debug if env("DEBUG") %}
|
||||||
{% end %}
|
{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,30 @@ module CliGen
|
|||||||
def initialize(@value, @index)
|
def initialize(@value, @index)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def flag? : Bool
|
||||||
|
if @value =~ CliGen::Regex::FLAG_REGEX
|
||||||
|
true
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def int? : Bool
|
||||||
|
if @value =~ /^[[:digit:]]+$/
|
||||||
|
true
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def float? : Bool
|
||||||
|
if @value =~ /^[[:digit:]]+(\.[[:digit:]]+)?$/
|
||||||
|
true
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# This serves as a trigger that tells the object that it has been processed
|
# This serves as a trigger that tells the object that it has been processed
|
||||||
#
|
#
|
||||||
# This will raise an exception if it is re-called after already having been
|
# This will raise an exception if it is re-called after already having been
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module CliGen::Coercable
|
module CliGen::Coercable
|
||||||
abstract def coerce(arg : String) : self
|
abstract def coerce(arg : String)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ require "time"
|
|||||||
require "./annotations"
|
require "./annotations"
|
||||||
require "./command/argument"
|
require "./command/argument"
|
||||||
require "./command/selection"
|
require "./command/selection"
|
||||||
require "./command/trigger"
|
require "./command/help_template"
|
||||||
require "./command/subcommand"
|
require "./command/subcommand"
|
||||||
|
|
||||||
module CliGen
|
module CliGen
|
||||||
|
|||||||
@@ -1,28 +1,34 @@
|
|||||||
module CliGen
|
module CliGen
|
||||||
class Command
|
class Command
|
||||||
macro argument(variable, long, description, short = nil, validation = nil, on_match = nil)
|
macro argument(variable, description, long = nil, short = nil, validation = nil, on_match = nil, def_setter = false)
|
||||||
|
{% 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 %}
|
{% raise "ERROR : CliGen::Command.argument : First argument (#{variable}) must be a TypeDeclaration (ex: '<var> : <type> [= val]')" unless variable.is_a? TypeDeclaration %}
|
||||||
{% name = variable.var %}
|
{% name = variable.var %}
|
||||||
{% type = variable.type %}
|
{% type = variable.type %}
|
||||||
{% if short %}
|
{% if short %}
|
||||||
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided short must be a string" unless short.is_a? StringLiteral %}
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided short must be a string" unless short.is_a? StringLiteral %}
|
||||||
{% end %}
|
{% end %}
|
||||||
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided long must be a string" unless long.is_a? StringLiteral || long == nil %}
|
{% if long %}
|
||||||
{% raise "ERROR : CliGen::Command.argument(#{name}) : You must provide a short or long" unless long || short %}
|
{% 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}) : You must provide a description" unless description %}
|
||||||
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided description must be a String" unless description.is_a? StringLiteral %}
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided description must be a String" unless description.is_a? StringLiteral %}
|
||||||
{% unless on_match.nil? %}
|
{% unless on_match.nil? %}
|
||||||
{% puts on_match %}
|
{% 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 must be a Proc" unless on_match.is_a? ProcLiteral %}
|
||||||
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided on_match return type must be a Bool" unless on_match.return_type == Nil %}
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided on_match return type must be Nil" unless on_match.return_type.resolve == Nil %}
|
||||||
{% end %}
|
{% end %}
|
||||||
{% unless validation.nil? %}
|
{% 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 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 == Bool %}
|
{% 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? %}
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided validation provided validation must have an input variable" if validation.args.empty? %}
|
||||||
{% arg = validation.args.first %}
|
{% arg = validation.args.first %}
|
||||||
{% unless arg.restriction == type %}
|
{% unless arg.restriction == type %}
|
||||||
{% example = "->(#{arg.name} : #{type}) : #{type} { #{validation.body} }" %}
|
{% example = "->(#{arg.name} : #{type}) : Bool { #{validation.body} }" %}
|
||||||
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided validation input value must be #{type}. EX: #{example}" %}
|
{% raise "ERROR : CliGen::Command.argument(#{name}) : Provided validation input value must be #{type}. EX: #{example}" %}
|
||||||
{% end %}
|
{% end %}
|
||||||
{% end %}
|
{% end %}
|
||||||
@@ -30,12 +36,14 @@ module CliGen
|
|||||||
@[CliGen::Argument(short: {{short}}, long: {{long}}, description: {{description}}, validation: {{validation}}, on_match: {{on_match}})]
|
@[CliGen::Argument(short: {{short}}, long: {{long}}, description: {{description}}, validation: {{validation}}, on_match: {{on_match}})]
|
||||||
@{{variable}}
|
@{{variable}}
|
||||||
|
|
||||||
|
{% if def_setter %}
|
||||||
def {{variable.var}}= (value : {{type}})
|
def {{variable.var}}= (value : {{type}})
|
||||||
{% unless validation.nil? %}
|
{% unless validation.nil? %}
|
||||||
raise "ERROR : #{@type.name}##{@def.name} : Provided value #{value} is not passing validation" unless {{validation}}.call(value)
|
raise "ERROR : #{@type.name}##{@def.name} : Provided value #{value} is not passing validation" unless {{validation}}.call(value)
|
||||||
{% end %}
|
{% end %}
|
||||||
@{{name}} = value
|
@{{name}} = value
|
||||||
end
|
end
|
||||||
|
{% end %}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
module CliGen
|
||||||
|
class Command
|
||||||
|
macro help_template(filepath)
|
||||||
|
{% raise "ERROR : CliGen::Command.help_template : #{filepath} does not exist" unless file_exists? filepath %}
|
||||||
|
HELP_TEMPLATE = {{`readlink -f #{filepath}`.strip.stringify}}
|
||||||
|
{% puts "DEBUG : #{@type.name} : Set HELP_TEMPLATE to #{filepath}" if env("DEBUG") %}
|
||||||
|
{% debug if env("DEBUG") %}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
module CliGen
|
|
||||||
class Command
|
|
||||||
macro trigger(short, long, argument = nil, &on_match)
|
|
||||||
{% raise "ERROR : CliGen::Command.trigger : Provided short must be a string" unless short.is_a? StringLiteral %}
|
|
||||||
{% raise "ERROR : CliGen::Command.trigger : Provided long must be a string" unless long.is_a? StringLiteral %}
|
|
||||||
{% raise "ERROR : CliGen::Command.trigger : Must provide a block for on_match trigger" unless on_match %}
|
|
||||||
{% name = long.gsub(/--/, "") %}
|
|
||||||
|
|
||||||
@[CliGen::Trigger(short: {{short}}, long: {{long}}, argument: {{argument}})]
|
|
||||||
{% if argument %}
|
|
||||||
def self.__cligen_trigger__{{name}}__({{name}} : {{argument}}) : Nil
|
|
||||||
{{on_match.body}}
|
|
||||||
end
|
|
||||||
{% else %}
|
|
||||||
def self.__cligen_trigger__{{name}}__ : Nil
|
|
||||||
{{on_match.body}}
|
|
||||||
end
|
|
||||||
{% end %}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -33,10 +33,6 @@ module CliGen
|
|||||||
@flags = (flags + CliGen::GLOBAL_FLAGS + @commands.flat_map(&.flags)).uniq
|
@flags = (flags + CliGen::GLOBAL_FLAGS + @commands.flat_map(&.flags)).uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
def help : String
|
|
||||||
ECR.render("src/cligen/template/cmd_help.ecr")
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_for_duplicates!(flags : Array(BaseFlag)) : Nil
|
def check_for_duplicates!(flags : Array(BaseFlag)) : Nil
|
||||||
shorts = flags.compact_map(&.short)
|
shorts = flags.compact_map(&.short)
|
||||||
short_duplicates = [] of String
|
short_duplicates = [] of String
|
||||||
@@ -79,6 +75,7 @@ module CliGen
|
|||||||
if subcommand?(arg)
|
if subcommand?(arg)
|
||||||
return CliGen::MatchType::SubCommand
|
return CliGen::MatchType::SubCommand
|
||||||
end
|
end
|
||||||
|
|
||||||
case arg
|
case arg
|
||||||
when "-h", "--help"
|
when "-h", "--help"
|
||||||
CliGen::MatchType::Help
|
CliGen::MatchType::Help
|
||||||
@@ -111,6 +108,10 @@ module CliGen
|
|||||||
subcommands.any?{|f| f.name == arg}
|
subcommands.any?{|f| f.name == arg}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def flag?(arg : String) : BaseFlag
|
||||||
|
@flags.any?(&.matches?(arg))
|
||||||
|
end
|
||||||
|
|
||||||
# Converts String array to Arg array and hands off to the typed process method
|
# Converts String array to Arg array and hands off to the typed process method
|
||||||
def process(args : Array(String)) : Nil
|
def process(args : Array(String)) : Nil
|
||||||
new_args = args.each_with_index.map { |arg, i| CliGen::Arg.new(value: arg, index: i) }.to_a
|
new_args = args.each_with_index.map { |arg, i| CliGen::Arg.new(value: arg, index: i) }.to_a
|
||||||
@@ -143,6 +144,22 @@ module CliGen
|
|||||||
{% end %}
|
{% end %}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def help : String
|
||||||
|
{% begin %}
|
||||||
|
{% if T.has_constant? "HELP_TEMPLATE" %}
|
||||||
|
{% puts "#{T} was found to have HELP_TEMPLATE defined using this instead" if env("DEBUG") %}
|
||||||
|
ECR.render({{T.constant("HELP_TEMPLATE")}})
|
||||||
|
{% elsif CliGen.has_constant? "HELP_OVERRIDE_TEMPLATE" %} # If we have a global override use it
|
||||||
|
{% puts "Global override found. Using" if env("DEBUG") %}
|
||||||
|
ECR.render({{CliGen::HELP_OVERRIDE_TEMPLATE}})
|
||||||
|
{% else %}
|
||||||
|
{% puts "No type overrided help output. Using default" if env("DEBUG") %}
|
||||||
|
ECR.render("src/cligen/template/cmd_help.ecr")
|
||||||
|
{% end %} # otherwise
|
||||||
|
{% debug if env("DEBUG") %}
|
||||||
|
{% end %}
|
||||||
|
end
|
||||||
|
|
||||||
def check! : Nil
|
def check! : Nil
|
||||||
@flags.each(&.check!)
|
@flags.each(&.check!)
|
||||||
check_for_duplicates!(@flags)
|
check_for_duplicates!(@flags)
|
||||||
@@ -238,7 +255,7 @@ module CliGen
|
|||||||
{% if T.has_method?(:main) %}
|
{% if T.has_method?(:main) %}
|
||||||
cls.main
|
cls.main
|
||||||
{% else %}
|
{% else %}
|
||||||
raise "ERROR : CommandNode({{T}})#{{@def.name}} : No subcommand matched and no #main defined"
|
raise "ERROR : CommandNode({{T}})\#{{@def.name}} : No subcommand matched and no #main defined"
|
||||||
{% end %}
|
{% end %}
|
||||||
end
|
end
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|||||||
+22
-15
@@ -17,8 +17,8 @@ module CliGen
|
|||||||
@description : String
|
@description : String
|
||||||
)
|
)
|
||||||
# if the user provides just a "--long" I want the @long_key to match it
|
# if the user provides just a "--long" I want the @long_key to match it
|
||||||
if @long.includes?(" ")
|
if @long =~ /\s|=/
|
||||||
@long_key = @long.split(" ").first
|
@long_key = @long.split(/\s|=/).first
|
||||||
else
|
else
|
||||||
@long_key = @long
|
@long_key = @long
|
||||||
end
|
end
|
||||||
@@ -64,25 +64,31 @@ module CliGen
|
|||||||
raise "ERROR : Flag({{T}}) : Array requires an argument but provided array is empty" if argv.empty?
|
raise "ERROR : Flag({{T}}) : Array requires an argument but provided array is empty" if argv.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if argv.first.flag?
|
||||||
|
abort "ERROR : Flag({{T}}) : Provided argument was a flag (#{argv.first.value})"
|
||||||
|
end
|
||||||
|
|
||||||
{% if T == Bool %}
|
{% if T == Bool %}
|
||||||
@value = true
|
@value = true
|
||||||
{% elsif T <= Array %}
|
{% elsif T <= Array %}
|
||||||
{% raise "ERROR : Flag(#{T}) : You cannot define multiple types of array entries" if T.type_vars.size > 1 %}
|
{% raise "ERROR : Flag(#{T}) : You cannot define multiple types of array entries" if T.type_vars.size > 1 %}
|
||||||
{% elem = T.type_vars.first %}
|
{% elem = T.type_vars.first %}
|
||||||
argv.each do |arg|
|
argv.each do |arg|
|
||||||
break if arg.value.starts_with('-')
|
break if arg.flag?
|
||||||
{% if elem == Int32 %}
|
{% 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
|
(@value ||= [] of Int32) << arg.value.to_i
|
||||||
{% elsif elem == String %}
|
{% elsif elem == String %}
|
||||||
(@value ||= [] of String) << arg.value
|
(@value ||= [] of String) << arg.value
|
||||||
{% elsif elem < CliGen::Coercable %}
|
{% elsif elem.class < CliGen::Coercable %}
|
||||||
if arg.value.includes?(",")
|
{% delim = elem.has_constant?("DELIMITER") ? elem.constant("DELIMITER") : ',' %}
|
||||||
(@value ||= [] of {{elem}}) += arg.value.split(",").map{|i| {{elem}}.coerce(i)}
|
if arg.value.includes?({{delim}})
|
||||||
|
@value = (@value || [] of {{elem}}) + arg.value.split({{delim}}).map{|i| {{elem}}.coerce(i)}
|
||||||
else
|
else
|
||||||
(@value ||= [] of {{elem}}) << {{elem}}.coerce(arg.value)
|
@value = (@value || [] of {{elem}}) + [({{elem}}.coerce(arg.value))]
|
||||||
end
|
end
|
||||||
{% else %}
|
{% else %}
|
||||||
{% raise "ERROR : Flag(#{T}) : #{elem} is not a coercable type. If you wish to coerce it from a bare string include CliGen::Coercable & implement the class method" %}
|
{% raise "ERROR : Flag(#{T}) : #{elem} is not a coercable type. If you wish to coerce it from a bare string extend with CliGen::Coercable & implement the class method" %}
|
||||||
{% end %}
|
{% end %}
|
||||||
arg.processed
|
arg.processed
|
||||||
end
|
end
|
||||||
@@ -95,7 +101,7 @@ module CliGen
|
|||||||
{% elsif T == String %} # String
|
{% elsif T == String %} # String
|
||||||
@value = argv.first.value
|
@value = argv.first.value
|
||||||
argv.first.processed
|
argv.first.processed
|
||||||
{% elsif T < CliGen::Parsable %}
|
{% elsif T.class < CliGen::Parseable %}
|
||||||
processed = argv.select(&.processed?)
|
processed = argv.select(&.processed?)
|
||||||
@value = T.parse_args(argv)
|
@value = T.parse_args(argv)
|
||||||
post_processed = argv.select(&.processed?)
|
post_processed = argv.select(&.processed?)
|
||||||
@@ -103,7 +109,7 @@ module CliGen
|
|||||||
raise "ERROR : Flag({{T}}, long: #{@long_key})#process : Your {{T}}#process_args did not mark processed args as processed. Please check your code"
|
raise "ERROR : Flag({{T}}, long: #{@long_key})#process : Your {{T}}#process_args did not mark processed args as processed. Please check your code"
|
||||||
end
|
end
|
||||||
{% else %}
|
{% else %}
|
||||||
{% raise "ERROR : Flag({{T}}, long: #{@long_key})#process : Generic Type #{T} is not supported. To add support you must include CliGen::Parsable & implement the class method" %}
|
{% raise "ERROR : Flag({{T}}#process : Generic Type #{T} is not supported. To add support you must include CliGen::Parsable & implement the class method" %}
|
||||||
{% end %}
|
{% end %}
|
||||||
|
|
||||||
validate!
|
validate!
|
||||||
@@ -180,17 +186,18 @@ module CliGen
|
|||||||
raw.split(',').map(&.to_i)
|
raw.split(',').map(&.to_i)
|
||||||
{% elsif elem == String %}
|
{% elsif elem == String %}
|
||||||
raw.split(',')
|
raw.split(',')
|
||||||
{% elsif elem < CliGen::Coercable %}
|
{% elsif elem.class < CliGen::Coercable %}
|
||||||
raw.split(',').map{|i| {{elem}}.coerce(i)}
|
{% delim = elem.has_constant?("DELIMITER") ? elem.constant("DELIMITER") : ',' %}
|
||||||
|
raw.split({{delim}}).map{|i| {{elem}}.coerce(i)}
|
||||||
{% else %}
|
{% else %}
|
||||||
{% raise "ERROR : Flag(#{T}) : #{elem} is not a coercable type. If you wish to coerce it from a bare string include CliGen::Coercable & implement the class method" %}
|
{% raise "ERROR : Flag(#{T}) : #{elem} is not a coercable type. If you wish to coerce it from a bare string extend CliGen::Coercable & implement the class method" %}
|
||||||
{% end %}
|
{% end %}
|
||||||
{% elsif T == String %} # String
|
{% elsif T == String %} # String
|
||||||
raw
|
raw
|
||||||
{% elsif T < CliGen::Coercable %}
|
{% elsif T.class < CliGen::Coercable %}
|
||||||
T.coerce(raw)
|
T.coerce(raw)
|
||||||
{% else %}
|
{% else %}
|
||||||
{% raise "ERROR : Flag(#{T}) : #{T} is not a coercable type. If you wish to coerce it from a bare string include CliGen::Coercable & implement the class method" %}
|
{% raise "ERROR : Flag(#{T}) : #{T} is not a coercable type. If you wish to coerce it from a bare string extend CliGen::Coercable & implement the class method" %}
|
||||||
{% end %}
|
{% end %}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module CliGen::Parseable
|
module CliGen::Parseable
|
||||||
abstract def parse_args(args : Array(CliGen::Arg)) : self
|
abstract def parse_args(args : Array(CliGen::Arg))
|
||||||
end
|
end
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
module CliGen::Regex
|
module CliGen::Regex
|
||||||
FLAG_REGEX=/^(-[a-zA-Z]|--[a-zA-Z-_]+)$/
|
FLAG_REGEX=/^(-[a-zA-Z]|--[a-zA-Z-_0-9]+)/
|
||||||
FLAG_WITH_ARG=/^(?<flag>(-[a-zA-Z]|--[a-zA-Z-_]+))="?(?<arg>\S+?)"?$/
|
FLAG_WITH_ARG=/^(?<flag>(-[a-zA-Z]|--[a-zA-Z-_]+))="?(?<arg>\S+?)"?$/
|
||||||
FLAG_MULTIPLE_SHORT=/^-[a-zA-Z]+$/
|
FLAG_MULTIPLE_SHORT=/^-[a-zA-Z]+$/
|
||||||
SHORT_WITH_INLINE_ARG=/^-[a-zA-Z][a-zA-Z0-9]+$/
|
SHORT_WITH_INLINE_ARG=/^-[a-zA-Z][a-zA-Z0-9]+$/
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ Flags:
|
|||||||
Other Commands
|
Other Commands
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
<%- @commands.each do |command| -%>
|
<%- @commands.each do |command| -%>
|
||||||
<%= "%-10s %s" % [ command.name, command.description ] %>
|
<%= "%-15s %s" % [ command.name, command.description ] %>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
|
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
@@ -25,7 +25,7 @@ Other Commands
|
|||||||
SubCommands of <%= @name %>:
|
SubCommands of <%= @name %>:
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
<%- subcommands.each do |cmd| -%>
|
<%- subcommands.each do |cmd| -%>
|
||||||
<%= "%-10s %s" % [cmd.name, cmd.description] %>
|
<%= "%-15s %s" % [cmd.name, cmd.description] %>
|
||||||
<%- end -%>
|
<%- end -%>
|
||||||
|
|
||||||
<%- cmds = subcommands.select{|c| ! c.examples.nil? } -%>
|
<%- cmds = subcommands.select{|c| ! c.examples.nil? } -%>
|
||||||
|
|||||||
Reference in New Issue
Block a user