Parse

This is the frontend @cast and @main of Comonicon.

The @main command will use generate the following functions in the module:

  1. the entry function for CLI command_main.
  2. comonicon_install: for command build and installation.
  3. comonicon_install_path: for path build and installation.
  4. 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.ComoniconModule

All 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.

source
Comonicon.CommandExceptionType
CommandException <: Exception

Abstract type for command exceptions. All command exceptions should contain an exitcode field.

source
Comonicon.cmd_errorFunction
cmd_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.

source
Comonicon.cmd_exitFunction
cmd_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.

source
Comonicon.default_nameMethod
default_name(x::String)

Return the lowercase of a given package name. It will ignore the suffix if it ends with ".jl".

source
Comonicon.get_versionMethod
get_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".

source
Comonicon.parse_kwargsMethod
parse_kwargs(fn::JLFunction) -> flags, options

Parse the keyword arguments of function expression fn into intermediate Julia CLI objects JLFlag and JLOption.

source
Comonicon.set_cmd!Function
set_cmd!(cmds::Dict, cmd)

register cmd in the command registry cmds, which usually is a constant CASTED_COMMANDS under given module.

source
Comonicon.@castMacro
@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
source
Comonicon.@lazyloadMacro
@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.

Warning

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.

source
Comonicon.@mainMacro
@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()
source