Committing before help rework
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
# CliGen::Command.argument Macro
|
||||
|
||||
## TOC
|
||||
- [Overview](#Overview)
|
||||
|
||||
## Overview
|
||||
This macro as explained briefly in the [Macros Doc](../Macros.md), handles setting up and configuring instance variables & configuring instance variables & annotations as well as checking for misconfigurations in your provided macro arguments before you experience.
|
||||
|
||||
Overall this is used for annotating instance variables for the CliGen framework can know how to create your [CliGen::Flag(T)][flag-doc] objects.
|
||||
|
||||
```crystal
|
||||
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
|
||||
```
|
||||
|
||||
## Caveots
|
||||
### Dedicated short & long flasg
|
||||
A unfortunate limitation is that the `-h|--help` & `-v|--verbose` flags are all allocated to two internal flags used by all [CommandNode(T)][commandnode-doc] objects
|
||||
|
||||
### Duplicate Short Flags
|
||||
While this is limited to Flags defined in your Command
|
||||
|
||||
## Arguments
|
||||
### 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)][flag-doc].
|
||||
|
||||
### 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][flag-doc](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.
|
||||
|
||||
```crystal
|
||||
validation: ->(i : Int32) : Bool do
|
||||
(1..23).includes?(i)
|
||||
end
|
||||
```
|
||||
*Example: Int Validator*
|
||||
|
||||
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).
|
||||
|
||||
```crystal
|
||||
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
|
||||
```
|
||||
*Example: Log level setter*
|
||||
|
||||
NOTE: This specific example will be reworked once Enum support is added to the framework to do checking directly.
|
||||
|
||||
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.
|
||||
|
||||
```crystal
|
||||
options: %w[ a b c ]
|
||||
```
|
||||
*Example: Options for string var*
|
||||
|
||||
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
|
||||
|
||||
```crystal
|
||||
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
|
||||
```
|
||||
*Example: Deletgating to runtime*
|
||||
|
||||
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.
|
||||
|
||||
```crystal
|
||||
format: /^([a-z0-9]+)(,?[a-z0-9]+)+$/
|
||||
```
|
||||
EX: filtering for csv formatted info
|
||||
|
||||
|
||||
[command-doc]: ../../Command.md
|
||||
[flag-doc]: ../../Flag.md
|
||||
[commandnode-doc]: ../../CommandNode.md
|
||||
Reference in New Issue
Block a user