Changing to cligen

This commit is contained in:
Tristan Ancelet
2026-02-23 13:08:56 -06:00
parent 9b50633c0e
commit 136298e67c
7 changed files with 32 additions and 32 deletions

View File

@@ -1,4 +1,4 @@
name: cli_generator name: cligen
version: 0.1.0 version: 0.1.0
authors: authors:

View File

@@ -1,8 +1,8 @@
require "spec" require "spec"
require "../src/command" require "../src/command"
@[CliGenerator::CommandInfo(description: "Test")] @[CliGen::CommandInfo(description: "Test")]
class CommandSubclass < CliGenerator::Command class CommandSubclass < CliGen::Command
define_argument(testvar, define_argument(testvar,
type: Int32, type: Int32,
@@ -22,19 +22,19 @@ EXAMPLES = [
"Have test" "Have test"
] ]
@[CliGenerator::SubCommand(description: "test", examples: ::EXAMPLES)] @[CliGen::SubCommand(description: "test", examples: ::EXAMPLES)]
def CommandSubclass.do_thing def CommandSubclass.do_thing
puts "HI" puts "HI"
end end
@[CliGenerator::CommandPreRun] @[CliGen::CommandPreRun]
def CommandSubclass.check_things def CommandSubclass.check_things
puts "I was run" puts "I was run"
end end
## Need to make sure EVERYTHING is generated before testing ## Need to make sure EVERYTHING is generated before testing
macro finished macro finished
describe CliGenerator::Command do describe CliGen::Command do
describe "subclassing" do describe "subclassing" do
@@ -57,7 +57,7 @@ describe CliGenerator::Command do
CommandSubclass::HEADER.includes?("Examples").should be_true CommandSubclass::HEADER.includes?("Examples").should be_true
end end
{% pre_runs = CommandSubclass.class.methods.select(&.annotation(::CliGenerator::CommandPreRun)) %} {% pre_runs = CommandSubclass.class.methods.select(&.annotation(::CliGen::CommandPreRun)) %}
{% run = CommandSubclass.class.methods.find{|m| m.name.stringify == "run"}.stringify %} {% run = CommandSubclass.class.methods.find{|m| m.name.stringify == "run"}.stringify %}
{% if pre_runs.size > 0 %} {% if pre_runs.size > 0 %}
describe "when defining pre-run methods" do describe "when defining pre-run methods" do
@@ -69,7 +69,7 @@ describe CliGenerator::Command do
end end
{% end %} {% end %}
{% subcommands = CommandSubclass.class.methods.select(&.annotation(::CliGenerator::SubCommand)) %} {% subcommands = CommandSubclass.class.methods.select(&.annotation(::CliGen::SubCommand)) %}
{% unless subcommands.empty? %} {% unless subcommands.empty? %}
describe "should have subcommands" do describe "should have subcommands" do
{% for subcommand in subcommands %} {% for subcommand in subcommands %}
@@ -79,7 +79,7 @@ describe CliGenerator::Command do
{% end %} {% end %}
end end
{% end %} {% end %}
{% arguments = CommandSubclass.class.methods.select(&.annotation(::CliGenerator::CommandArgument)) %} {% arguments = CommandSubclass.class.methods.select(&.annotation(::CliGen::CommandArgument)) %}
{% unless arguments.empty? %} {% unless arguments.empty? %}
describe "should have arguments" do describe "should have arguments" do
{% for argument in arguments %} {% for argument in arguments %}
@@ -105,7 +105,7 @@ describe CliGenerator::Command do
{% unless arguments.empty? %} {% unless arguments.empty? %}
describe "for arguments" do describe "for arguments" do
{% for argument in arguments %} {% for argument in arguments %}
{% anno = argument.annotation(::CliGenerator::CommandArgument) %} {% anno = argument.annotation(::CliGen::CommandArgument) %}
it "has " + {{anno[:long].stringify}} do it "has " + {{anno[:long].stringify}} do
{{make_parser}}.includes?({{anno[:long]}}).should be_true {{make_parser}}.includes?({{anno[:long]}}).should be_true
end end

View File

@@ -1,6 +1,6 @@
require "option_parser" require "option_parser"
module CliGenerator module CliGen
VERSION = "0.1.0" VERSION = "0.1.0"
record AdditionalDefaultFlag, record AdditionalDefaultFlag,
@@ -70,8 +70,8 @@ module CliGenerator
ROOT_COMMAND = OptionParser.new do |parser| ROOT_COMMAND = OptionParser.new do |parser|
parser.banner = "#{PROGRAM_NAME} [command] [flags]" parser.banner = "#{PROGRAM_NAME} [command] [flags]"
{% commands = ::CliGenerator::Command.subclasses %} {% commands = ::CliGen::Command.subclasses %}
{% raise "ERROR : No commands defined (no subclasses of ::CliGenerator::Command were found)" if commands.empty? %} {% raise "ERROR : No commands defined (no subclasses of ::CliGen::Command were found)" if commands.empty? %}
{% for command in commands %} {% for command in commands %}
{{command.name}}.make_parser(parser) {{command.name}}.make_parser(parser)
{% end %} {% end %}

View File

@@ -3,7 +3,7 @@ require "time"
require "./command/parser" require "./command/parser"
module CliGenerator module CliGen
annotation CommandPreRun annotation CommandPreRun
end end
@@ -19,7 +19,7 @@ module CliGenerator
class Command class Command
extend CliGenerator::Parser extend CliGen::Parser
@@action : String = "" @@action : String = ""
@@ -33,12 +33,12 @@ module CliGenerator
end end
macro define_actions macro define_actions
ACTIONS = {{@type.class.methods.select(&.annotation(::CliGenerator::SubCommand)).map(&.name.stringify)}} of String ACTIONS = {{@type.class.methods.select(&.annotation(::CliGen::SubCommand)).map(&.name.stringify)}} of String
end end
macro define_header macro define_header
{% name = @type.name.split("::").last.downcase.id %} {% name = @type.name.split("::").last.downcase.id %}
{% info_annos = @type.class.methods.select(&.annotation(::CliGenerator::SubCommand)).map(&.annotation(::CliGenerator::SubCommand)) %} {% info_annos = @type.class.methods.select(&.annotation(::CliGen::SubCommand)).map(&.annotation(::CliGen::SubCommand)) %}
{% examples = [] of StringLiteral %} {% examples = [] of StringLiteral %}
{% info_annos.select(&.[](:examples)).map(&.[](:examples).resolve).each(&.each{|example| examples << example}) %} {% info_annos.select(&.[](:examples)).map(&.[](:examples).resolve).each(&.each{|example| examples << example}) %}
HEADER = [ HEADER = [
@@ -78,7 +78,7 @@ module CliGenerator
end end
{% end %} {% end %}
@[::CliGenerator::CommandArgument(type: {{type}}, short: {{short}}, long: {{long}}, description: {{description}})] @[::CliGen::CommandArgument(type: {{type}}, short: {{short}}, long: {{long}}, description: {{description}})]
def self.{{arg_name}}(var : String) : Nil def self.{{arg_name}}(var : String) : Nil
{% if check %} {% if check %}
## If the check exists go ahead and call it ## If the check exists go ahead and call it
@@ -94,14 +94,14 @@ module CliGenerator
{% end %} {% end %}
{% if _type == "Time" %} {% if _type == "Time" %}
formats = [ formats = [
CliGenerator::Regex::INPUT_DATETIME_REGEX, CliGen::Regex::INPUT_DATETIME_REGEX,
CliGenerator::Regex::INPUT_DATE_REGEX CliGen::Regex::INPUT_DATE_REGEX
] ]
abort "ERROR : Command : {{arg_name}} : Incorrect format for provided data #{var}" unless formats.any?{|f| var.match(f)} abort "ERROR : Command : {{arg_name}} : Incorrect format for provided data #{var}" unless formats.any?{|f| var.match(f)}
if var =~ formats[0] if var =~ formats[0]
@@{{variable}} = Time.parse_local(var, CliGenerator::Format::INPUT_DATETIME_FORMAT) @@{{variable}} = Time.parse_local(var, CliGen::Format::INPUT_DATETIME_FORMAT)
elsif var =~ formats[1] elsif var =~ formats[1]
@@{{variable}} = Time.parse_local(var, CliGenerator::Format::INPUT_DATE_FORMAT) @@{{variable}} = Time.parse_local(var, CliGen::Format::INPUT_DATE_FORMAT)
end end
{% elsif _type == "Array" %} {% elsif _type == "Array" %}
{% if _subtype == "Int32" %} {% if _subtype == "Int32" %}
@@ -123,7 +123,7 @@ module CliGenerator
macro define_runner macro define_runner
def self.run def self.run
{% pre_run_commands = @type.class.methods.select(&.annotation(::CliGenerator::CommandPreRun)) %} {% pre_run_commands = @type.class.methods.select(&.annotation(::CliGen::CommandPreRun)) %}
{% unless pre_run_commands.empty? %} {% unless pre_run_commands.empty? %}
## Ensuring that all runs that are tagged with the the CommandPreRun annotation are run ## Ensuring that all runs that are tagged with the the CommandPreRun annotation are run
{% for method in pre_run_commands %} {% for method in pre_run_commands %}
@@ -131,7 +131,7 @@ module CliGenerator
{% end %} {% end %}
{% end %} {% end %}
{% methods = @type.class.methods.select(&.annotation(::CliGenerator::SubCommand)) %} {% methods = @type.class.methods.select(&.annotation(::CliGen::SubCommand)) %}
{% raise "ERROR : No commands defined for #{@type.name}" if methods.empty? %} {% raise "ERROR : No commands defined for #{@type.name}" if methods.empty? %}
{% begin %} {% begin %}
case @@action case @@action

View File

@@ -1,4 +1,4 @@
module CliGenerator::Parser module CliGen::Parser
macro extended macro extended
{% verbatim do %} {% verbatim do %}
@@ -7,26 +7,26 @@ module CliGenerator::Parser
{% puts "#{@type.name} OptionParser is being generated" %} {% puts "#{@type.name} OptionParser is being generated" %}
{% name = @type.name.split("::").last %} {% name = @type.name.split("::").last %}
{% var = name.downcase %} {% var = name.downcase %}
{% info = @type.annotation(::CliGenerator::CommandInfo) %} {% info = @type.annotation(::CliGen::CommandInfo) %}
{% raise "ERROR : No CommandInfo annotation provided to #{@type.name}" unless info %} {% raise "ERROR : No CommandInfo annotation provided to #{@type.name}" unless info %}
subparser = OptionParser.new do |parser| subparser = OptionParser.new do |parser|
parser.banner = {{@type.name}}::HEADER parser.banner = {{@type.name}}::HEADER
{% subcommands = @type.class.methods.select(&.annotation(::CliGenerator::SubCommand)) %} {% subcommands = @type.class.methods.select(&.annotation(::CliGen::SubCommand)) %}
{% if subcommands.size > 0 %} {% if subcommands.size > 0 %}
define_section("Subcommands", parser) define_section("Subcommands", parser)
{% for subcommand in subcommands %} {% for subcommand in subcommands %}
{% subcommand_anno = subcommand.annotation(::CliGenerator::SubCommand) %} {% subcommand_anno = subcommand.annotation(::CliGen::SubCommand) %}
parser.on({{subcommand.name.stringify}}, {{subcommand_anno[:description]}}){ parser.on({{subcommand.name.stringify}}, {{subcommand_anno[:description]}}){
{{@type.name}}.action= {{subcommand.name.stringify}} {{@type.name}}.action= {{subcommand.name.stringify}}
} }
{% end %} {% end %}
{% end %} {% end %}
{% arguments = @type.class.methods.select(&.annotation(::CliGenerator::CommandArgument)) %} {% arguments = @type.class.methods.select(&.annotation(::CliGen::CommandArgument)) %}
{% if arguments.size > 0 %} {% if arguments.size > 0 %}
define_section("Provide Arguments", parser) define_section("Provide Arguments", parser)
{% for argument in arguments %} {% for argument in arguments %}
{% argument_anno = argument.annotation(::CliGenerator::CommandArgument) %} {% argument_anno = argument.annotation(::CliGen::CommandArgument) %}
{% if argument_anno[:short] == "" && argument_anno[:long] != "" %} {% if argument_anno[:short] == "" && argument_anno[:long] != "" %}
parser.on({{argument_anno[:long]}}, {{argument_anno[:description]}}){|val| parser.on({{argument_anno[:long]}}, {{argument_anno[:description]}}){|val|
{% elsif argument_anno[:short] != "" && argument_anno[:long] == "" %} {% elsif argument_anno[:short] != "" && argument_anno[:long] == "" %}

View File

@@ -1,4 +1,4 @@
module CliGenerator::Format module CliGen::Format
INPUT_DATETIME_FORMAT = "%Y-%m-%d" INPUT_DATETIME_FORMAT = "%Y-%m-%d"
INPUT_TIME_FORMAT = "%Y-%m-%d %H:%M:%S" INPUT_TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
end end

View File

@@ -1,4 +1,4 @@
module CliGenerator::Regex module CliGen::Regex
INPUT_DATETIME_REGEX = /^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$/ 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}$/ INPUT_DATE_REGEX = /^[0-9]{4}-[0-9]{2}-[0-9]{2}$/
end end