Parse
This is the frontend @cast
and @main
of Comonicon
.
The @main
command will use generate the following functions in the module:
- the entry function for CLI
command_main
. comonicon_install
: for command build and installation.comonicon_install_path
: for path build and installation.julia_main
: for building standalone applications.
And a registry constant CASTED_COMMANDS
in the module, one can find the original Comonicon AST by indexing CASTED_COMMANDS
by your command name.
References
Comonicon.Comonicon
— ModuleAll the terminals are under my command. Comonicon
is a CLI (Command Line Interface) generator that features light-weight dependency (optional to have zero dependency), fast start-up time and easy to use. See the website for more info.
Comonicon.CommandError
— Typestruct CommandError <: CommandException
Exception type for general CLI compatible errors thrown by cmd_error
.
Comonicon.CommandException
— TypeCommandException <: Exception
Abstract type for command exceptions. All command exceptions should contain an exitcode
field.
Comonicon.CommandExit
— Typestruct CommandExit <: CommandException
Exception type for cmd_exit
.
Comonicon.cmd_error
— Functioncmd_error(msg::String, code::Int = 1)
Throw a CommandError
with message msg
and return code code
. This is preferred as exception handle when writing a CLI compatible Julia program.
When the program is running in normal Julia execution the error will print as normal Julia exception with stacktrace.
When the progrm is running from a CLI entry, the exception is printed as standard CLI exceptions with exit code (default is 1
). Then the corresponding help message is printed.
Comonicon.cmd_exit
— Functioncmd_exit(code::Int = 0)
Exit the CLI program with code
. This method is preferred over exit
to make sure the program won't exit directly without handling the exception.
Comonicon.default_name
— Methoddefault_name(x::String)
Return the lowercase of a given package name. It will ignore the suffix if it ends with ".jl".
Comonicon.get_version
— Methodget_version(m::Module)
Get the version of a given module. It will try to find the version of Project.toml
if the given module is a project module. If fails, it returns v"0.0.0"
.
Comonicon.parse_kwargs
— Methodparse_kwargs(fn::JLFunction) -> flags, options
Parse the keyword arguments of function expression fn
into intermediate Julia CLI objects JLFlag
and JLOption
.
Comonicon.rm_format
— Functionrm_format(md)
Remove Markdown DOM and flatten to strings.
Comonicon.set_cmd!
— Functionset_cmd!(cmds::Dict, cmd)
register cmd
in the command registry cmds
, which usually is a constant CASTED_COMMANDS
under given module.
Comonicon.write_cmd
— Methodwrite_cmd(filename, cmd::Entry)
Write a command to filename
.
Comonicon.@cast
— Macro@cast <function definition>
@cast <module definition>
Denote a Julia expression is a command. If the expression is a function definition, it will be parsed as a leaf command, if the expression is a module definition or module name, it will be parsed as a node command. This macro must be used with @main
to create a multi-command CLI.
Quick Example
# in a script or module
"""
sum two numbers.
# Args
- `x`: first number
- `y`: second number
# Options
- `-p, --precision=<type>`: precision of the calculation.
# Flags
- `-f, --fastmath`: enable fastmath.
"""
@cast function sum(x, y; precision::String="float32", fastmath::Bool=false)
# implementation
return
end
"product two numbers"
@cast function prod(x, y)
return
end
@main
Comonicon.@lazyload
— Macro@lazyload expr @cast <valid castable expr>
Evaluate expr
if command f
is called. This is useful for reducing the latency of scripts that has subcmds depend on plotting, serialization etc.
Please see @cast
for valid expression specifications.
This macro only works at top-level command and thus can only be used in Main
and only works in scripts. Using this macro in any other module or a project module will not work.
Comonicon.@main
— Macro@main
@main <function definition>
Main entry of the CLI application.
Quick Example
# in a script or module
"""
sum two numbers.
# Args
- `x`: first number
- `y`: second number
# Options
- `-p, --precision=<type>`: precision of the calculation.
# Flags
- `-f, --fastmath`: enable fastmath.
"""
@main function sum(x, y; precision::String="float32", fastmath::Bool=false)
# implementation
return
end
CLI Definitions and Julia Syntax Mapping
positional arguments normal inputs, these are mapped as Julia function arguments, e.g
sum 1 2
sum
is the command, and 1
, 2
are positional arguments.
options arguments with syntax --<name>=<value>
or --<name> <value>
, these are mapped as Julia keyword arguments, e.g
sum --precision=float32 1 2
--precision
is the option of command sum
and has value float32
.
short options arguments with syntax -<letter>=<value>
or -<letter><value>
or --<letter> <value>
, the letter is usually the first character of a normal option, e.g
sum -pfloat32 1 2
-p
is the same as --precision
, but in short hand, this is enabled by writing corresponding docstring (see the next section on docstring syntax).
flags like options, but without any value, e.g --<name>
, this is mapped to a special type of keyword argument that is of type Bool
and has default value false
, e.g
sum --fastmath
short flags flags with syntax -<letter>
, the letter should be the first character of the corresponding normal flag, e.g
sum -f
Doc String Syntax
Each different kind of inputs must have a different level-1 section (markdown syntax #<section name>
).
The docstring must have section name:
#Args
or#Arguments
to declare the documentation of positional arguments.#Options
to declare the documentation of options.#Flags
to declare the documentation of flags.
Examples
The simplest usage is creating the following commands
"""
an example command
# Args
- `x`: first argument
- `y`: second argument
- `z`: last argument
# Flags
- `-f, --flag`: a flag, optionally can be a short flag.
# Options
- `-o, --option=<int>`: an option, optionally can be short option.
"""
@cast function mycommand(x, y, z; flag::Bool=false, option::Int=2)
# some implementation
return
end
@cast function myothercommand(xs...)
# another command with variatic arguments
return
end
"""
My main command.
"""
@main # declare the entry
this can be used in command line as mycommand 1 2 3 --flag
, you can also just type -h
to check the detailed help info.
The command line documentation will be generated automatically from your Julia docstring.
If you have deeper hierachy of commands, you can also put @cast
on a Julia module.
using Comonicon
@cast module NodeCommand
using Comonicon
@cast module NodeSubCommand
using Comonicon
@cast bar(x) = println("bar $x")
end
@cast foo(x) = println("foo $x")
@main
end
NodeCommand.command_main()