# 機能設計書 44-ライフサイクルスクリプト

## 概要

本ドキュメントは、Bunパッケージマネージャーのライフサイクルスクリプト実行機能に関する設計書である。preinstall、postinstall、prepare等のnpmライフサイクルスクリプトの実行管理について詳述する。

### 本機能の処理概要

ライフサイクルスクリプト機能は、パッケージのインストール前後、ビルド時などに自動実行されるスクリプトを管理・実行する機能である。npmのライフサイクルフック仕様に準拠し、パッケージのネイティブモジュールビルド（node-gyp等）やセットアップ処理を自動化する。

**業務上の目的・背景**：多くのnpmパッケージは、インストール後にネイティブモジュールのコンパイル、TypeScriptのビルド、設定ファイルの生成などが必要である。ライフサイクルスクリプトにより、これらの処理を自動化し、開発者の手動介入なしにパッケージを利用可能な状態にする。セキュリティの観点から、スクリプト実行は`--trust`フラグまたはtrustedDependencies設定で明示的に許可する必要がある。

**機能の利用シーン**：
- `bun install` 実行時のpostinstallスクリプト実行
- ネイティブモジュール（bcrypt、sharp等）のビルド
- `bun install --trust <pkg>`での信頼済みパッケージ追加
- `bun run prepare`でのprepareスクリプト実行

**主要な処理内容**：
1. package.jsonからscriptsフィールドの解析
2. ライフサイクルフックの順序付け（preinstall → install → postinstall）
3. 信頼済みパッケージの判定（trustedDependencies）
4. 子プロセスでのスクリプト実行
5. 実行結果の収集とエラーハンドリング
6. node-gyp環境の設定

**関連システム・外部連携**：
- シェル（sh、cmd.exe）
- node-gyp、prebuild等のネイティブビルドツール
- 環境変数（PATH、npm_lifecycle_event等）

**権限による制御**：デフォルトでは未信頼パッケージのスクリプトは実行されない。`--trust`フラグまたはtrustedDependencies設定が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | install | 補助機能 | インストール前後のスクリプト実行 |

## 機能種別

プロセス管理（外部プロセス実行）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| script_name | string | Yes | スクリプト名（preinstall等） | 有効なライフサイクル名 |
| script_command | string | Yes | 実行するコマンド | シェルで実行可能なコマンド |
| package_path | path | Yes | パッケージのディレクトリパス | 存在するディレクトリ |
| trusted | boolean | No | 信頼済みフラグ | デフォルトfalse |

### 入力データソース

- package.json（scriptsフィールド）
- bunfig.toml（trustedDependencies）
- 環境変数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| exit_code | number | スクリプトの終了コード |
| stdout | string | 標準出力 |
| stderr | string | 標準エラー出力 |
| duration | number | 実行時間（ミリ秒） |

### 出力先

- 標準出力/標準エラー（ログ表示時）
- lifecycle_script_time_log（実行時間記録）

## 処理フロー

### 処理シーケンス

```
1. スクリプトの収集
   └─ 全パッケージからライフサイクルスクリプトを収集
2. 信頼性チェック
   └─ trustedDependenciesまたは--trustで許可されているか確認
3. 実行順序の決定
   └─ 依存関係に基づいて実行順序をトポロジカルソート
4. 環境変数の設定
   └─ npm_lifecycle_event、PATH、INIT_CWD等を設定
5. スクリプト実行
   └─ 子プロセスで各スクリプトを実行
6. 結果の収集
   └─ 終了コード、出力、実行時間を記録
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[スクリプト収集]
    B --> C{スクリプトあり?}
    C -->|No| D[終了]
    C -->|Yes| E{信頼済み?}
    E -->|No| F[スキップ: 警告表示]
    E -->|Yes| G[環境変数設定]
    F --> H[次のパッケージへ]
    G --> I[子プロセス起動]
    I --> J{正常終了?}
    J -->|Yes| K[成功記録]
    J -->|No| L{--ignore-scripts?}
    L -->|Yes| M[警告のみ]
    L -->|No| N[エラー終了]
    K --> H
    M --> H
    H --> C
    N --> O[ロールバック]
    O --> D
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-44-01 | 実行順序 | preinstall → install → postinstall の順 | インストール時 |
| BR-44-02 | 信頼必須 | 未信頼パッケージのスクリプトは実行しない | デフォルト動作 |
| BR-44-03 | タイムアウト | スクリプト実行のデフォルトタイムアウトなし | --timeout で指定可能 |
| BR-44-04 | 並列実行 | 依存関係のないスクリプトは並列実行可能 | デフォルト動作 |
| BR-44-05 | node-gyp | node-gypビルドはJOBS環境変数で並列度制御 | ネイティブモジュール時 |

### 計算ロジック

JOBS環境変数の設定:
```
if thread_count > 2 and !env.has("JOBS"):
    JOBS = thread_count
