0
0

More than 1 year has passed since last update.

TypeScriptでコマンドラインパラメーター解析

Posted at

Node.jsのCLIなツールをいくつかTypeScriptで作っています。

毎回コマンドラインパラメーターの解析が似たような処理になるので、関数にして使い回していました。

せっかくなのでパッケージとして公開しています。

特徴

  • コマンドラインパラメーターの解析として、当然指定されたパラメーターの情報に合わせて解析します。
    TypeScript用なので解析結果は指定した名前と型のプロパティを持つオブジェクトとして返します。
    このときのオブジェクトの型は可能な限り指定されたパラメーターの情報を反映したものにしてあります。
  • 指定されたパラメーター情報からヘルプ用の文字列を生成します。
    CLIに指定されたパラメーターにエラーがあれば自動的にヘルプ用文字列を表示するようにもできます。
  • プロパティの型情報にはパラメーターのヘルプ用の文字列や制約などの情報を載せています。VS Codeなどの型を表示してくれるエディターであれば、プロパティにマウスカーソルを合わせるだけで、そのパラメーターの情報を表示してくれます。
    image.png

使い方

まずはパッケージをインストールします。

npm install optionalist

ソースコードからインポートします。

import { parse, unnamed, helpString } from 'optionalist';

parseが解析用の関数、unnamed、helpStringは使用するシンボルです。

コマンドラインパラメータの解析にはparse関数にコマンドラインの詳細を指定します。

const options = parse({
  help: {
    type: 'boolean',
    alone: true,
    describe: 'このヘルプを表示します。',
  },
  timeout: {
    type: 'number',
    default: 5000,
    describe: 'タイムアウトまでの時間(単位ミリ秒)を指定します。',
    example: 'milliseconds',
  },
  list: {
    multiple: true,
    describe: '処理対象のファイルを記載したファイルを指定します。',
    example: 'filepath',
  },
  [unnamed]: {
    describe: '処理対象のファイルを指定します。',
    example: 'filepath',
  },
  [helpString]: {
    describe: 'サンプル用のプログラム',
    showUsageOnError: true,
  },
} as const);

解析結果のoptionsalone: trueが指定されたパラメーターhelpがあるのでUnion型になっています。

そのままでは扱いにくいので、まずはhelpから処理していきます。

if (options.help) {
  options;
  // const options: {
  //   readonly help: true & {
  //       [description]: ["--help: このヘルプを表示します。", "is specified alone."];
  //   };
  //   readonly timeout?: undefined;
  //   readonly list?: undefined;
  //   readonly [unnamed]?: undefined;
  //   readonly [helpString]: string;
  // }

  process.stdout.write(options[helpString]);
  process.exit(0);
}

options.helpがtrueになっていると他のプロパティ([helpString]を除く)はundefinedになっていてhelp以外はアクセスできなくなっています。

[helpString]だけはアクセスできるようになっているので、表示して終了してしまいます。

早期exitoptions.helptrueである可能性を潰したら、optionsの型はこんな感じになっています。

options;
// const options: {
//   readonly [unnamed]: readonly string[];
//   readonly [helpString]: string;
//   readonly help?: undefined;
//   readonly timeout: number & {
//       [description]: ["--timeout milliseconds: タイムアウトまでの時間(単位ミリ秒)を指定します。", "as 5000 if omitted."];
//   };
//   readonly list: readonly string[] & {
//       ...;
//   };
// }

timeoutはデフォルト値が指定されているので非オプショナルなnumberlistは複数指定可能なので stringの配列になっています。

正確にはそれぞれヘルプ用文字列やデフォルト値、複数指定可能などの情報が付加されています。

options.timeout;
// (property) timeout: number & {
//     [description]: ["--timeout milliseconds: タイムアウトまでの時間(単位ミリ秒)を指定します。", "as 5000 if omitted."];
// }
options.list;
// (property) list: readonly string[] & {
//     [description]: ["--list filepath: 処理対象のファイルを記載したファイルを指定します。", "can be specified multiple."];
// }

パラメーター情報にどういうものが指定できるかはoptionalistの方で確認してください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0