# 通知設計書 25---debug-repeat measurements

## 概要

`--debug-repeat`オプション使用時に繰り返し実行測定結果をデバッグ出力する通知の設計書です。

### 本通知の処理概要

本通知は、Prettierの`--debug-repeat`オプションを使用した際に、formatWithCursor関数を指定回数繰り返し実行し、その平均実行時間を測定・出力するものです。`--debug-benchmark`より軽量な測定方法として、外部パッケージなしで使用できます。

**業務上の目的・背景**：パフォーマンス測定は開発において重要ですが、tinybenchのようなベンチマークライブラリのインストールが必要な場合があります。`--debug-repeat`オプションは、外部依存なしに簡易的なパフォーマンス測定を可能にし、迅速なパフォーマンス確認を支援します。また、環境変数`PRETTIER_PERF_REPEAT`でも同様の機能を利用できるため、CI/CD環境での自動測定にも適しています。

**通知の送信タイミング**：`--debug-repeat N`オプションが指定された状態（または`PRETTIER_PERF_REPEAT`環境変数が設定された状態）でファイルフォーマットを実行した際、format関数内で繰り返し実行が完了した後に出力されます。

**通知の受信者**：CLIを実行している開発者（標準エラー出力経由）。

**通知内容の概要**：複数のデバッグメッセージが出力されます：
1. 繰り返し実行開始メッセージ（実行回数を含む）
2. 繰り返し実行測定結果（JSON形式：repeat, hz, ms）

**期待されるアクション**：開発者は出力された測定結果（ops/sec、平均ミリ秒）を確認し、パフォーマンスの評価や比較分析を行います。

## 通知種別

CLIデバッグ出力（stderr）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期 |
| 優先度 | 低（デバッグ情報） |
| リトライ | 無 |

### 送信先決定ロジック

`--debug-repeat`オプションまたは`PRETTIER_PERF_REPEAT`環境変数が指定されている場合、logLevelが自動的にdebugに設定され、`logger.debug`メソッドで出力されます。

## 通知テンプレート

### CLI出力の場合

| 項目 | 内容 |
|-----|------|
| 出力先 | stderr |
| プレフィックス | `[debug]`（青色） |
| 形式 | テキスト（JSON含む） |

### 本文テンプレート

#### 繰り返し実行開始メッセージ
```
[debug] '{name}' found, running formatWithCursor {repeat} times.
```

#### 繰り返し実行結果メッセージ
```
[debug] '{name}' measurements for formatWithCursor: {
  "repeat": N,
  "hz": xxx.xx,
  "ms": x.xxx
}
```

### 添付ファイル

なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| name | パフォーマンステストフラグ名 | performanceTestFlag.name | Yes |
| repeat | 繰り返し実行回数 | performanceTestFlag.debugRepeat | Yes |
| hz | 1秒あたりの実行回数 | 1000 / averageMs | Yes |
| ms | 平均実行時間（ミリ秒） | (end - start) / repeat | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| CLI実行 | format関数実行時 | `context.performanceTestFlag?.debugRepeat > 0` | 繰り返し測定完了後 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `--debug-repeat`が未指定かつ`PRETTIER_PERF_REPEAT`未設定 | 測定自体が行われない |
| `--debug-repeat 0` | debugRepeatが0の場合は実行されない |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[CLI実行開始] --> B{--debug-repeat指定?}
    B -->|No| C{PRETTIER_PERF_REPEAT設定?}
    C -->|No| D[通常フォーマット処理]
    B -->|Yes| E[performanceTestFlag設定]
    C -->|Yes| E
    E --> F[logLevelをdebugに設定]
    F --> G[format関数呼び出し]
    G --> H{performanceTestFlag?.debugRepeat > 0?}
    H -->|No| D
    H -->|Yes| I[開始メッセージ出力]
    I --> J[タイムスタンプ記録開始]
    J --> K[formatWithCursorをrepeat回実行]
    K --> L[タイムスタンプ記録終了]
    L --> M[平均時間計算]
    M --> N[結果JSON出力]
    N --> O[処理完了]
