# 帳票設計書 11-差異ファイル一覧

## 概要

本ドキュメントは、Prettierの`--list-different`オプション（エイリアス: `-l`）によって出力される「差異ファイル一覧」の帳票設計について記述する。この帳票は、Prettierのフォーマット規則に従っていないファイルのパス一覧を標準出力に出力する機能である。

### 本帳票の処理概要

この帳票では、Prettierが指定されたファイル群をスキャンし、現在のファイル内容とPrettierによるフォーマット後の内容を比較して、差異があるファイルのパスを一覧として出力する。

**業務上の目的・背景**：CI/CDパイプラインやGitフック（pre-commit）において、コードスタイルが統一されているかを検証するために使用される。フォーマットが必要なファイルをリスト形式で取得することで、自動化スクリプトや外部ツールとの連携が容易になる。`--check`オプションと異なり、人間向けのサマリーメッセージを出力せず、純粋なファイルパス一覧のみを出力するため、パイプライン処理に適している。

**帳票の利用シーン**：
- CI/CDパイプラインで、フォーマット違反ファイルを検出し、自動修正するワークフロー
- pre-commitフックで、コミット前にフォーマットが必要なファイルを特定
- シェルスクリプトやMakefileでの自動化処理において、フォーマット未実施ファイルを抽出

**主要な出力内容**：
1. フォーマット差異があるファイルのパス（現在の作業ディレクトリからの相対パス、POSIX形式）
2. 標準入力からの処理時は `(stdin)` という固定文字列

**帳票の出力タイミング**：`prettier --list-different <ファイルパターン>` または `prettier -l <ファイルパターン>` コマンド実行時に、フォーマット差異があるファイルごとに即座に出力される。

**帳票の利用者**：開発者、CI/CDシステム、自動化スクリプト

## 帳票種別

ファイルリスト出力（標準出力へのテキスト出力）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | CLI（コマンドライン） | - | `prettier --list-different <files>` または `prettier -l <files>` |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | テキスト（標準出力） |
| 用紙サイズ | - |
| 向き | - |
| ファイル名 | - （標準出力への直接出力） |
| 出力方法 | 標準出力（stdout） |
| 文字コード | UTF-8 |

### 出力形式詳細

- 各ファイルパスは1行ごとに出力される
- ファイルパスは現在の作業ディレクトリからの相対パスで、POSIX形式（スラッシュ区切り）に正規化される
- 標準入力からの処理時は `(stdin)` が出力される

## 帳票レイアウト

### レイアウト概要

帳票はヘッダー部を持たず、フォーマット差異があるファイルのパスが1行ずつ出力される単純なリスト形式である。

```
┌─────────────────────────────────────┐
│ ファイルパス1                        │
│ ファイルパス2                        │
│ ファイルパス3                        │
│ ...                                 │
└─────────────────────────────────────┘
```

### 明細部

| No | 項目名 | 説明 | データ取得元 | 表示形式 | 列幅 |
|----|-------|------|-------------|---------|-----|
| 1 | ファイルパス | フォーマット差異があるファイルのパス | `path.relative(cwd, filename)` + `normalizeToPosix()` | 相対パス（POSIX形式） | 可変 |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| ファイルパターン | globパターンで指定されたファイル群 | Yes |
| フォーマット差異 | `prettier.check(input, options)` が `false` を返す | Yes |
| 無視対象外 | `.prettierignore` 等で無視されていない | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 処理順序 | globパターンによる展開順 |

### 改ページ条件

該当なし（テキスト出力のため）

## データベース参照仕様

該当なし（ファイルシステムからの読み込み）

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| フォーマット差異判定 | `output !== input` | - | フォーマット後の出力と入力を文字列比較 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[--list-different オプション指定] --> B[ファイルパターン展開]
    B --> C{各ファイルをループ}
    C --> D[ファイル読み込み]
    D --> E[prettier.format実行]
    E --> F{input !== output?}
    F -->|Yes| G[ファイルパスを標準出力へ出力]
    F -->|No| H[何も出力しない]
    G --> I{次のファイル?}
    H --> I
    I -->|Yes| C
    I -->|No| J{差異ファイルあり?}
    J -->|Yes| K[exitCode = 1]
    J -->|No| L[exitCode = 0]
    K --> M[終了]
    L --> M
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| パーサー不明 | 対象ファイルのパーサーが特定できない | `No parser could be inferred for file: {filename}` | --ignore-unknown オプションで無視可能 |
| パースエラー | ソースコードの構文エラー | `{filename}: SyntaxError: {message}` | ファイルの構文を修正 |
| ファイル読み込み失敗 | ファイルアクセス権限がない等 | `Unable to read file "{filename}": {error}` | ファイルパーミッションを確認 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 数千ファイル |
| 目標出力時間 | ファイル数に比例（1ファイルあたり数十ms） |
| 同時出力数上限 | なし（順次処理） |

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

