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"