# バッチ設計書 20-incr-check

## 概要

本ドキュメントは、Zigコンパイラのインクリメンタルコンパイル機能を検証するためのテストツール「incr-check」のバッチ設計書です。

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

incr-checkは、Zigコンパイラのインクリメンタルコンパイル機能が正しく動作することを検証するためのテストツールです。テストケースファイルを読み込み、コードの段階的な変更に対してコンパイラが正しいエラー検出や成功した実行結果を返すことを確認します。

**業務上の目的・背景**：Zigコンパイラの品質保証において、インクリメンタルコンパイル機能は開発者の生産性に直結する重要な機能です。コードを変更した際に、変更されていない部分を再コンパイルせず、変更部分のみを効率的に再コンパイルする機能が正しく動作することを保証するために、このテストツールが必要です。特に複数のバックエンド（sema、selfhosted、llvm、cbe）でのインクリメンタルコンパイルの動作を検証することで、コンパイラの信頼性を担保します。

**バッチの実行タイミング**：CI/CDパイプラインでのテスト実行時、開発者がインクリメンタルコンパイル機能の変更をテストする際に随時実行されます。

**主要な処理内容**：
1. テストケースファイルの解析（ターゲット、モジュール、更新ステップの抽出）
2. 各ターゲット・バックエンドに対するZigコンパイラの起動
3. インクリメンタルアップデートの適用と結果の検証
4. コンパイルエラー/成功の期待値との比較
5. 生成されたバイナリの実行と出力の検証

**前後の処理との関連**：Zigコンパイラ本体のビルドが完了していることが前提です。テスト結果はCI/CDの成功/失敗判定に使用されます。

**影響範囲**：テスト実行時に一時ディレクトリを作成し、テスト完了後に削除します。Zigコンパイラの動作検証のみを行い、実際のプロダクションコードには影響しません。

## バッチ種別

テスト・検証

## 実行スケジュール

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

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| Zigコンパイラ | テスト対象のZigコンパイラバイナリが存在すること |
| テストケースファイル | 有効な形式のテストケースファイルが存在すること |
| zig-lib-dir | cbeバックエンド使用時はライブラリディレクトリが必要 |

### 実行可否判定

テストケースファイルが有効な形式であり、指定されたターゲット・バックエンドの組み合わせが実行可能な場合に実行されます。ホストシステムで実行できないターゲットの場合は、実行をスキップします（QEMU、Wine、wasmtime、darlingエミュレータの使用も可能）。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| zig binary path | string | Yes | - | テスト対象のZigコンパイラのパス |
| input file | string | Yes | - | テストケースファイルのパス |
| --zig-lib-dir | string | No | - | Zigライブラリディレクトリのパス |
| --debug-log | string | No | - | デバッグログを有効にするスコープ |
| --preserve-tmp | flag | No | false | 一時ディレクトリを削除しない |
| --zig-cc-binary | string | No | - | zig ccのバイナリパス（cbeバックエンド用） |
| -fqemu | flag | No | false | QEMUエミュレータを有効化 |
| -fwine | flag | No | false | Wineエミュレータを有効化 |
| -fwasmtime | flag | No | false | wasmtimeエミュレータを有効化 |
| -fdarling | flag | No | false | darlingエミュレータを有効化 |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| テストケースファイル | テキスト | #キーでマークされた構造化テストファイル |

#### テストケースファイル形式

テストケースファイルは以下のディレクティブを使用して記述します：

| ディレクティブ | 説明 |
|---------------|------|
| #target={query}-{backend} | ターゲットとバックエンドの指定 |
| #module={name}={file} | 追加モジュールの定義 |
| #update={name} | 更新ステップの名前 |
| #file={path} | ファイル内容の開始 |
| #rm_file={path} | ファイルの削除 |
| #expect_stdout={value} | 期待される標準出力 |
| #expect_error={file}:{line}:{col}: {type}: {msg} | 期待されるコンパイルエラー |
| #expect_compile_log={value} | 期待されるコンパイルログ |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| 標準出力 | テキスト | テスト進捗とログ情報 |
| 標準エラー出力 | テキスト | エラーメッセージ |
| 終了コード | 整数 | 0=成功、非0=失敗 |

### 出力ファイル仕様

一時ディレクトリ（tmp_XXXXXXXX形式）にテスト用ファイルを生成しますが、テスト完了後に削除されます（--preserve-tmp指定時を除く）。

| 項目 | 内容 |
|-----|------|
| ファイル名 | tmp_{ランダム16進数} |
| 出力先 | カレントディレクトリ |
| 文字コード | UTF-8 |
| 区切り文字 | N/A |

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ Zigバイナリパス、入力ファイル、オプションを取得
2. テストケースファイルの読み込みと解析
   └─ Case.parse()でターゲット、モジュール、更新ステップを抽出