```

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

本機能はデータベースを使用しない。

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| NonZeroExit | スクリプトエラー | 終了コードが0以外 | スクリプト内容を確認 |
| Timeout | タイムアウト | 指定時間内に完了しない | タイムアウト値を調整 |
| NotTrusted | 信頼性エラー | 未信頼パッケージ | --trust で信頼を付与 |
| ShellNotFound | シェル未発見 | シェルが見つからない | シェルをインストール |
| PermissionDenied | 権限エラー | 実行権限がない | ファイル権限を確認 |

### リトライ仕様

スクリプト実行は自動リトライしない。失敗時はエラーメッセージを表示して終了。

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

スクリプト失敗時は、それまでの変更は維持される。ロールバックは手動で行う必要がある。

## パフォーマンス要件

- スクリプト起動: 100ms以内
- 並列実行対応（CPUコア数に応じた並列度）
- 長時間実行スクリプトの進捗表示

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

- **信頼モデル**: デフォルトでスクリプト実行は禁止
- **trustedDependencies**: 明示的に信頼するパッケージを設定
- **--trust**: インストール時に信頼を付与
- **サンドボックス**: 将来的なサンドボックス実行の検討

## 備考

- npm scripts互換
- シェバン（#!）対応
- Windows環境ではcmd.exeまたはPowerShellを使用
- 環境変数npm_lifecycle_eventにイベント名を設定

---

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

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

### 推奨読解順序

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

ライフサイクルスクリプト管理で使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | lifecycle_script_runner.zig | `src/install/lifecycle_script_runner.zig` | LifecycleScriptRunner構造体 |
| 1-2 | PackageManager.zig | `src/install/PackageManager.zig` | lifecycle_script_time_log、active_lifecycle_scripts |

**読解のコツ**: LifecycleScriptRunner.Script構造体でスクリプト情報を保持。

#### Step 2: スクリプト収集を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Package.zig | `src/install/Package.zig` | Scripts構造体、hasAnyScripts関数 |
| 2-2 | lifecycle_script_runner.zig | `src/install/lifecycle_script_runner.zig` | collectScripts関数 |

**主要処理フロー**:
1. Package.Scripts.Listでスクリプト一覧を保持
2. hasAnyScripts()でスクリプトの有無を判定

#### Step 3: 実行制御を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | PackageManager.zig | `src/install/PackageManager.zig` | configureEnvForScripts関数 |
| 3-2 | lifecycle_script_runner.zig | `src/install/lifecycle_script_runner.zig` | runScripts関数 |

**主要処理フロー**:
- **310-371行目（PackageManager.zig）**: configureEnvForScripts で環境変数を設定
- **343-351行目**: JOBS環境変数でnode-gypの並列度を制御

#### Step 4: 信頼性チェックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | PackageManager.zig | `src/install/PackageManager.zig` | trusted_deps_to_add_to_package_json |
| 4-2 | install.zig | `src/install/install.zig` | trustedDependencies設定 |

**主要処理フロー**:
- **110行目（PackageManager.zig）**: trusted_deps_to_add_to_package_json でスクリプト実行許可パッケージを管理

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

```
PackageManager
    │
    ├─ configureEnvForScripts()
    │      ├─ PATH設定
    │      ├─ JOBS設定（node-gyp並列度）
    │      └─ INIT_CWD設定
    │
    ├─ LifecycleScriptRunner
    │      │
    │      ├─ collectScripts()
    │      │      └─ package.jsonからスクリプト収集
    │      │
    │      ├─ checkTrust()
    │      │      └─ trustedDependencies確認
    │      │
    │      └─ runScripts()
    │             └─ 子プロセスでスクリプト実行
    │
    └─ lifecycle_script_time_log
           └─ 実行時間記録（500ms超過時）
```

### データフロー図

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

package.json ──────────▶ Scripts解析 ──────────────▶ スクリプト一覧
(scripts)                      │
                              ▼
trustedDependencies ───▶ 信頼性チェック ───────────▶ 実行可否判定
                              │
                              ▼
                      環境変数設定 ─────────────▶ env（PATH, JOBS等）
                              │
                              ▼
                      子プロセス起動 ───────────▶ スクリプト実行
                              │
                              ▼
                      結果収集 ─────────────────▶ exit_code/stdout/stderr
                              │
                              ▼
                      時間記録 ─────────────────▶ lifecycle_script_time_log
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| lifecycle_script_runner.zig | `src/install/lifecycle_script_runner.zig` | ソース | ライフサイクルスクリプト実行の中核 |
| PackageManager.zig | `src/install/PackageManager.zig` | ソース | 環境設定、実行時間記録 |
| Package.zig | `src/install/Package.zig` | ソース | Scripts構造体定義 |
| install.zig | `src/install/install.zig` | ソース | trustedDependencies設定 |
| run_command.zig | `src/cli/run_command.zig` | ソース | bun runでのスクリプト実行 |
| LifecycleScriptSubprocess.zig | `src/install/LifecycleScriptSubprocess.zig` | ソース | サブプロセス管理 |
