annotation CliGen::Argument

Overview

This is used for annotating instance variables for the CliGen framework can know how to create your CliGen::Flag(T) objects

WHILE this is usually being handled by the CliGen::Command.argument macro inside of the class body.

EX:

class MyCmd < CliGen::Command
  argument(myvar : String = "test",
          short: "-m",
          long: "--myvar",
          description: "This is my test flag",
          options: %w[ test test2 test3 ]
  )

  def main 
    puts "@myvar was #{@myvar}"
  end
end

However, this can also be done manually if you don't want to use the macros you will make me sad, but otherwise it's understandable if you want do it manually. Just understand that the macros are there for doing all of the validations for user-friendly implementation.

Expected Metadata:

short:

Type: StringLiteral

Required: false

This represents the short form of the flag bring provided. it is optional as not all flags have to have a short form flag.

long:

Type: StringLiteral

Required: true

This represents the long-form of the flag. It is required in order to generate the Flag(T).

description:

Type: StringLiteral Required: true

This is the description of your flag and is required for Flag(T) creation

delimiter:

Type: StringLiteral

Required: false

For Flag(Array(T)) flags this is the delimiter that will seperate any inline args (ex: "," will split "a,b,c") provided at the commandline. If nil/not provided, the framework will default to ',' as this is the usual choice.

env_var:

Type: StringLiteral

Required: false

This is the ENV VAR that can be used to specify your flag value when not provided by the user.

validation:

Type: ProcLiteral

Required: false

This is a proc that can be used to provide an ad-hoc way of verifying the value provided by a user.

EX: Int Validator

validation: ->(i : Int32) : Bool do
  (1..23).includes?(i)
end

This is used as a fallback to where the options: key doesn't cleanly provide enough of a check for the provided values.

Note: The input value MUST be the same as the value type as the instance variable. Otherwise CliGen will not compile. IF requested I can add a raw_validation: key as well to do the same but for just the String variable provided by the user.

on_match:

Type: ProcLiteral

Required: false

Much like validation, this is used as a hook for doing arbitrary actions with the parsed value from the user (very useful for global flags).

EX: Log level setter

on_match: ->(arg : String) do
  begin
    ::Log.setup(level: ::Log::Severity.parse(arg))
  rescue e : ArgumentError
    STDERR.puts "ERROR : Failed to set to #{arg} log level: (#{e.class}: #{e.message})"
  end
end

In this way you can use on_match: to hook a global flag and have it call some arbitrary method elsewhere in the codebase to help setup the environment before the main command is run.

options:

Type: ArrayLiteral(T)|Call

Required: false

CURRENTLY this is being as a way of providing a static set of values that we are to use when doing a provided argument.

EX: Options for string var

options: %w[ a b c ]

Howver, this currently also supports delegating the retrieval of values (in array format) to be learned at runtime by providing a call to a global methods/class method/util method/etc

EX: Deletgating to runtime

module MyModule
  def self.my_method : Array(String)
    if File.exists?("/etc/valid_things.txt")
      File.read("/etc/valid_things.txt").split(",")
    else
      %w[ a b c ]
    end
  end

  CliGen.add_global_flag(String, 
                         short: "-t",
                         long: "--test",
                         description: "This does things. I promise",
                         options: ::MyModule.my_method,
                         on_match: ->(t : String) do 
                           puts "Matched #{t}"
                         end
  )
end

Doing things this way gives you some runtime flexibility, but makes you responsible for ensuring that it doesn't crash or provide incorrect data at runtime. As (unfortunately) the framework doesn't account for developer error at runtime like it can at compile-time with a static array of values.

format:

Type: RegexLiteral

Required: false

This metadata is used to provide (mostly for strings when you don't have a statically known list of values that can be provided at runtime, but you want to filter out invalid options.

EX: filtering for csv formatted info

format: /^([a-z0-9]+)(,?[a-z0-9]+)+$/

Defined in:

cligen/annotations.cr