Upgrade to Pro — share decks privately, control downloads, hide ads and more …

祝!!System.CommandLine GA!!

Avatar for KM5075 KM5075
April 24, 2026
380

祝!!System.CommandLine GA!!

Avatar for KM5075

KM5075

April 24, 2026

Transcript

  1. Microsoft 公式の.NET 向け CLI パーサーライブラリ NuGet パッケージ: System.CommandLine リポジトリ: dotnet/command-line-api

    (GitHub ) .NET アプリにコマンドライン引数の解析機能を提供 オプション・引数・サブコマンドを宣言的に定義できる ヘルプ表示・バリデーション・タブ補完をサポート(dotnet-suggest ) dotnet コマンド自体も System.CommandLine 製 System.CommandLine とは? System.CommandLine とは? 5
  2. args[] を手動でパースすると… // 従来の方法 ← つらい if (args.Length > 0

    && args[0] == "--name") { var name = args[1]; // インデックスミス多発 } 純粋に1つのタスクだけを実行するならCLI ライブラリは不要。 ユーザーが入力したデータを受け取って、実行する処理を変えるようなケースでは arg のパースがしんどくなるためCLI ライブラリの使用が推奨。 なぜ CLI ライブラリを使用するか? なぜ CLI ライブラリを使用するか? 6
  3. CLI ツールの需要は高まっている? 自動化・CI/CD スクリプトとの連携 DevOps ツール・バッチ処理・開発補助ツール AI 連携をさせる場合、GUI ツールよりも安定 AI

    を使用して作成した業務効率化exe をまとめて管理することも可能 MCP との棲み分け なぜ CLI か?(続き) なぜ CLI か?(続き) 7
  4. 長い " ベータの旅" 時期 出来事 2020 年1 月 NuGet に

    版パッケージ初公開 0.3.0-alpha.20054.1 2020 〜2022 年 2.0.0-beta1 〜 beta3 リリース 2022 年〜2025 年 2.0.0-beta4.xxxx を最後に3 年間更新なし。 。 。 System.CommandLine の歴史 System.CommandLine の歴史 9
  5. 「Is this project dead? 」 ※2023 年 https://github.com/dotnet/command-line-api/issues/2285 「Roadmap for

    release? 」 ※2024 年 https://github.com/dotnet/command-line-api/issues/2500 Bata 版が長引いているときのコミュニティの反応 Bata 版が長引いているときのコミュニティの反応 10
  6. 「Announcing System.CommandLine 2.0.0-beta5 and our path to a stable release

    」 ※2025 年6 月 https://github.com/dotnet/command-line-api/issues/2576 そしてついに。 。 。 そしてついに。 。 。 11
  7. - 2.0.0-bata5 について API やメンバーのリネーム カスタム解析の改善 - 安定リリースについて - 一部実験プロジェクトの廃止について

    安定化リリースへの明確な道筋がなかったプロジェクトは非推奨に。 サードパーティーライブラリで代替 System.CommandLine としてはコア機能に集中 アナウンスの内容(抜粋) アナウンスの内容(抜粋) 12
  8. System.CommandLine.DragonFruit Main メソッドのみでCLI アプリケーションを完結させる 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"}"); } Stable Release で削除された機能たち2 Stable Release で削除された機能たち2 14
  9. 実行例 $ myapp --name Alice Hello, Alice! $ myapp --help

    # ← ヘルプ自動生成! 基本的な使い方: Option の実行例 基本的な使い方: Option の実行例 17
  10. 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}!"); }); 基本的な使い方: Option の追加 基本的な使い方: Option の追加 18
  11. Argument の定義 var fileArgument = Argument<string>("path"){ Description = "The path

    of file" }; rootCommand.Arguments.Add(nameArgument); rootCommand.SetAction( parseResult => { var path = parseResult.GetValue(nameArgument); Console.WriteLine($"Path is {path}!"); }); 基本的な使い方: Argument の定義 基本的な使い方: Argument の定義 20
  12. Option vs Argument の違い Option Argument 記法 --name Alice Alice

    (位置引数) 必須 任意(デフォルト値可) 通常は必須 例 --output ./out git add <pathspec> 基本的な使い方: Argument 基本的な使い方: Argument 21
  13. サブコマンドを実行する $ myapp add --item "タスクA" $ myapp list 基本的な使い方:

    サブコマンドの実行例 基本的な使い方: サブコマンドの実行例 22
  14. // 2. サブコマンド 'add' の定義とアクション設定 var addCommand = new Command("add",

    "新しいアイテムを追加します"); addCommand.SetAction(_ => { Console.WriteLine("「add」コマンドが実行されました。アイテムを追加します..."); }); // 3. サブコマンド 'list' の定義とアクション設定 var listCommand = new Command("list", "アイテムの一覧を表示します"); listCommand.SetAction(_ => { Console.WriteLine("「list」コマンドが実行されました。一覧を取得します..."); }); // 4. サブコマンドをルートに追加 rootCommand.Subcommands.Add(addCommand); rootCommand.Subcommands.Add(listCommand); 基本的な使い方: サブコマンドの使い方 基本的な使い方: サブコマンドの使い方 23
  15. 型バリデーションは自動 // int 型なので文字列を渡すとエラー var countOption = new Option<int>("--count", "繰り返し回数");

    // 必須オプションの設定 var nameOption = new Option<string>("--name", "名前") { IsRequired = true }; バリデーション バリデーション 24
  16. カスタムバリデーション Option<int> count = new Option<int>("--count") { Description = "The

    number of times to greet.", Required = true, }; // バリデーションロジック追加 count.Validators.Add(result => { if (result.GetValueOrDefault<int>() <= 0) { result.AddError("The count must be a positive integer."); } }); // ArgumentやCommandにもバリデーションロジックは追加可能 バリデーション バリデーション 25
  17. --help は自動生成 $ myapp --help Description: あいさつアプリ Options: --name <name>

    あいさつする相手の名前 [required] --version Show version information -?, -h, --help Show help and usage information ヘルプの自動生成 ヘルプの自動生成 26
  18. dotnet-suggest を用いることでサブコマンドやオプションの補完が可能。 ※この際に対象のExe のパスを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()); }); タブ補完 タブ補完 27
  19. 機能 方法 オプション定義 new Option<T>("--name") 位置引数 new Argument<T>("file") サブコマンド new

    Command("add") ヘルプ自動生成 --help で自動表示 バリデーション AddValidator() タブ補完 dotnet-suggest 連携 System.CommandLine でできること System.CommandLine でできること 30