# 画面設計書 23-upgrade

## 概要

本ドキュメントは、Bun CLIの`bun upgrade`コマンドの画面設計書です。`bun upgrade`コマンドは、Bun自体を最新バージョンにアップグレードするためのコマンドで、GitHubリリースから最新のバイナリをダウンロードして自動更新を行います。

### 本画面の処理概要

`bun upgrade`コマンドは、Bun実行ファイル自体を最新バージョンに更新する自己アップグレード機能を提供します。GitHubのリリースAPIから最新バージョン情報を取得し、プラットフォームに適したバイナリをダウンロードして置き換えます。

**業務上の目的・背景**：Bunは頻繁にアップデートされるランタイムであり、新機能やバグ修正を迅速に取り込むためにシンプルなアップグレード手段が必要です。`bun upgrade`はパッケージマネージャを介さず直接バイナリを更新することで、依存関係の問題なく常に最新版を利用できる環境を提供します。また、canary（開発版）とstable（安定版）の切り替えも容易に行えます。

**画面へのアクセス方法**：ターミナルで`bun upgrade`コマンドを実行します。`--canary`オプションで開発版、`--stable`オプションで安定版に切り替え可能です。

**主要な操作・処理内容**：
1. GitHub APIから最新リリース情報を取得
2. 現在のバージョンと最新バージョンを比較
3. プラットフォームに適したzipファイルをダウンロード
4. zipファイルを一時ディレクトリに展開
5. 新バイナリのバージョンを検証
6. 実行中のBunバイナリを新バイナリに置換
7. シェル補完の自動更新

**画面遷移**：エントリーポイントの`bun`コマンドから直接アクセス。アップグレード完了後はシェルに戻ります。

**権限による表示制御**：特にロールベースの権限制御はありません。ただし、Bunバイナリの配置ディレクトリへの書き込み権限が必要です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 16 | bun upgrade | 主機能 | Bun自体の最新バージョンへのアップグレード処理 |

## 画面種別

コマンドライン / 自己アップデート

## URL/ルーティング

- コマンド: `bun upgrade`
- エイリアス: なし

## 入出力項目

| 項目名 | 項目種別 | 型 | 必須 | 説明 |
|--------|----------|-----|------|------|
| --canary | フラグ | boolean | 任意 | 最新のcanary（開発版）をインストール |
| --stable | フラグ | boolean | 任意 | canaryから安定版にダウングレード |
| --profile | フラグ | boolean | 任意 | プロファイルビルドをインストール |

## 表示項目

| 項目名 | 表示条件 | 説明 |
|--------|----------|------|
| バージョン取得進捗 | バージョン確認中 | `Fetching version tags`の進捗表示 |
| ダウンロード進捗 | ダウンロード中 | `Downloading`の進捗表示（バイト単位） |
| 新バージョン案内 | 新バージョンがある場合 | `Bun v{version} is out! You're on v{current}` |
| 最新版確認メッセージ | 最新版の場合 | `Congrats! You're already on the latest version of Bun` |
| アップグレード完了メッセージ | 完了時 | リリースノートURLとchangelogリンク |

## イベント仕様

### 1-バージョン情報取得

GitHub APIから最新リリース情報を取得します。

- **トリガー**: コマンド実行時（`--canary`なしの場合）
- **処理内容**:
  - `api.github.com`または`GITHUB_API_DOMAIN`からリリース情報取得
  - `GITHUB_TOKEN`/`GITHUB_ACCESS_TOKEN`でレート制限緩和
  - レスポンスからtag_nameとassets情報をパース
  - プラットフォーム・アーキテクチャに適したzipファイルURLを特定

### 2-バージョン比較

現在のバージョンと最新バージョンを比較します。

- **トリガー**: バージョン情報取得成功後
- **処理内容**:
  - 現在のバージョン（`bun-v{version}`形式）と最新タグを比較
  - 同一の場合は「最新版」メッセージを表示して終了
  - 異なる場合はダウンロード処理に進む

### 3-バイナリダウンロード

最新バイナリのzipファイルをダウンロードします。

- **トリガー**: 新バージョンが利用可能な場合、または`--canary`指定時
- **処理内容**:
  - HTTPプロキシ設定を適用
  - バイト単位の進捗表示付きでダウンロード
  - zipファイルを一時ディレクトリに保存

### 4-展開と検証

ダウンロードしたzipを展開し、バイナリを検証します。

- **トリガー**: ダウンロード完了後
- **処理内容**:
  - POSIX: `unzip`コマンドで展開
  - Windows: PowerShell `Expand-Archive`で展開
  - 新バイナリを`--version`または`--revision`で実行して検証
  - バージョン文字列が期待値と一致するか確認

### 5-バイナリ置換

検証済みの新バイナリで現在のバイナリを置換します。

