# 機能設計書 47-yarn互換

## 概要

本ドキュメントは、Bunパッケージマネージャーのyarn互換機能に関する設計書である。yarn.lockからbun.lockbへの移行、yarn workspaces設定の読み込みについて詳述する。

### 本機能の処理概要

yarn互換機能は、既存のyarnプロジェクト（Yarn v1、v2+）からBunへのスムーズな移行を支援する機能である。yarn.lockのパースとbun.lockbへの変換を行う。

**業務上の目的・背景**：yarnは世界で最も広く使用されているパッケージマネージャーの一つである。多くのエンタープライズプロジェクトがyarnを採用しており、Bunへの移行時に既存のロックファイルを活用できることが重要である。yarn互換機能により、yarnプロジェクトをシームレスにBunで利用開始でき、移行リスクを最小限に抑えられる。

**機能の利用シーン**：
- yarnプロジェクトで初めて`bun install`を実行
- yarn.lockが存在する環境でのBun導入
- yarn workspaces を使用したmonorepoの移行

**主要な処理内容**：
1. yarn.lockの存在確認
2. ロックファイル形式（v1/v2+）の判定とパース
3. 依存関係情報の抽出とBun形式への変換
4. git依存関係、npm alias、file依存関係の処理
5. workspace依存関係の解決
6. bun.lockbの生成

**関連システム・外部連携**：
- yarn.lock（入力）
- .yarnrc.yml（Yarn v2+設定）
- bun.lockb（出力）
- package.json（workspaces）

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | install | 主機能 | yarn.lockからの移行 |

## 機能種別

データ変換（ロックファイル移行）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| yarn_lockfile | file | Yes | yarn.lock | 有効なyarn.lock形式 |
| specs | array | Yes | パッケージ仕様（name@version） | 有効な仕様形式 |
| version | string | Yes | 解決されたバージョン | セマンティックバージョン等 |
| resolved | string | No | 解決URL | URL形式 |
| integrity | string | No | SHA512ハッシュ | sha512-形式 |

### 入力データソース

- yarn.lock
- package.json（workspaces）
- .yarnrc.yml（オプション）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| lockfile | Lockfile | 変換されたBunロックファイル |
| entries | array | YarnLock.Entry配列 |
| packages | array | パッケージ情報の配列 |

### 出力先

- bun.lockb（バイナリロックファイル）
- メモリ内Lockfile構造

## 処理フロー

### 処理シーケンス

```
1. ファイル検出
   └─ yarn.lockの存在確認
2. 形式判定
   └─ Yarn v1 or v2+の判定
3. パース
   └─ 各エントリを解析
4. 依存タイプ判定
   └─ git、npm alias、file、workspace等の判定
5. パッケージ変換
   └─ 各エントリをBun形式に変換
6. 依存関係解決
   └─ dependencies、optionalDependencies等の処理
7. ロックファイル生成
   └─ bun.lockbの書き出し
```

### フローチャート

```mermaid
flowchart TD
    A[bun install開始] --> B{yarn.lock存在?}
    B -->|No| C[他のロックファイル確認]
    B -->|Yes| D[yarn.lockをパース]
    D --> E[エントリを順次処理]
    E --> F{依存タイプ判定}
    F -->|git| G[Git依存として処理]
    F -->|npm:| H[npm alias として処理]
    F -->|file:| I[ファイル依存として処理]
    F -->|workspace:| J[ワークスペース依存として処理]
    F -->|通常| K[npmパッケージとして処理]
    G --> L[エントリを統合]
    H --> L
    I --> L
    J --> L
    K --> L
    L --> M{全エントリ処理完了?}
    M -->|No| E
    M -->|Yes| N[bun.lockb生成]
    N --> O[終了]
    C --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-47-01 | 自動移行 | yarn.lock検出時に自動変換 | bun install実行時 |
| BR-47-02 | スコープパッケージ | @scope/pkg形式を適切に処理 | スコープ付きパッケージ |
| BR-47-03 | Git依存 | git+、github:等を認識 | Git依存時 |
| BR-47-04 | npmエイリアス | npm:pkg@version形式を処理 | エイリアス使用時 |
| BR-47-05 | workspace依存 | workspace:*、workspace:^を処理 | ワークスペース使用時 |
| BR-47-06 | ファイル依存 | file:./path形式を処理 | ローカルパッケージ時 |

### 計算ロジック

パッケージ名抽出:
```
// unquoted = "package@version"
getNameFromSpec(spec) =
    if spec[0] == '@':
        // スコープ付き: @scope/pkg@version
        return spec[0..second_at_index]
    else:
        return spec[0..first_at_index]
