Open6

Argument Parser trial

nonanonnononanonno

コマンドライン引数の解釈をいくつか試す。

nonanonnononanonno

まとめ

getopt jcli argparse
ヘルプ生成
ポジショナル引数
ロングオプション
ショートオプション
オプション別名
フラグ
配列
ハッシュ
引数の型チェック
エラーメッセージ 例外によるもの
サブコマンド
構造体より
パススルー (--)
ハンドラー
デフォルト値 ✓(代入が行われない)
必須オプション
nonanonnononanonno

getopt

基本的な使い方

import std.getopt;
import std.conv;
import std.path;
import std.stdio;

void main(string[] args)
{
    struct Opt
    {
        // required
        string req1;
        string req2;
        // optional
        string opt1;
        string[] opt2;
        string[string] opt3;
        bool flag;
    }

    Opt o;

    auto optRet = getopt(args,
        config.required, "req1|r", "help for required argument 1", &o.req1,
        config.required, "req2|q", "help for required argument 2", &o.req2,
        "opt1|o", "help for optional argument 1", &o.opt1,
        "opt2|p", "help for optional array argument 2 long long long long long long long long", &o.opt2,
        "opt3", "help for optional hash argument 3", &o.opt3,
        "flag|f", "help for flag argument", &o.flag,
    );
    if (optRet.helpWanted)
    {
        defaultGetoptPrinter(text("Usage: ", baseName(args[0]), " [options]"), optRet.options);
        return;
    }

    writeln(o);

}
nonanonnononanonno

ポジショナル引数を模擬

import std.getopt;
import std.conv;
import std.path;
import std.stdio;

void main(string[] args)
{
    bool flag;

    auto optRet = getopt(args,
        "flag|f", "help for flag argument", &flag,
    );
    if (optRet.helpWanted)
    {
        defaultGetoptPrinter(text("Usage: ", baseName(args[0]), " [name] [options]"), optRet
                .options);
        return;
    }
    assert(args.length >= 2);
    string name = args[1];

    writeln(name, " ", flag);

}
nonanonnononanonno

サブコマンド的な

import std.getopt;
import std.conv;
import std.format;
import std.path;
import std.stdio;

void main(string[] args)
{
    immutable helpTextFmt = `Usage: %s [command] [options]
Commands
========
    sub1 = SUB1
    sub2 = SUB2

Options
=======`;

    auto cmd = args.length > 1 ? args[1] : "";

    switch (cmd)
    {
    case "sub1":
        sub1(args[1 .. $], [args[0].baseName]);
        break;
    case "sub2":
        sub2(args[1 .. $], [args[0].baseName]);
        break;
    default:
        auto optRet = getopt(args,
            config.passThrough,
        );
        defaultGetoptPrinter(format!helpTextFmt(args[0].baseName),
            optRet.options);
        return;
    }
}

void sub1(string[] args, string[] prog = [])
{
    immutable helpTextFmt = `Usage: %-(%s %) [options]`;
    bool flag;
    auto optRet = getopt(args,
        "flag", &flag
    );
    if (optRet.helpWanted)
    {
        defaultGetoptPrinter(format!helpTextFmt(prog ~ args[0]),
            optRet.options);
        return;
    }

}

void sub2(string[] args, string[] prog = [])
{
    immutable helpTextFmt = `Usage: %-(%s %) [command] [options]
Commands
========
    sub1 = SUB1
    sub2 = SUB2

Options
=======`;

    auto cmd = args.length > 1 ? args[1] : "";

    switch (cmd)
    {
    case "sub1":
        subsub1(args[1 .. $], prog ~ args[0]);
        break;
    case "sub2":
        subsub2(args[1 .. $], prog ~ args[0]);
        break;
    default:
        auto optRet = getopt(args,
            config.passThrough,
        );
        defaultGetoptPrinter(format!helpTextFmt(prog ~ args[0]),
            optRet.options);
        return;
    }
}

void subsub1(string[] args, string[] prog = [])
{
    immutable helpTextFmt = `Usage: %-(%s %) [options]`;
    bool flag;
    auto optRet = getopt(args,
        "flag", &flag
    );
    if (optRet.helpWanted)
    {
        defaultGetoptPrinter(format!helpTextFmt(prog ~ args[0]),
            optRet.options);
        return;
    }
}

void subsub2(string[] args, string[] prog = [])
{
    immutable helpTextFmt = `Usage: %-(%s %) [options]`;
    bool flag;
    auto optRet = getopt(args,
        "flag", &flag
    );
    if (optRet.helpWanted)
    {
        defaultGetoptPrinter(format!helpTextFmt(prog ~ args[0]),
            optRet.options);
        return;
    }

}