- **トリガー**: バイナリ検証成功後
- **処理内容**:
  - POSIX: ファイル移動で直接置換
  - Windows: 実行中バイナリを`.outdated`にリネーム後、新バイナリを配置
  - 失敗時はロールバック（Windowsのみ）

### 6-シェル補完更新

アップグレード後にシェル補完を自動更新します。

- **トリガー**: バイナリ置換成功後
- **処理内容**:
  - 新バイナリで`bun completions`を実行
  - `IS_BUN_AUTO_UPDATE=true`環境変数で自動更新モード

## データベース更新仕様

本コマンドはデータベースを使用しません。ファイルシステムへの書き込みとHTTPリクエストを行います。

### 操作別ファイル影響一覧

| 操作（イベント） | 対象ファイル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| zipダウンロード | /tmp/{version}/bun.zip | CREATE | 一時ファイル作成 |
| zip展開 | /tmp/{version}/bun-{platform}/ | CREATE | バイナリ展開 |
| バイナリ置換 | {bun_install_path}/bun | UPDATE | 実行ファイル更新 |
| リネーム（Windows） | {bun_install_path}/bun.exe.outdated | CREATE | 旧バイナリ退避 |

## メッセージ仕様

| メッセージ種別 | メッセージ内容 | 表示条件 |
|--------------|---------------|----------|
| 成功 | `Congrats! You're already on the latest version of Bun (which is v{version})` | 最新版の場合 |
| 成功 | `Congrats! You're already on the latest canary build of Bun` | canary最新版の場合 |
| 情報 | `Bun v{new} is out! You're on v{current}` | 新バージョンがある場合 |
| 情報 | `Downgrading from Bun {version}-canary to Bun v{stable}` | canaryからstableへ |
| 成功 | `Upgraded. Welcome to Bun v{version}!` | アップグレード完了時 |
| エラー | `error: This command updates Bun itself, and does not take package names.` | パッケージ名が指定された場合 |
| エラー | `error: Canary builds are not available for this platform yet` | canaryが未対応の場合 |
| エラー | `error: Bun versions are currently unavailable` | バージョン取得失敗時 |
| エラー | `error: 'bun upgrade' is unsupported on systems without ld` | NixOS等で実行時 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| GitHub API 404 | エラーメッセージを表示し終了 |
| GitHub API 403 (レート制限) | HTTPForbiddenエラーを返す |
| GitHub API 429 | HTTPTooManyRequestsエラーを返す |
| GitHub API 5xx | GitHubIsDownエラーを返す |
| ダウンロードファイルが空 | エラーメッセージを表示し終了 |
| unzipコマンドが見つからない | PATHにunzipがない旨を表示し終了 |
| バイナリ検証失敗 | 一時ファイルを削除しエラー終了 |
| バイナリ移動失敗 | 手動インストール案内を表示し終了 |
| システムにldがない (NixOS等) | システムパッケージマネージャ使用を案内 |

## 備考

- canaryビルドはWindows非対応の場合があります
- NixOS等の不変システムでは`bun upgrade`は動作しません（システムパッケージマネージャを使用）
- 環境変数`GITHUB_API_DOMAIN`でGitHub APIドメインをカスタマイズ可能（企業プロキシ対応）
- 環境変数`BUN_DRY_RUN`でドライラン（実際の置換をスキップ）が可能
- Windowsでは実行中のexeを直接置換できないため、リネーム後に新バイナリを配置する方式を採用

---

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

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

### 推奨読解順序

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

まず、upgradeコマンドで使用される主要なデータ構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | upgrade_command.zig | `src/cli/upgrade_command.zig` | Version構造体（9-78行目）でバージョン情報とプラットフォーム情報を定義 |
| 1-2 | upgrade_command.zig | `src/cli/upgrade_command.zig` | platform_label, arch_label, triplet（38-50行目）でプラットフォーム識別子を定義 |
| 1-3 | upgrade_command.zig | `src/cli/upgrade_command.zig` | folder_name, zip_filename（50-53行目）でダウンロードファイル名を定義 |

**読解のコツ**: Zigのコンパイル時計算（comptime）を多用しており、プラットフォーム依存の文字列が静的に生成されています。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cli.zig | `src/cli.zig` | `bun upgrade`コマンドの判定（580行目: `RootCommandMatcher.case("upgrade")`) |
| 2-2 | cli.zig | `src/cli.zig` | UpgradeCommand.exec()呼び出し（910-913行目） |
| 2-3 | upgrade_command.zig | `src/cli/upgrade_command.zig` | exec()関数（318-349行目）がエラーハンドリング付きエントリーポイント |
| 2-4 | upgrade_command.zig | `src/cli/upgrade_command.zig` | _exec()関数（351行目〜）がメイン処理 |

