99 lines
2.8 KiB
Crystal
99 lines
2.8 KiB
Crystal
require "option_parser"
|
|
|
|
module CliGen
|
|
VERSION = "0.1.0"
|
|
|
|
record AdditionalDefaultFlag,
|
|
short : String?,
|
|
long : String?,
|
|
description : String,
|
|
work : Proc(Nil)
|
|
|
|
private ADDITIONAL_DEFAULT_FLAGS = [] of AdditionalDefaultFlag
|
|
|
|
def self.add_default_flag(short : String? = nil, long : String? = nil, description : String? = nil, &work : -> )
|
|
raise "ERROR : add_default_flag : You must provide a description" unless description
|
|
raise "ERROR : add_default_flag : You must provide at least long or short" unless [short, long].any?
|
|
ADDITIONAL_DEFAULT_FLAGS << AdditionalDefaultFlag.new(
|
|
short: short,
|
|
long: long,
|
|
description: description,
|
|
work: work
|
|
)
|
|
end
|
|
|
|
annotation DefaultFlag
|
|
end
|
|
|
|
macro define_section(section_name, parser)
|
|
{{parser}}.separator ""
|
|
{{parser}}.separator "{{section_name.id}}".colorize(:green)
|
|
{{parser}}.separator "-------------------------------------------------------------------------------".colorize(:blue)
|
|
end
|
|
|
|
|
|
macro define_default_flags(parser)
|
|
define_section("Misc Flags", {{parser}})
|
|
{{parser}}.on("-h", "--help", "Print out this help output"){ abort {{parser}} }
|
|
{{parser}}.invalid_option{|opt|
|
|
abort "#{PROGRAM_NAME} : invalid_option : Inavlid option provided #{opt}"
|
|
}
|
|
{{parser}}.invalid_option{|opt|
|
|
case opt
|
|
when /^-+[a-z-]+/
|
|
Logger.debug "#{PROGRAM_NAME} : ERROR : {{parser}} : invalid_option : Inavlid option provided #{opt}"
|
|
else
|
|
abort "#{PROGRAM_NAME} : ERROR : {{parser}} : invalid_option : Inavlid option provided #{opt}"
|
|
end
|
|
}
|
|
{{parser}}.missing_option{|opt|
|
|
abort "ERROR : {{parser}} : missing_option : Argument was not provided to #{opt}"
|
|
}
|
|
{{parser}}.unknown_args{|opt|
|
|
unless opt.empty?
|
|
case opt.first
|
|
when /^-+[a-z-]+$/
|
|
Logger.debug "ERROR : {{parser}} : unknown_args : #{opt} not a configured argument"
|
|
else
|
|
abort "ERROR : {{parser}} : unknown_args : #{opt} not a configured argument"
|
|
end
|
|
end
|
|
}
|
|
|
|
ADDITIONAL_DEFAULT_FLAGS.each do |flag|
|
|
args = [flag.short, flag.long, flag.description].reject(&.nil?)
|
|
{{parser}}.on(*args) &flag.work
|
|
end
|
|
end
|
|
|
|
macro define_root_parser
|
|
ROOT_COMMAND = OptionParser.new do |parser|
|
|
parser.banner = "#{PROGRAM_NAME} [command] [flags]"
|
|
|
|
{% commands = ::CliGen::Command.subclasses %}
|
|
{% raise "ERROR : No commands defined (no subclasses of ::CliGen::Command were found)" if commands.empty? %}
|
|
{% for command in commands %}
|
|
{{command.name}}.make_parser(parser)
|
|
{% end %}
|
|
|
|
define_default_flags(parser)
|
|
|
|
abort parser if ARGV.empty?
|
|
end
|
|
end
|
|
|
|
macro finished
|
|
{% verbatim do %}
|
|
macro finished
|
|
define_root_parser
|
|
end
|
|
{% end %}
|
|
end
|
|
|
|
def self.parse
|
|
ROOT_COMMAND.parse
|
|
end
|
|
end
|
|
|
|
require "./command"
|