Signature DSL
The signature DSL compresses a command's name, positional arguments, and
options into a single Dart string. CommandSignature.parse
(lib/src/console/command_signature.dart:57) splits that string at
registration time; the registry applies it to the underlying ArgParser.
Contents
- Overview
- Grammar
- Token Types
- Argument Modifiers
- Option Modifiers
- Description Annotation
- Name Validation
- Examples
- Related
Overview
String get signature => 'cmd:name {arg} {arg?} {arg=default} {--flag} {--option=val}';
The signature string is the primary way to declare a command's surface. The
alternative is configure(ArgParser), used when the DSL cannot express the
required structure (multi-allowed options, allowed-values lists).
Of the 21 built-in commands: 6 use the signature DSL, 5 use
configure(ArgParser) with flags, 10 have no flag surface.
Grammar
signature := name (whitespace token)*
name := lowercase with optional colon-separated namespace
token := '{' (argument | option) '}'
argument := name [modifier] [' : ' description]
option := '--' name [value-spec] [' : ' description]
modifier := '?' | '*' | '?*' | '=' default
value-spec := '=' | '=' default
CommandSignature.parse (command_signature.dart:57) runs four stages:
- Extract name (
command_signature.dart:65): split on the first whitespace or{viaRegExp(r'[\s{]'); everything before is the name. - Extract token blocks (
command_signature.dart:82): scan the tail withRegExp(r'\{([^}]+)\}'); each capture is one token body. - Classify each token (
command_signature.dart:86): bodies starting with--route to_parseOption; others route to_parseArgument. - Parse modifiers: arguments check
=first (default value), then suffix?*/*/?. Options check=to distinguish a value option from a boolean flag.
A : separator (RegExp(r'\s+:\s+'), command_signature.dart:218)
strips the description annotation before modifier parsing in both branches.
Token Types
| Token form | Type | Read via |
|---|---|---|
{name} |
Positional argument | ctx.input.argument('name') |
{--name} |
Boolean flag | ctx.input.flag('name') |
{--name=} |
Value option, no default | ctx.input.option('name') |
{--name=default} |
Value option with default | ctx.input.option('name') |
Argument Modifiers
| Syntax | isOptional |
isVariadic |
defaultValue |
Behaviour |
|---|---|---|---|---|
{name} |
false | false | null | Required positional. |
{name?} |
true | false | null | Optional; argument() returns null when absent. |
{name=default} |
true | false | "default" |
Inline default; implies optional. |
{name*} |
false | true | null | Variadic, one or more trailing values. |
{name?*} |
true | true | null | Optional variadic, zero or more. |
Modifiers are parsed in declaration order (command_signature.dart:125):
= check first, then suffix ?* before * before ?.
Option Modifiers
| Syntax | isFlag |
defaultValue |
Behaviour |
|---|---|---|---|
{--flag} |
true | null | Boolean switch; absent means false. |
{--option=} |
false | null | Value option; option() returns null when absent. |
{--option=value} |
false | "value" |
Value option with inline default. |
CommandSignature.applyTo (command_signature.dart:103) calls
parser.addFlag (with negatable: false) for booleans and
parser.addOption(defaultsTo: opt.defaultValue) for value options.
Description Annotation
Append : text after a token's name and modifiers to attach a description:
{name : Argument description}
{--flag : Boolean flag description}
{--option=default : Value option description}
_splitDescription (command_signature.dart:205) matches the first
\s+:\s+ in the body and returns (head, description). The description
flows into ArgParser as help for options and flags; for arguments it is
stored on ArgumentSpec for introspection.
Name Validation
Both patterns are defined in command_signature.dart:214-216.
Command name (_namePattern):
^[a-z0-9_]+([:-][a-z0-9_]+)*$
Allows colon-namespaced or hyphen-namespaced segments (e.g. plugin:install,
sync-monitors). Uppercase, dots, or consecutive separators throw.
Argument and option names (_argNamePattern):
^[a-z0-9][a-z0-9_-]*$
Must start with a lowercase letter or digit; subsequent characters may
include underscores and hyphens. Both patterns throw FormatException at
parse time with the invalid value and expected pattern quoted in the message.
Examples
tinker (lib/src/commands/tinker_command.dart:22)
String get signature => 'tinker '
'{--eval= : Evaluate a single Dart expression in the running app, '
'print the formatted result on stdout, and exit. Pipe-friendly.}';
CommandSignature result: name tinker, no arguments, one value option
eval (isFlag: false, defaultValue: null). ctx.input.option('eval')
returns null in REPL mode and the expression string when --eval is set.
plugin:install (lib/src/commands/plugin_install_command.dart:67)
String get signature => 'plugin:install '
'$baseFlags'
'{name : Plugin pubspec package name (e.g. magic_logger)} '
'{--provider= : Override the auto-derived provider class name} '
'{--bootstrap-command= : Sub-command to chain after registration} '
'{--use-yaml-only : Fail if install.yaml not found}';
CommandSignature result: name plugin:install, one required positional
argument name, three own options (provider value, bootstrap-command
value, use-yaml-only flag), plus the options from baseFlags expansion.
plugin:uninstall (lib/src/commands/plugin_uninstall_command.dart:54)
String get signature => 'plugin:uninstall '
'$baseFlags'
'{name : Plugin pubspec package name}';
CommandSignature result: name plugin:uninstall, one required positional
argument name, no own options beyond those from baseFlags expansion.
Related
../commands/: per-command reference with full signature listings and usage examples.