3. cbeバックエンド使用時のlib-dir検証
   └─ --zig-lib-dirが未指定の場合はエラー
4. 一時ディレクトリの作成
   └─ tmp_{ランダム16進数}形式のディレクトリを作成
5. 各ターゲットに対するテスト実行
   └─ ターゲットごとにZigコンパイラを起動
6. 各更新ステップの処理
   └─ ファイルの書き込み/削除、コンパイル結果の検証
7. 期待値との比較
   └─ コンパイルエラー、標準出力、終了コードを検証
8. 一時ディレクトリの削除
   └─ --preserve-tmpが未指定の場合のみ
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[引数解析]
    B --> C[テストケースファイル解析]
    C --> D{cbeバックエンド使用?}
    D -->|Yes| E{lib-dir指定?}
    D -->|No| F[一時ディレクトリ作成]
    E -->|Yes| F
    E -->|No| ERR1[エラー終了]
    F --> G[各ターゲットをループ]
    G --> H[Zigコンパイラ起動]
    H --> I[更新ステップをループ]
    I --> J[ファイル変更適用]
    J --> K[コンパイル実行]
    K --> L{期待される結果?}
    L -->|エラー期待| M[エラー内容検証]
    L -->|成功期待| N{バイナリ実行可能?}
    N -->|Yes| O[バイナリ実行・出力検証]
    N -->|No| P[スキップ]
    M --> Q{検証成功?}
    O --> Q
    P --> Q
    Q -->|Yes| R{次の更新あり?}
    Q -->|No| ERR2[テスト失敗]
    R -->|Yes| I
    R -->|No| S{次のターゲットあり?}
    S -->|Yes| G
    S -->|No| T[一時ディレクトリ削除]
    T --> U[バッチ終了]
```

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

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

本バッチはデータベースを使用しません。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| N/A | N/A | N/A | データベース操作なし |

### テーブル別操作詳細

データベース操作はありません。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 引数エラー | 必須引数が不足 | usageを表示して終了 |
| 1 | ファイルエラー | テストケースファイルが読めない | ファイルパスを確認 |
| 1 | パースエラー | テストケースファイルの形式が不正 | ファイル形式を修正 |
| 1 | コンパイルエラー | 期待と異なるコンパイル結果 | テストケースを確認 |
| 1 | 実行エラー | 期待と異なる実行結果 | テストケースを確認 |
| シグナル | 異常終了 | コンパイラがシグナルで終了 | コンパイラのバグを調査 |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

### 障害時対応

1. --preserve-tmpオプションを付けて再実行し、一時ファイルを保持
2. --debug-logオプションでデバッグログを有効化
3. 一時ディレクトリ内のファイルを確認してデバッグ

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | N/A（データベース不使用） |
| コミットタイミング | N/A |
| ロールバック条件 | N/A |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | テストケースごとに異なる |
| 目標処理時間 | テストケースの複雑さに依存 |
| メモリ使用量上限 | 制限なし（Zigコンパイラの制限に依存） |

## 排他制御

各テスト実行は独自の一時ディレクトリを使用するため、複数のincr-checkを同時に実行可能です。一時ディレクトリ名にはランダムな16進数が含まれるため、衝突のリスクは極めて低いです。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| 進捗ログ | 各ターゲット開始時 | ターゲット名とバックエンド |
| 進捗ログ | 各更新ステップ開始時 | 更新ステップ名 |
| エラーログ | エラー発生時 | エラー詳細とスタックトレース |
| 警告ログ | スキップ時 | スキップ理由（外部ターゲット実行不可等） |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| テスト失敗 | 1件以上 | CI/CDシステム |
| 異常終了 | シグナル受信 | CI/CDシステム |

## 備考

### サポートするバックエンド

| バックエンド | 説明 | コンパイラオプション |
|-------------|------|---------------------|
| sema | セマンティック解析のみ | -fno-emit-bin |
| selfhosted | セルフホストバックエンド | -fno-llvm -fno-lld |
| llvm | LLVMバックエンド | -fllvm -flld |
| cbe | Cバックエンド（zig cc経由） | -ofmt=c -lc |

### 外部エミュレータ対応

ホストシステムで直接実行できないターゲットの場合、以下のエミュレータを使用可能：

- QEMU（-fqemu）
- Wine（-fwine）
- wasmtime（-fwasmtime）
- darling（-fdarling）

### 関連ファイル

- `tools/incr-check.zig`: 本バッチの実装