**主要処理フロー**:
1. **318-336行目**: パッケージ名が誤って渡されていないかチェック
2. **351-361行目**: HTTP初期化と環境変数ロード
3. **363-417行目**: canary/stableフラグの判定とバージョン取得
4. **419-520行目**: zipファイルのダウンロード
5. **521-614行目**: zipの展開（POSIX/Windows分岐）
6. **616-688行目**: バイナリ検証
7. **690-814行目**: バイナリ置換処理
8. **817-833行目**: シェル補完更新

#### Step 3: バージョン情報取得

GitHub APIからのバージョン情報取得を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | upgrade_command.zig | `src/cli/upgrade_command.zig` | getLatestVersion()関数（89-305行目） |
| 3-2 | upgrade_command.zig | `src/cli/upgrade_command.zig` | API URL構築（121-129行目）でGitHubリポジトリを指定 |
| 3-3 | upgrade_command.zig | `src/cli/upgrade_command.zig` | レスポンスパース（186-290行目）でtag_nameとassetsを抽出 |

#### Step 4: ダウンロードと展開

バイナリのダウンロードと展開処理を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | upgrade_command.zig | `src/cli/upgrade_command.zig` | HTTP.AsyncHTTP.initSync（431-442行目）でダウンロード初期化 |
| 4-2 | upgrade_command.zig | `src/cli/upgrade_command.zig` | POSIX unzip処理（526-560行目） |
| 4-3 | upgrade_command.zig | `src/cli/upgrade_command.zig` | Windows PowerShell展開（561-614行目） |

#### Step 5: バイナリ置換

バイナリの置換処理を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | upgrade_command.zig | `src/cli/upgrade_command.zig` | selfExePath()でインストール先取得（691行目） |
| 5-2 | upgrade_command.zig | `src/cli/upgrade_command.zig` | Windows: リネーム方式（756-770行目） |
| 5-3 | upgrade_command.zig | `src/cli/upgrade_command.zig` | POSIX/Windows: moveFileZ（773行目） |

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

```
bun upgrade
    │
    ├─ cli.zig: Command.which()
    │      └─ "upgrade"を検出 → UpgradeCommand
    │
    └─ UpgradeCommand.exec()
           │
           ├─ パッケージ名チェック（誤用防止）
           │
           ├─ _exec()
           │      │
           │      ├─ HTTP.HTTPThread.init()
           │      │
           │      ├─ [stableモード]
           │      │      └─ getLatestVersion()
           │      │             ├─ GitHub API呼び出し
           │      │             └─ JSONパース (tag_name, assets)
           │      │
           │      ├─ [canaryモード]
           │      │      └─ 固定URL使用
           │      │
           │      ├─ HTTP.AsyncHTTP.sendSync() [zipダウンロード]
           │      │
           │      ├─ [POSIX]
           │      │      └─ unzip -q -o
           │      ├─ [Windows]
           │      │      └─ PowerShell Expand-Archive
           │      │
           │      ├─ bun --version [バイナリ検証]
           │      │
           │      ├─ [Windows]
           │      │      └─ 旧バイナリを.outdatedにリネーム
           │      │
           │      ├─ moveFileZ() [バイナリ置換]
           │      │
           │      └─ bun completions [シェル補完更新]
           │
           └─ [エラー時]
                  └─ 手動インストールコマンド案内
```

### データフロー図

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

コマンドライン引数     ───▶ フラグ判定                  ───▶ use_canary, use_profile
(--canary, --stable)        (canary/stable)

GitHub API            ───▶ getLatestVersion()          ───▶ Version構造体
(releases/latest)           JSONパース                      (tag, zip_url, size)

zip_url               ───▶ HTTP.AsyncHTTP              ───▶ zipバイト列
                            (プロキシ対応)

zipバイト列           ───▶ 一時ファイル書き込み        ───▶ /tmp/{version}/bun.zip

bun.zip               ───▶ unzip / Expand-Archive      ───▶ /tmp/{version}/bun-{platform}/bun

新bun                 ───▶ --version実行               ───▶ バージョン文字列
                            (検証)

新bun                 ───▶ moveFileZ()                 ───▶ {install_dir}/bun
                            (バイナリ置換)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| upgrade_command.zig | `src/cli/upgrade_command.zig` | ソース | upgradeコマンドのメイン実装 |
| cli.zig | `src/cli.zig` | ソース | CLIコマンドルーター |
| create_command.zig | `src/cli/create_command.zig` | ソース | initializeStore()関数を提供 |
| http.zig | `src/http.zig` | ソース | HTTPクライアント（AsyncHTTP） |
| env_loader.zig | `src/env_loader.zig` | ソース | 環境変数ローダー（プロキシ設定） |
| install_completions_command.zig | `src/cli/install_completions_command.zig` | ソース | シェル補完インストール |