- ファイルパスのみの出力であり、ファイル内容は出力されない
- `.prettierignore` で指定されたファイルは自動的に除外される
- `node_modules` 配下はデフォルトで除外される

## 備考

- `--check` オプションと排他的に使用（同時指定時はエラー）
- `--write` オプションと組み合わせ可能（差異ファイルを出力しつつ修正も実行）
- 終了コード: 差異ファイルあり=1、差異ファイルなし=0

---

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

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

### 推奨読解順序

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

まず、CLIオプションの定義を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cli-options.evaluate.js | `src/cli/cli-options.evaluate.js` | `listDifferent` オプションの定義（210-216行目）を確認 |

**読解のコツ**: `listDifferent` は `alias: "l"` で短縮形 `-l` を持ち、`category: optionCategories.CATEGORY_OUTPUT` でOutputカテゴリに分類されている。

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.js | `src/cli/index.js` | `main()` 関数でオプション検証と分岐処理を確認 |

**主要処理フロー**:
1. **49-51行目**: `--check` と `--list-different` の排他チェック
2. **97-100行目**: 標準入力かファイルパターンかの判定
3. **102-108行目**: 標準入力の場合は `formatStdin()` を呼び出し
4. **111-113行目**: ファイルパターンがある場合は `formatFiles()` を呼び出し

#### Step 3: ファイル処理層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | format.js | `src/cli/format.js` | `listDifferent()` 関数（85-100行目）と `formatFiles()` 関数（272-504行目）を確認 |

**主要処理フロー**:
- **85-100行目**: `listDifferent()` 関数 - 標準入力用の差異チェック
  - `prettier.check()` を使用してフォーマット差異を判定
  - 差異がある場合は `context.logger.log(filename)` でファイル名を出力
  - `process.exitCode = 1` を設定
- **458-464行目**: ファイル処理での差異検出と出力
  - `isDifferent` が `true` かつ `listDifferent` オプション時に `context.logger.log(fileNameToDisplay)` を実行
  - `numberOfUnformattedFilesFound` をインクリメント
- **496-502行目**: 終了コードの設定

#### Step 4: ロガー層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | logger.js | `src/cli/logger.js` | `createLogFunc()` 関数で `log` メソッドの実装を確認 |

**主要処理フロー**:
- **35行目**: `log` レベルは `process.stdout` へ出力
- **46-47行目**: メッセージを出力（改行付き）

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

```
src/cli/index.js
    │
    ├─ run()
    │      └─ main()
    │             ├─ context.argv.listDifferent チェック
    │             │
    │             ├─ [標準入力] formatStdin()
    │             │      └─ listDifferent() ─────────────────┐
    │             │             └─ prettier.check()          │
    │             │                    └─ context.logger.log()│
    │             │                                          │
    │             └─ [ファイル] formatFiles()                 │
    │                    ├─ expandPatterns()                  │
    │                    ├─ format()                          │
    │                    │      └─ prettier.formatWithCursor()│
    │                    ├─ isDifferent 判定                  │
    │                    └─ context.logger.log() ─────────────┘
    │
    └─ src/cli/logger.js
           └─ createLogger()
                  └─ process.stdout.write()
```

### データフロー図

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

ファイルパターン ───▶ expandPatterns() ───▶ ファイルリスト
                              │
                              ▼
                      ファイル内容読込
                              │
                              ▼
                    prettier.format() / check()
                              │
                              ▼
                      差異判定 (input !== output)
                              │
                              ▼
                      ┌───────┴───────┐
                      │差異あり       │差異なし
                      ▼               ▼
              logger.log(path)     何も出力しない
                      │
                      ▼
               stdout ───▶ ファイルパス一覧
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.js | `src/cli/index.js` | ソース | CLIエントリーポイント、オプション検証 |
| format.js | `src/cli/format.js` | ソース | ファイルフォーマット処理、差異検出・出力 |
| cli-options.evaluate.js | `src/cli/cli-options.evaluate.js` | ソース | CLIオプション定義 |
| logger.js | `src/cli/logger.js` | ソース | ログ出力機能 |
| context.js | `src/cli/context.js` | ソース | CLIコンテキスト管理 |
| utilities.js | `src/cli/utilities.js` | ソース | ユーティリティ関数（normalizeToPosix等） |
| list-different.js | `tests/integration/__tests__/list-different.js` | テスト | 統合テスト |