```

## データベース参照・更新仕様

### 参照テーブル一覧

なし

### 更新テーブル一覧

なし

## エラー処理

### エラーケース一覧

なし（単純なループ処理のため）

### リトライ仕様

なし

## 配信設定

### レート制限

なし（CLI実行ごとに1回）

### 配信時間帯

制限なし

## セキュリティ考慮事項

- 測定結果にはパフォーマンス情報のみが含まれ、機密情報は含まれない
- 環境変数からも設定可能なため、CI/CD環境での使用に適している

## 備考

- `--debug-repeat`はCLIオプション、`PRETTIER_PERF_REPEAT`は環境変数
- 外部パッケージ（tinybench）不要で軽量に使用可能
- mockable.getTimestamp()を使用して時間を計測（テスト時のモック対応）
- 実際の出力はスキップされる（skipped print code or write files）
- `--debug-benchmark`と異なり、統計的な分析は行わない

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、performanceTestFlagオブジェクトの構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | context.js | `src/cli/context.js` | performanceTestFlagゲッターのdebugRepeat部分を確認 |
| 1-2 | cli-options.evaluate.js | `src/cli/cli-options.evaluate.js` | debugRepeatオプションの定義を確認 |

**読解のコツ**: context.jsの69-84行目でdebugRepeatおよびPRETTIER_PERF_REPEATの処理を確認。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.js | `src/cli/index.js` | performanceTestFlag時のlogger設定変更を確認 |

**主要処理フロー**:
1. **28-30行目**: performanceTestFlag有効時のloggerをdebugに変更

#### Step 3: 繰り返し実行処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | format.js | `src/cli/format.js` | format関数内のdebugRepeat処理 |

**主要処理フロー**:
- **184-208行目**: debugRepeat時の処理
- **185-188行目**: 繰り返し実行開始メッセージ
- **189-192行目**: ループ実行
- **193-198行目**: 結果計算
- **199-207行目**: 結果の出力

### プログラム呼び出し階層図

```
src/cli/index.js::run()
    │
    ├─ new Context()
    │      │
    │      └─ context.performanceTestFlag（getter）
    │             │
    │             ├─ debugRepeat判定
    │             │
    │             └─ PRETTIER_PERF_REPEAT判定
    │
    ├─ logLevelをdebugに変更
    │
    └─ main()
           │
           └─ formatFiles() / formatStdin()
                  │
                  └─ format()
                         │
                         ├─ mockable.getTimestamp()（開始）
                         │
                         ├─ for loop: formatWithCursor() × repeat回
                         │
                         ├─ mockable.getTimestamp()（終了）
                         │
                         └─ logger.debug()（結果出力）
```

### データフロー図

```
[入力]                       [処理]                        [出力]

--debug-repeat N ────▶ performanceTestFlag設定 ────▶ debugRepeat: N
        or
PRETTIER_PERF_REPEAT
                                    │
入力ファイル ───────────▶ format関数
                                    │
                                    ├─▶ start = getTimestamp()
                                    │
                                    ├─▶ formatWithCursor() × N回
                                    │
                                    ├─▶ end = getTimestamp()
                                    │
                                    └─▶ 平均時間計算 ────▶ [debug] 測定結果JSON
                                                               │
                                                               └─▶ stderr
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| format.js | `src/cli/format.js` | ソース | 繰り返し実行処理の実装 |
| context.js | `src/cli/context.js` | ソース | performanceTestFlagゲッター |
| index.js | `src/cli/index.js` | ソース | CLIエントリーポイント、logLevel変更 |
| logger.js | `src/cli/logger.js` | ソース | ログ出力機能 |
| cli-options.evaluate.js | `src/cli/cli-options.evaluate.js` | ソース | debugRepeatオプション定義 |
| mockable.js | `src/cli/mockable.js` | ソース | getTimestamp関数（テスト用モック対応） |
