# バッチ設計書 6-sort-imports

## 概要

本ドキュメントは、インポート文のソート処理バッチ「sort-imports.ts」の設計仕様を記載する。

### 本バッチの処理概要

Zigソースファイル内のimport文を規則に従って自動ソートする。未使用のインポートを削除し、インポートをグループ化して可読性を向上させる。

**業務上の目的・背景**：大規模なZigコードベースでは、インポート文の順序が開発者によって異なり、コードレビューや差分確認の妨げとなる。また、未使用のインポートがコードに残ることでコンパイル時間や可読性に悪影響を与える。本バッチはインポート文を自動的にソート・整理することで、コードスタイルの統一とコード品質の維持を支援する。

**バッチの実行タイミング**：開発者が手動で実行（随時）。コミット前やコードレビュー前に使用。

**主要な処理内容**：
1. コマンドライン引数からファイルパスまたはディレクトリを取得
2. 対象ファイル（.zig）に対して以下の処理を実行：
   - インラインconst宣言をパース
   - @import()文を含む宣言を抽出
   - インポートパスを解析してグループ化
   - 未使用の宣言を検出・削除（オプション）
   - グループごとにソートして再配置
   - @This()宣言を適切な位置に移動

**前後の処理との関連**：独立したコード整形ツールとして動作。CI/CDパイプラインでの自動チェックにも使用可能。

**影響範囲**：指定されたZigソースファイルの内容を変更する。

## バッチ種別

コード整形 / 品質ツール

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（手動実行） |
| 実行時刻 | - |
| 実行曜日 | - |
| 実行日 | - |
| トリガー | 手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| 対象ファイル | .zigファイルが存在すること |

### 実行可否判定

- ファイルパスが指定されていない場合はUsageを表示して終了

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| files | string[] | Yes | - | ファイルパスまたはディレクトリパス |
| --help | flag | No | - | ヘルプ表示 |
| --include-pub | flag | No | false | pub宣言も含めてソート |
| --keep-unused | flag | No | false | 未使用インポートを保持 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| Zigソースファイル | テキスト | 対象ソースコード |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| Zigソースファイル | テキスト | ソート後のソースコード |
| 標準出力 | テキスト | 処理結果サマリー |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | 入力ファイルと同じ（上書き） |
| 文字コード | UTF-8 |

## 処理フロー

### 処理シーケンス

```
1. 引数パース
   └─ ファイルパス/ディレクトリ、オプションを取得

2. ファイル列挙
   └─ ディレクトリの場合は再帰的に.zigファイルを取得

3. ファイルごとの処理ループ
   └─ 以下の処理を繰り返し適用（未使用削除で変更がある間）

4. パス正規化
   └─ @import("file.zig")を@import("./file.zig")に正規化

5. 宣言パース
   └─ const X = ...;形式の宣言を抽出

6. 未使用検出
   └─ ファイル内で1回しか出現しない非pub宣言を未使用と判定

7. インポートグループ化
   └─ @import()のパスに基づいてグループを構築

8. グループマージ
   └─ 1項目のみのグループを親グループにマージ

9. グループソート
   └─ グループ内をアルファベット順でソート

10. 出力生成
    └─ 元の位置を削除し、グループごとに空行を挟んで再配置

11. @This()移動
    └─ @This()宣言をファイル先頭に移動

12. 書き込み
    └─ 変更があった場合のみファイルを更新
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B{引数チェック}
    B -->|NG| C[Usage表示・終了]
    B -->|OK| D[ファイル列挙]
    D --> E[ファイルループ]
    E --> F[ファイル読み込み]
    F --> G[パス正規化]
    G --> H[宣言パース]
    H --> I[未使用検出]
    I --> J[グループ化]
    J --> K[グループマージ]
    K --> L[ソート]
    L --> M[出力生成]
    M --> N[@This移動]
    N --> O{変更あり?}
    O -->|はい| P[ファイル書き込み]
    O -->|いいえ| Q[スキップ]
    P --> R{再処理必要?}
    Q --> E
    R -->|はい| F
    R -->|いいえ| E
    E -->|終了| S[サマリー出力]
    S --> T[バッチ終了]
```

## データベース操作仕様

### 操作別データベース影響一覧

本バッチはデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 引数エラー | ファイルパス未指定 | Usage表示して終了 |
| - | ファイル処理エラー | ファイル読み書き失敗 | エラーメッセージ表示、次ファイルへ継続 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

### 障害時対応

- 個別ファイルの処理失敗時はエラーを出力し、次のファイルの処理を継続
- 全ファイル処理後にエラー件数を報告

## トランザクション仕様

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | ファイル単位 |
| コミットタイミング | ファイル処理完了時 |
| ロールバック条件 | なし（書き込み前に変更有無を確認） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 複数ファイル（プロジェクト全体） |
| 目標処理時間 | ファイルサイズに依存 |
| メモリ使用量上限 | ファイルサイズに依存 |

## 排他制御

同一ファイルへの同時書き込みは想定しない。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 完了ログ | ファイル処理成功時 | "Done: {filepath}" |
| サマリー | 全処理完了時 | 成功件数、エラー件数 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| - | - | - |

## 備考

### 対象宣言パターン

```
(?:pub )?const ([a-zA-Z0-9_]+) = (.+);(\s*\/\/[^\n]*)?$
```

- オプションのpub修飾子
- const宣言
- 識別子名
- 初期化式
- オプションの行末コメント

### 未使用判定ロジック

- 非pub宣言で、ファイル内での出現回数が宣言行のみ（1回）の場合に未使用と判定
- doc comment（///）が直前にある宣言は対象外

### インポートパス正規化

デフォルト（normalizePaths = "./"）：
- `@import("file.zig")` → `@import("./file.zig")`
- `@import("./../file.zig")` → `@import("../file.zig")`

### @This()の特別処理

`@This()`を返す宣言は、ファイルの先頭（ファイルコメントの直後）に移動される。
これはZigの慣習として、selfまたはSelfを最初に宣言することが推奨されているため。

### グループ化ロジック

インポートは解決されたパスに基づいてグループ化される：
1. @import()のパスを基準にグループを構築
2. 1項目のみのグループは親グループにマージ
3. 子グループを持つ項目は子グループの先頭に移動
