2025年6月に「Announcing System.CommandLine 2.0.0-beta5 and our path to a stable release」が公開され、長らくベータ版が続いていた System.CommandLine がついに.NET 10 と同じタイミングで安定版リリースされました。
System.CommandLine は Microsoft 公式の .NET 向け CLI パーサーライブラリです。オプション・引数・サブコマンドを宣言的に定義でき、ヘルプ表示・バリデーション・タブ補完などをサポートしています。dotnet コマンド自体もこのライブラリで実装されています。
安定版で非推奨・削除されたライブラリ
安定化に際して、明確なリリースへの道筋がなかった一部のプロジェクトが廃止・非推奨になりました。
System.CommandLine.NamingConventionBinder
オプション名や引数名を、パラメーターやプロパティに自動バインディングする機能を提供していたパッケージです。安定版ではコアライブラリから切り離され、廃止されました。
System.CommandLine.Hosting
Microsoft.Extensions.Hosting との統合をサポートするパッケージです。こちらも廃止対象となりました。
System.CommandLine.Rendering
構造化されたコマンドライン出力レンダリングをサポートするパッケージです。こちらも廃止されました。
System.CommandLine.DragonFruit
Main メソッドのみで CLI アプリケーションを完結させるパッケージです。
// DragonFruit を使用した例(廃止済み)
static void Main(int intOption = 42, bool boolOption = false, FileInfo fileOption = null)
{
Console.WriteLine($"The value of intOption is: {intOption}");
Console.WriteLine($"The value of boolOption is: {boolOption}");
Console.WriteLine($"The value of fileOption is: {fileOption?.FullName ?? "null"}");
}
代替として紹介されたライブラリ
廃止されたパッケージの代替として、公式アナウンスで以下のサードパーティーライブラリが紹介されています。
Spectre.Console
コンソール出力をリッチにするためのライブラリです。Python の Rich ライブラリに強く影響を受けており、テーブルやグリッド・パネルなどを簡単に出力できます。
DotMake.CommandLine
System.CommandLine をラップする形で実装された、クラスベースの CLI ライブラリです。
基本的な使い方
Option の定義
Option<T> を使ってオプションを定義します。
var nameOption = new Option<string>("--name")
{
Description = "あいさつする相手の名前",
DefaultValueFactory = _ => "World" // デフォルト値を設定する場合
};
var rootCommand = new RootCommand("あいさつアプリ");
rootCommand.Options.Add(nameOption);
rootCommand.SetAction(parseResult =>
{
var name = parseResult.GetValue(nameOption);
Console.WriteLine($"Hello, {name}!");
});
$ myapp --name Alice
Hello, Alice!
Argument の定義
Argument<T> を使って位置引数を定義します。
var fileArgument = new Argument<string>("path") { Description = "The path of file" };
rootCommand.Arguments.Add(fileArgument);
rootCommand.SetAction(parseResult =>
{
var path = parseResult.GetValue(fileArgument);
Console.WriteLine($"Path is {path}!");
});
Option と Argument の違いは以下のとおりです。
| Option | Argument | |
|---|---|---|
| 記法 | --name Alice |
Alice(位置引数) |
| 必須 | 任意(デフォルト値可) | 通常は必須 |
| 例 | --output ./out |
git add <pathspec> |
サブコマンドの定義
Command を使ってサブコマンドを定義し、RootCommand に追加します。
var addCommand = new Command("add", "新しいアイテムを追加します");
addCommand.SetAction(_ =>
{
Console.WriteLine("「add」コマンドが実行されました。");
});
var listCommand = new Command("list", "アイテムの一覧を表示します");
listCommand.SetAction(_ =>
{
Console.WriteLine("「list」コマンドが実行されました。");
});
rootCommand.Subcommands.Add(addCommand);
rootCommand.Subcommands.Add(listCommand);
$ myapp add
「add」コマンドが実行されました。
$ myapp list
「list」コマンドが実行されました。
バリデーション
型バリデーションは自動で行われます。int 型に文字列を渡すとエラーになります。
// 型バリデーションは自動
var countOption = new Option<int>("--count") { Description = "繰り返し回数" };
// 必須オプションの設定
var nameOption = new Option<string>("--name") { Description = "名前", Required = true };
Validators を使ってカスタムバリデーションを追加することもできます。
var countOption = new Option<int>("--count")
{
Description = "繰り返す回数",
Required = true,
};
countOption.Validators.Add(result =>
{
if (result.GetValueOrDefault<int>() <= 0)
{
result.AddError("The count must be a positive integer.");
}
});
Argument や Command にもバリデーションロジックを追加できます。
ヘルプの自動生成
--help オプションは自動で生成されます。Description に設定した内容が表示されます。
$ myapp --help
Description: あいさつアプリ
Options:
--name <name> あいさつする相手の名前 [required]
--version Show version information
-?, -h, --help Show help and usage information
タブ補完
dotnet-suggest を使うことで、サブコマンドやオプションのタブ補完が可能です。対象の実行ファイルのパスを dotnet-suggest register --command-path で登録する必要があります。
さらに CompletionSources を実装することで、動的な補完候補の構成もできます。
var idArg = new Argument<int>("id") { Description = "完了にするTodoのID" };
idArg.CompletionSources.Add((ctx) =>
{
var todos = repo.GetAll();
return todos.Where(t => !t.IsCompleted).Select(t => t.Id.ToString());
});
まとめ
System.CommandLine 安定版で提供される主な機能は以下のとおりです。
| 機能 | 方法 |
|---|---|
| オプション定義 | new Option<T>("--name") |
| 位置引数 | new Argument<T>("file") |
| サブコマンド | new Command("add") |
| ヘルプ自動生成 |
--help で自動表示 |
| バリデーション | Validators.Add() |
| タブ補完 |
dotnet-suggest 連携 |
安定版では一部のパッケージが廃止されましたが、コア機能は整理・強化されています。CLI ツールの開発には引き続き System.CommandLine が有力な選択肢となりそうです。
参考