```

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

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

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ParseError | パースエラー | yarn.lock形式が不正 | ロックファイルを再生成 |
| InvalidSpec | 仕様エラー | パッケージ仕様が不正 | 依存関係を確認 |
| GitUrlError | URLエラー | Git URLが不正 | URLを確認 |
| UnknownDependencyType | 型エラー | 未知の依存タイプ | yarnバージョンを確認 |
| WorkspaceNotFound | 未発見 | ワークスペースパッケージが存在しない | パッケージを確認 |

### リトライ仕様

パースエラーは自動リトライしない。手動での修正を促す。

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

移行処理はアトミック。失敗時はbun.lockbを生成しない。

## パフォーマンス要件

- パース処理: 1秒以内（5,000エントリまで）
- 変換処理: 500ms以内（通常規模）
- メモリ使用: O(n)（エントリ数に比例）

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

- integrityハッシュの維持
- resolvedURLの検証
- Git URLのスキーム確認

## 備考

- Yarn v1（yarn.lock形式）に対応
- Yarn v2+（yarn.lock新形式）も基本対応
- package.json workspacesをそのまま使用可能

---

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

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

### 推奨読解順序

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

yarnロックファイル解析で使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | yarn.zig | `src/install/yarn.zig` | YarnLock構造体、Entry構造体 |

**読解のコツ**: YarnLock.Entry構造体のフィールドがyarn.lockの各エントリに対応する。

#### Step 2: パース処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | yarn.zig | `src/install/yarn.zig` | YarnLock.parse関数 |

**主要処理フロー**:
- **1-42行目**: Entry構造体の定義とフィールド
- **18-41行目**: deinit関数でメモリ解放
- **43-71行目**: getNameFromSpec関数でパッケージ名を抽出
- **73-128行目**: getVersionFromSpec関数でバージョンを抽出

#### Step 3: 依存タイプ判定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | yarn.zig | `src/install/yarn.zig` | isGitDependency、isNpmAlias等のヘルパー関数 |

**主要処理フロー**:
- **130-135行目**: isGitDependency関数でGit依存を判定
- **137-139行目**: isNpmAlias関数でnpm:エイリアスを判定
- **141-143行目**: isRemoteTarball関数でリモートtarballを判定
- **145-148行目**: isWorkspaceDependency関数でworkspace依存を判定
- **150-154行目**: isFileDependency関数でファイル依存を判定

#### Step 4: Git URL処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | yarn.zig | `src/install/yarn.zig` | parseGitUrl関数 |

**主要処理フロー**:
- **156-201行目**: parseGitUrl関数でGit URLを解析
- **162-169行目**: git+プレフィックスの除去
- **171-184行目**: github:形式の処理
- **184-198行目**: github.com URLの処理

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

```
PackageManager
    │
    └─ YarnLock.parse()
           │
           ├─ 行ごとにパース
           │      └─ エントリ識別（インデント0）
           │
           ├─ Entry.getNameFromSpec()
           │      └─ パッケージ名抽出
           │
           ├─ Entry.getVersionFromSpec()
           │      └─ バージョン抽出
           │
           ├─ 依存タイプ判定
           │      ├─ isGitDependency()
           │      ├─ isNpmAlias()
           │      ├─ isRemoteTarball()
           │      ├─ isWorkspaceDependency()
           │      └─ isFileDependency()
           │
           ├─ parseGitUrl()
           │      └─ Git URL解析
           │
           └─ consolidateAndAppendEntry()
                  └─ エントリ統合
```

### データフロー図

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

yarn.lock ──────────────▶ 行分割 ───────────────────▶ 行配列
                              │
                              ▼
                      インデント判定 ───────────────▶ エントリ境界
                              │
                              ▼
                      specs解析 ─────────────────▶ パッケージ仕様
                              │
                              ▼
                      依存タイプ判定 ────────────────▶ git/npm/file/workspace
                              │
                              ▼
                      URL/バージョン解析 ───────────▶ resolved/integrity
                              │
                              ▼
                      dependencies解析 ─────────────▶ 依存関係マップ
                              │
                              ▼
                      Entry構築 ─────────────────▶ YarnLock.Entry[]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| yarn.zig | `src/install/yarn.zig` | ソース | yarnロックファイル解析の中核 |
| lockfile.zig | `src/install/lockfile.zig` | ソース | Lockfile構造体定義 |
| PackageManager.zig | `src/install/PackageManager.zig` | ソース | 移行処理の呼び出し |
| dependency.zig | `src/install/dependency.zig` | ソース | 依存関係解析 |
| semver.zig | `src/semver.zig` | ソース | セマンティックバージョン処理 |
| strings.zig | `src/string.zig` | ソース | 文字列操作ユーティリティ |
