ae.utils.funopt
ae.utils.funopt
is a std.getopt
enhancer:
import std.stdio, ae.utils.funopt;
int run(bool verbose, string input, string output)
{
// ...
return 0;
}
int main(string[] args)
{
try
return funopt!run(args);
catch (Exception e)
{
stderr.writeln("Error: ", e.msg);
return 1;
}
}
Running program --verbose input.txt output.txt
will cause run
to be called with the appropriate arguments.
Additionally, funopt
will generate and print a usage text if a mandatory parameter was not specified, or when --help
is present:
$ program
Usage: program [--verbose] INPUT OUTPUT
Error: No input specified.
The usage text is generated from the function signature as a string constant during compilation. Optional arguments and arrays are handled appropriately.
If naked types are not sufficiently expressive, ae.utils.funopt
provides some wrapper templates which allow specifying additional properties, such as a single-letter shorthand variant, --help
descriptions, or non-boolean switches:
int run(
Switch!("Enable verbose logging", 'v') verbose,
Option!(int, "Number of tries") tries,
Option!(int, "Seconds to wait each try", "SECS") timeout,
string filename,
string output = "default",
string[] extraFiles = null,
)
The automatically-generated usage for the above function signature will be:
Usage: program [OPTION]... FILENAME [OUTPUT] [EXTRA-FILES]...
Options:
-v, --verbose Enable verbose logging
--tries=N Number of tries
--timeout=SECS Seconds to wait each try
If your program has multiple sub-commands (as do e.g. git
/hg
/svn
), ae.utils.funopt
has a funoptDispatch
function which can call an appropriate static method, as well as generate a list of actions for --help
text:
import ae.utils.funopt;
struct Actions
{
static:
@(`Creates a new repository at this location.`)
void init() { /* ... */ }
@(`Pulls in changes from an existing repository at the given URL.`)
void pull(bool shallow, bool recursive, string url) { /* ... */ }
@(`Pushes changes to the repository at specified URL.`)
void push(bool force, string url) { /* ... */ }
}
void main(string[] args)
{
return funoptDispatch!Actions(args);
}
Method descriptions are currently specified using a string UDA, however it should be possible to move to documentation comments if/when DMD pull request #3531 is merged.
Example output:
$ scm --help
Usage: scm ACTION [ACTION-ARGUMENTS]...
Actions:
init Creates a new repository at this location.
pull Pulls in changes from an existing repository at the given URL.
push Pushes changes to the repository at specified URL.
$ scm pull --help
Usage: scm pull [--shallow] [--recursive] URL
Code: ae.utils.funopt